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__

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"
-```
-
-
-
## __堆栈追踪信息__

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"
- <<"