diff --git a/README.md b/README.md index 7d12178..5bef07a 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,12 @@ I refactored parser and make it easier to maintain. The EBNF is also refactored. +## Version 4.0 + +Parser in this version will pre-calculate some mathematical equations. + +This will make bytecode vm running more quickly. + # Abstract Syntax Tree ## Version 1.2 @@ -64,6 +70,12 @@ Now you can add your own functions as builtin-functions in this interpreter! I decide to save the ast interpreter after releasing v4.0. Because it took me a long time to think and write... +## Version 5.0 + +I change my mind.AST interpreter leaves me too much things to do. + +If i continue saving this interpreter,it will be harder for me to make the bytecode vm become more efficient. + # Byte Code Interpreter ## Version 4.0 @@ -94,4 +106,10 @@ var (a,b,c)=(1,2,3); 0x00000004: pnum 0x00000002 (3) 0x00000005: load 0x00000002 (c) 0x00000006: nop 0x00000000 -``` \ No newline at end of file +``` + +## Version 5.0 + +I decide to optimize bytecode vm in this version. + +Because it takes more than 1.5s to count i from 0 to 4000000-1.This is not efficient at all! \ No newline at end of file diff --git a/main.cpp b/main.cpp index 88e0451..20d5641 100644 --- a/main.cpp +++ b/main.cpp @@ -4,7 +4,6 @@ nasal_lexer lexer; nasal_parse parse; nasal_import import; std::string inputfile="null"; -nasal_runtime runtime; nasal_codegen code_generator; nasal_bytecode_vm bytevm; @@ -16,7 +15,6 @@ void help() std::cout<<">> [del ] clear the input filename.\n"; std::cout<<">> [lex ] use lexer to turn code into tokens.\n"; std::cout<<">> [ast ] do parsing and check the abstract syntax tree.\n"; - std::cout<<">> [run ] run abstract syntax tree.\n"; std::cout<<">> [code ] show byte code.\n"; std::cout<<">> [exec ] execute program on bytecode vm.\n"; std::cout<<">> [logo ] print logo of nasal .\n"; @@ -82,33 +80,6 @@ void ast_print() return; } -void runtime_start() -{ - lexer.openfile(inputfile); - lexer.scanner(); - if(lexer.get_error()) - { - die("lexer",inputfile); - return; - } - parse.set_toklist(lexer.get_token_list()); - parse.main_process(); - if(parse.get_error()) - { - die("parse",inputfile); - return; - } - import.link(parse.get_root()); - if(import.get_error()) - { - die("import",inputfile); - return; - } - runtime.set_root(import.get_root()); - runtime.run(); - return; -} - void show_bytecode() { lexer.openfile(inputfile); @@ -176,7 +147,7 @@ int main() system("cls"); #endif logo(); - std::cout<<">> Nasal interpreter ver 3.0 .\n"; + std::cout<<">> Nasal interpreter ver 5.0 .\n"; std::cout<<">> Code: https://github.com/ValKmjolnir/Nasal-Interpreter\n"; std::cout<<">> Info: http://wiki.flightgear.org/Nasal_scripting_language\n"; std::cout<<">> Input \"help\" to get help .\n"; @@ -204,8 +175,6 @@ int main() lex_func(); else if(command=="ast") ast_print(); - else if(command=="run") - runtime_start(); else if(command=="code") show_bytecode(); else if(command=="exec") diff --git a/nasal.h b/nasal.h index 9643c48..e028236 100644 --- a/nasal.h +++ b/nasal.h @@ -133,7 +133,6 @@ std::string trans_number_to_string(double number) #include "nasal_import.h" #include "nasal_gc.h" #include "nasal_builtin.h" -#include "nasal_runtime.h" #include "nasal_codegen.h" #include "nasal_bytecode_vm.h" diff --git a/nasal_builtin.h b/nasal_builtin.h index 5af4b73..7117adc 100644 --- a/nasal_builtin.h +++ b/nasal_builtin.h @@ -8,9 +8,10 @@ // return nil; // } // builtin function nasal_call_builtin_std_cout is wrapped up by print - +std::map builtin_use_string_table; // used to find values that builtin function uses -#define in_builtin_find(value_name_string) (local_scope_addr>=0?nasal_vm.gc_get(local_scope_addr).get_closure().get_value_address(value_name_string):-1) +#define in_builtin_find(value_name_string)\ + (local_scope_addr>=0?nasal_vm.gc_get(local_scope_addr).get_closure().get_value_address(builtin_use_string_table[value_name_string]):-1) // used to check found value's type // types are:vm_nil vm_number vm_string vm_vector vm_hash vm_function // dynamic values will be generated as vector by the outer function diff --git a/nasal_bytecode_vm.h b/nasal_bytecode_vm.h index 0a50db6..fdd4f45 100644 --- a/nasal_bytecode_vm.h +++ b/nasal_bytecode_vm.h @@ -6,13 +6,16 @@ class nasal_bytecode_vm private: bool main_loop_break_mark; int ptr; + int me_index; // this is the index of "me" in string_table int global_scope_addr; // garbage collector and memory manager nasal_virtual_machine vm; // byte codes store here std::vector exec_code; // main calculation stack - std::stack value_stack; +#define VALUE_STACK_MAX_DEPTH 2048 + int* value_stack; + int* value_stack_top; // stack for mem_call std::stack pointer_stack; // local scope for function block @@ -89,6 +92,7 @@ private: void opr_return(); public: nasal_bytecode_vm(); + ~nasal_bytecode_vm(); void clear(); void run(std::vector&,std::vector&,std::vector&); void nas_switch_threading(std::vector&,std::vector&,std::vector&); @@ -96,16 +100,23 @@ public: nasal_bytecode_vm::nasal_bytecode_vm() { + value_stack=new int[VALUE_STACK_MAX_DEPTH]; + value_stack_top=value_stack; local_scope_stack.push(-1); for(int i=0;builtin_func_table[i].func_pointer;++i) builtin_func_hashmap[builtin_func_table[i].func_name]=builtin_func_table[i].func_pointer; return; } +nasal_bytecode_vm::~nasal_bytecode_vm() +{ + delete []value_stack; + return; +} void nasal_bytecode_vm::clear() { vm.clear(); global_scope_addr=-1; - while(!value_stack.empty())value_stack.pop(); + value_stack_top=value_stack; while(!pointer_stack.empty())pointer_stack.pop(); while(!local_scope_stack.empty())local_scope_stack.pop(); local_scope_stack.push(-1); @@ -150,52 +161,51 @@ void nasal_bytecode_vm::opr_nop() } void nasal_bytecode_vm::opr_load() { - int val_addr=value_stack.top(); - value_stack.pop(); - vm.gc_get(local_scope_stack.top()>=0?local_scope_stack.top():global_scope_addr).get_closure().add_new_value(string_table[exec_code[ptr].index],val_addr); + int val_addr=*value_stack_top--; + vm.gc_get(local_scope_stack.top()>=0?local_scope_stack.top():global_scope_addr).get_closure().add_new_value(exec_code[ptr].index,val_addr); return; } void nasal_bytecode_vm::opr_pushnum() { int val_addr=vm.gc_alloc(vm_number); vm.gc_get(val_addr).set_number(number_table[exec_code[ptr].index]); - value_stack.push(val_addr); + *(++value_stack_top)=val_addr; return; } void nasal_bytecode_vm::opr_pushone() { int val_addr=vm.gc_alloc(vm_number); vm.gc_get(val_addr).set_number(1); - value_stack.push(val_addr); + *(++value_stack_top)=val_addr; return; } void nasal_bytecode_vm::opr_pushzero() { int val_addr=vm.gc_alloc(vm_number); vm.gc_get(val_addr).set_number(0); - value_stack.push(val_addr); + *(++value_stack_top)=val_addr; return; } void nasal_bytecode_vm::opr_pushnil() { - value_stack.push(vm.gc_alloc(vm_nil)); + *(++value_stack_top)=vm.gc_alloc(vm_nil); return; } void nasal_bytecode_vm::opr_pushstr() { int val_addr=vm.gc_alloc(vm_string); vm.gc_get(val_addr).set_string(string_table[exec_code[ptr].index]); - value_stack.push(val_addr); + *(++value_stack_top)=val_addr; return; } void nasal_bytecode_vm::opr_newvec() { - value_stack.push(vm.gc_alloc(vm_vector)); + *(++value_stack_top)=vm.gc_alloc(vm_vector); return; } void nasal_bytecode_vm::opr_newhash() { - value_stack.push(vm.gc_alloc(vm_hash)); + *(++value_stack_top)=vm.gc_alloc(vm_hash); return; } void nasal_bytecode_vm::opr_newfunc() @@ -209,50 +219,46 @@ void nasal_bytecode_vm::opr_newfunc() vm.gc_get(val_addr).get_func().set_closure_addr(tmp_closure); vm.del_reference(tmp_closure); } - value_stack.push(val_addr); + *(++value_stack_top)=val_addr; return; } void nasal_bytecode_vm::opr_vecapp() { - int val_addr=value_stack.top(); - value_stack.pop(); - vm.gc_get(value_stack.top()).get_vector().add_elem(val_addr); + int val_addr=*value_stack_top--; + vm.gc_get(*value_stack_top).get_vector().add_elem(val_addr); return; } void nasal_bytecode_vm::opr_hashapp() { - int val_addr=value_stack.top(); - value_stack.pop(); - int hash_addr=value_stack.top(); + int val_addr=*value_stack_top--; + int hash_addr=*value_stack_top; vm.gc_get(hash_addr).get_hash().add_elem(string_table[exec_code[ptr].index],val_addr); return; } void nasal_bytecode_vm::opr_para() { - vm.gc_get(value_stack.top()).get_func().add_para(string_table[exec_code[ptr].index]); + vm.gc_get(*value_stack_top).get_func().add_para(exec_code[ptr].index); return; } void nasal_bytecode_vm::opr_defpara() { - int val_addr=value_stack.top(); - value_stack.pop(); - vm.gc_get(value_stack.top()).get_func().add_para(string_table[exec_code[ptr].index],val_addr); + int val_addr=*value_stack_top--; + vm.gc_get(*value_stack_top).get_func().add_para(exec_code[ptr].index,val_addr); return; } void nasal_bytecode_vm::opr_dynpara() { - vm.gc_get(value_stack.top()).get_func().add_para(string_table[exec_code[ptr].index],-1,true); + vm.gc_get(*value_stack_top).get_func().add_para(exec_code[ptr].index,-1,true); return; } void nasal_bytecode_vm::opr_entry() { - vm.gc_get(value_stack.top()).get_func().set_entry(exec_code[ptr].index); + vm.gc_get(*value_stack_top).get_func().set_entry(exec_code[ptr].index); return; } void nasal_bytecode_vm::opr_unot() { - int val_addr=value_stack.top(); - value_stack.pop(); + int val_addr=*value_stack_top--; nasal_scalar& ref=vm.gc_get(val_addr); int type=ref.get_type(); int new_value_address=-1; @@ -282,159 +288,70 @@ void nasal_bytecode_vm::opr_unot() } else die("unot: incorrect value type"); - value_stack.push(new_value_address); + *(++value_stack_top)=new_value_address; vm.del_reference(val_addr); return; } void nasal_bytecode_vm::opr_usub() { - int val_addr=value_stack.top(); - value_stack.pop(); - nasal_scalar& ref=vm.gc_get(val_addr); - int type=ref.get_type(); - double num=std::nan(""); - if(type==vm_number) - num=ref.get_number(); - else if(type==vm_string) - num=trans_string_to_number(ref.get_string()); + int val_addr=*value_stack_top--; int new_value_address=vm.gc_alloc(vm_number); - vm.gc_get(new_value_address).set_number(-num); - value_stack.push(new_value_address); + vm.gc_get(new_value_address).set_number(-vm.gc_get(val_addr).to_number()); + *(++value_stack_top)=new_value_address; vm.del_reference(val_addr); return; } void nasal_bytecode_vm::opr_add() { - int val_addr2=value_stack.top(); - value_stack.pop(); - int val_addr1=value_stack.top(); - value_stack.pop(); - nasal_scalar& a_ref=vm.gc_get(val_addr1); - nasal_scalar& b_ref=vm.gc_get(val_addr2); - int a_ref_type=a_ref.get_type(); - int b_ref_type=b_ref.get_type(); - double a_num=std::nan(""); - double b_num=std::nan(""); - if(a_ref_type==vm_number) - a_num=a_ref.get_number(); - else if(a_ref_type==vm_string) - a_num=trans_string_to_number(a_ref.get_string()); - if(b_ref_type==vm_number) - b_num=b_ref.get_number(); - else if(b_ref_type==vm_string) - b_num=trans_string_to_number(b_ref.get_string()); - + int val_addr2=*value_stack_top--; + int val_addr1=*value_stack_top--; int new_value_address=vm.gc_alloc(vm_number); - vm.gc_get(new_value_address).set_number(a_num+b_num); - value_stack.push(new_value_address); + vm.gc_get(new_value_address).set_number(vm.gc_get(val_addr1).to_number()+vm.gc_get(val_addr2).to_number()); + *(++value_stack_top)=new_value_address; vm.del_reference(val_addr1); vm.del_reference(val_addr2); return; } void nasal_bytecode_vm::opr_sub() { - int val_addr2=value_stack.top(); - value_stack.pop(); - int val_addr1=value_stack.top(); - value_stack.pop(); - nasal_scalar& a_ref=vm.gc_get(val_addr1); - nasal_scalar& b_ref=vm.gc_get(val_addr2); - int a_ref_type=a_ref.get_type(); - int b_ref_type=b_ref.get_type(); - double a_num=std::nan(""); - double b_num=std::nan(""); - if(a_ref_type==vm_number) - a_num=a_ref.get_number(); - else if(a_ref_type==vm_string) - a_num=trans_string_to_number(a_ref.get_string()); - if(b_ref_type==vm_number) - b_num=b_ref.get_number(); - else if(b_ref_type==vm_string) - b_num=trans_string_to_number(b_ref.get_string()); - + int val_addr2=*value_stack_top--; + int val_addr1=*value_stack_top--; int new_value_address=vm.gc_alloc(vm_number); - vm.gc_get(new_value_address).set_number(a_num-b_num); - value_stack.push(new_value_address); + vm.gc_get(new_value_address).set_number(vm.gc_get(val_addr1).to_number()-vm.gc_get(val_addr2).to_number()); + *(++value_stack_top)=new_value_address; vm.del_reference(val_addr1); vm.del_reference(val_addr2); return; } void nasal_bytecode_vm::opr_mul() { - int val_addr2=value_stack.top(); - value_stack.pop(); - int val_addr1=value_stack.top(); - value_stack.pop(); - nasal_scalar& a_ref=vm.gc_get(val_addr1); - nasal_scalar& b_ref=vm.gc_get(val_addr2); - int a_ref_type=a_ref.get_type(); - int b_ref_type=b_ref.get_type(); - double a_num=std::nan(""); - double b_num=std::nan(""); - if(a_ref_type==vm_number) - a_num=a_ref.get_number(); - else if(a_ref_type==vm_string) - a_num=trans_string_to_number(a_ref.get_string()); - if(b_ref_type==vm_number) - b_num=b_ref.get_number(); - else if(b_ref_type==vm_string) - b_num=trans_string_to_number(b_ref.get_string()); - + int val_addr2=*value_stack_top--; + int val_addr1=*value_stack_top--; int new_value_address=vm.gc_alloc(vm_number); - vm.gc_get(new_value_address).set_number(a_num*b_num); - value_stack.push(new_value_address); + vm.gc_get(new_value_address).set_number(vm.gc_get(val_addr1).to_number()*vm.gc_get(val_addr2).to_number()); + *(++value_stack_top)=new_value_address; vm.del_reference(val_addr1); vm.del_reference(val_addr2); return; } void nasal_bytecode_vm::opr_div() { - int val_addr2=value_stack.top(); - value_stack.pop(); - int val_addr1=value_stack.top(); - value_stack.pop(); - nasal_scalar& a_ref=vm.gc_get(val_addr1); - nasal_scalar& b_ref=vm.gc_get(val_addr2); - int a_ref_type=a_ref.get_type(); - int b_ref_type=b_ref.get_type(); - double a_num=std::nan(""); - double b_num=std::nan(""); - if(a_ref_type==vm_number) - a_num=a_ref.get_number(); - else if(a_ref_type==vm_string) - a_num=trans_string_to_number(a_ref.get_string()); - if(b_ref_type==vm_number) - b_num=b_ref.get_number(); - else if(b_ref_type==vm_string) - b_num=trans_string_to_number(b_ref.get_string()); - + int val_addr2=*value_stack_top--; + int val_addr1=*value_stack_top--; int new_value_address=vm.gc_alloc(vm_number); - vm.gc_get(new_value_address).set_number(a_num/b_num); - value_stack.push(new_value_address); + vm.gc_get(new_value_address).set_number(vm.gc_get(val_addr1).to_number()/vm.gc_get(val_addr2).to_number()); + *(++value_stack_top)=new_value_address; vm.del_reference(val_addr1); vm.del_reference(val_addr2); return; } void nasal_bytecode_vm::opr_lnk() { - int val_addr2=value_stack.top(); - value_stack.pop(); - int val_addr1=value_stack.top(); - value_stack.pop(); - nasal_scalar& a_ref=vm.gc_get(val_addr1); - nasal_scalar& b_ref=vm.gc_get(val_addr2); - int a_ref_type=a_ref.get_type(); - int b_ref_type=b_ref.get_type(); - if((a_ref_type!=vm_number && a_ref_type!=vm_string)||(b_ref_type!=vm_number && b_ref_type!=vm_string)) - { - die("lnk: error value type"); - return; - } - std::string a_str=(a_ref_type==vm_number)? trans_number_to_string(a_ref.get_number()):a_ref.get_string(); - std::string b_str=(b_ref_type==vm_number)? trans_number_to_string(b_ref.get_number()):b_ref.get_string(); + int val_addr2=*value_stack_top--; + int val_addr1=*value_stack_top--; int new_value_address=vm.gc_alloc(vm_string); - vm.gc_get(new_value_address).set_string(a_str+b_str); - value_stack.push(new_value_address); + vm.gc_get(new_value_address).set_string(vm.gc_get(val_addr1).to_string()+vm.gc_get(val_addr2).to_string()); + *(++value_stack_top)=new_value_address; vm.del_reference(val_addr1); vm.del_reference(val_addr2); return; @@ -443,28 +360,12 @@ void nasal_bytecode_vm::opr_addeq() { int* mem_addr=pointer_stack.top(); pointer_stack.pop(); - int val_addr2=value_stack.top(); - value_stack.pop(); + int val_addr2=*value_stack_top--; int val_addr1=*mem_addr; - nasal_scalar& a_ref=vm.gc_get(val_addr1); - nasal_scalar& b_ref=vm.gc_get(val_addr2); - int a_ref_type=a_ref.get_type(); - int b_ref_type=b_ref.get_type(); - double a_num=std::nan(""); - double b_num=std::nan(""); - if(a_ref_type==vm_number) - a_num=a_ref.get_number(); - else if(a_ref_type==vm_string) - a_num=trans_string_to_number(a_ref.get_string()); - if(b_ref_type==vm_number) - b_num=b_ref.get_number(); - else if(b_ref_type==vm_string) - b_num=trans_string_to_number(b_ref.get_string()); - int new_value_address=vm.gc_alloc(vm_number); - vm.gc_get(new_value_address).set_number(a_num+b_num); + vm.gc_get(new_value_address).set_number(vm.gc_get(val_addr1).to_number()+vm.gc_get(val_addr2).to_number()); vm.add_reference(new_value_address); - value_stack.push(new_value_address); + *(++value_stack_top)=new_value_address; vm.del_reference(*mem_addr); *mem_addr=new_value_address; vm.del_reference(val_addr2); @@ -474,28 +375,12 @@ void nasal_bytecode_vm::opr_subeq() { int* mem_addr=pointer_stack.top(); pointer_stack.pop(); - int val_addr2=value_stack.top(); - value_stack.pop(); + int val_addr2=*value_stack_top--; int val_addr1=*mem_addr; - nasal_scalar& a_ref=vm.gc_get(val_addr1); - nasal_scalar& b_ref=vm.gc_get(val_addr2); - int a_ref_type=a_ref.get_type(); - int b_ref_type=b_ref.get_type(); - double a_num=std::nan(""); - double b_num=std::nan(""); - if(a_ref_type==vm_number) - a_num=a_ref.get_number(); - else if(a_ref_type==vm_string) - a_num=trans_string_to_number(a_ref.get_string()); - if(b_ref_type==vm_number) - b_num=b_ref.get_number(); - else if(b_ref_type==vm_string) - b_num=trans_string_to_number(b_ref.get_string()); - int new_value_address=vm.gc_alloc(vm_number); - vm.gc_get(new_value_address).set_number(a_num-b_num); + vm.gc_get(new_value_address).set_number(vm.gc_get(val_addr1).to_number()-vm.gc_get(val_addr2).to_number()); vm.add_reference(new_value_address); - value_stack.push(new_value_address); + *(++value_stack_top)=new_value_address; vm.del_reference(*mem_addr); *mem_addr=new_value_address; vm.del_reference(val_addr2); @@ -505,28 +390,12 @@ void nasal_bytecode_vm::opr_muleq() { int* mem_addr=pointer_stack.top(); pointer_stack.pop(); - int val_addr2=value_stack.top(); - value_stack.pop(); + int val_addr2=*value_stack_top--; int val_addr1=*mem_addr; - nasal_scalar& a_ref=vm.gc_get(val_addr1); - nasal_scalar& b_ref=vm.gc_get(val_addr2); - int a_ref_type=a_ref.get_type(); - int b_ref_type=b_ref.get_type(); - double a_num=std::nan(""); - double b_num=std::nan(""); - if(a_ref_type==vm_number) - a_num=a_ref.get_number(); - else if(a_ref_type==vm_string) - a_num=trans_string_to_number(a_ref.get_string()); - if(b_ref_type==vm_number) - b_num=b_ref.get_number(); - else if(b_ref_type==vm_string) - b_num=trans_string_to_number(b_ref.get_string()); - int new_value_address=vm.gc_alloc(vm_number); - vm.gc_get(new_value_address).set_number(a_num*b_num); + vm.gc_get(new_value_address).set_number(vm.gc_get(val_addr1).to_number()*vm.gc_get(val_addr2).to_number()); vm.add_reference(new_value_address); - value_stack.push(new_value_address); + *(++value_stack_top)=new_value_address; vm.del_reference(*mem_addr); *mem_addr=new_value_address; vm.del_reference(val_addr2); @@ -536,28 +405,12 @@ void nasal_bytecode_vm::opr_diveq() { int* mem_addr=pointer_stack.top(); pointer_stack.pop(); - int val_addr2=value_stack.top(); - value_stack.pop(); + int val_addr2=*value_stack_top--; int val_addr1=*mem_addr; - nasal_scalar& a_ref=vm.gc_get(val_addr1); - nasal_scalar& b_ref=vm.gc_get(val_addr2); - int a_ref_type=a_ref.get_type(); - int b_ref_type=b_ref.get_type(); - double a_num=std::nan(""); - double b_num=std::nan(""); - if(a_ref_type==vm_number) - a_num=a_ref.get_number(); - else if(a_ref_type==vm_string) - a_num=trans_string_to_number(a_ref.get_string()); - if(b_ref_type==vm_number) - b_num=b_ref.get_number(); - else if(b_ref_type==vm_string) - b_num=trans_string_to_number(b_ref.get_string()); - int new_value_address=vm.gc_alloc(vm_number); - vm.gc_get(new_value_address).set_number(a_num/b_num); + vm.gc_get(new_value_address).set_number(vm.gc_get(val_addr1).to_number()/vm.gc_get(val_addr2).to_number()); vm.add_reference(new_value_address); - value_stack.push(new_value_address); + *(++value_stack_top)=new_value_address; vm.del_reference(*mem_addr); *mem_addr=new_value_address; vm.del_reference(val_addr2); @@ -567,24 +420,12 @@ void nasal_bytecode_vm::opr_lnkeq() { int* mem_addr=pointer_stack.top(); pointer_stack.pop(); - int val_addr2=value_stack.top(); - value_stack.pop(); + int val_addr2=*value_stack_top--; int val_addr1=*mem_addr; - nasal_scalar& a_ref=vm.gc_get(val_addr1); - nasal_scalar& b_ref=vm.gc_get(val_addr2); - int a_ref_type=a_ref.get_type(); - int b_ref_type=b_ref.get_type(); - if((a_ref_type!=vm_number && a_ref_type!=vm_string)||(b_ref_type!=vm_number && b_ref_type!=vm_string)) - { - die("lnkeq: error value type"); - return; - } - std::string a_str=(a_ref_type==vm_number)? trans_number_to_string(a_ref.get_number()):a_ref.get_string(); - std::string b_str=(b_ref_type==vm_number)? trans_number_to_string(b_ref.get_number()):b_ref.get_string(); int new_value_address=vm.gc_alloc(vm_string); - vm.gc_get(new_value_address).set_string(a_str+b_str); + vm.gc_get(new_value_address).set_string(vm.gc_get(val_addr1).to_string()+vm.gc_get(val_addr2).to_string()); vm.add_reference(new_value_address); - value_stack.push(new_value_address); + *(++value_stack_top)=new_value_address; vm.del_reference(*mem_addr); *mem_addr=new_value_address; vm.del_reference(val_addr2); @@ -594,7 +435,7 @@ void nasal_bytecode_vm::opr_meq() { int* mem_addr=pointer_stack.top(); pointer_stack.pop(); - int val_addr=value_stack.top(); + int val_addr=*value_stack_top; vm.add_reference(val_addr); vm.del_reference(*mem_addr); *mem_addr=val_addr; @@ -602,15 +443,13 @@ void nasal_bytecode_vm::opr_meq() } void nasal_bytecode_vm::opr_eq() { - int val_addr2=value_stack.top(); - value_stack.pop(); - int val_addr1=value_stack.top(); - value_stack.pop(); + int val_addr2=*value_stack_top--; + int val_addr1=*value_stack_top--; if(val_addr1==val_addr2) { int new_value_address=vm.gc_alloc(vm_number); vm.gc_get(new_value_address).set_number(1); - value_stack.push(new_value_address); + *(++value_stack_top)=new_value_address; vm.del_reference(val_addr1); vm.del_reference(val_addr2); return; @@ -623,7 +462,7 @@ void nasal_bytecode_vm::opr_eq() { int new_value_address=vm.gc_alloc(vm_number); vm.gc_get(new_value_address).set_number(1); - value_stack.push(new_value_address); + *(++value_stack_top)=new_value_address; vm.del_reference(val_addr1); vm.del_reference(val_addr2); return; @@ -636,25 +475,14 @@ void nasal_bytecode_vm::opr_eq() std::string bstr=b_ref.get_string(); int new_value_address=vm.gc_alloc(vm_number); vm.gc_get(new_value_address).set_number((double)(astr==bstr)); - value_stack.push(new_value_address); + *(++value_stack_top)=new_value_address; vm.del_reference(val_addr1); vm.del_reference(val_addr2); return; } - double a_num; - double b_num; - if(a_ref_type==vm_number) - a_num=a_ref.get_number(); - else - a_num=trans_string_to_number(a_ref.get_string()); - if(b_ref_type==vm_number) - b_num=b_ref.get_number(); - else - b_num=trans_string_to_number(b_ref.get_string()); - int new_value_address=vm.gc_alloc(vm_number); - vm.gc_get(new_value_address).set_number((double)(a_num==b_num)); - value_stack.push(new_value_address); + vm.gc_get(new_value_address).set_number((double)(a_ref.to_number()==b_ref.to_number())); + *(++value_stack_top)=new_value_address; vm.del_reference(val_addr1); vm.del_reference(val_addr2); return; @@ -663,7 +491,7 @@ void nasal_bytecode_vm::opr_eq() { int new_value_address=vm.gc_alloc(vm_number); vm.gc_get(new_value_address).set_number(0); - value_stack.push(new_value_address); + *(++value_stack_top)=new_value_address; vm.del_reference(val_addr1); vm.del_reference(val_addr2); return; @@ -672,15 +500,13 @@ void nasal_bytecode_vm::opr_eq() } void nasal_bytecode_vm::opr_neq() { - int val_addr2=value_stack.top(); - value_stack.pop(); - int val_addr1=value_stack.top(); - value_stack.pop(); + int val_addr2=*value_stack_top--; + int val_addr1=*value_stack_top--; if(val_addr1==val_addr2) { int new_value_address=vm.gc_alloc(vm_number); vm.gc_get(new_value_address).set_number(0); - value_stack.push(new_value_address); + *(++value_stack_top)=new_value_address; vm.del_reference(val_addr1); vm.del_reference(val_addr2); return; @@ -693,7 +519,7 @@ void nasal_bytecode_vm::opr_neq() { int new_value_address=vm.gc_alloc(vm_number); vm.gc_get(new_value_address).set_number(0); - value_stack.push(new_value_address); + *(++value_stack_top)=new_value_address; vm.del_reference(val_addr1); vm.del_reference(val_addr2); return; @@ -706,25 +532,14 @@ void nasal_bytecode_vm::opr_neq() std::string bstr=b_ref.get_string(); int new_value_address=vm.gc_alloc(vm_number); vm.gc_get(new_value_address).set_number((double)(astr!=bstr)); - value_stack.push(new_value_address); + *(++value_stack_top)=new_value_address; vm.del_reference(val_addr1); vm.del_reference(val_addr2); return; } - double a_num; - double b_num; - if(a_ref_type==vm_number) - a_num=a_ref.get_number(); - else - a_num=trans_string_to_number(a_ref.get_string()); - if(b_ref_type==vm_number) - b_num=b_ref.get_number(); - else - b_num=trans_string_to_number(b_ref.get_string()); - int new_value_address=vm.gc_alloc(vm_number); - vm.gc_get(new_value_address).set_number((double)(a_num!=b_num)); - value_stack.push(new_value_address); + vm.gc_get(new_value_address).set_number((double)(a_ref.to_number()!=b_ref.to_number())); + *(++value_stack_top)=new_value_address; vm.del_reference(val_addr1); vm.del_reference(val_addr2); return; @@ -733,7 +548,7 @@ void nasal_bytecode_vm::opr_neq() { int new_value_address=vm.gc_alloc(vm_number); vm.gc_get(new_value_address).set_number(1); - value_stack.push(new_value_address); + *(++value_stack_top)=new_value_address; vm.del_reference(val_addr1); vm.del_reference(val_addr2); return; @@ -744,10 +559,8 @@ void nasal_bytecode_vm::opr_neq() } void nasal_bytecode_vm::opr_less() { - int val_addr2=value_stack.top(); - value_stack.pop(); - int val_addr1=value_stack.top(); - value_stack.pop(); + int val_addr2=*value_stack_top--; + int val_addr1=*value_stack_top--; nasal_scalar& a_ref=vm.gc_get(val_addr1); nasal_scalar& b_ref=vm.gc_get(val_addr2); int a_ref_type=a_ref.get_type(); @@ -757,36 +570,23 @@ void nasal_bytecode_vm::opr_less() std::string a_str=a_ref.get_string(); std::string b_str=b_ref.get_string(); int new_value_address=vm.gc_alloc(vm_number); - vm.gc_get(new_value_address).set_number((double)(a_strb_str)); - value_stack.push(new_value_address); + vm.gc_get(new_value_address).set_number(a_str>b_str); + *(++value_stack_top)=new_value_address; vm.del_reference(val_addr1); vm.del_reference(val_addr2); return; } - double a_num=std::nan(""); - double b_num=std::nan(""); - if(a_ref_type==vm_number) - a_num=a_ref.get_number(); - else if(a_ref_type==vm_string) - a_num=trans_string_to_number(a_ref.get_string()); - if(b_ref_type==vm_number) - b_num=b_ref.get_number(); - else if(b_ref_type==vm_string) - b_num=trans_string_to_number(b_ref.get_string()); - int new_value_address=vm.gc_alloc(vm_number); - vm.gc_get(new_value_address).set_number((double)(a_num>b_num)); - value_stack.push(new_value_address); + vm.gc_get(new_value_address).set_number(a_ref.to_number()>b_ref.to_number()); + *(++value_stack_top)=new_value_address; vm.del_reference(val_addr1); vm.del_reference(val_addr2); return; } void nasal_bytecode_vm::opr_geq() { - int val_addr2=value_stack.top(); - value_stack.pop(); - int val_addr1=value_stack.top(); - value_stack.pop(); + int val_addr2=*value_stack_top--; + int val_addr1=*value_stack_top--; nasal_scalar& a_ref=vm.gc_get(val_addr1); nasal_scalar& b_ref=vm.gc_get(val_addr2); int a_ref_type=a_ref.get_type(); @@ -874,34 +648,22 @@ void nasal_bytecode_vm::opr_geq() std::string a_str=a_ref.get_string(); std::string b_str=b_ref.get_string(); int new_value_address=vm.gc_alloc(vm_number); - vm.gc_get(new_value_address).set_number((double)(a_str>=b_str)); - value_stack.push(new_value_address); + vm.gc_get(new_value_address).set_number(a_str>=b_str); + *(++value_stack_top)=new_value_address; vm.del_reference(val_addr1); vm.del_reference(val_addr2); return; } - double a_num=std::nan(""); - double b_num=std::nan(""); - if(a_ref_type==vm_number) - a_num=a_ref.get_number(); - else if(a_ref_type==vm_string) - a_num=trans_string_to_number(a_ref.get_string()); - if(b_ref_type==vm_number) - b_num=b_ref.get_number(); - else if(b_ref_type==vm_string) - b_num=trans_string_to_number(b_ref.get_string()); - int new_value_address=vm.gc_alloc(vm_number); - vm.gc_get(new_value_address).set_number((double)(a_num>=b_num)); - value_stack.push(new_value_address); + vm.gc_get(new_value_address).set_number(a_ref.to_number()>=b_ref.to_number()); + *(++value_stack_top)=new_value_address; vm.del_reference(val_addr1); vm.del_reference(val_addr2); return; } void nasal_bytecode_vm::opr_pop() { - vm.del_reference(value_stack.top()); - value_stack.pop(); + vm.del_reference(*value_stack_top--); return; } void nasal_bytecode_vm::opr_jmp() @@ -911,19 +673,19 @@ void nasal_bytecode_vm::opr_jmp() } void nasal_bytecode_vm::opr_jmptrue() { - if(check_condition(value_stack.top())) + if(check_condition(*value_stack_top)) ptr=exec_code[ptr].index-1; return; } void nasal_bytecode_vm::opr_jmpfalse() { - if(!check_condition(value_stack.top())) + if(!check_condition(*value_stack_top)) ptr=exec_code[ptr].index-1; return; } void nasal_bytecode_vm::opr_counter() { - if(vm.gc_get(value_stack.top()).get_type()!=vm_vector) + if(vm.gc_get(*value_stack_top).get_type()!=vm_vector) { die("cnt: must use vector in forindex/foreach"); return; @@ -933,71 +695,61 @@ void nasal_bytecode_vm::opr_counter() } void nasal_bytecode_vm::opr_forindex() { - nasal_vector& ref=vm.gc_get(value_stack.top()).get_vector(); + nasal_vector& ref=vm.gc_get(*value_stack_top).get_vector(); counter_stack.top()++; if(counter_stack.top()>=ref.size()) { - vm.del_reference(value_stack.top()); - value_stack.pop(); + vm.del_reference(*value_stack_top--); counter_stack.pop(); ptr=exec_code[ptr].index-1; return; } int res=vm.gc_alloc(vm_number); vm.gc_get(res).set_number((double)counter_stack.top()); - value_stack.push(res); + *(++value_stack_top)=res; return; } void nasal_bytecode_vm::opr_foreach() { - nasal_vector& ref=vm.gc_get(value_stack.top()).get_vector(); + nasal_vector& ref=vm.gc_get(*value_stack_top).get_vector(); counter_stack.top()++; if(counter_stack.top()>=ref.size()) { - vm.del_reference(value_stack.top()); - value_stack.pop(); + vm.del_reference(*value_stack_top--); counter_stack.pop(); ptr=exec_code[ptr].index-1; return; } int res=ref.get_value_address(counter_stack.top()); vm.add_reference(res); - value_stack.push(res); + *(++value_stack_top)=res; return; } void nasal_bytecode_vm::opr_call() { int val_addr=-1; - std::string symbol=string_table[exec_code[ptr].index]; + int name_index=exec_code[ptr].index; if(local_scope_stack.top()>=0) - val_addr=vm.gc_get(local_scope_stack.top()).get_closure().get_value_address(symbol); + val_addr=vm.gc_get(local_scope_stack.top()).get_closure().get_value_address(name_index); if(val_addr<0) - val_addr=vm.gc_get(global_scope_addr).get_closure().get_value_address(symbol); + val_addr=vm.gc_get(global_scope_addr).get_closure().get_value_address(name_index); if(val_addr<0) { - die("call: cannot find symbol named \""+symbol+"\""); + die("call: cannot find symbol named \""+string_table[name_index]+"\""); return; } vm.add_reference(val_addr); - value_stack.push(val_addr); + *(++value_stack_top)=val_addr; return; } void nasal_bytecode_vm::opr_callv() { - int val_addr=value_stack.top(); - value_stack.pop(); - int vec_addr=value_stack.top(); - value_stack.pop(); + int val_addr=*value_stack_top--; + int vec_addr=*value_stack_top--; int type=vm.gc_get(vec_addr).get_type(); if(type==vm_vector) { - int num; - switch(vm.gc_get(val_addr).get_type()) - { - case vm_number:num=(int)vm.gc_get(val_addr).get_number();break; - case vm_string:num=(int)trans_string_to_number(vm.gc_get(val_addr).get_string());break; - default:die("callv: error value type");break; - } + int num=vm.gc_get(val_addr).to_number(); int res=vm.gc_get(vec_addr).get_vector().get_value_address(num); if(res<0) { @@ -1005,18 +757,12 @@ void nasal_bytecode_vm::opr_callv() return; } vm.add_reference(res); - value_stack.push(res); + *(++value_stack_top)=res; } else if(type==vm_string) { std::string str=vm.gc_get(vec_addr).get_string(); - int num; - switch(vm.gc_get(val_addr).get_type()) - { - case vm_number:num=(int)vm.gc_get(val_addr).get_number();break; - case vm_string:num=(int)trans_string_to_number(vm.gc_get(val_addr).get_string());break; - default:die("callv: error value type");break; - } + int num=vm.gc_get(val_addr).to_number(); int str_size=str.length(); if(num<-str_size || num>=str_size) { @@ -1025,7 +771,7 @@ void nasal_bytecode_vm::opr_callv() } int res=vm.gc_alloc(vm_number); vm.gc_get(res).set_number((double)str[(num+str_size)%str_size]); - value_stack.push(res); + *(++value_stack_top)=res; } else if(type==vm_hash) { @@ -1042,11 +788,11 @@ void nasal_bytecode_vm::opr_callv() } if(vm.gc_get(res).get_type()==vm_function) { - vm.gc_get(vm.gc_get(res).get_func().get_closure_addr()).get_closure().add_new_value("me",val_addr); + vm.gc_get(vm.gc_get(res).get_func().get_closure_addr()).get_closure().add_new_value(me_index,val_addr); vm.add_reference(val_addr); } vm.add_reference(res); - value_stack.push(res); + *(++value_stack_top)=res; } vm.del_reference(val_addr); vm.del_reference(vec_addr); @@ -1054,7 +800,7 @@ void nasal_bytecode_vm::opr_callv() } void nasal_bytecode_vm::opr_callvi() { - int val_addr=value_stack.top(); + int val_addr=*value_stack_top; if(vm.gc_get(val_addr).get_type()!=vm_vector) { die("callvi: multi-definition/multi-assignment must use a vector"); @@ -1067,13 +813,12 @@ void nasal_bytecode_vm::opr_callvi() return; } vm.add_reference(res); - value_stack.push(res); + *(++value_stack_top)=res; return; } void nasal_bytecode_vm::opr_callh() { - int val_addr=value_stack.top(); - value_stack.pop(); + int val_addr=*value_stack_top--; if(vm.gc_get(val_addr).get_type()!=vm_hash) { die("callh: must call a hash"); @@ -1087,17 +832,16 @@ void nasal_bytecode_vm::opr_callh() } vm.add_reference(res); if(vm.gc_get(res).get_type()==vm_function) - vm.gc_get(vm.gc_get(res).get_func().get_closure_addr()).get_closure().add_new_value("me",val_addr); + vm.gc_get(vm.gc_get(res).get_func().get_closure_addr()).get_closure().add_new_value(me_index,val_addr); else vm.del_reference(val_addr); - value_stack.push(res); + *(++value_stack_top)=res; return; } void nasal_bytecode_vm::opr_callf() { - int para_addr=value_stack.top(); - value_stack.pop(); - int func_addr=value_stack.top(); + int para_addr=*value_stack_top--; + int func_addr=*value_stack_top; if(vm.gc_get(func_addr).get_type()!=vm_function) { die("callf: called a value that is not a function"); @@ -1112,7 +856,7 @@ void nasal_bytecode_vm::opr_callf() if(vm.gc_get(para_addr).get_type()==vm_vector) { nasal_vector& ref_vec=vm.gc_get(para_addr).get_vector(); - std::vector& ref_para=ref.get_para(); + std::vector& ref_para=ref.get_para(); std::vector& ref_default=ref.get_default(); int i=0; for(;i=0) { int vec_addr=vm.gc_alloc(vm_vector); for(;i& ref_para=ref.get_para(); + std::vector& ref_para=ref.get_para(); std::vector& ref_default=ref.get_default(); - if(ref.get_dynamic_para().length()) + if(ref.get_dynamic_para()>=0) { die("callf: special call cannot use dynamic parameter"); return; } for(int i=0;i=0) - mem_addr=vm.gc_get(local_scope_stack.top()).get_closure().get_mem_address(symbol); + mem_addr=vm.gc_get(local_scope_stack.top()).get_closure().get_mem_address(name_index); if(!mem_addr) - mem_addr=vm.gc_get(global_scope_addr).get_closure().get_mem_address(symbol); + mem_addr=vm.gc_get(global_scope_addr).get_closure().get_mem_address(name_index); if(!mem_addr) - die("mcall: cannot find symbol named \""+symbol+"\""); + die("mcall: cannot find symbol named \""+string_table[name_index]+"\""); pointer_stack.push(mem_addr); return; } void nasal_bytecode_vm::opr_mcallv() { - int val_addr=value_stack.top(); - value_stack.pop(); + int val_addr=*value_stack_top--; int* vec_addr=pointer_stack.top(); pointer_stack.pop(); int type=vm.gc_get(*vec_addr).get_type(); @@ -1370,17 +1109,23 @@ void nasal_bytecode_vm::opr_return() vm.del_reference(closure_addr); ptr=call_stack.top(); call_stack.pop(); - int tmp=value_stack.top(); - value_stack.pop(); + int tmp=*value_stack_top--; // delete function - vm.del_reference(value_stack.top()); - value_stack.pop(); - value_stack.push(tmp); + vm.del_reference(*value_stack_top); + *value_stack_top=tmp; return; } void nasal_bytecode_vm::run(std::vector& strs,std::vector& nums,std::vector& exec) { + me_index=-1; string_table=strs; + builtin_use_string_table.clear(); + for(int i=0;i& strs,std::vector& builtin_die_state=false; global_scope_addr=vm.gc_alloc(vm_closure); - time_t begin_time=std::time(NULL); + clock_t begin_time=clock(); // main loop for(ptr=0;main_loop_break_mark;++ptr) (this->*opr_table[exec_code[ptr].op])(); - time_t end_time=std::time(NULL); - time_t total_run_time=end_time-begin_time; - if(total_run_time>=1) - std::cout<<">> [vm] process exited after "<> [vm] process exited after "< para_name; - std::string dynamic_para_name; + std::vector para_name; + int dynamic_para_name; std::vector default_para_addr; public: nasal_function(nasal_virtual_machine&); ~nasal_function(); void set_entry(int); int get_entry(); - void add_para(std::string,int,bool); - std::vector& get_para(); - std::string get_dynamic_para(); + void add_para(int,int,bool); + std::vector& get_para(); + int get_dynamic_para(); std::vector& get_default(); void set_closure_addr(int); int get_closure_addr(); - void set_arguments(nasal_ast&); - nasal_ast& get_arguments(); - void set_run_block(nasal_ast&); - nasal_ast& get_run_block(); }; class nasal_closure @@ -94,15 +89,15 @@ private: // and this memory_manager_memory space stores an address to garbage_collector_memory // and this address points to an nasal_hash nasal_virtual_machine& vm; - std::list > elems; + std::list > elems; public: nasal_closure(nasal_virtual_machine&); ~nasal_closure(); void add_scope(); void del_scope(); - void add_new_value(std::string,int); - int get_value_address(std::string); - int* get_mem_address(std::string); + void add_new_value(int,int); + int get_value_address(int); + int* get_mem_address(int); void set_closure(nasal_closure&); }; @@ -110,7 +105,16 @@ class nasal_scalar { protected: int type; - void* scalar_ptr; + union + { + double num; + std::string* str; + nasal_vector* vec; + nasal_hash* hash; + nasal_function* func; + nasal_closure* cls; + }ptr; + public: nasal_scalar(); ~nasal_scalar(); @@ -119,7 +123,9 @@ public: void set_number(double); void set_string(std::string); int get_type(); + double to_number(); double get_number(); + std::string to_string(); std::string get_string(); nasal_vector& get_vector(); nasal_hash& get_hash(); @@ -184,12 +190,14 @@ int nasal_vector::size() { return elems.size(); } +int nasal_vector::operator[](const int index) +{ + return elems[index]; +} int nasal_vector::get_value_address(int index) { int vec_size=elems.size(); - int left_range=-vec_size; - int right_range=vec_size-1; - if(indexright_range) + if(index<-vec_size || index>=vec_size) { std::cout<<">> [runtime] nasal_vector::get_value_address: index out of range: "<right_range) + if(index<-vec_size || index>=vec_size) { std::cout<<">> [runtime] nasal_vector::get_mem_address: index out of range: "<=0) vm.del_reference(default_para_addr[i]); - argument_list.clear(); - function_expr.clear(); return; } void nasal_function::set_entry(int etr) @@ -406,22 +408,22 @@ int nasal_function::get_entry() { return entry; } -void nasal_function::add_para(std::string name,int val_addr=-1,bool is_dynamic=false) +void nasal_function::add_para(int name_index,int val_addr=-1,bool is_dynamic=false) { if(is_dynamic) { - dynamic_para_name=name; + dynamic_para_name=name_index; return; } - para_name.push_back(name); + para_name.push_back(name_index); default_para_addr.push_back(val_addr); return; } -std::vector& nasal_function::get_para() +std::vector& nasal_function::get_para() { return para_name; } -std::string nasal_function::get_dynamic_para() +int nasal_function::get_dynamic_para() { return dynamic_para_name; } @@ -442,55 +444,37 @@ int nasal_function::get_closure_addr() { return closure_addr; } -void nasal_function::set_arguments(nasal_ast& node) -{ - argument_list=node; - return; -} -nasal_ast& nasal_function::get_arguments() -{ - return argument_list; -} -void nasal_function::set_run_block(nasal_ast& node) -{ - function_expr=node; - return; -} -nasal_ast& nasal_function::get_run_block() -{ - return function_expr; -} /*functions of nasal_closure*/ nasal_closure::nasal_closure(nasal_virtual_machine& nvm):vm(nvm) { - std::map new_scope; + std::map new_scope; elems.push_back(new_scope); return; } nasal_closure::~nasal_closure() { - for(std::list >::iterator i=elems.begin();i!=elems.end();++i) - for(std::map::iterator j=i->begin();j!=i->end();++j) + for(std::list >::iterator i=elems.begin();i!=elems.end();++i) + for(std::map::iterator j=i->begin();j!=i->end();++j) vm.del_reference(j->second); elems.clear(); return; } void nasal_closure::add_scope() { - std::map new_scope; + std::map new_scope; elems.push_back(new_scope); return; } void nasal_closure::del_scope() { - std::map& last_scope=elems.back(); - for(std::map::iterator i=last_scope.begin();i!=last_scope.end();++i) + std::map& last_scope=elems.back(); + for(std::map::iterator i=last_scope.begin();i!=last_scope.end();++i) vm.del_reference(i->second); elems.pop_back(); return; } -void nasal_closure::add_new_value(std::string key,int value_address) +void nasal_closure::add_new_value(int key,int value_address) { if(elems.back().find(key)!=elems.back().end()) { @@ -501,33 +485,33 @@ void nasal_closure::add_new_value(std::string key,int value_address) elems.back()[key]=value_address; return; } -int nasal_closure::get_value_address(std::string key) +int nasal_closure::get_value_address(int key) { int ret_address=-1; - for(std::list >::iterator i=elems.begin();i!=elems.end();++i) + for(std::list >::iterator i=elems.begin();i!=elems.end();++i) if(i->find(key)!=i->end()) ret_address=(*i)[key]; return ret_address; } -int* nasal_closure::get_mem_address(std::string key) +int* nasal_closure::get_mem_address(int key) { int* ret_address=NULL; - for(std::list >::iterator i=elems.begin();i!=elems.end();++i) + for(std::list >::iterator i=elems.begin();i!=elems.end();++i) if(i->find(key)!=i->end()) ret_address=&((*i)[key]); return ret_address; } void nasal_closure::set_closure(nasal_closure& tmp) { - for(std::list >::iterator i=elems.begin();i!=elems.end();++i) - for(std::map::iterator j=i->begin();j!=i->end();++j) + for(std::list >::iterator i=elems.begin();i!=elems.end();++i) + for(std::map::iterator j=i->begin();j!=i->end();++j) vm.del_reference(j->second); elems.clear(); - for(std::list >::iterator i=tmp.elems.begin();i!=tmp.elems.end();++i) + for(std::list >::iterator i=tmp.elems.begin();i!=tmp.elems.end();++i) { - std::map new_scope; + std::map new_scope; elems.push_back(new_scope); - for(std::map::iterator j=i->begin();j!=i->end();++j) + for(std::map::iterator j=i->begin();j!=i->end();++j) { int value_addr=j->second; vm.add_reference(value_addr); @@ -540,8 +524,7 @@ void nasal_closure::set_closure(nasal_closure& tmp) /*functions of nasal_scalar*/ nasal_scalar::nasal_scalar() { - this->type=vm_nil; - this->scalar_ptr=(void*)NULL; + type=vm_nil; return; } nasal_scalar::~nasal_scalar() @@ -549,20 +532,17 @@ nasal_scalar::~nasal_scalar() // must set type and scalar_ptr to default first // this operation will avoid SIGTRAP caused by circular reference // circular reference will cause using destructor repeatedly - int tmp_type=this->type; - void* tmp_ptr=this->scalar_ptr; - - this->type=vm_nil; - this->scalar_ptr=NULL; + int tmp_type=type; + type=vm_nil; switch(tmp_type) { case vm_nil: break; - case vm_number: delete (double*)(tmp_ptr); break; - case vm_string: delete (std::string*)(tmp_ptr); break; - case vm_vector: delete (nasal_vector*)(tmp_ptr); break; - case vm_hash: delete (nasal_hash*)(tmp_ptr); break; - case vm_function: delete (nasal_function*)(tmp_ptr); break; - case vm_closure: delete (nasal_closure*)(tmp_ptr); break; + case vm_number: break; + case vm_string: delete ptr.str; break; + case vm_vector: delete ptr.vec; break; + case vm_hash: delete ptr.hash; break; + case vm_function: delete ptr.func; break; + case vm_closure: delete ptr.cls; break; } return; } @@ -571,75 +551,93 @@ void nasal_scalar::clear() // must set type and scalar_ptr to default first // this operation will avoid SIGTRAP caused by circular reference // circular reference will cause using destructor repeatedly - int tmp_type=this->type; - void* tmp_ptr=this->scalar_ptr; - - this->type=vm_nil; - this->scalar_ptr=NULL; + int tmp_type=type; + type=vm_nil; switch(tmp_type) { case vm_nil: break; - case vm_number: delete (double*)(tmp_ptr); break; - case vm_string: delete (std::string*)(tmp_ptr); break; - case vm_vector: delete (nasal_vector*)(tmp_ptr); break; - case vm_hash: delete (nasal_hash*)(tmp_ptr); break; - case vm_function: delete (nasal_function*)(tmp_ptr); break; - case vm_closure: delete (nasal_closure*)(tmp_ptr); break; + case vm_number: break; + case vm_string: delete ptr.str; break; + case vm_vector: delete ptr.vec; break; + case vm_hash: delete ptr.hash; break; + case vm_function: delete ptr.func; break; + case vm_closure: delete ptr.cls; break; } return; } void nasal_scalar::set_type(int nasal_scalar_type,nasal_virtual_machine& nvm) { - this->type=nasal_scalar_type; + type=nasal_scalar_type; switch(nasal_scalar_type) { - case vm_nil: this->scalar_ptr=(void*)NULL; break; - case vm_number: this->scalar_ptr=(void*)(new double); break; - case vm_string: this->scalar_ptr=(void*)(new std::string); break; - case vm_vector: this->scalar_ptr=(void*)(new nasal_vector(nvm)); break; - case vm_hash: this->scalar_ptr=(void*)(new nasal_hash(nvm)); break; - case vm_function: this->scalar_ptr=(void*)(new nasal_function(nvm)); break; - case vm_closure: this->scalar_ptr=(void*)(new nasal_closure(nvm)); break; + case vm_nil: break; + case vm_number: ptr.num=0; break; + case vm_string: ptr.str=new std::string; break; + case vm_vector: ptr.vec=new nasal_vector(nvm); break; + case vm_hash: ptr.hash=new nasal_hash(nvm); break; + case vm_function: ptr.func=new nasal_function(nvm); break; + case vm_closure: ptr.cls=new nasal_closure(nvm); break; } return; } void nasal_scalar::set_number(double num) { - *(double*)(this->scalar_ptr)=num; + ptr.num=num; return; } void nasal_scalar::set_string(std::string str) { - *(std::string*)(this->scalar_ptr)=str; + *ptr.str=str; return; } int nasal_scalar::get_type() { - return this->type; + return type; +} +double nasal_scalar::to_number() +{ + switch(type) + { + case vm_nil:return 0; + case vm_number: return ptr.num; + case vm_string: return trans_string_to_number(*ptr.str); + default: return std::nan(""); + } + return 0; } double nasal_scalar::get_number() { - return *(double*)(this->scalar_ptr); + return ptr.num; +} +std::string nasal_scalar::to_string() +{ + switch(type) + { + case vm_number:return trans_number_to_string(ptr.num); + case vm_string:return *ptr.str; + default:return ""; + } + return ""; } std::string nasal_scalar::get_string() { - return *(std::string*)(this->scalar_ptr); + return *ptr.str; } nasal_vector& nasal_scalar::get_vector() { - return *(nasal_vector*)(this->scalar_ptr); + return *ptr.vec; } nasal_hash& nasal_scalar::get_hash() { - return *(nasal_hash*)(this->scalar_ptr); + return *ptr.hash; } nasal_function& nasal_scalar::get_func() { - return *(nasal_function*)(this->scalar_ptr); + return *ptr.func; } nasal_closure& nasal_scalar::get_closure() { - return *(nasal_closure*)(this->scalar_ptr); + return *ptr.cls; } /*functions of nasal_virtual_machine*/ @@ -701,12 +699,12 @@ int nasal_virtual_machine::gc_alloc(int val_type) if(garbage_collector_free_space.empty()) { int mem_size=garbage_collector_memory.size(); - garbage_collector_memory.resize(mem_size+64); - for(int i=mem_size;iref_cnt=1; + new_unit->elem.set_type(val_type,*this); + return ret; } int ret=garbage_collector_free_space.front(); gc_unit& unit_ref=*garbage_collector_memory[ret]; diff --git a/nasal_runtime.h b/nasal_runtime.h deleted file mode 100644 index f694fd0..0000000 --- a/nasal_runtime.h +++ /dev/null @@ -1,1896 +0,0 @@ -#ifndef __NASAL_RUNTIME_H__ -#define __NASAL_RUNTIME_H__ - -enum runtime_returned_state -{ - rt_return=1, - rt_error, - rt_break, - rt_continue, - rt_exit_without_error -}; - -class nasal_runtime -{ -private: - nasal_virtual_machine nasal_vm; - std::map builtin_func_hashmap; - // function_return_address is an address in garbage_collector_memory - int function_returned_address; - // global_scope_address is an address in garbage_collector_memory - int global_scope_address; - - nasal_ast root; - - // if error occurred,this value will add 1 - int error; - void die(int,std::string); - - // generate vector and return gc place of this vector - int vector_generation(nasal_ast&,int); - // generate hash and return gc place of this hash - int hash_generation(nasal_ast&,int); - // generate function and return gc place of this function - int function_generation(nasal_ast&,int); - - /* - functions after this note may have parameter named 'local_scope_addr' - if no local scope existing when calling these functions,use -1 - */ - - // main expression block running process - void main_progress(); - // function/loop/conditional expression block running process - int block_progress(nasal_ast&,int); - // run loop - void before_for_loop(nasal_ast&,int); - void after_each_for_loop(nasal_ast&,int); - int loop_progress(nasal_ast&,int); - // run conditional - bool check_condition(int); - int conditional_progress(nasal_ast&,int); - // get scalars in complex data structure like vector/hash/function/closure(scope) - int call_scalar(nasal_ast&,int); - int call_vector(nasal_ast&,int,int); - int call_hash(nasal_ast&,int,int); - int call_function(nasal_ast&,int,int,int); - int call_builtin_function(std::string,int); - // get scalars' memory place in complex data structure like vector/hash/function/closure(scope) - int* call_scalar_mem(nasal_ast&,int); - int* call_vector_mem(nasal_ast&,int*,int); - int* call_hash_mem(nasal_ast&,int*,int); - // calculate scalars - int nasal_scalar_add(int,int); - int nasal_scalar_sub(int,int); - int nasal_scalar_mult(int,int); - int nasal_scalar_div(int,int); - int nasal_scalar_link(int,int); - int nasal_scalar_unary_sub(int); - int nasal_scalar_unary_not(int); - int nasal_scalar_cmp_equal(int,int); - int nasal_scalar_cmp_not_equal(int,int); - int nasal_scalar_cmp_less(int,int); - int nasal_scalar_cmp_greater(int,int); - int nasal_scalar_cmp_less_or_equal(int,int); - int nasal_scalar_cmp_greater_or_equal(int,int); - int calculation(nasal_ast&,int); - void definition(nasal_ast&,int); - void multi_assignment(nasal_ast&,int); - - // builtin_func defined here - void load_builtin_function(); -public: - nasal_runtime(); - ~nasal_runtime(); - void set_root(nasal_ast&); - void run(); -}; - -nasal_runtime::nasal_runtime() -{ - error=0; - this->root.clear(); - this->global_scope_address=-1; - this->load_builtin_function(); - return; -} -nasal_runtime::~nasal_runtime() -{ - error=0; - this->root.clear(); - this->global_scope_address=-1; - this->builtin_func_hashmap.clear(); - return; -} -void nasal_runtime::die(int line,std::string info) -{ - ++error; - std::cout<<">> [runtime] line "<root=parse_result; - return; -} -void nasal_runtime::run() -{ - // this state is reserved for builtin_die - builtin_die_state=false; - - this->error=0; - this->function_returned_address=-1; - - this->global_scope_address=nasal_vm.gc_alloc(vm_closure); - - time_t begin_time=std::time(NULL); - main_progress(); - time_t end_time=std::time(NULL); - - nasal_vm.del_reference(global_scope_address); - nasal_vm.clear(); - - time_t total_run_time=end_time-begin_time; - if(total_run_time>=1) - std::cout<<">> [runtime] process exited after "<=0) - ref_of_this_function.set_closure_addr(local_scope_addr); - else - { - int new_closure=nasal_vm.gc_alloc(vm_closure); - ref_of_this_function.set_closure_addr(new_closure); - nasal_vm.del_reference(new_closure); - } - return new_addr; -} -void nasal_runtime::main_progress() -{ - int expr_number=root.get_children().size(); - int process_returned_value_addr=-1; - for(int i=0;i=0) - value_address=nasal_vm.gc_get(local_scope_addr).get_closure().get_value_address(val_name); - if(value_address<0) - value_address=nasal_vm.gc_get(global_scope_address).get_closure().get_value_address(val_name); - if(value_address<0) - { - value_address=call_builtin_function(val_name,local_scope_addr); - if(value_address>=0) - return value_address; - else - { - if(builtin_func_hashmap.find(val_name)!=builtin_func_hashmap.end()) - die(node.get_children()[0].get_line(),"call "+val_name+" failed"); - else - die(node.get_children()[0].get_line()," cannot find \""+val_name+"\""); - return -1; - } - } - nasal_vm.add_reference(value_address); - } - else - value_address=calculation(node.get_children()[0],local_scope_addr); - int call_expr_size=node.get_children().size(); - int last_call_hash_addr=-1; - for(int i=1;i called_value_addrs; - nasal_vector& reference_value=nasal_vm.gc_get(base_value_addr).get_vector(); - for(int i=0;i=end_index) - { - die(subvec_node.get_children()[0].get_line(),"begin index is greater than end index"); - return -1; - } - int vsize=reference_value.size(); - if(begin_index<-vsize || begin_index>vsize-1 || end_index<-vsize || end_index>vsize-1) - { - die(node.get_children()[i].get_line(),"begin index or end index is out of range"); - return -1; - } - for(int i=begin_index;i<=end_index;++i) - called_value_addrs.push_back(reference_value.get_value_address(i)); - nasal_vm.del_reference(begin_value_addr); - nasal_vm.del_reference(end_value_addr); - } - else - { - int index_value_addr=calculation(node.get_children()[i],local_scope_addr); - int index_value_type=nasal_vm.gc_get(index_value_addr).get_type(); - if(index_value_type!=vm_number && index_value_type!=vm_string) - { - die(node.get_children()[i].get_line(),"index must be number/string"); - return -1; - } - int index_num=0; - if(index_value_type==vm_string) - { - std::string str=nasal_vm.gc_get(index_value_addr).get_string(); - double number=trans_string_to_number(str); - index_num=(int)number; - } - else - index_num=(int)nasal_vm.gc_get(index_value_addr).get_number(); - nasal_vm.del_reference(index_value_addr); - called_value_addrs.push_back(reference_value.get_value_address(index_num)); - } - } - // generate sub-vector - if(call_size==1 && node.get_children()[0].get_type()!=ast_subvec) - { - int value_addr=called_value_addrs[0]; - nasal_vm.add_reference(value_addr); - return_value_addr=value_addr; - } - else - { - return_value_addr=nasal_vm.gc_alloc(vm_vector); - nasal_vector& return_vector=nasal_vm.gc_get(return_value_addr).get_vector(); - int vec_size=called_value_addrs.size(); - for(int i=0;i1) - { - die(node.get_line(),"use only one key to call a hash"); - return -1; - } - nasal_ast& tmp=node.get_children()[0]; - if(tmp.get_type()==ast_subvec) - { - die(tmp.get_line(),"cannot slice hash"); - return -1; - } - int str_addr=calculation(tmp,local_scope_addr); - if(str_addr<0 || nasal_vm.gc_get(str_addr).get_type()!=vm_string) - { - die(tmp.get_line(),"must use string as the key"); - return -1; - } - std::string str=nasal_vm.gc_get(str_addr).get_string(); - int value_addr=nasal_vm.gc_get(base_value_addr).get_hash().get_value_address(str); - nasal_vm.add_reference(value_addr); - return_value_addr=value_addr; - } - else - { - if(call_size>1) - { - die(node.get_line(),"use only one index to call a string"); - return -1; - } - nasal_ast& tmp=node.get_children()[0]; - if(tmp.get_type()==ast_subvec) - { - die(tmp.get_line(),"cannot slice string (use substr)"); - return -1; - } - int index_value_addr=calculation(tmp,local_scope_addr); - int index_value_type=nasal_vm.gc_get(index_value_addr).get_type(); - if(index_value_type!=vm_number && index_value_type!=vm_string) - { - die(tmp.get_line(),"index is not a number/numerable string"); - return -1; - } - int index_num=0; - if(index_value_type==vm_string) - { - std::string str=nasal_vm.gc_get(index_value_addr).get_string(); - double number=trans_string_to_number(str); - index_num=(int)number; - } - else - index_num=(int)nasal_vm.gc_get(index_value_addr).get_number(); - nasal_vm.del_reference(index_value_addr); - return_value_addr=nasal_vm.gc_alloc(vm_number); - std::string str=nasal_vm.gc_get(base_value_addr).get_string(); - int str_size=str.length(); - if(index_num>=str_size || index_num<-str_size) - { - die(tmp.get_line(),"index out of range"); - return -1; - } - nasal_vm.gc_get(return_value_addr).set_number((double)str[(index_num+str_size)%str_size]); - } - return return_value_addr; -} -int nasal_runtime::call_hash(nasal_ast& node,int base_value_addr,int local_scope_addr) -{ - int value_type=nasal_vm.gc_get(base_value_addr).get_type(); - if(value_type!=vm_hash) - { - die(node.get_line(),"called a value that is not a hash"); - return -1; - } - std::string str=node.get_str(); - int ret_value_addr=nasal_vm.gc_get(base_value_addr).get_hash().get_value_address(str); - if(ret_value_addr<0) - { - die(node.get_line(),"cannot find member named \""+str+"\""); - return -1; - } - nasal_vm.add_reference(ret_value_addr); - return ret_value_addr; -} -int nasal_runtime::call_function(nasal_ast& node,int base_value_addr,int last_call_hash_addr,int local_scope_addr) -{ - int ret_value_addr=-1; - int value_type=nasal_vm.gc_get(base_value_addr).get_type(); - if(value_type!=vm_function) - { - die(node.get_line(),"called a value that is not a function"); - return -1; - } - nasal_function& reference_of_func=nasal_vm.gc_get(base_value_addr).get_func(); - int run_closure_addr=reference_of_func.get_closure_addr(); - nasal_closure& run_closure=nasal_vm.gc_get(run_closure_addr).get_closure(); - run_closure.add_scope(); - if(last_call_hash_addr>=0) - { - // set hash.me - nasal_vm.add_reference(last_call_hash_addr); - run_closure.add_new_value("me",last_call_hash_addr); - } - nasal_ast& argument_format=reference_of_func.get_arguments(); - if(!node.get_children().size()) - { - if(argument_format.get_children().size() && argument_format.get_children()[0].get_type()!=ast_default_arg && argument_format.get_children()[0].get_type()!=ast_dynamic_id) - { - die(node.get_line(),"lack argument(s)"); - return -1; - } - else if(argument_format.get_children().size() && argument_format.get_children()[0].get_type()==ast_dynamic_id) - { - // load null dynamic-id - int vector_value_addr=nasal_vm.gc_alloc(vm_vector); - run_closure.add_new_value(argument_format.get_children()[0].get_str(),vector_value_addr); - } - else if(argument_format.get_children().size() && argument_format.get_children()[0].get_type()==ast_default_arg) - { - // load default values - int size=argument_format.get_children().size(); - for(int i=0;i args_usage_table; // check arguments in argument_format is correctly used - std::map default_args_table; // check default arguments - std::map default_args_node; // if one of default arguments is not in use,use default value - // load arguments' name. - int arg_format_size=argument_format.get_children().size(); - for(int i=0;i::iterator i=default_args_table.begin();i!=default_args_table.end();++i) - if(!i->second) - { - int value_addr=calculation(*default_args_node[i->first],local_scope_addr); - if(value_addr<0) - return -1; - run_closure.add_new_value(i->first,value_addr); - args_usage_table[i->first]=true; - } - // use null vector if dynamic-identifier haven't been initialized. - if(argument_format.get_children().back().get_type()==ast_dynamic_id) - { - std::string dyn_str=argument_format.get_children().back().get_str(); - if(!args_usage_table[dyn_str]) - { - args_usage_table[dyn_str]=true; - int vector_value_addr=nasal_vm.gc_alloc(vm_vector); - run_closure.add_new_value(dyn_str,vector_value_addr); - } - } - // check if each argument is initialized. - for(std::map::iterator i=args_usage_table.begin();i!=args_usage_table.end();++i) - if(!i->second) - { - die(node.get_line(),"argument named \""+i->first+"\" is not in use"); - return -1; - } - } - else - { - std::vector args; // store value address of input arguments - int size=node.get_children().size(); - for(int i=0;iarg_format_size && argument_format.get_children().back().get_type()!=ast_dynamic_id) - { - die(node.get_line(),"too much arguments"); - return -1; - } - for(int i=0;i=0) - { - ret_value_addr=function_returned_address; - function_returned_address=-1; - } - else - ret_value_addr=nasal_vm.gc_alloc(vm_nil); - return ret_value_addr; -} -int nasal_runtime::call_builtin_function(std::string val_name,int local_scope_addr) -{ - int ret_value_addr=-1; - if(builtin_func_hashmap.find(val_name)!=builtin_func_hashmap.end()) - { - ret_value_addr=(*builtin_func_hashmap[val_name])(local_scope_addr,nasal_vm); - error+=builtin_die_state; - } - return ret_value_addr; -} -int* nasal_runtime::call_scalar_mem(nasal_ast& node,int local_scope_addr) -{ - int* mem_address=NULL; - if(node.get_type()==ast_identifier) - { - std::string id_name=node.get_str(); - if(local_scope_addr>=0) - mem_address=nasal_vm.gc_get(local_scope_addr).get_closure().get_mem_address(id_name); - if(!mem_address) - mem_address=nasal_vm.gc_get(global_scope_address).get_closure().get_mem_address(id_name); - if(!mem_address) - { - die(node.get_line(),"cannot find \""+id_name+"\""); - return NULL; - } - return mem_address; - } - std::string id_name=node.get_children()[0].get_str(); - if(local_scope_addr>=0) - mem_address=nasal_vm.gc_get(local_scope_addr).get_closure().get_mem_address(id_name); - if(!mem_address) - mem_address=nasal_vm.gc_get(global_scope_address).get_closure().get_mem_address(id_name); - if(!mem_address) - { - die(node.get_children()[0].get_line(),"cannot find \""+id_name+"\""); - return NULL; - } - int call_expr_size=node.get_children().size(); - for(int i=1;i> [vm] scalar_add: memory returned an invalid address.\n"; - return -1; - } - - nasal_scalar& a_ref=nasal_vm.gc_get(a_scalar_addr); - nasal_scalar& b_ref=nasal_vm.gc_get(b_scalar_addr); - int a_ref_type=a_ref.get_type(); - int b_ref_type=b_ref.get_type(); - double a_num=(1/0.0)+(-1/0.0); - double b_num=(1/0.0)+(-1/0.0); - if(a_ref_type==vm_number) - a_num=a_ref.get_number(); - else if(a_ref_type==vm_string) - a_num=trans_string_to_number(a_ref.get_string()); - if(b_ref_type==vm_number) - b_num=b_ref.get_number(); - else if(b_ref_type==vm_string) - b_num=trans_string_to_number(b_ref.get_string()); - - int new_value_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(new_value_address).set_number(a_num+b_num); - return new_value_address; -} -int nasal_runtime::nasal_scalar_sub(int a_scalar_addr,int b_scalar_addr) -{ - if(a_scalar_addr<0 || b_scalar_addr<0) - { - std::cout<<">> [vm] scalar_sub: memory returned an invalid address.\n"; - return -1; - } - - nasal_scalar& a_ref=nasal_vm.gc_get(a_scalar_addr); - nasal_scalar& b_ref=nasal_vm.gc_get(b_scalar_addr); - int a_ref_type=a_ref.get_type(); - int b_ref_type=b_ref.get_type(); - double a_num=(1/0.0)+(-1/0.0); - double b_num=(1/0.0)+(-1/0.0); - if(a_ref_type==vm_number) - a_num=a_ref.get_number(); - else if(a_ref_type==vm_string) - a_num=trans_string_to_number(a_ref.get_string()); - if(b_ref_type==vm_number) - b_num=b_ref.get_number(); - else if(b_ref_type==vm_string) - b_num=trans_string_to_number(b_ref.get_string()); - - int new_value_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(new_value_address).set_number(a_num-b_num); - return new_value_address; -} -int nasal_runtime::nasal_scalar_mult(int a_scalar_addr,int b_scalar_addr) -{ - if(a_scalar_addr<0 || b_scalar_addr<0) - { - std::cout<<">> [vm] scalar_mult: memory returned an invalid address.\n"; - return -1; - } - - nasal_scalar& a_ref=nasal_vm.gc_get(a_scalar_addr); - nasal_scalar& b_ref=nasal_vm.gc_get(b_scalar_addr); - int a_ref_type=a_ref.get_type(); - int b_ref_type=b_ref.get_type(); - double a_num=(1/0.0)+(-1/0.0); - double b_num=(1/0.0)+(-1/0.0); - if(a_ref_type==vm_number) - a_num=a_ref.get_number(); - else if(a_ref_type==vm_string) - a_num=trans_string_to_number(a_ref.get_string()); - if(b_ref_type==vm_number) - b_num=b_ref.get_number(); - else if(b_ref_type==vm_string) - b_num=trans_string_to_number(b_ref.get_string()); - - int new_value_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(new_value_address).set_number(a_num*b_num); - return new_value_address; -} -int nasal_runtime::nasal_scalar_div(int a_scalar_addr,int b_scalar_addr) -{ - if(a_scalar_addr<0 || b_scalar_addr<0) - { - std::cout<<">> [vm] scalar_div: memory returned an invalid address.\n"; - return -1; - } - - nasal_scalar& a_ref=nasal_vm.gc_get(a_scalar_addr); - nasal_scalar& b_ref=nasal_vm.gc_get(b_scalar_addr); - int a_ref_type=a_ref.get_type(); - int b_ref_type=b_ref.get_type(); - double a_num=(1/0.0)+(-1/0.0); - double b_num=(1/0.0)+(-1/0.0); - if(a_ref_type==vm_number) - a_num=a_ref.get_number(); - else if(a_ref_type==vm_string) - a_num=trans_string_to_number(a_ref.get_string()); - if(b_ref_type==vm_number) - b_num=b_ref.get_number(); - else if(b_ref_type==vm_string) - b_num=trans_string_to_number(b_ref.get_string()); - - int new_value_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(new_value_address).set_number(a_num/b_num); - return new_value_address; -} -int nasal_runtime::nasal_scalar_link(int a_scalar_addr,int b_scalar_addr) -{ - if(a_scalar_addr<0 || b_scalar_addr<0) - { - std::cout<<">> [vm] scalar_link: memory returned an invalid address.\n"; - return -1; - } - nasal_scalar& a_ref=nasal_vm.gc_get(a_scalar_addr); - nasal_scalar& b_ref=nasal_vm.gc_get(b_scalar_addr); - int a_ref_type=a_ref.get_type(); - int b_ref_type=b_ref.get_type(); - if((a_ref_type!=vm_number && a_ref_type!=vm_string)||(b_ref_type!=vm_number && b_ref_type!=vm_string)) - { - std::cout<<">> [vm] scalar_link: error value type.\n"; - return -1; - } - std::string a_str; - std::string b_str; - a_str=(a_ref_type==vm_number)? trans_number_to_string(a_ref.get_number()):a_ref.get_string(); - b_str=(b_ref_type==vm_number)? trans_number_to_string(b_ref.get_number()):b_ref.get_string(); - int new_value_address=nasal_vm.gc_alloc(vm_string); - nasal_vm.gc_get(new_value_address).set_string(a_str+b_str); - return new_value_address; -} -int nasal_runtime::nasal_scalar_unary_sub(int a_scalar_addr) -{ - if(a_scalar_addr<0) - { - std::cout<<">> [vm] scalar_unary_sub: memory returned an invalid address.\n"; - return -1; - } - - nasal_scalar& a_ref=nasal_vm.gc_get(a_scalar_addr); - int a_ref_type=a_ref.get_type(); - double a_num=(1/0.0)+(-1/0.0); - if(a_ref_type==vm_number) - a_num=a_ref.get_number(); - else if(a_ref_type==vm_string) - a_num=trans_string_to_number(a_ref.get_string()); - - int new_value_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(new_value_address).set_number(-a_num); - return new_value_address; -} -int nasal_runtime::nasal_scalar_unary_not(int a_scalar_addr) -{ - if(a_scalar_addr<0) - { - std::cout<<">> [vm] scalar_unary_not: memory returned an invalid address.\n"; - return -1; - } - nasal_scalar& a_ref=nasal_vm.gc_get(a_scalar_addr); - int a_ref_type=a_ref.get_type(); - int new_value_address=-1; - if(a_ref_type==vm_nil) - { - new_value_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(new_value_address).set_number(1); - } - else if(a_ref_type==vm_number) - { - double number=(a_ref.get_number()==0); - new_value_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(new_value_address).set_number(number); - } - else if(a_ref_type==vm_string) - { - double number=trans_string_to_number(a_ref.get_string()); - if(std::isnan(number)) - { - new_value_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(new_value_address).set_number(!(a_ref.get_string()).length()); - } - else - { - new_value_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(new_value_address).set_number((double)(number==0)); - } - } - else - std::cout<<">> [vm] scalar_unary_not: error value type.\n"; - return new_value_address; -} -int nasal_runtime::nasal_scalar_cmp_equal(int a_scalar_addr,int b_scalar_addr) -{ - if(a_scalar_addr<0 || b_scalar_addr<0) - { - std::cout<<">> [vm] scalar_cmp_equal: memory returned an invalid address.\n"; - return -1; - } - if(a_scalar_addr==b_scalar_addr) - { - int new_value_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(new_value_address).set_number(1); - return new_value_address; - } - nasal_scalar& a_ref=nasal_vm.gc_get(a_scalar_addr); - nasal_scalar& b_ref=nasal_vm.gc_get(b_scalar_addr); - int a_ref_type=a_ref.get_type(); - int b_ref_type=b_ref.get_type(); - if(a_ref_type==vm_nil && b_ref_type==vm_nil) - { - int new_value_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(new_value_address).set_number(1); - return new_value_address; - } - else if((a_ref_type==vm_number || a_ref_type==vm_string) && (b_ref_type==vm_number || b_ref_type==vm_string)) - { - if(a_ref_type==vm_string && b_ref_type==vm_string) - { - std::string astr=a_ref.get_string(); - std::string bstr=b_ref.get_string(); - int new_value_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(new_value_address).set_number((double)(astr==bstr)); - return new_value_address; - } - double a_num; - double b_num; - if(a_ref_type==vm_number) - a_num=a_ref.get_number(); - else - a_num=trans_string_to_number(a_ref.get_string()); - if(b_ref_type==vm_number) - b_num=b_ref.get_number(); - else - b_num=trans_string_to_number(b_ref.get_string()); - - int new_value_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(new_value_address).set_number((double)(a_num==b_num)); - return new_value_address; - } - else - { - int new_value_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(new_value_address).set_number(0); - return new_value_address; - } - return -1; -} -int nasal_runtime::nasal_scalar_cmp_not_equal(int a_scalar_addr,int b_scalar_addr) -{ - if(a_scalar_addr<0 || b_scalar_addr<0) - { - std::cout<<">> [vm] scalar_cmp_not_equal: memory returned an invalid address.\n"; - return -1; - } - if(a_scalar_addr==b_scalar_addr) - { - int new_value_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(new_value_address).set_number(0); - return new_value_address; - } - nasal_scalar& a_ref=nasal_vm.gc_get(a_scalar_addr); - nasal_scalar& b_ref=nasal_vm.gc_get(b_scalar_addr); - int a_ref_type=a_ref.get_type(); - int b_ref_type=b_ref.get_type(); - if(a_ref_type==vm_nil && b_ref_type==vm_nil) - { - int new_value_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(new_value_address).set_number(0); - return new_value_address; - } - else if((a_ref_type==vm_number || a_ref_type==vm_string) && (b_ref_type==vm_number || b_ref_type==vm_string)) - { - if(a_ref_type==vm_string && b_ref_type==vm_string) - { - std::string astr=a_ref.get_string(); - std::string bstr=b_ref.get_string(); - int new_value_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(new_value_address).set_number((double)(astr!=bstr)); - return new_value_address; - } - double a_num; - double b_num; - if(a_ref_type==vm_number) - a_num=a_ref.get_number(); - else - a_num=trans_string_to_number(a_ref.get_string()); - if(b_ref_type==vm_number) - b_num=b_ref.get_number(); - else - b_num=trans_string_to_number(b_ref.get_string()); - - int new_value_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(new_value_address).set_number((double)(a_num!=b_num)); - return new_value_address; - } - else - { - int new_value_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(new_value_address).set_number(1); - return new_value_address; - } - return -1; -} -int nasal_runtime::nasal_scalar_cmp_less(int a_scalar_addr,int b_scalar_addr) -{ - if(a_scalar_addr<0 || b_scalar_addr<0) - { - std::cout<<">> [vm] scalar_cmp_less: memory returned an invalid address.\n"; - return -1; - } - - nasal_scalar& a_ref=nasal_vm.gc_get(a_scalar_addr); - nasal_scalar& b_ref=nasal_vm.gc_get(b_scalar_addr); - int a_ref_type=a_ref.get_type(); - int b_ref_type=b_ref.get_type(); - if(a_ref_type==vm_string && b_ref_type==vm_string) - { - std::string a_str=a_ref.get_string(); - std::string b_str=b_ref.get_string(); - int new_value_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(new_value_address).set_number((double)(a_str> [vm] scalar_cmp_greater: memory returned an invalid address.\n"; - return -1; - } - - nasal_scalar& a_ref=nasal_vm.gc_get(a_scalar_addr); - nasal_scalar& b_ref=nasal_vm.gc_get(b_scalar_addr); - int a_ref_type=a_ref.get_type(); - int b_ref_type=b_ref.get_type(); - if(a_ref_type==vm_string && b_ref_type==vm_string) - { - std::string a_str=a_ref.get_string(); - std::string b_str=b_ref.get_string(); - int new_value_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(new_value_address).set_number((double)(a_str>b_str)); - return new_value_address; - } - double a_num=(1/0.0)+(-1/0.0); - double b_num=(1/0.0)+(-1/0.0); - if(a_ref_type==vm_number) - a_num=a_ref.get_number(); - else if(a_ref_type==vm_string) - a_num=trans_string_to_number(a_ref.get_string()); - if(b_ref_type==vm_number) - b_num=b_ref.get_number(); - else if(b_ref_type==vm_string) - b_num=trans_string_to_number(b_ref.get_string()); - - int new_value_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(new_value_address).set_number((double)(a_num>b_num)); - return new_value_address; -} -int nasal_runtime::nasal_scalar_cmp_less_or_equal(int a_scalar_addr,int b_scalar_addr) -{ - if(a_scalar_addr<0 || b_scalar_addr<0) - { - std::cout<<">> [vm] scalar_cmp_lequal: memory returned an invalid address.\n"; - return -1; - } - - nasal_scalar& a_ref=nasal_vm.gc_get(a_scalar_addr); - nasal_scalar& b_ref=nasal_vm.gc_get(b_scalar_addr); - int a_ref_type=a_ref.get_type(); - int b_ref_type=b_ref.get_type(); - if(a_ref_type==vm_string && b_ref_type==vm_string) - { - std::string a_str=a_ref.get_string(); - std::string b_str=b_ref.get_string(); - int new_value_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(new_value_address).set_number((double)(a_str<=b_str)); - return new_value_address; - } - double a_num=(1/0.0)+(-1/0.0); - double b_num=(1/0.0)+(-1/0.0); - if(a_ref_type==vm_number) - a_num=a_ref.get_number(); - else if(a_ref_type==vm_string) - a_num=trans_string_to_number(a_ref.get_string()); - if(b_ref_type==vm_number) - b_num=b_ref.get_number(); - else if(b_ref_type==vm_string) - b_num=trans_string_to_number(b_ref.get_string()); - - int new_value_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(new_value_address).set_number((double)(a_num<=b_num)); - return new_value_address; -} -int nasal_runtime::nasal_scalar_cmp_greater_or_equal(int a_scalar_addr,int b_scalar_addr) -{ - if(a_scalar_addr<0 || b_scalar_addr<0) - { - std::cout<<">> [vm] scalar_cmp_gequal: memory returned an invalid address.\n"; - return -1; - } - - nasal_scalar& a_ref=nasal_vm.gc_get(a_scalar_addr); - nasal_scalar& b_ref=nasal_vm.gc_get(b_scalar_addr); - int a_ref_type=a_ref.get_type(); - int b_ref_type=b_ref.get_type(); - if(a_ref_type==vm_string && b_ref_type==vm_string) - { - std::string a_str=a_ref.get_string(); - std::string b_str=b_ref.get_string(); - int new_value_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(new_value_address).set_number((double)(a_str>=b_str)); - return new_value_address; - } - double a_num=(1/0.0)+(-1/0.0); - double b_num=(1/0.0)+(-1/0.0); - if(a_ref_type==vm_number) - a_num=a_ref.get_number(); - else if(a_ref_type==vm_string) - a_num=trans_string_to_number(a_ref.get_string()); - if(b_ref_type==vm_number) - b_num=b_ref.get_number(); - else if(b_ref_type==vm_string) - b_num=trans_string_to_number(b_ref.get_string()); - - int new_value_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(new_value_address).set_number((double)(a_num>=b_num)); - return new_value_address; -} -int nasal_runtime::calculation(nasal_ast& node,int local_scope_addr) -{ - // after this process, a new address(in nasal_vm.garbage_collector_memory) will be returned - int ret_address=-1; - int calculation_type=node.get_type(); - if(calculation_type==ast_null) - { - ret_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(ret_address).set_number(1); - } - else if(calculation_type==ast_nil) - ret_address=nasal_vm.gc_alloc(vm_nil); - else if(calculation_type==ast_number) - { - ret_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(ret_address).set_number(node.get_num()); - } - else if(calculation_type==ast_string) - { - ret_address=nasal_vm.gc_alloc(vm_string); - nasal_vm.gc_get(ret_address).set_string(node.get_str()); - } - else if(calculation_type==ast_identifier) - { - if(local_scope_addr>=0) - ret_address=nasal_vm.gc_get(local_scope_addr).get_closure().get_value_address(node.get_str()); - if(ret_address<0) - ret_address=nasal_vm.gc_get(global_scope_address).get_closure().get_value_address(node.get_str()); - if(ret_address<0) - { - die(node.get_line(),"cannot find \""+node.get_str()+"\""); - ret_address=nasal_vm.gc_alloc(vm_nil); - } - nasal_vm.add_reference(ret_address); - } - else if(calculation_type==ast_vector) - ret_address=vector_generation(node,local_scope_addr); - else if(calculation_type==ast_hash) - ret_address=hash_generation(node,local_scope_addr); - else if(calculation_type==ast_function) - ret_address=function_generation(node,local_scope_addr); - else if(calculation_type==ast_call) - ret_address=call_scalar(node,local_scope_addr); - else if(calculation_type==ast_add) - { - int left_gc_addr=calculation(node.get_children()[0],local_scope_addr); - int right_gc_addr=calculation(node.get_children()[1],local_scope_addr); - ret_address=nasal_scalar_add(left_gc_addr,right_gc_addr); - // delete the reference of temporary values - nasal_vm.del_reference(left_gc_addr); - nasal_vm.del_reference(right_gc_addr); - } - else if(calculation_type==ast_sub) - { - int left_gc_addr=calculation(node.get_children()[0],local_scope_addr); - int right_gc_addr=calculation(node.get_children()[1],local_scope_addr); - ret_address=nasal_scalar_sub(left_gc_addr,right_gc_addr); - // delete the reference of temporary values - nasal_vm.del_reference(left_gc_addr); - nasal_vm.del_reference(right_gc_addr); - } - else if(calculation_type==ast_mult) - { - int left_gc_addr=calculation(node.get_children()[0],local_scope_addr); - int right_gc_addr=calculation(node.get_children()[1],local_scope_addr); - ret_address=nasal_scalar_mult(left_gc_addr,right_gc_addr); - // delete the reference of temporary values - nasal_vm.del_reference(left_gc_addr); - nasal_vm.del_reference(right_gc_addr); - } - else if(calculation_type==ast_div) - { - int left_gc_addr=calculation(node.get_children()[0],local_scope_addr); - int right_gc_addr=calculation(node.get_children()[1],local_scope_addr); - ret_address=nasal_scalar_div(left_gc_addr,right_gc_addr); - // delete the reference of temporary values - nasal_vm.del_reference(left_gc_addr); - nasal_vm.del_reference(right_gc_addr); - } - else if(calculation_type==ast_link) - { - int left_gc_addr=calculation(node.get_children()[0],local_scope_addr); - int right_gc_addr=calculation(node.get_children()[1],local_scope_addr); - ret_address=nasal_scalar_link(left_gc_addr,right_gc_addr); - // delete the reference of temporary values - nasal_vm.del_reference(left_gc_addr); - nasal_vm.del_reference(right_gc_addr); - } - else if(calculation_type==ast_cmp_equal) - { - int left_gc_addr=calculation(node.get_children()[0],local_scope_addr); - int right_gc_addr=calculation(node.get_children()[1],local_scope_addr); - ret_address=nasal_scalar_cmp_equal(left_gc_addr,right_gc_addr); - // delete the reference of temporary values - nasal_vm.del_reference(left_gc_addr); - nasal_vm.del_reference(right_gc_addr); - } - else if(calculation_type==ast_cmp_not_equal) - { - int left_gc_addr=calculation(node.get_children()[0],local_scope_addr); - int right_gc_addr=calculation(node.get_children()[1],local_scope_addr); - ret_address=nasal_scalar_cmp_not_equal(left_gc_addr,right_gc_addr); - // delete the reference of temporary values - nasal_vm.del_reference(left_gc_addr); - nasal_vm.del_reference(right_gc_addr); - } - else if(calculation_type==ast_less_than) - { - int left_gc_addr=calculation(node.get_children()[0],local_scope_addr); - int right_gc_addr=calculation(node.get_children()[1],local_scope_addr); - ret_address=nasal_scalar_cmp_less(left_gc_addr,right_gc_addr); - // delete the reference of temporary values - nasal_vm.del_reference(left_gc_addr); - nasal_vm.del_reference(right_gc_addr); - } - else if(calculation_type==ast_less_equal) - { - int left_gc_addr=calculation(node.get_children()[0],local_scope_addr); - int right_gc_addr=calculation(node.get_children()[1],local_scope_addr); - ret_address=nasal_scalar_cmp_less_or_equal(left_gc_addr,right_gc_addr); - // delete the reference of temporary values - nasal_vm.del_reference(left_gc_addr); - nasal_vm.del_reference(right_gc_addr); - } - else if(calculation_type==ast_greater_than) - { - int left_gc_addr=calculation(node.get_children()[0],local_scope_addr); - int right_gc_addr=calculation(node.get_children()[1],local_scope_addr); - ret_address=nasal_scalar_cmp_greater(left_gc_addr,right_gc_addr); - // delete the reference of temporary values - nasal_vm.del_reference(left_gc_addr); - nasal_vm.del_reference(right_gc_addr); - } - else if(calculation_type==ast_greater_equal) - { - int left_gc_addr=calculation(node.get_children()[0],local_scope_addr); - int right_gc_addr=calculation(node.get_children()[1],local_scope_addr); - ret_address=nasal_scalar_cmp_greater_or_equal(left_gc_addr,right_gc_addr); - // delete the reference of temporary values - nasal_vm.del_reference(left_gc_addr); - nasal_vm.del_reference(right_gc_addr); - } - else if(calculation_type==ast_and) - { - int left_gc_addr=calculation(node.get_children()[0],local_scope_addr); - if(!check_condition(left_gc_addr)) - { - nasal_vm.del_reference(left_gc_addr); - ret_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(ret_address).set_number(0); - } - else - { - int right_gc_addr=calculation(node.get_children()[1],local_scope_addr); - if(!check_condition(right_gc_addr)) - { - nasal_vm.del_reference(left_gc_addr); - nasal_vm.del_reference(right_gc_addr); - ret_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(ret_address).set_number(0); - } - else - { - nasal_vm.del_reference(left_gc_addr); - ret_address=right_gc_addr; - } - } - } - else if(calculation_type==ast_or) - { - int left_gc_addr=calculation(node.get_children()[0],local_scope_addr); - if(check_condition(left_gc_addr)) - ret_address=left_gc_addr; - else - { - int right_gc_addr=calculation(node.get_children()[1],local_scope_addr); - if(check_condition(right_gc_addr)) - { - nasal_vm.del_reference(left_gc_addr); - ret_address=right_gc_addr; - } - else - { - nasal_vm.del_reference(left_gc_addr); - nasal_vm.del_reference(right_gc_addr); - ret_address=nasal_vm.gc_alloc(vm_number); - nasal_vm.gc_get(ret_address).set_number(0); - } - } - } - else if(calculation_type==ast_unary_not) - { - int addr=calculation(node.get_children()[0],local_scope_addr); - ret_address=nasal_scalar_unary_not(addr); - // delete the reference of temporary values - nasal_vm.del_reference(addr); - } - else if(calculation_type==ast_unary_sub) - { - int addr=calculation(node.get_children()[0],local_scope_addr); - ret_address=nasal_scalar_unary_sub(addr); - // delete the reference of temporary values - nasal_vm.del_reference(addr); - } - else if(calculation_type==ast_trinocular) - { - int condition_addr=calculation(node.get_children()[0],local_scope_addr); - if(check_condition(condition_addr)) - ret_address=calculation(node.get_children()[1],local_scope_addr); - else - ret_address=calculation(node.get_children()[2],local_scope_addr); - // delete the reference of temporary values - nasal_vm.del_reference(condition_addr); - } - else if(calculation_type==ast_equal) - { - int* scalar_mem_space=call_scalar_mem(node.get_children()[0],local_scope_addr); - if(!scalar_mem_space) return -1; - int new_scalar_gc_addr=calculation(node.get_children()[1],local_scope_addr); - nasal_vm.del_reference(*scalar_mem_space); - *scalar_mem_space=new_scalar_gc_addr; - nasal_vm.add_reference(new_scalar_gc_addr);// this reference is reserved for ret_address - ret_address=new_scalar_gc_addr; - } - else if(calculation_type==ast_add_equal) - { - int* scalar_mem_space=call_scalar_mem(node.get_children()[0],local_scope_addr); - if(!scalar_mem_space) return -1; - int scalar_val_space=*scalar_mem_space; - int new_scalar_gc_addr=calculation(node.get_children()[1],local_scope_addr); - int result_val_address=nasal_scalar_add(scalar_val_space,new_scalar_gc_addr); - nasal_vm.del_reference(new_scalar_gc_addr); - nasal_vm.del_reference(scalar_val_space); - *scalar_mem_space=result_val_address; - nasal_vm.add_reference(result_val_address);// this reference is reserved for ret_address - ret_address=result_val_address; - } - else if(calculation_type==ast_sub_equal) - { - int* scalar_mem_space=call_scalar_mem(node.get_children()[0],local_scope_addr); - if(!scalar_mem_space) return -1; - int scalar_val_space=*scalar_mem_space; - int new_scalar_gc_addr=calculation(node.get_children()[1],local_scope_addr); - int result_val_address=nasal_scalar_sub(scalar_val_space,new_scalar_gc_addr); - nasal_vm.del_reference(new_scalar_gc_addr); - nasal_vm.del_reference(scalar_val_space); - *scalar_mem_space=result_val_address; - nasal_vm.add_reference(result_val_address);// this reference is reserved for ret_address - ret_address=result_val_address; - } - else if(calculation_type==ast_div_equal) - { - int* scalar_mem_space=call_scalar_mem(node.get_children()[0],local_scope_addr); - if(!scalar_mem_space) return -1; - int scalar_val_space=*scalar_mem_space; - int new_scalar_gc_addr=calculation(node.get_children()[1],local_scope_addr); - int result_val_address=nasal_scalar_div(scalar_val_space,new_scalar_gc_addr); - nasal_vm.del_reference(new_scalar_gc_addr); - nasal_vm.del_reference(scalar_val_space); - *scalar_mem_space=result_val_address; - nasal_vm.add_reference(result_val_address);// this reference is reserved for ret_address - ret_address=result_val_address; - } - else if(calculation_type==ast_mult_equal) - { - int* scalar_mem_space=call_scalar_mem(node.get_children()[0],local_scope_addr); - if(!scalar_mem_space) return -1; - int scalar_val_space=*scalar_mem_space; - int new_scalar_gc_addr=calculation(node.get_children()[1],local_scope_addr); - int result_val_address=nasal_scalar_mult(scalar_val_space,new_scalar_gc_addr); - nasal_vm.del_reference(new_scalar_gc_addr); - nasal_vm.del_reference(scalar_val_space); - *scalar_mem_space=result_val_address; - nasal_vm.add_reference(result_val_address);// this reference is reserved for ret_address - ret_address=result_val_address; - } - else if(calculation_type==ast_link_equal) - { - int* scalar_mem_space=call_scalar_mem(node.get_children()[0],local_scope_addr); - if(!scalar_mem_space) return -1; - int scalar_val_space=*scalar_mem_space; - int new_scalar_gc_addr=calculation(node.get_children()[1],local_scope_addr); - int result_val_address=nasal_scalar_link(scalar_val_space,new_scalar_gc_addr); - nasal_vm.del_reference(new_scalar_gc_addr); - nasal_vm.del_reference(scalar_val_space); - *scalar_mem_space=result_val_address; - nasal_vm.add_reference(result_val_address);// this reference is reserved for ret_address - ret_address=result_val_address; - } - else - { - die(node.get_line(),"cannot calculate expression: "+ast_str(node.get_type())); - ret_address=nasal_vm.gc_alloc(vm_nil); - } - return ret_address; -} -void nasal_runtime::definition(nasal_ast& node,int local_scope_addr) -{ - nasal_ast& define_node=node.get_children()[0]; - nasal_ast& value_node=node.get_children()[1]; - if(define_node.get_type()==ast_identifier) - { - std::string new_name=define_node.get_str(); - int value_addr=calculation(value_node,local_scope_addr); - if(value_addr<0) - return; - nasal_vm.gc_get(local_scope_addr<0?global_scope_address:local_scope_addr).get_closure().add_new_value(new_name,value_addr); - } - else - { - std::vector identifier_table; - int id_size=define_node.get_children().size(); - for(int i=0;i value_table; - for(int i=0;i value_table; - for(int i=0;i0.01) { @@ -136,18 +137,22 @@ while(error>0.01) backward(i); } cnt+=1; - print('epoch ',cnt,':',error); + show+=1; + if(show==100) + { + show=0; + print('epoch ',cnt,':',error); + } } print('\afinished.'); -while(1) +var vec=[ + [0,0], + [0,1], + [1,0], + [1,1] +]; +foreach(var v;vec) { - var vec=[]; - var command=input(); - if(command=="exit")break; - append(vec,num(command)); - command=input(); - if(command=="exit")break; - append(vec,num(command)); - run(vec); - print(output[0].out); + run(v); + print(v,': ',output[0].out); } \ No newline at end of file