diff --git a/README.md b/README.md index 740163d..a091ade 100644 --- a/README.md +++ b/README.md @@ -761,6 +761,8 @@ If get this, Congratulations!
Must use `var` to define variables This interpreter uses more strict syntax to make sure it is easier for you to program and debug. +And flightgear's nasal interpreter also has the same rule. +So do not use variable without using `var` to declare it. In Andy's interpreter: @@ -794,32 +796,6 @@ code: undefined symbol "i"
-
Default dynamic arguments not supported - -In this interpreter, -function doesn't put dynamic args into vector `arg` by default. -So if you use `arg` without definition, -you'll get an error of `undefined symbol`. - -```javascript -var f=func(){ - println(arg) -} -f(1,2,3); -``` - -Compilation result: - -```javascript -code: undefined symbol "arg" - --> test.nas:2:15 - | -2 | println(arg) - | ^ undefined symbol "arg" -``` - -
- ## __Trace Back Info__ ![stackoverflow](./doc/gif/stackoverflow.gif) diff --git a/doc/README_zh.md b/doc/README_zh.md index a721005..90ee530 100644 --- a/doc/README_zh.md +++ b/doc/README_zh.md @@ -735,6 +735,7 @@ dylib.dlclose(dlhandle.lib);
必须用 var 定义变量 这个解释器使用了更加严格的语法检查来保证你可以更轻松地debug。这是非常有必要的严格,否则debug会非常痛苦。 +同样的,flightgear 内置的 nasal 解释器也采取了类似的措施,所以使用变量前务必用 `var` 先进行声明。 在Andy的解释器中: @@ -762,29 +763,6 @@ code: undefined symbol "i" ```
-
默认不定长参数 - -这个解释器在运行时,函数不会将超出参数表的那部分不定长参数放到默认的`arg`中。所以你如果不定义`arg`就使用它,那你只会得到`undefined symbol`。 - -```javascript -var f=func(){ - println(arg) -} -f(1,2,3); -``` - -编译结果: - -```javascript -code: undefined symbol "arg" - --> test.nas:2:15 - | -2 | println(arg) - | ^ undefined symbol "arg" -``` - -
- ## __堆栈追踪信息__ ![stackoverflow](../doc/gif/stackoverflow.gif) diff --git a/makefile b/makefile index 0fbaaad..1b571d5 100644 --- a/makefile +++ b/makefile @@ -1,5 +1,23 @@ STD=c++17 +NASAL_HEADER=\ + src/ast_dumper.h\ + src/ast_visitor.h\ + src/nasal_ast.h\ + src/nasal_builtin.h\ + src/nasal_codegen.h\ + src/nasal_dbg.h\ + src/nasal_err.h\ + src/nasal_gc.h\ + src/nasal_import.h\ + src/nasal_lexer.h\ + src/nasal_opcode.h\ + src/nasal_parse.h\ + src/nasal_vm.h\ + src/nasal.h\ + src/optimizer.h\ + src/symbol_finder.h + NASAL_OBJECT=\ build/nasal_err.o\ build/nasal_ast.o\ @@ -29,55 +47,96 @@ nasal.exe: $(NASAL_OBJECT) | build build: @ if [ ! -d build ]; then mkdir build; fi -build/main.o: src/nasal.h src/nasal_err.h src/nasal_lexer.h src/main.cpp | build +build/main.o: $(NASAL_HEADER) src/main.cpp | build $(CXX) -std=$(STD) -c -O3 src/main.cpp -fno-exceptions -fPIC -o build/main.o -I . build/nasal_misc.o: src/nasal.h src/nasal_misc.cpp | build $(CXX) -std=$(STD) -c -O3 src/nasal_misc.cpp -fno-exceptions -fPIC -o build/nasal_misc.o -I . -build/nasal_err.o: src/nasal_err.h src/nasal_err.cpp | build +build/nasal_err.o: src/nasal.h src/nasal_err.h src/nasal_err.cpp | build $(CXX) -std=$(STD) -c -O3 src/nasal_err.cpp -fno-exceptions -fPIC -o build/nasal_err.o -I . -build/nasal_gc.o: src/nasal_gc.h src/nasal_gc.cpp | build +build/nasal_gc.o: src/nasal.h src/nasal_gc.h src/nasal_gc.cpp | build $(CXX) -std=$(STD) -c -O3 src/nasal_gc.cpp -fno-exceptions -fPIC -o build/nasal_gc.o -I . -build/nasal_import.o: src/nasal_import.h src/nasal_import.cpp | build +build/nasal_import.o: \ + src/nasal.h\ + src/nasal_ast.h\ + src/nasal_lexer.h\ + src/nasal_parse.h\ + src/nasal_import.h src/nasal_import.cpp | build $(CXX) -std=$(STD) -c -O3 src/nasal_import.cpp -fno-exceptions -fPIC -o build/nasal_import.o -I . -build/nasal_lexer.o: src/nasal_lexer.h src/nasal_lexer.cpp | build +build/nasal_lexer.o: \ + src/nasal.h\ + src/nasal_err.h\ + src/nasal_lexer.h src/nasal_lexer.cpp | build $(CXX) -std=$(STD) -c -O3 src/nasal_lexer.cpp -fno-exceptions -fPIC -o build/nasal_lexer.o -I . -build/nasal_ast.o: src/nasal_ast.h src/nasal_ast.cpp | build +build/nasal_ast.o: \ + src/nasal.h\ + src/nasal_err.h\ + src/nasal_ast.h src/nasal_ast.cpp | build $(CXX) -std=$(STD) -c -O3 src/nasal_ast.cpp -fno-exceptions -fPIC -o build/nasal_ast.o -I . -build/nasal_builtin.o: src/nasal_builtin.h src/nasal_builtin.cpp | build +build/nasal_builtin.o: \ + src/nasal.h\ + src/nasal_gc.h\ + src/nasal_builtin.h src/nasal_builtin.cpp | build $(CXX) -std=$(STD) -c -O3 src/nasal_builtin.cpp -fno-exceptions -fPIC -o build/nasal_builtin.o -I . -build/nasal_codegen.o: src/nasal_codegen.h src/nasal_codegen.cpp | build +build/nasal_codegen.o: $(NASAL_HEADER) src/nasal_codegen.h src/nasal_codegen.cpp | build $(CXX) -std=$(STD) -c -O3 src/nasal_codegen.cpp -fno-exceptions -fPIC -o build/nasal_codegen.o -I . -build/nasal_opcode.o: src/nasal_opcode.h src/nasal_opcode.cpp | build +build/nasal_opcode.o: \ + src/nasal.h\ + src/nasal_builtin.h\ + src/nasal_opcode.h src/nasal_opcode.cpp | build $(CXX) -std=$(STD) -c -O3 src/nasal_opcode.cpp -fno-exceptions -fPIC -o build/nasal_opcode.o -I . -build/nasal_parse.o: src/nasal_parse.h src/nasal_parse.cpp src/nasal_ast.h | build +build/nasal_parse.o: \ + src/nasal.h\ + src/nasal_ast.h\ + src/nasal_lexer.h\ + src/nasal_err.h\ + src/nasal_parse.h src/nasal_parse.cpp src/nasal_ast.h | build $(CXX) -std=$(STD) -c -O3 src/nasal_parse.cpp -fno-exceptions -fPIC -o build/nasal_parse.o -I . -build/optimizer.o: src/optimizer.h src/optimizer.cpp src/nasal_ast.h | build +build/optimizer.o: \ + src/nasal.h\ + src/nasal_err.h\ + src/nasal_ast.h\ + src/ast_visitor.h\ + src/optimizer.h src/optimizer.cpp src/nasal_ast.h | build $(CXX) -std=$(STD) -c -O3 src/optimizer.cpp -fno-exceptions -fPIC -o build/optimizer.o -I . -build/symbol_finder.o: src/symbol_finder.h src/symbol_finder.cpp src/nasal_ast.h | build +build/symbol_finder.o: \ + src/nasal.h\ + src/nasal_err.h\ + src/nasal_ast.h\ + src/ast_visitor.h\ + src/symbol_finder.h src/symbol_finder.cpp src/nasal_ast.h | build $(CXX) -std=$(STD) -c -O3 src/symbol_finder.cpp -fno-exceptions -fPIC -o build/symbol_finder.o -I . -build/ast_visitor.o: src/nasal_ast.h src/ast_visitor.h src/ast_visitor.cpp | build +build/ast_visitor.o: \ + src/nasal.h\ + src/nasal_err.h\ + src/nasal_ast.h\ + src/ast_visitor.h src/ast_visitor.cpp | build $(CXX) -std=$(STD) -c -O3 src/ast_visitor.cpp -fno-exceptions -fPIC -o build/ast_visitor.o -I . -build/ast_dumper.o: src/nasal_ast.h src/ast_visitor.h src/ast_dumper.h src/ast_dumper.cpp +build/ast_dumper.o: \ + src/nasal.h\ + src/nasal_err.h\ + src/nasal_ast.h\ + src/ast_visitor.h\ + src/ast_dumper.h src/ast_dumper.cpp | build $(CXX) -std=$(STD) -c -O3 src/ast_dumper.cpp -fno-exceptions -fPIC -o build/ast_dumper.o -I . -build/nasal_vm.o: src/nasal_vm.h src/nasal_vm.cpp | build +build/nasal_vm.o: $(NASAL_HEADER) src/nasal_vm.h src/nasal_vm.cpp | build $(CXX) -std=$(STD) -c -O3 src/nasal_vm.cpp -fno-exceptions -fPIC -o build/nasal_vm.o -I . -build/nasal_dbg.o: src/nasal_dbg.h src/nasal_dbg.cpp | build +build/nasal_dbg.o: $(NASAL_HEADER) src/nasal_dbg.h src/nasal_dbg.cpp | build $(CXX) -std=$(STD) -c -O3 src/nasal_dbg.cpp -fno-exceptions -fPIC -o build/nasal_dbg.o -I . .PHONY: clean diff --git a/module/fib.cpp b/module/fib.cpp index 1e6ae92..41c1449 100644 --- a/module/fib.cpp +++ b/module/fib.cpp @@ -16,7 +16,7 @@ var fib(var* args, usize size, gc* ngc) { if (!size) { return nas_err("fib","lack arguments"); } - var num=args[0]; + var num = args[0]; return var::num(fibonaci(num.tonum())); } @@ -24,15 +24,15 @@ var quick_fib(var* args, usize size, gc* ngc) { if (!size) { return nas_err("quick_fib","lack arguments"); } - double num=args[0].tonum(); + double num = args[0].tonum(); if (num<2) { return var::num(num); } - double a=1,b=1,res=0; - for(double i=1;ialloc(vm_obj); + var res = ngc->alloc(vm_obj); res.obj().set(ghost_for_test, new u32, &ngc->global_ghost_type_table); return res; } var set_new_ghost(var* args, usize size, gc* ngc) { - var res=args[0]; + var res = args[0]; if (!res.objchk(ghost_for_test)) { - std::cout<<"set_new_ghost: not ghost for test type.\n"; + std::cout << "set_new_ghost: not ghost for test type.\n"; return nil; } - f64 num=args[1].num(); - *((u32*)res.obj().ptr)=static_cast(num); - std::cout<<"set_new_ghost: successfully set ghost = "<(num); + std::cout << "set_new_ghost: successfully set ghost = " << num << "\n"; return nil; } var print_new_ghost(var* args, usize size, gc* ngc) { - var res=args[0]; + var res = args[0]; if (!res.objchk(ghost_for_test)) { - std::cout<<"print_new_ghost: not ghost for test type.\n"; + std::cout << "print_new_ghost: not ghost for test type.\n"; return nil; } - std::cout<<"print_new_ghost: "<exists("fib_for_test")) { - nasal_fib_module::ghost_for_test=table->get_ghost_type_index("fib_for_test"); + nasal_fib_module::ghost_for_test = table->get_ghost_type_index("fib_for_test"); return nasal_fib_module::func_tbl; } - nasal_fib_module::ghost_for_test=table->register_ghost_type( + nasal_fib_module::ghost_for_test = table->register_ghost_type( "fib_for_test", nasal_fib_module::ghost_for_test_destructor ); diff --git a/src/main.cpp b/src/main.cpp index 7d9b8fa..d20d64c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -145,7 +145,7 @@ void execute( // get running time if (cmd&VM_TIME) { f64 tm = (clk::now()-start).count()*1.0/den; - std::clog << "process exited after " << tm << "s.\n\n"; + std::clog << " process exited after " << tm << "s.\n\n"; } } diff --git a/src/nasal.h b/src/nasal.h index f12c9a4..bf97efc 100644 --- a/src/nasal.h +++ b/src/nasal.h @@ -32,7 +32,7 @@ using u64 = std::uint64_t; using usize = std::size_t; using f64 = double; -const u32 STACK_DEPTH=4096; +const u32 STACK_DEPTH = 4096; f64 hex2f(const char*); f64 oct2f(const char*); diff --git a/src/nasal_builtin.cpp b/src/nasal_builtin.cpp index 3f0326f..a097810 100644 --- a/src/nasal_builtin.cpp +++ b/src/nasal_builtin.cpp @@ -1210,12 +1210,6 @@ var builtin_millisec(var* local, gc& ngc) { return var::num(res); } -var builtin_sysargv(var* local, gc& ngc) { - var res = ngc.alloc(vm_vec); - res.vec().elems = ngc.env_argv; - return res; -} - var builtin_gcextend(var* local, gc& ngc) { var type = local[1]; if (type.type!=vm_str) { @@ -1356,7 +1350,6 @@ nasal_builtin_table builtin[] = { {"__costatus", builtin_costatus}, {"__corun", builtin_corun}, {"__millisec", builtin_millisec}, - {"__sysargv", builtin_sysargv}, {"__gcextd", builtin_gcextend}, {"__logtime", builtin_logtime}, {"__ghosttype", builtin_ghosttype}, diff --git a/src/nasal_builtin.h b/src/nasal_builtin.h index 2169a3a..7dd25bc 100644 --- a/src/nasal_builtin.h +++ b/src/nasal_builtin.h @@ -124,7 +124,6 @@ var builtin_coyield(var*, gc&); var builtin_costatus(var*, gc&); var builtin_corun(var*, gc&); var builtin_millisec(var*, gc&); -var builtin_sysargv(var*, gc&); var builtin_gcextend(var*, gc&); var builtin_logtime(var*, gc&); var builtin_ghosttype(var*, gc&); diff --git a/src/nasal_codegen.cpp b/src/nasal_codegen.cpp index f84c53e..730b705 100644 --- a/src/nasal_codegen.cpp +++ b/src/nasal_codegen.cpp @@ -211,6 +211,21 @@ void codegen::func_gen(function* node) { // search symbols first, must use after loading parameters // or the location of symbols will change and cause fatal error find_symbol(block); + // add special varibale "arg", which is used to store overflowed args + // but if dynamic parameter is declared, this variable will be useless + // for example: + // var f = func(a) {print(arg)} + // f(1, 2, 3); + // then the arg is [2, 3], because 1 is accepted by "a" + // so in fact "f" is the same as: + // var f = func(a, arg...) {return(arg)} + auto arg = std::string("arg"); + // this is used to avoid confliction with defined parameter + while(local_find(arg)>=0) { + arg = "0" + arg; + } + add_symbol(arg); + in_iterloop.push(0); block_gen(block); in_iterloop.pop(); @@ -1094,13 +1109,7 @@ const error& codegen::compile(parse& parse, linker& import) { // add special symbol globals, which is a hash stores all global variables add_symbol("globals"); - // add special symbol arg here, which is used to store function arguments - // for example: - // var f = func(a) {print(arg)} - // f(1, 2, 3); - // then the arg is [2, 3], because 1 is accepted by "a" - // so in fact "f" is the same as: - // var f = func(a, arg...) {return(arg)} + // add special symbol arg here, which is used to store command line args add_symbol("arg"); find_symbol(parse.tree()); // search symbols first diff --git a/src/nasal_dbg.cpp b/src/nasal_dbg.cpp index d88e181..66b73f6 100644 --- a/src/nasal_dbg.cpp +++ b/src/nasal_dbg.cpp @@ -2,14 +2,13 @@ std::vector dbg::parse(const std::string& cmd) { std::vector res; - usize last=0; - usize pos=cmd.find(" ", 0); + usize last = 0, pos = cmd.find(" ", 0); while(pos!=std::string::npos) { if (pos>last) { res.push_back(cmd.substr(last, pos-last)); } - last=pos+1; - pos=cmd.find(" ", last); + last = pos+1; + pos = cmd.find(" ", last); } if (last dbg::parse(const std::string& cmd) { } u16 dbg::file_index(const std::string& filename) const { - for(u16 i=0;i\n" - <<" h, help | get help\n" - <<" bt, backtrace | get function call trace\n" - <<" c, continue | run program until break point or exit\n" - <<" f, file | see all the compiled files\n" - <<" g, global | see global values\n" - <<" l, local | see local values\n" - <<" u, upval | see upvalue\n" - <<" r, register | show vm register detail\n" - <<" a, all | show global,local and upvalue\n" - <<" n, next | execute next bytecode\n" - <<" q, exit | exit debugger\n" - <<"