Skip to the content.

Getting started

You will end this page with a C++ program that runs one line of script and prints hello.

Install

CMake, with this repo as a subdirectory:

add_subdirectory(ReScripted)
target_link_libraries(your_app PRIVATE ReScripted::ReScripted)

Without CMake: copy include/ReScripted.h onto your include path. Compile as C++17.

There is no .a or .so to link. The header is the library.

Four calls, every time

Every ReScripted program does the same four things:

  1. Engine engine — the object that holds languages, C++ functions, and loaded scripts
  2. engine.add_language(...) — “scripts in this language look like this”
  3. engine.bind("print", ...) — “when a script says print, run this C++”
  4. engine.eval(...) or load / run — run a script

A program that prints hello

This is Mini: let, fn, { }, ;. Copy the whole thing. It should print hello.

#include <ReScripted.h>
#include <iostream>

int main() {
    rescripted::Engine engine;

    // JSON: what Mini scripts look like. Compiled into this program.
    engine.add_language(RESCRIPTED_LANGUAGE(R"({
        "name": "Mini",
        "extensions": [".mini"],
        "variables": {
            "enabled": true,
            "declaration_keywords": ["let"],
            "assignment_operators": ["="]
        },
        "functions": {
            "enabled": true,
            "declaration_keywords": ["fn"],
            "return_keywords": ["return"]
        },
        "tokens": { "statement_terminators": [";"] },
        "blocks": { "delimiter": { "enabled": true, "open": "{", "close": "}" } },
        "entry_point": { "top_level_execution": true }
    })"));

    // Built-in print only returns a string. This one writes to the console.
    engine.bind("print", [](const std::vector<rescripted::Value>& args) {
        for (const auto& arg : args) {
            std::cout << arg.to_string() << '\n';
        }
        return rescripted::Value();
    });

    engine.eval("print(\"hello\");", "Mini");
}

What each part is:

This short JSON is enough for hello world. A language you ship should be a full file — copy examples/mini/mini.json or see Language JSON.

A script as a file

eval is for one-liners. Real scripts live on disk.

Part of examples/mini/hello.mini:

let greeting = "hello from Mini";
print(greeting);

fn shout(name) {
    return "hey " + name;
}

examples/mini/host.cpp (trimmed):

engine.add_language(rescripted::Language::compile(rescripted::embed::mini));

engine.bind("print", /* same lambda as above */);

auto id = engine.load_file("hello.mini");  // parse; shout now exists
engine.run(id);                            // greeting is set; print runs
engine.call("shout", {rescripted::Value("world")});  // "hey world"
engine.unload(id);                         // greeting and shout are gone

print is still there after unload. Host functions are not part of the script.

How rescripted::embed::mini gets into the program is the next page.

Next

The working copy of this setup is examples/mini/ in this repo.