Muesli 0.1.3

Table of Contents


Next: , Previous: (dir), Up: (dir)

Muesli

This manual is for Muesli, version 0.1.3, a library for Multiple Utility, Evaluation and Scripting Languages Interface.

Copyright © 2008 Biocomputing-Developmental Systems Centre, University of Limerick, Ireland.

Muesli was initially developed as part of an Evolutionary Computation project, which is funded by Science Foundation Ireland. (The parent project is not yet released, but will be GPL'ed when it is released.)

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later versions published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled “GNU Free Documentation License”.


Next: , Previous: Top, Up: Top

1 Overview

Muesli is a library to interface an application to multiple programming language evaluators (normally, interpreters).


Next: , Previous: Overview, Up: Overview

1.1 Purpose

Muesli allows your program to call any one (or more) of a number of programming language interpreters through a consistent interface, such that you can choose the language to use at run-time.

It can be used anywhere where you want to use a scripting language but don't want to be restricted to any particular scripting language.

It was originally developed to support a Grammatical Evolution system, which evolves programs in any language by using a BNF grammar to convert bytestring chromosomes to program fragments as dictated by the grammar.


Previous: Purpose, Up: Overview

1.2 Installation

Muesli uses the GNU autotools system for building itself, so installation is very conventional. It builds into itself adaptors for any of its programming languages that it finds already installed when you configure it, so you must install the languages you want first.

  1. Install the languages you want to interface to, if they are not already provided on your system.
  2. Configure the system, by typing ./configure into a shell at the top level of the Muesli distribution tree.

    Inspect the output of the configure script more carefully than usual. You may well find that the configure script has failed to spot some of the languages installed. In the author's experience, the problem is usually that a language interpreter library has been installed with a version number, without a symbolic link from the corresponding name without a version number. You will have to do these manually (unless someone has written a library directory preener that the author is unaware of). Another possible problem is something being installed in a non-standard directory; making a symbolic link from a standard library directory will fix this. Having fixed these, re-run configure.

  3. Build the library, by typing make.
  4. As root, or using sudo, install the library by typing make install.


Next: , Previous: Overview, Up: Top

2 Introduction to Muesli

Muesli lets you find evaluators for programming languages (specified by name or by filename extension) and apply those evaluators to pieces of text, retrieving the results as numbers, strings or booleans. (Arrays, lists and maps are not yet supported, but probably should be in later versions.)

Muesli is a C library, so it should be possible to link it with programs written in a variety of languages. (The parts of Muesli that link to interpreters written in C++ are in C++, to get the right linkage.)

You will normally have to add extensions to each language to make it operate the internals of each application. You might find SWIG (http://www.swig.org) useful for this. Some such support for applications is built into Muesli, but you don't have to use it.

It supports:

Muesli provides some support for extending the languages to which it interfaces. (It is not, however, a wrapper generator.) Some extensions are provided as part of the system.


Next: , Previous: Introduction to Muesli, Up: Top

3 Language nesting

Muesli has a feature allowing a script to be written in a mixture of programming languages. This uses a modified string evaluator, that looks for language nesting markers and converts them to the appropriate syntax for the outer language to call the inner one. This is then applied recursively. It is perhaps best explained by an example:

(+ 3
  {{lua: return 4 *
    {{python: 2 * 6}}
  * 7 }}
)


Next: , Previous: Language nesting, Up: Top

4 Application Programming Interface

The interface to Muesli is a collection of C functions, along with some necessary type definitions.


Next: , Previous: Application Programming Interface, Up: Application Programming Interface

4.1 Initialization

To initialize Muesli, your application has to call

void
muesli_register_evaluators(void *new_app_params,
                           void *new_app_data,
                           option_handler_t params_handler,
                           struct option *getopt_options)

new_app_params’ is a pointer to a structure describing the command-line options given to your application, if you are putting them in such a structure. ‘new_app_data’ is a pointer to the root data structure of your application, if it has one. These are used for passing information to built-in procedures of the interpreters to which Muesli interfaces, including particularly any such procedures that you add for accessing your data. You don't have to work this way; you can keep your settings and data in lots of separate globals, and Muesli will not object.

params_handler’ is a function for setting and getting parameters such as those set on the command line or from a settings menu. See Parameter control.

getopt_options’ is a long options structure as used by ‘getopt’; this will probably be the one you were already using before converting your application to use Muesli. It will be made available to the option-related functions of each language interface.


Next: , Previous: Initialization, Up: Application Programming Interface

4.2 Adding your extensions

Typically, users of Muesli will need to add extra functions to each interpreter. To do this, write a function that adds those functions, then tell Muesli about that function by calling, for each evaluator:

void
muesli_set_evaluator_app_specializer(char *evaluator_name,
                                     evaluator_specializer_t
                                          specializer)

You can do this any time until you access the evaluator using ‘muesli_get_named_evaluator’. The type ‘evaluator_specializer_t’ describes a function which takes an ‘evaluator_interface’ structure as its argument, and extends the evaluator that that points to.

Each evaluator has two names, the language name and the implementation name. The name you should give for ‘evaluator_name’ is the implementation name, as a different specializer is likely to be needed for each implementation of a language.

The evaluator-independent macros ‘Muesli_Add_Fn_0’ to ‘Muesli_Add_Fn_5’ are available for adding ordinary functions to your evaluator interface. These functions, of course, must be evaluator-specific; we have simply abstracted out the action of defining a new builtin function. ‘Muesli_Add_Fn_V’ adds a builtin taking a variable number of arguments, and ‘Muesli_Add_Fn_N’ adds one that does not evaluate its arguments (like a `special form' in Lisp).


Next: , Previous: Adding extensions, Up: Application Programming Interface

4.3 Accessing evaluators

Having done this, you can get an ‘evaluator_interface’ structure for the language you want by calling

evaluator_interface *
muesli_get_named_evaluator(const char *evaluator_name,
                           int exit_if_not_found)

This does any initialization needed for the underlying interpreter.

Each evaluator has a language name and an implementation name. This function will find the evaluator using either of them. So, for example, the Guile evaluator can be found from the name “guile” or the name “scheme”.

To get the name of an evaluator corresponding to a filename extension, you can call

const char
*muesli_get_language_by_extension(const char *extension)


Next: , Previous: Accessing evaluators, Up: Application Programming Interface

4.4 Evaluating code fragments

Having got an ‘evaluator_interface’, you can evaluate things with it, by calling

muesli_value_t result =
  (my_evaluator->eval_string)(my_evaluator,
                              const char *program_fragment,
                              unsigned int fragment_length,
                              int transient);

where the result type is as declared in

typedef struct muesli_value_t {
  union {
    float as_float;
    const char *as_string;
    int as_int;
    int as_bool;
  } data;
  value_type_tag_t type;
  value_type_tag_t element_type;
  value_storage_t storage;
} muesli_value_t;

of which the ‘type’ field is defined thus:

typedef enum {
  muesli_value_none,
  muesli_value_float,
  muesli_value_integer,
  muesli_value_string,
  muesli_value_boolean,
  muesli_value_error
} value_type_tag_t;

The ‘element_type’ field is reserved for later use; it will be used when the main ‘type’ is an array type.

The ‘storage’ field is not yet used, but will later indicate who owns the memory used, for types that require memory allocation. It is defined thus:

typedef enum {
  private_storage,
  malloced_by_language,
  malloced_by_muesli
} value_storage_t;

When you declare a variable of type ‘muesli_value_t’, unless you fill it in immediately, you can make it explictly `empty' using the macro ‘ANULL_VALUE(v)’.

The fragment length is passed in as a separate argument, as Muesli does not assume that languages treat a null byte as a string terminator. In practice, many of the language implementations ignore this, and treat the program fragment as null-terminated anyway. If you are sure that all the languages you will be working with use null-terminated strings, you could pass in 0 (or anything else) here.

transient’ is a boolean, which if true indicates that the evaluation is not expected to have any side-effects. This may let the interpreter optimize it (by marking its memory allocation configuration, and returning to that configuration afterwards, avoiding garbage collection if possible). This is aimed at evaluation of individuals in Genetic Programming systems, which was the original application of Muesli.

For convenience, we also provide

muesli_value_t
muesli_eval_in_language(const char *language,
		        const char *fragment,
                        unsigned int fragment_length,
                        int transient)

This finds the necessary evaluator (initializing it if necessary) and applies it, without your program needing to hang on to evaluator structures.

If you always expect one particular type back from the fragment, to save you from writing a converter function with a switch statement each time, we provide the functions:

muesli_eval_to_WHATEVER(evaluator_interface *ev,
                        char *fragment,
                        unsigned int fragment_length,
                        int transient,
                        int *success_flag_p)

where WHATEVER can be any of string, float, int, or bool. These functions each have the appropriate return type.


Next: , Previous: Evaluating code, Up: Application Programming Interface

4.5 Loading files

To load a file using an evaluator interface, call

  (my_evaluator->load_file)(my_evaluator, filename);

To load a file by its extension, without having to find the evaluator interface yourself, you can call

void muesli_load_file(const char *filename)

This will analyze the filename and work out which evaluator to use.


Next: , Previous: Loading files, Up: Application Programming Interface

4.6 Closing down evaluators

Each evaluator interface structure provides a ‘close_evaluator’ function, which is called with the interface structure as its only argument.

There is also a function ‘muesli_close_evaluators()’ which closes all evaluators that have been initialized.

You may well not need to do any closedown; on the other hand, you may find it conceptually tidy.


Next: , Previous: Closing down evaluators, Up: Application Programming Interface

4.7 Extension built-in functions

Muesli extends each of its languages (except for those using separate processes) with a few extra built-in functions, for parameter control and for access to Muesli's own evaluation facilities. These extra functions can be used in programs / scripts in the interpreted languages.

You can also add your own extension functions; Muesli offers some support to make this more consistent between languages. You will need to write a version of each of your functions for each language that you want to use. You may find SWIG (http://www.swig.org/) useful for packaging the underlying functions into functions that each language can call.

Where the names of Muesli's own extensions are built from several natural-language words, the conventions of that programming language are followed for combining the words into an identifier. For example, `set parameter' becomes ‘set-parameter’ in Lisp-type languages, ‘SetParameter’ or ‘setParameter’ in CamelCasing languages, and ‘set_parameter’ in other languages.


Next: , Previous: Extension functions, Up: Extension functions

4.7.1 Parameter control

Muesli provides a language-neutral interface to your application's parameter settings (typically those parameters that can be set as command-line options or through a preferences dialog). This allows you to provide scripted access to parameters without having to write an interface for each scripting language.

When you initialize Muesli (see Initialization), you can pass in an option handler function, which is part of your application. This function contains your parameter-setting code, and may also be used in your command-line parsing. Muesli uses it as the internals of its ‘set-parameter’ and ‘get-parameter’ extension functions in each language. It is defined thus:

typedef muesli_value_t
(*option_handler_t)(void *params_block,
                    char opt,
                    char *value_string,
                    float value_number,
                    int set,
                    const char *from_language);

params_block’ is a structure defined by your application. ‘opt’ is an option character (as provided by ‘getopt’), ‘value_string’ is the value given for the option (and ‘value_number’ is the value as a number if appropriate, in which case ‘value_string’ should be ‘NULL’), and ‘set’ tells whether to set (otherwise, get) the option.

If ‘set’ is 0, the value of the option should be returned as the result. This result is then passed back to the script, by the language's ‘get parameter’ function.

from_language’ should be the name of the programming language from which the option is being set. It should be NULL when not being called from an interpreter (for example, when called when parsing the command line). This is partly so that you can insist on an option being given only once on the command line, while allowing it to be changed later from a script, and partly so that if some of your parameters hold scripting fragments, you can arrange for your system to know which language they are in, by assuming it is the same language from which the parameter was set.

Such an option handler function will typically be a wrapping around something that does a ‘switch’ statement using the result of ‘getopt’. It should generally be possible to use the same function from your application's command line argument parser, thus making the same options available on the command line and through all available scripting languages, without having to write a separate option setting function for each programming language.

You can then access your embedding application's parameters from a script through the Muesli API functions ‘muesli_set_parameter’ and ‘muesli_get_parameter’ which are wrapped as builtin extension functions in each interfaced language. (A few languages cannot do this, for example the pipe connection to an external program.) These functions appear as ‘(set-parameter param value)’ and ‘(get-parameter param)’ in Lisp-style languages, ‘SetParameter(parameter, value)’ and ‘GetParameter(parameter)’ in CamelCasing languages, and ‘set_parameter(parameter, value)’ and ‘get_parameter(parameter)’ in other languages.

Languages with table, hash, map, dictionary or other associative array data types may also implement extension functions to return all parameters as a table, and to modify multiple parameters from a table. These functions will be called ‘parameters’ and ‘modify parameters’ in the syntax appropriate for that language.


Next: , Previous: Parameter control, Up: Extension functions

4.7.2 Calling other evaluators

Just as your application can use Muesli to call code fragments in a variety of languages, those fragments can use Muesli likewise, through wrappings of the function ‘muesli_eval_in_language’, which appear as ‘(eval-in-language language script)’, ‘eval_in_language(language, script)’, or ‘EvalInLanguage(language, script)’ according to the syntax of the calling language.


Previous: Calling other evaluators, Up: Extension functions

4.7.3 Adding your own native functions

Having called ‘muesli_register_evaluators’, you can then call ‘muesli_set_evaluator_app_specializer(language_name, function)’, which tells Muesli that when the specified language is initialized, that function is to be run to add any application-specific language extensions. The function is called with one argument, a pointer to an ‘evaluator_interface’ structure.

Muesli defines some macros for use in such functions. ‘Muesli_Add_Fn_0’ through to ‘Muesli_Add_Fn_5’ add a function with the corresponding number of arguments; ‘Muesli_Add_Fn_V’ adds a function with a variable number of arguments; and ‘Muesli_Add_Fn_N’ adds a function which requires its arguments unevaluated (in Lisp terms, a “special form”).

These macros take three arguments: a pointer to the interface structure, the function name, and the function itself.

They are implemented using the ‘add_function’ slot of the interface structure, and so can only be used for language interfaces which provide such a function.


Next: , Previous: Extension functions, Up: Application Programming Interface

4.8 Interactive use

Muesli provides a basic Read-Eval-Print Loop (REPL) for any language, in the function ‘muesli_evaluator_repl’, which takes one argument, the name of the language to interpret.


Next: , Previous: Interactive use, Up: Application Programming Interface

4.9 Listing and querying

The function

int
muesli_print_interpreter_names(FILE *stream,
                               const char *format,
                               const char *selected_name,
                               const char *selected_flag,
			       unsigned int *widest_language_return,
                               unsigned int *widest_implementation_return);

will list the interpreter names to stream using format, which should contain ‘%s’ where the language name is to appear and another ‘%s’ where the implementation name is to appear. If selected_name is non-NULL, if one of the names is equal to selected_name, selected_flag is printed after it if there is a second ‘%s’ in the format (or the string ‘" (selected)"’ is used if selected_flag is NULL).

The return value is the number of language implementations found.

widest_language_return’ and ‘widest_implementation_return’, if non-NULL, are pointers to variables to fill in with the width of the longest language name and the longest implementation name.

If you pass in NULL as the value of ‘stream’, this function will count the implementations and work out the maximum name lengths, but not print anything. You can use this to work out column widths for a columnar listing of the languages. The demo program muesli-demo.c contains an example of this.

If you just want to check whether a particular language is supported on your system, you can call

int muesli_evaluator_is_defined(const char *evaluator_name)


Previous: Listing and querying, Up: Application Programming Interface

4.10 Testing

You can test the installation by calling this function from a program:

int test_evaluators(int seconds);

This evaluates a simple expression in each language for the given number of seconds, and reports back how many times it evaluated the expression for each language. (The expressions are all the same calculation, expressed in the relevant syntax for each language.) If the number of seconds is zero (or less), it does a one-off test of each evaluator.


Next: , Previous: Application Programming Interface, Up: Top

5 Languages supported

Muesli's language interfaces are in a range of stages of implementation (initially according to the needs of the project from which Muesli was split).

Erlang erlangPlaceholder A language with deep support for concurrency
exec execComplete Execs an external program, and reads its result from its stdout.
GhostScript ghostscriptPlaceholder A PostScript-compatible language
Guile guileComplete A Scheme interpreter; the official extension language of the GNU project. Available from http://www.gnu.org/software/guile/.
Haskell haskellComplete Uses an external process (based on the ‘pipe’ evaluator), so cannot support extensions for applications
JavaScript javascriptIncomplete JavaScript (SpiderMonkey implementation); see http://www.mozilla.org/js/spidermonkey/
Common Lisp lispComplete Uses an external process (based on the ‘pipe’ evaluator), so cannot support extensions for applications
Lua luaComplete http://www.lua.org/ Needs readline, ncurses libraries.
Octave octaveComplete The Octave maths language, similar to Matlab; see http://www.gnu.org/software/octave/
Perl perlIncomplete See http://www.perl.com/
pipe pipeComplete This evaluator starts up a program in another process with pipes to and from it, and sends the strings to evaluate to it and gets the result from it.
Prolog prologNot ready The Programming in Logic language, SWI implementation; see http://www.swi-prolog.org/
Python pythonComplete The Python language, see http://www.python.org/
R RIncomplete The R statistical language, similar to S
Ruby rubyPlaceholder The Ruby language, see http://www.ruby-lang.org/
SIOD siodComplete A small Scheme interpreter (Scheme In One Day), available from http://people.delphiforums.com/gjc/siod.html, or in an extended version from http://www.nongnu.org/muesli/ulsiod.html
Slang s-langNot ready S-lang, see http://www.s-lang.org/
Smalltalk smalltalkPlaceholder A classic object-oriented language
libtcc tccNot ready Tiny C Compiler, available from http://www.tinycc.org/
Tcl tclComplete Tool Control Language, available from http://www.tcl.tk/doc/

Muesli supports some further evaluators that are not conventional textual programming languages. The interface to these is extended to cover supplying argument values separately, as they cannot realistically be put in using ‘sprintf’.

stack-bytecode stack-codeComplete A fast and light byte-coded stack interpreter built into Muesli.
Parrot parrotPlaceholder Execute Parrot bytecodes
JVM jvmPlaceholder Execute JVM bytecodes
machine-code machineComplete Calls blocks of machine code directly.
custom customTemplate A stub interface for the application programmer to use as the base for a custom interface (e.g. to special hardware, or to a neural network emulator); may also be used as the template for new language interfaces.
zero zeroComplete Always returns 0. This is the evaluator_interface equivalent of /dev/zero or /dev/null. It's extremely fast, so we use it as the baseline for timing tests of the other evaluators.

Detailed notes on each language interface follow, including information about what has been done and what still needs to be done on each.


Next: , Previous: Languages supported, Up: Languages supported

5.1 Binary languages

Most of the languages supported by Muesli are conventional, textual, programming languages, in which program fragments are typically human-readable ASCII strings.

For faster evaluation of code fragments, Muesli also provides `binary' evaluators, whose languages are not textual. They are provided because Muesli was originally written to support an evolutionary programming system, which has the option of producing machine code or bytecodes for speed.

The `binary' evaluators need to have any arguments passed to them by special means, as they cannot be embedded using ‘snprintf’ as is possible for textual evaluators.

As well as the actual binary evaluators, Muesli provides a half-way house, called `stack code', which is a simple byte-code stack-based interpreted language in which all the bytecodes are printable ASCII characters and generally have some mnemonic value. This is meant as a stand-in for machine code while developing the areas of the application that normally work with Muesli and machine code.


Next: , Previous: Binary languages, Up: Binary languages

5.1.1 stack-code

The stack-based bytecode evaluator is one written specially for Muesli's parent application, and is designed to be fast, simple, and to have a lot in common with the machine-code evaluator. (In fact it was originally written to exercise the parts of the system surrounding machine-code evaluation, before using actual machine-code.)

Each character in the program string is an instruction. Whitespace characters are no-ops.

a-zPush a number, 0..25 respectively, onto the stack, typically for use as a register number or function number
0-9If the previous instruction was not a digit, push this digit onto the stack; if the previous instruction was a digit, multiply the number at the top of the stack by ten, and add this digit.
<Pop a register number, then pop a value into that register
>Pop a register number, then push the contents of that register
=Duplicate the top item of the stack
_Pop an item from the stack
:Exchange the top two items of the stack
+Take two numbers from the stack, and push their sum
- Take two numbers from the stack, and push their difference
*Take two numbers from the stack, and push their product
/Take two numbers from the stack, and push the second divided by the first
\Take two numbers from the stack, and push the first divided by the second
&Take two numbers from the stack as booleans (0.0 is false, anything else is true) and push their conjunction (`and' function)
|Take two numbers from the stack as booleans (0.0 is false, anything else is true) and push their disjunction (`or' function)
~Take one number from the stack as a boolean (0.0 is false, anything else is true) and push its negation (`not' function)
?Use the number on the top of the stack as an index into 4-byte sized units in the application variables, and fetch a float from there and replace the number on the top of the stack with it
!Execute a numbered function (see separate table, below)
.Return from the program, returning the value on the top of the stack
#Skip until the next newline character. This is a way of inserting comments into your stack-code program, but with cost at run-time.

The following table lists the functions callable through the ‘!’ operator, and the initial values of registers (the other registers start with 0.0 in them).

0 aAtan
2 cCos
3 dacos
4 eexp e
11 lLog
14 o 1.0 (one)
15 p pi
17 r sqrt(2)
18 sSin
19 tTan 2.0 (two)
20 uatan2
21 vasin

There is a mechanism by which you can add to, or replace, these functions, but that currently requires C programming (a call to ‘stack_bytecode_add_app_fn’). Most of the built-in ones are inlined into the stack-code interpreter, and as the stack-code interpreter is a single C function, written for speed, this is probably the next-best to machine code for speed.


Next: , Previous: stack-code, Up: Binary languages

5.1.2 machine


Next: , Previous: machine, Up: Binary languages

5.1.3 Parrot

Not yet supported.


Previous: Parrot, Up: Binary languages

5.1.4 JVM

Not yet supported.


Next: , Previous: Binary languages, Up: Languages supported

5.2 Common Lisp

This uses the pipe evaluator to talk to a Common Lisp sub-process, by default sbcl. See pipe.

You can override the choice of Lisp system with the environment variable COMMON_LISP.

Your application should be sure to call the ‘close_evaluator’ function of the interface before it quits; otherwise the Lisp process will be left running.

The Lisp evaluator currently only looks for a number as the result.


Next: , Previous: Common Lisp, Up: Languages supported

5.3 custom

The ‘custom’ evaluator interface doesn't contain an evaluator: it is just a stub interface for you to fill in with your own evaluator.

Possible applications of this include interfacing to neural nets, or to special hardware.

You can also use it as a template for starting a new language interface.

Anyway, if you want to be doing this kind of stuff, you'll be working on the source code, so should be reading the source, muesli-custom.c (which is commented), not the documentation, so that's the end of this documentation section.


Next: , Previous: custom, Up: Languages supported

5.4 Erlang

Not yet supported (but it has an interpreter library, which we detect in the configuration script).


Next: , Previous: Erlang, Up: Languages supported

5.5 exec

The ‘exec’ evaluator splits the text of the code fragment into separate arguments at whitespace (quotes may be used to include whitespace in an argument), to make an ‘argv’-style array. If the ‘underlying_program’ field of the evaluator is non-nil, it is used for ‘argv[0]’, and the elements of the code fragment are used for ‘argv[1]’ onwards; if ‘underlying_program’ is null, all the ‘argv’ elements come from the code fragment.

The external program named in ‘argv[0]’ is then run, with the remaining elements as its command-line arguments.

The program should output its result onto standard output, as the first number it outputs within the first 1024 bytes of output (any further output is ignored). This version of Muesli only looks for a number coming back from the program, as it comes from a Genetic Programming background, and so is looking for a fitness score.


Next: , Previous: exec, Up: Languages supported

5.6 GhostScript

Not yet supported (but it has an interpreter library, which we detect in the configuration script).


Next: , Previous: GhostScript, Up: Languages supported

comment node-name, next, previous, up

5.7 Guile

Guile is an implementation of Scheme, and is the official extension language of the GNU project.


Next: , Previous: Guile, Up: Languages supported

5.8 Haskell

This uses the pipe evaluator to talk to a Haskell sub-process, by default hugs. See pipe.

You can override the choice of Haskell system with the environment variable HASKELL.

Your application should be sure to call the ‘close_evaluator’ function of the interface before it quits; otherwise the Haskell process will be left running.

The Haskell evaluator currently only looks for a number as the result.


Next: , Previous: Haskell, Up: Languages supported

5.9 JavaScript

Complete except for multiple parameter setting / getting.


Next: , Previous: JavaScript, Up: Languages supported

5.10 Lua

The Lua interface is reasonably complete.

There are exciting possibilities for further work, using the language's `meta-tables' feature to make the table returned by the ‘parameters’ builtin function be `live' data, so that if the script using it changes it, the parameters in the application are set accordingly by calling ‘set_parameter’.


Next: , Previous: Lua, Up: Languages supported

5.11 Octave

Supported. Uses Octave `structures' for multiple parameters.


Next: , Previous: Octave, Up: Languages supported

5.12 Perl

The Perl interface isn't complete. It does initialize, and evaluate strings, and it has extension functions for single parameters, for calling other languages, and for calling the custom evaluator. No file loading yet, and no bulk parameter handling yet.


Next: , Previous: Perl, Up: Languages supported

5.13 pipe

You need to give this one some extra information, to determine the program to connect to and how to talk to it. This extra information is stored in the ‘evaluator_interface’ structure, as follows:

  char *underlying_program;
  char *underlying_startup_string;
  char *underlying_prompt_string;
  char *underlying_shutdown_command;

You can set these directly (this is C,and styled as C, not C++).

The ‘pipe’ evaluator starts an external program, named by ‘underlying_program’, connected to Muesli by a pair of pipes, and sends each individual to it, and reads the returning bytestream to find a number, which is used as the result.

This is intended to allow external language systems, such as SBCL (Common Lisp) to be used for the evaluator (it is copied and filled in to make the Lisp (see Common Lisp) and Haskell (see Haskell) evaluator interfaces); but it could be used in other ways; any program that reads pieces of text and replies with numbers could be used.

The program should output its result onto standard output. Muesli reads the program's output for the result, then searches it for an occurrence of its ‘underlying_prompt_string’ if one is given, so that the prompt is not mistaken for part of the next result.

The pipe evaluator currently only looks for a number as the result.

You can set an ‘underlying_startup_string’, which is searched for when the application starts. You need to do this if, and only if, the application outputs either any numbers, or any occurrences of the ‘underlying_prompt_string’, during its startup.

Your application should be sure to call the ‘close_evaluator’ function of the interface before it quits; otherwise the child process will be left running.


Next: , Previous: pipe, Up: Languages supported

5.14 Prolog

In progress, using the embeddable library of SWI Prolog. Unfortunately this doesn't seem to provide a C interface to executing a textual piece of Prolog.

Most of the symbols defined by this interpreter library are sensibly prefixed, but ‘warning’ clashes with tcc. I've got round that by adding the line

#define warning pl__warning

to src/pl-incl.h before compiling this library.


Next: , Previous: Prolog, Up: Languages supported

5.15 Python

Now seems to be working; please thrash it and let me know how it holds up.


Next: , Previous: Python, Up: Languages supported

5.16 R

Not yet supported (but it has an interpreter library, which we detect in the configuration script).

Some of the coding is done, but there is a crashing bug as it initializes, looking for directory.


Next: , Previous: R, Up: Languages supported

5.17 Ruby

Not yet supported (but it has an interpreter library, which we detect in the configuration script).


Next: , Previous: Ruby, Up: Languages supported

5.18 S-lang

Being worked on.


Next: , Previous: S-lang, Up: Languages supported

5.19 SIOD

SIOD is usually the most complete of our interfaces, as it was the first, and is also de-facto the main scripting language for Muesli's original application. This is probably the best place to look for reference when adding or completing further language interfaces.

Rather than using the original distribution of SIOD, we recommend that you use our lightly modified one, ULSIOD (University of Limerick SIOD), which has all its internal functions renamed to start with the prefix ‘siod_’. This avoids clashes with names in other evaluators. (The one we first hit was ‘load’, which is also defined in tcc.)

In fact, the connection to the original SIOD is now languishing, and may be withdrawn.


Next: , Previous: SIOD, Up: Languages supported

5.20 Smalltalk

Not yet supported; I hope to use syx (Smalltalk YX) which is documented as being embeddable.


Next: , Previous: Smalltalk, Up: Languages supported

5.21 tcc

The tcc interface isn't complete, and needs some more thought, as tcc works differently from normal interpreters: each time it is called to evaluate some code, a new instance of tcc is created. This spoils our assumption that you can pre-load your language with useful functions from a file, ready to call from your code fragments. There's sure to be a way round this, I just haven't had the time to do so.


Previous: tcc, Up: Languages supported

5.22 Tcl

The Tcl interface has a slightly different format for the ‘parameters’ call: it must be provided with a table to fill in.


Next: , Previous: Languages supported, Up: Top

6 Status

This chapter gives the status of each language implementation, so you can see which features you should expect to work in each language. It's also for use by the maintainers, to see what still needs to be done.

In the table below, the columns represent these features:

Init Initialize
Eval Evaluate string
Load Load file
Param Set / Get parameters singly
Params Set / Get parameters to / from table
EvLang Evaluate in (other) language
Cus Call custom evaluator

The possible status values are:

Y Done
0.5 Half-done
- Not yet done
n/a Not applicable
U You fill this in to suit your application

Name Init Eval Load Param Params EvLang Cus
custom U U U U U U n/a
Erlang - - - - - - -
exec Y Y n/a n/a n/a n/a n/a
ghostscript - - - - - - -
guile Y Y Y Y Y Y Y
haskell Y Y Y n/a n/a n/a n/a
javascript Y Y - 0.5 - - -
jvm - - - - - - -
lisp Y Y Y n/a n/a n/a n/a
lua Y Y Y Y Y Y Y
machine Y Y n/a - - - -
octave Y Y Y Y Y Y Y
parrot - - - - - - -
perl Y Y - Y - Y Y
pipe Y Y Y n/a n/a n/a n/a
prolog - - - - - - -
python Y Y Y Y Y Y Y
R - - - - - - -
ruby - - - - - - -
s-lang Y 0.5 Y Y - Y Y
siod Y Y Y Y Y Y Y
Smalltalk Y - - - - - -
stack-code Y Y Y - - - -
tcc - Y Y - - - -
tcl Y Y Y Y Y Y Y
zero Y Y n/a n/a n/a n/a n/a


Next: , Previous: Status, Up: Top

7 Planned further work

The list of planned further work on Muesli is held in Muesli's task tracker at https://savannah.nongnu.org/task/?group=muesli.


Next: , Previous: Future plans, Up: Top

8 Examples

An annotated example application is provided in the distribution, in the source file muesli-demo.c.


Next: , Previous: Examples, Up: Top

Appendix A Frequently Asked Questions


Next: , Previous: FAQ, Up: Top

Appendix B Copying This Manual

B.1 GNU Free Documentation License

Version 1.2, November 2002
     Copyright © 2000,2001,2002 Free Software Foundation, Inc.
     59 Temple Place, Suite 330, Boston, MA  02111-1307, USA
     
     Everyone is permitted to copy and distribute verbatim copies
     of this license document, but changing it is not allowed.
  1. PREAMBLE

    The purpose of this License is to make a manual, textbook, or other functional and useful document free in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others.

    This License is a kind of “copyleft”, which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software.

    We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.

  2. APPLICABILITY AND DEFINITIONS

    This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The “Document”, below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as “you”. You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law.

    A “Modified Version” of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language.

    A “Secondary Section” is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document's overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them.

    The “Invariant Sections” are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none.

    The “Cover Texts” are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words.

    A “Transparent” copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modification by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not “Transparent” is called “Opaque”.

    Examples of suitable formats for Transparent copies include plain ascii without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, PostScript or PDF designed for human modification. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for output purposes only.

    The “Title Page” means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, “Title Page” means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text.

    A section “Entitled XYZ” means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific section name mentioned below, such as “Acknowledgements”, “Dedications”, “Endorsements”, or “History”.) To “Preserve the Title” of such a section when you modify the Document means that it remains a section “Entitled XYZ” according to this definition.

    The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License.

  3. VERBATIM COPYING

    You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3.

    You may also lend copies, under the same conditions stated above, and you may publicly display copies.

  4. COPYING IN QUANTITY

    If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Document's license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects.

    If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages.

    If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public.

    It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.

  5. MODIFICATIONS

    You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version:

    1. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission.
    2. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement.
    3. State on the Title page the name of the publisher of the Modified Version, as the publisher.
    4. Preserve all the copyright notices of the Document.
    5. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.
    6. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below.
    7. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document's license notice.
    8. Include an unaltered copy of this License.
    9. Preserve the section Entitled “History”, Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled “History” in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence.
    10. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the “History” section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission.
    11. For any section Entitled “Acknowledgements” or “Dedications”, Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein.
    12. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles.
    13. Delete any section Entitled “Endorsements”. Such a section may not be included in the Modified Version.
    14. Do not retitle any existing section to be Entitled “Endorsements” or to conflict in title with any Invariant Section.
    15. Preserve any Warranty Disclaimers.

    If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version's license notice. These titles must be distinct from any other section titles.

    You may add a section Entitled “Endorsements”, provided it contains nothing but endorsements of your Modified Version by various parties—for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard.

    You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one.

    The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version.

  6. COMBINING DOCUMENTS

    You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers.

    The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work.

    In the combination, you must combine any sections Entitled “History” in the various original documents, forming one section Entitled “History”; likewise combine any sections Entitled “Acknowledgements”, and any sections Entitled “Dedications”. You must delete all sections Entitled “Endorsements.”

  7. COLLECTIONS OF DOCUMENTS

    You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects.

    You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.

  8. AGGREGATION WITH INDEPENDENT WORKS

    A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an “aggregate” if the copyright resulting from the compilation is not used to limit the legal rights of the compilation's users beyond what the individual works permit. When the Document is included an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document.

    If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Document's Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate.

  9. TRANSLATION

    Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warrany Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail.

    If a section in the Document is Entitled “Acknowledgements”, “Dedications”, or “History”, the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title.

  10. TERMINATION

    You may not copy, modify, sublicense, or distribute the Document except as expressly provided for under this License. Any other attempt to copy, modify, sublicense or distribute the Document is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.

  11. FUTURE REVISIONS OF THIS LICENSE

    The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See http://www.gnu.org/copyleft/.

    Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License “or any later version” applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation.


Next: , Previous: Copying This Manual, Up: Top

Appendix C References


Previous: References, Up: Top

Concept Index

Function Index