Maude bindings for other languages¶
The maude
library is implemented using the Simple Wrapper and Interface Generator (SWIG), which allows generating bindings for some more languages other than Python. All the functionality of the Python library documented here is available through the same API to the other languages, although the Python instance includes several adaptations to its specific features and conventions (iterators, automatic conversion of data structures, default arguments, and so on) that may not match or not be implemented in the other targets. Furthermore, only the Python version has been extensively used and tested for the moment.
For building the library in a specific language, you should pass the appropriate value of the LANGUAGE
variable to the CMake build script. For example, to build the Java binding in the java-build
subdirectory of the source tree you should write:
$ cd java-build
$ cmake .. -DLANGUAGE=java
$ make
In general, this would generate some language-specific code and a binary plugin. For simplicity, we will use Linux file names like maude.so
for the plugin in the following explanations, but the extension would be dll
in Windows, dylib
in macOS, etc.
To avoid building Maude itself by reusing an already compiled version of Maude as a library, the option -DBUILD_LIBMAUDE=OFF
may be useful. More information is available in the repository.
Java¶
For building the Java binding, pass -DLANGUAGE=java
to CMake and make the generated project. This yields a shared library libmaudejni.so
and a JAR file maudejni.jar
including all the Java classes in the bindings. When running Java, maudejni.jar
should be included in the class path and libmaudejni.so
in the library path. For example, to run the following piece of code with libmaudejni.so
in the current directory in Linux, run
$ javac -cp maudejni.jar Example.java
$ LD_LIBRARY_PATH=. java -cp libmaude.jar:. Example
The method System.loadLibrary
should be called before using any function in the language bindings.
import es.ucm.maude.bindings.*;
public class Example {
public static void main(String[] args) {
System.loadLibrary("maudejni");
maude.init();
var m = maude.getModule("NAT");
Term t = m.parseTerm("2 * 3");
t.reduce();
System.out.println(t);
}
}
Unless you have set the JAVA_PACKAGE_NAME
CMake variable otherwise, all classes in the library will belong to the es.maude.ucm.bindings
package.
C#¶
For building the C# binding, pass -DLANGUAGE=chsarp
to CMake, build the project, and then compile the generated .cs
with the C# implementation of choice. The machine-code library libmaudecs.so
is generated by the build system. The user may also generate a .NET assembly out of the C# code to better distribute the bindings. For example, the following code works with Mono
$ cmake .. -DLANGUAGE=csharp
$ make
$ mcs *.cs -target:library -out:maudecs.dll
and produces an assembly maudecs.dll
that should be referenced when compiling the desired C# program and will be used when running it.
$ mcs -r:maudecs.dll elsewhere/Main.cs
$ mono Main.exe
All classes of the Maude library are gathered in the Maude
namespace.
using System;
using Maude;
class Example
{
public static void Main()
{
maude.init();
var m = maude.getModule("NAT");
var t = m.parseTerm("2 * 3");
t.reduce();
Console.WriteLine(t);
}
}
Guile¶
Guile is an implementation of Scheme, a dialect of Lisp.
For building the binding, pass -DLANGUAGE=guile
to CMake. Native module linkage is used by default, but this can be changed in the CMakeLists.txt
file. Generating an object-oriented module with GOOPS is also possible, see Swig’s documentation on Guile for the details.
Finally, load the generated module as shown below within Guile (maude.so
is assumed to be in the current working directory).
(load-extension "./maude" "scm_init_maude_module")
(use-modules (maude))
(init)
(define m (getModule "NAT"))
(define t (Module-parseTerm m "2 * 3"))
(Term-reduce t)
(display (Term-toString t))
(newline)
Javascript¶
Javascript modules can be generated for Node, JavaScriptCore, and V8. The CMake build script only supports the first two, with -DLANGUAGE=node
and -DLANGUAGE=jsc
respectively. Moreover, the second case requires some manual intervention. Swig does not work out of the box with the most recent versions of Node.
var maude = require('maude')
maude.init()
var m = maude.getModule('NAT')
var t = m.parseTerm('2 * 3')
t.reduce()
console.log(t.toString())
Lua¶
For building the binding as a dynamic Lua module, simply pass -DLANGUAGE=lua
to CMake. For building a Lua interpreter statically linked to the bindings, see Swig’s documentation on Lua.
Finally, run Lua with the generated maude.so
in the package path, and load it with require("maude")
.
require("maude")
maude.init()
m = maude.getModule("NAT")
t = m:parseTerm("2 * 3")
t:reduce()
print(t)
R¶
For building the R binding, simply pass -DLANGUAGE=r
to CMake. Two files are produced, maude.so
and maude.R
. The library is loaded into R as shown below.
dyn.load(paste("maude", .Platform$dynlib.ext, sep=""))
source("maude.R")
cacheMetaData(1)
init()
m = getCurrentModule()
t = m$parseTerm('1 + 2')
t$reduce()
print(t$show())
Tcl¶
For building the Tcl binding as a dynamic module, simply pass -DLANGUAGE=tcl
to CMake. The generated maude.so
should be loaded with load
in Tcl.
load ./maude.so
init
set m [getModule "NAT"]
set t [$m parseTerm "2 * 3"]
$t reduce
puts [$t toString]