• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

docs/H03-May-2022-4,2402,503

spec/H03-Aug-2021-265234

src/H03-Aug-2021-54,33145,661

.gitignoreH A D03-Aug-2021247 3029

LICENSEH A D03-Aug-20211 KiB2217

MakefileH A D03-May-20223.3 KiB151118

README.mdH A D03-Aug-20217.7 KiB169123

build.rabsH A D03-May-2022141 96

builddocs.shH A D03-Aug-2021111 52

common.rabsH A D03-Aug-20212.3 KiB9581

editor.miniH A D03-Aug-20212.9 KiB120119

README.md

1# Minilang is a small extensible scripting language for embedding in C/C++ applications
2
3Minilang is a simple language designed to be embedded into C/C++ applications with minimal fuss and maximum effect.
4
5## Key Features
6
7Minilang was designed from the ground up to be embedded into C/C++ applications. As a result, it has a rich API for embedding that support a wide range of use cases.
8
9### Minimal Dependencies
10
11Minilang only has one required dependency, the [Hans-Boehm conservative garbage collector](https://github.com/ivmai/bdwgc), which is commonly available in the standard repositories of most Linux distributions, in Homebrew on macOS and easily built from source.
12
13### Code Safety
14
15Minilang's VM is safe, there is no way to access raw memory to perform unsafe type-casting, indexing operations are bounds checked, arguments to internal functions are type-checked, etc. Minilang only provides core functionality by default, and does not provide file or network functions, module loading, or any other potentially unsafe functions.
16
17### Extensible
18
19Although Minilang's core functionality is intentionally restricted, functionality can be easily added by the host application, either globally or each time Minilang code is loaded. For example, there is no built-in `print()` function, one must be added by the host application. This extra step means that the `print()` function can write to a file or log instead if desired, or even send text across a websocket to display in a browser.
20
21### Flexible Code Loading
22
23The C API provides functions for incremental source code loading, allowing Minilang to be used for interactive sessions such as REPL shells and notebooks as well as loading complete Minilang code from files, databases, etc.
24
25### Source Level Debugging
26
27The C API also provides features for source level debugging of Minilang code. The host application can specify a debugger when running any function and the VM will invoke the debugger at breakpoints, errors, etc. The debugger API is flexible, debugging can be implementing in a console, desktop GUI or even across a network.
28
29### Stackless Execution and One-Shot Continuations
30
31Minilang uses a stackless VM for execution. Moreover, every function call passes the calling state to the called function, returns are implemented by resuming the calling state. This provides a number of additional features:
32
33* **Inline Asynchronous Calls** Any Minilang function call can be asynchronous without any change in the calling code.
34* **Parallel Asynchronous Calls** Multiple asynchronous calls can also be launched in parallel, with the calling state resumed automatically when all the calls have completed. Minilang is thus suitable for scripting complex workflows in distributed applications.
35* **Preemptive Multitasking** Minilang can optionally use a scheduler to swap the running VM state.
36
37### Per-Context Settings
38
39Every Minilang state has an associated context which is inherited by default from the calling state but can be explicitly set by the host application. The context stores local settings such as the current debugger, preemptive scheduler, etc. The host application can register additional context settings.
40
41### Multi-tenant Support
42
43Combining all of the above features, Minilang is ideal for multi-tenant distributed applications.
44
45## History
46
47Minilang was originally designed for [Rabs](https://github.com/wrapl/rabs), an imperative
48parallel build system. As result, it was designed with the following requirements:
49
50* **Minimal dependencies:** Minilang only has one required dependency, the [Hans-Boehm conservative garbage collector](https://github.com/ivmai/bdwgc), which is commonly available in the standard repositories of most Linux distributions, in Homebrew on macOS and easily built from source.
51* **Allow callbacks for identifier lookups:** This allows build functions in Rabs to use dynamic (context aware) scoping.
52* **Easy to add functions in C:** It is easy to add new functions to Minilang as required.
53* **Easy to store Minilang objects in C:** References to build functions can be easily stored and called when required.
54* **Full support for closures:** Closures (functions which capture their surrounding scope) make complex build functions simpler to write and store.
55* **Closures are hashable:** Checksums can be computed for Minilang functions (using SHA256) in order to check if a target needs to be rebuilt.
56
57Additional features have been added since the original use in Rabs.
58
59* **Configurable builds** Minilang can be built with Rabs (as well as Make) enabling several optional features as desired.
60* **Module system** Minilang files can be loaded as modules, with imports and exports.
61* **Gnome introspection suppport** Minilang can be built with support for Gnome introspection, providing automatic bindings for a wide range of libraries including GUI, networking, etc.
62* **Continuation based implementation** Function calls are implemented using one-short continuation based approach. This adds (optional) support for the following:
63  - **Asynchronous calls**
64  - **Cooperative multitasking**
65  - **Preemptive multitasking**
66
67## Simple example
68
69> example1.c
70
71```c
72#include <stdio.h>
73#include <minilang/minilang.h>
74
75static ml_value_t *print(void *Data, int Count, ml_value_t **Args) {
76	ml_value_t *StringMethod = ml_method("string");
77	for (int I = 0; I < Count; ++I) {
78		ml_value_t *Result = Args[I];
79		if (Result->Type != MLStringT) {
80			Result = ml_simple_call(StringMethod, 1, &Result);
81			if (Result->Type == MLErrorT) return Result;
82			if (Result->Type != MLStringT) return ml_error("ResultError", "string method did not return string");
83		}
84		fwrite(ml_string_value(Result), 1, ml_string_length(Result), stdout);
85	}
86	fflush(stdout);
87	return MLNil;
88}
89
90int main(int Argc, char **Argv) {
91	ml_init();
92	stringmap_t *Globals = stringmap_new();
93	stringmap_insert(Globals, "print", ml_cfunction(NULL, print));
94	ml_value_state_t *State = ml_value_state_new(NULL);
95	ml_load_file((ml_state_t *)State, (ml_getter_t)stringmap_search, Globals, "example1.mini", NULL);
96	if (State->Value->Type == MLErrorT) {
97		ml_error_print(State->Value);
98		exit(1);
99	}
100	ml_call((ml_state_t *)State, State->Value, 0, NULL);
101	if (State->Value->Type == MLErrorT) {
102		ml_error_print(State->Value);
103		exit(1);
104	}
105}
106```
107
108> example1.mini
109
110```lua
111for X in 1 .. 10 do
112	print('{X} ')
113end
114print('done.\n')
115```
116
117> output
118```sh
119$ gcc -o example1 example1.c -lminilang -lgc
120$ ./example1
1211 2 3 4 5 6 7 8 9 10 done.
122$
123```
124
125## Building
126
127### Using make
128
129```console
130$ git clone https://github.com/wrapl/minilang
131$ cd minilang
132$ make -j4
133$ make install PREFIX=/usr/local
134```
135
136This will build and install a vanilla version of Minilang in `PREFIX`.
137
138### Using Rabs
139
140```console
141$ git clone https://github.com/wrapl/minilang
142$ cd minilang
143$ rabs -p4 -DPREFIX=/usr/local install
144```
145
146This will build and install a vanilla version of Minilang in `PREFIX`.
147
148Additional options can be enabled when building Minilang with Rabs. For example, to enable GTK+ support, pass `-DGTK` when building.
149
150```console
151$ rabs -p4 -DPREFIX=/usr/local -DGTK install
152```
153
154Currently the following optional features are available:
155
156| Build Flags | Description |
157| --- | --- |
158| `-DMATH` | Adds additional maths functions, including multi-dimensional numeric arrays |
159| `-DGTK` | Adds Gnome introspection support |
160| `-DCBOR` | Adds support for serializing and deserializing Minilang values to/from CBOR |
161| `-DSCHEDULER` | Adds support for preemptive multitasking |
162| `-DMODULES` | Adds support for loading Minilang files as modules. Enables `-DSCHEDULER` |
163| `-DASM` | Uses assembly code implementations for certain features on supported platforms |
164| `-DTABLES` | Adds a table type (similar to a dataframe, datatable, etc). Enables `-DMATH` |
165| `-DQUEUES` | Adds a priority queue type |
166
167## Documentation
168
169Full documentation can be found [here](https://minilang.readthedocs.io).