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