BananaScript Execution Modes

https://github.com/shajunxing/banana-script there are three execution modes:

Run In Source Code

For example, there are two source code files, 20-source-0.js:

js 复制代码
function foo() {
    print("Greetings.");
    throw "Boom!";
}

20-source-1.js:

js 复制代码
foo();

Can run these two files by following command:

复制代码
js 20-source-0.js 20-source-1.js

Output:

复制代码
Greetings.
Runtime Error: {'line':3,'message':'Boom!'}

Compile To Bytecode

If add -c parameter, means compile:

复制代码
js -c 20-source-0.js 20-source-1.js -c

Will generate following files:

复制代码
Bytecode written to:
    examples\20-source-1-bc.bin
    examples\20-source-1-bc.txt
Cross reference written to:
    examples\20-source-1-xref.bin
    examples\20-source-1-xref.txt

Suffix with -bc are bytecode files, suffix with -xref are cross reference files. Can be run by following command:

复制代码
js -b 20-source-1-bc.bin -x 20-source-1-xref.bin

Same output:

复制代码
Greetings.
Runtime Error: {'line':3,'message':'Boom!'}

Cross reference files are optional, if not specified, will not know runtime errors corresponding lines, for example:

复制代码
js -b 20-source-1-bc.bin

Output:

复制代码
Greetings.
Runtime Error: 'Boom!'

Compile To Standalone Executables

.txt files can be included into custom c codes, for example 20-source.c:

c 复制代码
#include "../src/js-vm.h"
#include "../src/js-std-lang.h"
#include "../src/js-std-os.h"
#pragma comment(lib, "../bin/js.lib")
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "winmm.lib")

int main(int argc, char *argv[]) {
    uint8_t bc[] = {
#include "20-source-1-bc.txt"
    };
    uint32_t xref[] = {
#include "20-source-1-xref.txt"
    };
    struct js_vm vm = js_static_vm(bc, xref);
    js_declare_argc_argv(&vm, argc, argv);
    js_declare_std_lang_functions(&vm);
    js_declare_std_os_functions(&vm);
    return js_default_routine(&vm);
}

Can use msvc generate 20-source.exe and execute it:

复制代码
cl 20-source.c && 20-source.exe

Same output:

复制代码
Greetings.
Runtime Error: {'line':3,'message':'Boom!'}

Another example demonstrate how to declare c function forward(), 16-hybrid.c:

c 复制代码
#include "../src/js-vm.h"
#include "../src/js-std-lang.h"
#include "../src/js-std-os.h"
#pragma comment(lib, "../bin/js.lib")
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "winmm.lib")

struct js_result js_std_forward(struct js_vm *vm, uint16_t argc, struct js_value *argv) {
    js_assert(argc > 0);
    js_assert(js_is_function(argv));
    return js_call(vm, *argv, argc - 1, argv + 1);
}

int main(int argc, char *argv[]) {
    uint8_t bc[] = {
#include "16-hybrid-bc.txt"
    };
    uint32_t xref[] = {
#include "16-hybrid-xref.txt"
    };
    struct js_vm vm = js_static_vm(bc, xref);
    js_declare_argc_argv(&vm, argc, argv);
    js_declare_std_lang_functions(&vm);
    js_declare_std_os_functions(&vm);
    js_declare_variable_sz(&vm, "forward", js_c_function(js_std_forward));
    return js_default_routine(&vm);
}

This forward() function is same meaning as js codefunction forward(func, ...args) { return func(...args); }. It is inviked in 16-hybrid.js:

js 复制代码
forward(function(...args) {
    forward(function(...args) {
        forward(function(...args) {
            print(...args);
        }, ...args);
    }, ...args);
}, null, true, 3.14, "hello");

Run following command:

复制代码
js -c 16-hybrid.js && cl 16-hybrid.c && 16-hybrid.exe

To see output:

复制代码
null true 3.14 hello