diff --git a/nasal.h b/nasal.h index df349ee..c010d4b 100644 --- a/nasal.h +++ b/nasal.h @@ -26,7 +26,7 @@ #include "nasal_import.h" #include "nasal_codegen.h" #include "nasal_gc.h" -#include "nasal_runtime.h" #include "nasal_builtin.h" +#include "nasal_runtime.h" #endif diff --git a/nasal_builtin.h b/nasal_builtin.h index 9471898..03b17e4 100644 --- a/nasal_builtin.h +++ b/nasal_builtin.h @@ -1,17 +1,115 @@ #ifndef __NASAL_BUILTIN_H__ #define __NASAL_BUILTIN_H__ +// builtin functions must be called inside a outer function like this: +// var print=func(elements...) +// { +// nasal_call_builtin_std_cout(elements); +// return nil; +// } +// builtin function nasal_call_builtin_std_cout is wrapped up by print + +// 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) +// 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 #define in_builtin_check(value_addr,value_type) (nasal_vm.gc_get(value_addr).get_type()==(value_type)) -int nasal_runtime::builtin_print(int local_scope_addr) +// declaration of builtin functions +// to add new builtin function,declare it here and write the definition below +int builtin_print(int); +int builtin_append(int); +int builtin_setsize(int); +int builtin_system(int); +int builtin_input(int); +int builtin_sleep(int); +int builtin_finput(int); +int builtin_foutput(int); +int builtin_split(int); +int builtin_rand(int); +int builtin_id(int); +int builtin_int(int); +int builtin_num(int); +int builtin_pop(int); +int builtin_str(int); +int builtin_size(int); +int builtin_xor(int); +int builtin_and(int); +int builtin_or(int); +int builtin_nand(int); +int builtin_not(int); +int builtin_sin(int); +int builtin_cos(int); +int builtin_tan(int); +int builtin_exp(int); +int builtin_ln(int); +int builtin_sqrt(int); +int builtin_atan2(int); +int builtin_time(int); +int builtin_contains(int); +int builtin_delete(int); +int builtin_getkeys(int); +int builtin_import(int); +int builtin_die_state; +int builtin_die(int); +int builtin_type(int); +int builtin_substr(int); + +// register builtin function's name and it's address here in this table below +// this table must and with {"",NULL} +struct FUNC_TABLE +{ + std::string func_name; + int (*func_pointer)(int x); +} builtin_func_table[]= +{ + {"nasal_call_builtin_std_cout", builtin_print}, + {"nasal_call_builtin_push_back", builtin_append}, + {"nasal_call_builtin_set_size", builtin_setsize}, + {"nasal_call_builtin_system", builtin_system}, + {"nasal_call_builtin_input", builtin_input}, + {"nasal_call_builtin_sleep", builtin_sleep}, + {"nasal_call_builtin_finput", builtin_finput}, + {"nasal_call_builtin_foutput", builtin_foutput}, + {"nasal_call_builtin_split", builtin_split}, + {"nasal_call_builtin_rand", builtin_rand}, + {"nasal_call_builtin_get_id", builtin_id}, + {"nasal_call_builtin_trans_int", builtin_int}, + {"nasal_call_builtin_trans_num", builtin_num}, + {"nasal_call_builtin_pop_back", builtin_pop}, + {"nasal_call_builtin_trans_str", builtin_str}, + {"nasal_call_builtin_size", builtin_size}, + {"nasal_call_builtin_xor", builtin_xor}, + {"nasal_call_builtin_and", builtin_and}, + {"nasal_call_builtin_or", builtin_or}, + {"nasal_call_builtin_nand", builtin_nand}, + {"nasal_call_builtin_not", builtin_not}, + {"nasal_call_builtin_sin", builtin_sin}, + {"nasal_call_builtin_cos", builtin_cos}, + {"nasal_call_builtin_tan", builtin_tan}, + {"nasal_call_builtin_exp", builtin_exp}, + {"nasal_call_builtin_cpp_math_ln", builtin_ln}, + {"nasal_call_builtin_cpp_math_sqrt", builtin_sqrt}, + {"nasal_call_builtin_cpp_atan2", builtin_atan2}, + {"nasal_call_builtin_time", builtin_time}, + {"nasal_call_builtin_contains", builtin_contains}, + {"nasal_call_builtin_delete", builtin_delete}, + {"nasal_call_builtin_get_keys", builtin_getkeys}, + {"nasal_call_import", builtin_import}, + {"nasal_call_builtin_die", builtin_die}, + {"nasal_call_builtin_type", builtin_type}, + {"nasal_call_builtin_substr", builtin_substr}, + {"", NULL} +}; + +int builtin_print(int local_scope_addr) { // get arguments int vector_value_addr=in_builtin_find("elements"); if(vector_value_addr<0 || !in_builtin_check(vector_value_addr,vm_vector)) { std::cout<<">> [runtime] builtin_print: \"elements\" has wrong value type(must be vector).\n"; - ++error; return -1; } // main process @@ -35,20 +133,18 @@ int nasal_runtime::builtin_print(int local_scope_addr) int ret_addr=nasal_vm.gc_alloc(vm_nil); return ret_addr; } -int nasal_runtime::builtin_append(int local_scope_addr) +int builtin_append(int local_scope_addr) { int vector_value_addr=in_builtin_find("vector"); int elem_value_addr=in_builtin_find("elements"); if(vector_value_addr<0 || !in_builtin_check(vector_value_addr,vm_vector)) { std::cout<<">> [runtime] builtin_append: \"vector\" has wrong value type(must be vector).\n"; - ++error; return -1; } if(elem_value_addr<0 || !in_builtin_check(elem_value_addr,vm_vector)) { std::cout<<">> [runtime] builtin_append: \"elements\" has wrong value type(must be vector).\n"; - ++error; return -1; } nasal_vector& ref_vector=nasal_vm.gc_get(vector_value_addr).get_vector(); @@ -63,27 +159,24 @@ int nasal_runtime::builtin_append(int local_scope_addr) int ret_addr=nasal_vm.gc_alloc(vm_nil); return ret_addr; } -int nasal_runtime::builtin_setsize(int local_scope_addr) +int builtin_setsize(int local_scope_addr) { int vector_value_addr=in_builtin_find("vector"); int size_value_addr=in_builtin_find("size"); if(vector_value_addr<0 || nasal_vm.gc_get(vector_value_addr).get_type()!=vm_vector) { std::cout<<">> [runtime] builtin_setsize: \"vector\" has wrong value type(must be vector).\n"; - ++error; return -1; } if(size_value_addr<0) { std::cout<<">> [runtime] builtin_setsize: \"size\" has wrong value type(must be string or number).\n"; - ++error; return -1; } int type=nasal_vm.gc_get(size_value_addr).get_type(); if(type!=vm_number && type!=vm_string) { std::cout<<">> [runtime] builtin_setsize: size is not a number.\n"; - ++error; return -1; } int number; @@ -96,7 +189,6 @@ int nasal_runtime::builtin_setsize(int local_scope_addr) if(std::isnan(tmp)) { std::cout<<">> [runtime] builtin_setsize: size is not a numerable string.\n"; - ++error; return -1; } number=(int)tmp; @@ -104,7 +196,6 @@ int nasal_runtime::builtin_setsize(int local_scope_addr) if(number<0) { std::cout<<">> [runtime] builtin_setsize: size must be greater than -1.\n"; - ++error; return -1; } nasal_vector& ref_vector=nasal_vm.gc_get(vector_value_addr).get_vector(); @@ -126,13 +217,12 @@ int nasal_runtime::builtin_setsize(int local_scope_addr) return ret_addr; } -int nasal_runtime::builtin_system(int local_scope_addr) +int builtin_system(int local_scope_addr) { int str_value_addr=in_builtin_find("str"); if(str_value_addr<0 || nasal_vm.gc_get(str_value_addr).get_type()!=vm_string) { std::cout<<">> [runtime] builtin_system: \"str\" has wrong value type(must be string).\n"; - ++error; return -1; } std::string str=nasal_vm.gc_get(str_value_addr).get_string(); @@ -147,7 +237,7 @@ int nasal_runtime::builtin_system(int local_scope_addr) return ret_addr; } -int nasal_runtime::builtin_input(int local_scope_addr) +int builtin_input(int local_scope_addr) { int ret_addr=nasal_vm.gc_alloc(vm_string); std::string str; @@ -156,13 +246,12 @@ int nasal_runtime::builtin_input(int local_scope_addr) return ret_addr; } -int nasal_runtime::builtin_sleep(int local_scope_addr) +int builtin_sleep(int local_scope_addr) { int value_addr=in_builtin_find("duration"); if(value_addr<0 || (nasal_vm.gc_get(value_addr).get_type()!=vm_string && nasal_vm.gc_get(value_addr).get_type()!=vm_number)) { std::cout<<">> [runtime] builtin_sleep: \"duration\" has wrong value type(must be string or number).\n"; - ++error; return -1; } unsigned long sleep_time=0; @@ -173,7 +262,6 @@ int nasal_runtime::builtin_sleep(int local_scope_addr) if(std::isnan(number)) { std::cout<<">> [runtime] builtin_sleep: this is not a numerable string.\n"; - ++error; return -1; }sleep_time=(unsigned long)number; } @@ -184,13 +272,12 @@ int nasal_runtime::builtin_sleep(int local_scope_addr) return ret_addr; } -int nasal_runtime::builtin_finput(int local_scope_addr) +int builtin_finput(int local_scope_addr) { int value_addr=in_builtin_find("filename"); if(value_addr<0 || nasal_vm.gc_get(value_addr).get_type()!=vm_string) { std::cout<<">> [runtime] builtin_finput: \"filename\" has wrong value type(must be string).\n"; - ++error; return -1; } std::string filename=nasal_vm.gc_get(value_addr).get_string(); @@ -212,20 +299,18 @@ int nasal_runtime::builtin_finput(int local_scope_addr) return ret_addr; } -int nasal_runtime::builtin_foutput(int local_scope_addr) +int builtin_foutput(int local_scope_addr) { int value_addr=in_builtin_find("filename"); int str_value_addr=in_builtin_find("str"); if(value_addr<0 || nasal_vm.gc_get(value_addr).get_type()!=vm_string) { std::cout<<">> [runtime] builtin_foutput: \"filename\" has wrong value type(must be string).\n"; - ++error; return -1; } if(str_value_addr<0 || nasal_vm.gc_get(str_value_addr).get_type()!=vm_string) { std::cout<<">> [runtime] builtin_foutput: \"str\" has wrong value type(must be string).\n"; - ++error; return -1; } std::string filename=nasal_vm.gc_get(value_addr).get_string(); @@ -237,20 +322,18 @@ int nasal_runtime::builtin_foutput(int local_scope_addr) return ret_addr; } -int nasal_runtime::builtin_split(int local_scope_addr) +int builtin_split(int local_scope_addr) { int delimeter_value_addr=in_builtin_find("delimeter"); int string_value_addr=in_builtin_find("string"); if(delimeter_value_addr<0 || nasal_vm.gc_get(delimeter_value_addr).get_type()!=vm_string) { std::cout<<">> [runtime] builtin_split: \"delimeter\" has wrong value type(must be string).\n"; - ++error; return -1; } if(string_value_addr<0 || nasal_vm.gc_get(string_value_addr).get_type()!=vm_string) { std::cout<<">> [runtime] builtin_split: \"string\" has wrong value type(must be string).\n"; - ++error; return -1; } std::string delimeter=nasal_vm.gc_get(delimeter_value_addr).get_string(); @@ -306,13 +389,12 @@ int nasal_runtime::builtin_split(int local_scope_addr) } return ret_addr; } -int nasal_runtime::builtin_rand(int local_scope_addr) +int builtin_rand(int local_scope_addr) { int value_addr=in_builtin_find("seed"); if(value_addr<0 || (nasal_vm.gc_get(value_addr).get_type()!=vm_number && nasal_vm.gc_get(value_addr).get_type()!=vm_nil)) { std::cout<<">> [runtime] builtin_rand: \"seed\" has wrong value type(must be nil or number).\n"; - ++error; return -1; } if(nasal_vm.gc_get(value_addr).get_type()==vm_number) @@ -329,26 +411,24 @@ int nasal_runtime::builtin_rand(int local_scope_addr) nasal_vm.gc_get(ret_addr).set_number(num); return ret_addr; } -int nasal_runtime::builtin_id(int local_scope_addr) +int builtin_id(int local_scope_addr) { int value_addr=in_builtin_find("thing"); if(value_addr<0) { std::cout<<">> [runtime] builtin_id: cannot find \"thing\".\n"; - ++error; return -1; } int ret_addr=nasal_vm.gc_alloc(vm_number); nasal_vm.gc_get(ret_addr).set_number((double)value_addr); return ret_addr; } -int nasal_runtime::builtin_int(int local_scope_addr) +int builtin_int(int local_scope_addr) { int value_addr=in_builtin_find("value"); if(value_addr<0 || nasal_vm.gc_get(value_addr).get_type()!=vm_number) { std::cout<<">> [runtime] builtin_int: \"value\" has wrong value type(must be number).\n"; - ++error; return -1; } int number=(int)nasal_vm.gc_get(value_addr).get_number(); @@ -356,13 +436,12 @@ int nasal_runtime::builtin_int(int local_scope_addr) nasal_vm.gc_get(ret_addr).set_number((double)number); return ret_addr; } -int nasal_runtime::builtin_num(int local_scope_addr) +int builtin_num(int local_scope_addr) { int value_addr=in_builtin_find("value"); if(value_addr<0 || !in_builtin_check(value_addr,vm_string)) { std::cout<<">> [runtime] builtin_num: \"value\" has wrong value type(must be string).\n"; - ++error; return -1; } std::string str=nasal_vm.gc_get(value_addr).get_string(); @@ -370,25 +449,23 @@ int nasal_runtime::builtin_num(int local_scope_addr) nasal_vm.gc_get(ret_addr).set_number(trans_string_to_number(str)); return ret_addr; } -int nasal_runtime::builtin_pop(int local_scope_addr) +int builtin_pop(int local_scope_addr) { int value_addr=in_builtin_find("vector"); if(value_addr<0 || nasal_vm.gc_get(value_addr).get_type()!=vm_vector) { std::cout<<">> [runtime] builtin_pop: \"vector\" has wrong value type(must be vector).\n"; - ++error; return -1; } int ret_addr=nasal_vm.gc_get(value_addr).get_vector().del_elem(); return ret_addr; } -int nasal_runtime::builtin_str(int local_scope_addr) +int builtin_str(int local_scope_addr) { int value_addr=in_builtin_find("number"); if(value_addr<0 || nasal_vm.gc_get(value_addr).get_type()!=vm_number) { std::cout<<">> [runtime] builtin_str: \"number\" has wrong value type(must be number).\n"; - ++error; return -1; } double number=nasal_vm.gc_get(value_addr).get_number(); @@ -396,13 +473,12 @@ int nasal_runtime::builtin_str(int local_scope_addr) nasal_vm.gc_get(ret_addr).set_string(trans_number_to_string(number)); return ret_addr; } -int nasal_runtime::builtin_size(int local_scope_addr) +int builtin_size(int local_scope_addr) { int value_addr=in_builtin_find("object"); if(value_addr<0) { std::cout<<">> [runtime] builtin_size: cannot find value \"object\".\n"; - ++error; return -1; } int type=nasal_vm.gc_get(value_addr).get_type(); @@ -427,20 +503,18 @@ int nasal_runtime::builtin_size(int local_scope_addr) } return ret_addr; } -int nasal_runtime::builtin_xor(int local_scope_addr) +int builtin_xor(int local_scope_addr) { int a_addr=in_builtin_find("a"); int b_addr=in_builtin_find("b"); if(a_addr<0 || nasal_vm.gc_get(a_addr).get_type()!=vm_number) { std::cout<<">> [runtime] builtin_xor: \"a\" has wrong value type(must be number).\n"; - ++error; return -1; } if(b_addr<0 || nasal_vm.gc_get(b_addr).get_type()!=vm_number) { std::cout<<">> [runtime] builtin_xor: \"b\" has wrong value type(must be number).\n"; - ++error; return -1; } int number_a=(int)nasal_vm.gc_get(a_addr).get_number(); @@ -449,20 +523,18 @@ int nasal_runtime::builtin_xor(int local_scope_addr) nasal_vm.gc_get(ret_addr).set_number((double)(number_a^number_b)); return ret_addr; } -int nasal_runtime::builtin_and(int local_scope_addr) +int builtin_and(int local_scope_addr) { int a_addr=in_builtin_find("a"); int b_addr=in_builtin_find("b"); if(a_addr<0 || nasal_vm.gc_get(a_addr).get_type()!=vm_number) { std::cout<<">> [runtime] builtin_and: \"a\" has wrong value type(must be number).\n"; - ++error; return -1; } if(b_addr<0 || nasal_vm.gc_get(b_addr).get_type()!=vm_number) { std::cout<<">> [runtime] builtin_and: \"b\" has wrong value type(must be number).\n"; - ++error; return -1; } int number_a=(int)nasal_vm.gc_get(a_addr).get_number(); @@ -471,20 +543,18 @@ int nasal_runtime::builtin_and(int local_scope_addr) nasal_vm.gc_get(ret_addr).set_number((double)(number_a&number_b)); return ret_addr; } -int nasal_runtime::builtin_or(int local_scope_addr) +int builtin_or(int local_scope_addr) { int a_addr=in_builtin_find("a"); int b_addr=in_builtin_find("b"); if(a_addr<0 || nasal_vm.gc_get(a_addr).get_type()!=vm_number) { std::cout<<">> [runtime] builtin_or: \"a\" has wrong value type(must be number).\n"; - ++error; return -1; } if(b_addr<0 || nasal_vm.gc_get(b_addr).get_type()!=vm_number) { std::cout<<">> [runtime] builtin_or: \"b\" has wrong value type(must be number).\n"; - ++error; return -1; } int number_a=(int)nasal_vm.gc_get(a_addr).get_number(); @@ -493,20 +563,18 @@ int nasal_runtime::builtin_or(int local_scope_addr) nasal_vm.gc_get(ret_addr).set_number((double)(number_a|number_b)); return ret_addr; } -int nasal_runtime::builtin_nand(int local_scope_addr) +int builtin_nand(int local_scope_addr) { int a_addr=in_builtin_find("a"); int b_addr=in_builtin_find("b"); if(a_addr<0 || nasal_vm.gc_get(a_addr).get_type()!=vm_number) { std::cout<<">> [runtime] builtin_nand: \"a\" has wrong value type(must be number).\n"; - ++error; return -1; } if(b_addr<0 || nasal_vm.gc_get(b_addr).get_type()!=vm_number) { std::cout<<">> [runtime] builtin_nand: \"b\" has wrong value type(must be number).\n"; - ++error; return -1; } int number_a=(int)nasal_vm.gc_get(a_addr).get_number(); @@ -515,13 +583,12 @@ int nasal_runtime::builtin_nand(int local_scope_addr) nasal_vm.gc_get(ret_addr).set_number((double)(~(number_a&number_b))); return ret_addr; } -int nasal_runtime::builtin_not(int local_scope_addr) +int builtin_not(int local_scope_addr) { int a_addr=in_builtin_find("a"); if(a_addr<0 || nasal_vm.gc_get(a_addr).get_type()!=vm_number) { std::cout<<">> [runtime] builtin_not: \"a\" has wrong value type(must be number).\n"; - ++error; return -1; } int number=(int)nasal_vm.gc_get(a_addr).get_number(); @@ -529,13 +596,12 @@ int nasal_runtime::builtin_not(int local_scope_addr) nasal_vm.gc_get(ret_addr).set_number((double)(~number)); return ret_addr; } -int nasal_runtime::builtin_sin(int local_scope_addr) +int builtin_sin(int local_scope_addr) { int value_addr=in_builtin_find("x"); if(value_addr<0 || nasal_vm.gc_get(value_addr).get_type()!=vm_number) { std::cout<<">> [runtime] builtin_sin: \"x\" has wrong value type(must be number).\n"; - ++error; return -1; } double number=nasal_vm.gc_get(value_addr).get_number(); @@ -543,13 +609,12 @@ int nasal_runtime::builtin_sin(int local_scope_addr) nasal_vm.gc_get(ret_addr).set_number(sin(number)); return ret_addr; } -int nasal_runtime::builtin_cos(int local_scope_addr) +int builtin_cos(int local_scope_addr) { int value_addr=in_builtin_find("x"); if(value_addr<0 || nasal_vm.gc_get(value_addr).get_type()!=vm_number) { std::cout<<">> [runtime] builtin_cos: \"x\" has wrong value type(must be number).\n"; - ++error; return -1; } double number=nasal_vm.gc_get(value_addr).get_number(); @@ -557,13 +622,12 @@ int nasal_runtime::builtin_cos(int local_scope_addr) nasal_vm.gc_get(ret_addr).set_number(cos(number)); return ret_addr; } -int nasal_runtime::builtin_tan(int local_scope_addr) +int builtin_tan(int local_scope_addr) { int value_addr=in_builtin_find("x"); if(value_addr<0 || nasal_vm.gc_get(value_addr).get_type()!=vm_number) { std::cout<<">> [runtime] builtin_tan: \"x\" has wrong value type(must be number).\n"; - ++error; return -1; } double number=nasal_vm.gc_get(value_addr).get_number(); @@ -571,13 +635,12 @@ int nasal_runtime::builtin_tan(int local_scope_addr) nasal_vm.gc_get(ret_addr).set_number(tan(number)); return ret_addr; } -int nasal_runtime::builtin_exp(int local_scope_addr) +int builtin_exp(int local_scope_addr) { int value_addr=in_builtin_find("x"); if(value_addr<0 || nasal_vm.gc_get(value_addr).get_type()!=vm_number) { std::cout<<">> [runtime] builtin_exp: \"x\" has wrong value type(must be number).\n"; - ++error; return -1; } double number=nasal_vm.gc_get(value_addr).get_number(); @@ -585,13 +648,12 @@ int nasal_runtime::builtin_exp(int local_scope_addr) nasal_vm.gc_get(ret_addr).set_number(exp(number)); return ret_addr; } -int nasal_runtime::builtin_ln(int local_scope_addr) +int builtin_ln(int local_scope_addr) { int value_addr=in_builtin_find("x"); if(value_addr<0 || nasal_vm.gc_get(value_addr).get_type()!=vm_number) { std::cout<<">> [runtime] builtin_ln: \"x\" has wrong value type(must be number).\n"; - ++error; return -1; } double number=nasal_vm.gc_get(value_addr).get_number(); @@ -599,13 +661,12 @@ int nasal_runtime::builtin_ln(int local_scope_addr) nasal_vm.gc_get(ret_addr).set_number(log(number)/log(2.7182818284590452354)); return ret_addr; } -int nasal_runtime::builtin_sqrt(int local_scope_addr) +int builtin_sqrt(int local_scope_addr) { int value_addr=in_builtin_find("x"); if(value_addr<0 || nasal_vm.gc_get(value_addr).get_type()!=vm_number) { std::cout<<">> [runtime] builtin_sqrt: \"x\" has wrong value type(must be number).\n"; - ++error; return -1; } double number=nasal_vm.gc_get(value_addr).get_number(); @@ -613,20 +674,18 @@ int nasal_runtime::builtin_sqrt(int local_scope_addr) nasal_vm.gc_get(ret_addr).set_number(sqrt(number)); return ret_addr; } -int nasal_runtime::builtin_atan2(int local_scope_addr) +int builtin_atan2(int local_scope_addr) { int x_value_addr=in_builtin_find("x"); int y_value_addr=in_builtin_find("y"); if(x_value_addr<0 || nasal_vm.gc_get(x_value_addr).get_type()!=vm_number) { std::cout<<">> [runtime] builtin_atan2: \"x\" has wrong value type(must be number).\n"; - ++error; return -1; } if(y_value_addr<0 || nasal_vm.gc_get(y_value_addr).get_type()!=vm_number) { std::cout<<">> [runtime] builtin_atan2: \"y\" has wrong value type(must be number).\n"; - ++error; return -1; } double x=nasal_vm.gc_get(x_value_addr).get_number(); @@ -635,13 +694,12 @@ int nasal_runtime::builtin_atan2(int local_scope_addr) nasal_vm.gc_get(ret_addr).set_number(atan2(y,x)); return ret_addr; } -int nasal_runtime::builtin_time(int local_scope_addr) +int builtin_time(int local_scope_addr) { int value_addr=in_builtin_find("begin_time"); if(value_addr<0 || nasal_vm.gc_get(value_addr).get_type()!=vm_number) { std::cout<<">> [runtime] builtin_time: \"begin_time\" has wrong value type(must be number).\n"; - ++error; return -1; } time_t begin_time=(time_t)nasal_vm.gc_get(value_addr).get_number(); @@ -649,20 +707,18 @@ int nasal_runtime::builtin_time(int local_scope_addr) nasal_vm.gc_get(ret_addr).set_number((double)time(&begin_time)); return ret_addr; } -int nasal_runtime::builtin_contains(int local_scope_addr) +int builtin_contains(int local_scope_addr) { int hash_addr=in_builtin_find("hash"); int key_addr=in_builtin_find("key"); if(hash_addr<0 || !in_builtin_check(hash_addr,vm_hash)) { std::cout<<">> [runtime] builtin_contains: \"hash\" has wrong type(must be hash).\n"; - ++error; return -1; } if(key_addr<0 || !in_builtin_check(key_addr,vm_string)) { std::cout<<">> [runtime] builtin_contains: \"key\" has wrong type(must be string).\n"; - ++error; return -1; } std::string key=nasal_vm.gc_get(key_addr).get_string(); @@ -671,20 +727,18 @@ int nasal_runtime::builtin_contains(int local_scope_addr) nasal_vm.gc_get(ret_addr).set_number((double)contains); return ret_addr; } -int nasal_runtime::builtin_delete(int local_scope_addr) +int builtin_delete(int local_scope_addr) { int hash_addr=in_builtin_find("hash"); int key_addr=in_builtin_find("key"); if(hash_addr<0 || !in_builtin_check(hash_addr,vm_hash)) { std::cout<<">> [runtime] builtin_delete: \"hash\" has wrong type(must be hash).\n"; - ++error; return -1; } if(key_addr<0 || !in_builtin_check(key_addr,vm_string)) { std::cout<<">> [runtime] builtin_delete: \"key\" has wrong type(must be string).\n"; - ++error; return -1; } std::string key=nasal_vm.gc_get(key_addr).get_string(); @@ -692,48 +746,44 @@ int nasal_runtime::builtin_delete(int local_scope_addr) int ret_addr=nasal_vm.gc_alloc(vm_nil); return ret_addr; } -int nasal_runtime::builtin_getkeys(int local_scope_addr) +int builtin_getkeys(int local_scope_addr) { int hash_addr=in_builtin_find("hash"); if(hash_addr<0 || !in_builtin_check(hash_addr,vm_hash)) { std::cout<<">> [runtime] builtin_delete: \"hash\" has wrong type(must be hash).\n"; - ++error; return -1; } int ret_addr=nasal_vm.gc_get(hash_addr).get_hash().get_keys(); return ret_addr; } -int nasal_runtime::builtin_import(int local_scope_addr) +int builtin_import(int local_scope_addr) { // this function is used in preprocessing. // this function will return nothing when running. - ++error; std::cout<<">> [runtime] builtin_import: cannot use import when running.\n"; int ret_addr=nasal_vm.gc_alloc(vm_nil); return ret_addr; } -int nasal_runtime::builtin_die(int local_scope_addr) +int builtin_die(int local_scope_addr) { int str_addr=in_builtin_find("str"); if(str_addr<0 || !in_builtin_check(str_addr,vm_string)) { std::cout<<">> [runtime] builtin_die: \"str\" has wrong type(must be string).\n"; - ++error; return -1; } - ++error; + builtin_die_state=1; std::cout<<">> [runtime] error: "<> [runtime] builtin_type: cannot find \"object\".\n"; - ++error; return -1; } int type=nasal_vm.gc_get(value_addr).get_type(); @@ -749,7 +799,7 @@ int nasal_runtime::builtin_type(int local_scope_addr) } return ret_addr; } -int nasal_runtime::builtin_substr(int local_scope_addr) +int builtin_substr(int local_scope_addr) { int str_addr=in_builtin_find("str"); int begin_addr=in_builtin_find("begin"); @@ -757,19 +807,16 @@ int nasal_runtime::builtin_substr(int local_scope_addr) if(str_addr<0 || !in_builtin_check(str_addr,vm_string)) { std::cout<<">> [runtime] builtin_substr: cannot find \"str\" or wrong type(must be string).\n"; - ++error; return -1; } if(begin_addr<0 || !in_builtin_check(begin_addr,vm_number)) { std::cout<<">> [runtime] builtin_substr: cannot find \"begin\" or wrong type(must be number).\n"; - ++error; return -1; } if(length_addr<0 || !in_builtin_check(length_addr,vm_number)) { std::cout<<">> [runtime] builtin_substr: cannot find \"length\" or wrong type(must be number).\n"; - ++error; return -1; } std::string str=nasal_vm.gc_get(str_addr).get_string(); @@ -778,7 +825,6 @@ int nasal_runtime::builtin_substr(int local_scope_addr) if(begin>=str.length() || begin+len>=str.length()) { std::cout<<">> [runtime] builtin_substr: index out of range.\n"; - ++error; return -1; } std::string tmp=""; diff --git a/nasal_gc.h b/nasal_gc.h index d523fb2..9758763 100644 --- a/nasal_gc.h +++ b/nasal_gc.h @@ -132,7 +132,6 @@ class nasal_virtual_machine } }; private: - bool error_info_output_switch; nasal_scalar error_returned_value; std::queue garbage_collector_free_space; std::vector garbage_collector_memory; @@ -143,14 +142,14 @@ public: ~nasal_virtual_machine(); void clear(); void debug(); - int gc_alloc(int); // garbage collector gives a new space - nasal_scalar& gc_get(int); // get scalar that stored in gc + int gc_alloc(int); // garbage collector gives a new space + nasal_scalar& gc_get(int); // get scalar that stored in gc void add_reference(int); void del_reference(int); - int mem_alloc(int); // memory gives a new space - int mem_free(int); // give space back to memory - int mem_change(int,int); // change value in memory space - int mem_get(int); // get value in memory space + int mem_alloc(int); // memory gives a new space + void mem_free(int); // give space back to memory + void mem_change(int,int); // change value in memory space + int mem_get(int); // get value in memory space }; /* @@ -161,10 +160,10 @@ public: nasal_virtual_machine nasal_vm; nasal_scalar nasal_scalar_calculator; // error values set here,if defined before nasal_vm,SIGSEGV will occur. -nasal_vector error_vector; -nasal_hash error_hash; +nasal_vector error_vector; +nasal_hash error_hash; nasal_function error_function; -nasal_closure error_closure; +nasal_closure error_closure; /*functions of nasal_vector*/ nasal_vector::nasal_vector() @@ -1092,12 +1091,10 @@ int nasal_scalar::nasal_scalar_cmp_greater_or_equal(int a_scalar_addr,int b_scal /*functions of nasal_virtual_machine*/ nasal_virtual_machine::nasal_virtual_machine() { - error_info_output_switch=true; return; } nasal_virtual_machine::~nasal_virtual_machine() { - error_info_output_switch=false; int gc_mem_size=garbage_collector_memory.size(); int mm_mem_size=memory_manager_memory.size(); for(int i=0;i> [vm] gc_get:unexpected memory \'"<> [vm] gc_add_ref:unexpected memory \'"<> [vm] gc_del_ref:unexpected memory \'"<del_reference(memory_manager_memory[memory_address>>8][memory_address&0xff]); memory_manager_free_space.push(memory_address); } - else - { - if(error_info_output_switch) - std::cout<<">> [vm] mem_free:unexpected memory \'"<del_reference(memory_manager_memory[memory_address>>8][memory_address&0xff]); memory_manager_memory[memory_address>>8][memory_address&0xff]=value_address; } - else - { - if(error_info_output_switch) - std::cout<<">> [vm] mem_change:unexpected memory \'"<>8][memory_address&0xff]; - else - { - if(error_info_output_switch) - std::cout<<">> [vm] mem_get:unexpected memory \'"<=tok_list_size) break; @@ -1204,7 +1203,7 @@ nasal_ast nasal_parse::multi_assgin() nasal_ast node; node.set_line(tok_list[ptr].line); node.set_type(ast_multi_assign); - node.add_child(multi_scalar()); + node.add_child(multi_scalar(true)); ++ptr; if(ptr>=tok_list_size || tok_list[ptr].type!=tok_equal) { @@ -1218,7 +1217,7 @@ nasal_ast nasal_parse::multi_assgin() return node; } if(tok_list[ptr].type==tok_left_curve) - node.add_child(check_multi_scalar()?multi_scalar():calculation()); + node.add_child(check_multi_scalar()?multi_scalar(false):calculation()); else node.add_child(calculation()); return node; diff --git a/nasal_runtime.h b/nasal_runtime.h index d24e78a..4093828 100644 --- a/nasal_runtime.h +++ b/nasal_runtime.h @@ -13,7 +13,7 @@ enum runtime_returned_state class nasal_runtime { private: - std::map builtin_func_hashmap; + 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 @@ -64,42 +64,6 @@ private: void multi_assignment(nasal_ast&,int); // builtin_func defined here - int builtin_print(int); - int builtin_append(int); - int builtin_setsize(int); - int builtin_system(int); - int builtin_input(int); - int builtin_sleep(int); - int builtin_finput(int); - int builtin_foutput(int); - int builtin_split(int); - int builtin_rand(int); - int builtin_id(int); - int builtin_int(int); - int builtin_num(int); - int builtin_pop(int); - int builtin_str(int); - int builtin_size(int); - int builtin_xor(int); - int builtin_and(int); - int builtin_or(int); - int builtin_nand(int); - int builtin_not(int); - int builtin_sin(int); - int builtin_cos(int); - int builtin_tan(int); - int builtin_exp(int); - int builtin_ln(int); - int builtin_sqrt(int); - int builtin_atan2(int); - int builtin_time(int); - int builtin_contains(int); - int builtin_delete(int); - int builtin_getkeys(int); - int builtin_import(int); - int builtin_die(int); - int builtin_type(int); - int builtin_substr(int); void load_builtin_function(); public: nasal_runtime(); @@ -132,50 +96,6 @@ void nasal_runtime::die(int line,std::string info) } void nasal_runtime::load_builtin_function() { - struct FUNC_TABLE - { - std::string func_name; - int (nasal_runtime::*func_pointer)(int x); - } builtin_func_table[]= - { - {"nasal_call_builtin_std_cout", nasal_runtime::builtin_print}, - {"nasal_call_builtin_push_back", nasal_runtime::builtin_append}, - {"nasal_call_builtin_set_size", nasal_runtime::builtin_setsize}, - {"nasal_call_builtin_system", nasal_runtime::builtin_system}, - {"nasal_call_builtin_input", nasal_runtime::builtin_input}, - {"nasal_call_builtin_sleep", nasal_runtime::builtin_sleep}, - {"nasal_call_builtin_finput", nasal_runtime::builtin_finput}, - {"nasal_call_builtin_foutput", nasal_runtime::builtin_foutput}, - {"nasal_call_builtin_split", nasal_runtime::builtin_split}, - {"nasal_call_builtin_rand", nasal_runtime::builtin_rand}, - {"nasal_call_builtin_get_id", nasal_runtime::builtin_id}, - {"nasal_call_builtin_trans_int", nasal_runtime::builtin_int}, - {"nasal_call_builtin_trans_num", nasal_runtime::builtin_num}, - {"nasal_call_builtin_pop_back", nasal_runtime::builtin_pop}, - {"nasal_call_builtin_trans_str", nasal_runtime::builtin_str}, - {"nasal_call_builtin_size", nasal_runtime::builtin_size}, - {"nasal_call_builtin_xor", nasal_runtime::builtin_xor}, - {"nasal_call_builtin_and", nasal_runtime::builtin_and}, - {"nasal_call_builtin_or", nasal_runtime::builtin_or}, - {"nasal_call_builtin_nand", nasal_runtime::builtin_nand}, - {"nasal_call_builtin_not", nasal_runtime::builtin_not}, - {"nasal_call_builtin_sin", nasal_runtime::builtin_sin}, - {"nasal_call_builtin_cos", nasal_runtime::builtin_cos}, - {"nasal_call_builtin_tan", nasal_runtime::builtin_tan}, - {"nasal_call_builtin_exp", nasal_runtime::builtin_exp}, - {"nasal_call_builtin_cpp_math_ln", nasal_runtime::builtin_ln}, - {"nasal_call_builtin_cpp_math_sqrt", nasal_runtime::builtin_sqrt}, - {"nasal_call_builtin_cpp_atan2", nasal_runtime::builtin_atan2}, - {"nasal_call_builtin_time", nasal_runtime::builtin_time}, - {"nasal_call_builtin_contains", nasal_runtime::builtin_contains}, - {"nasal_call_builtin_delete", nasal_runtime::builtin_delete}, - {"nasal_call_builtin_get_keys", nasal_runtime::builtin_getkeys}, - {"nasal_call_import", nasal_runtime::builtin_import}, - {"nasal_call_builtin_die", nasal_runtime::builtin_die}, - {"nasal_call_builtin_type", nasal_runtime::builtin_type}, - {"nasal_call_builtin_substr", nasal_runtime::builtin_substr}, - {"", NULL} - }; 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; @@ -187,6 +107,9 @@ void nasal_runtime::set_root(nasal_ast& parse_result) } void nasal_runtime::run() { + // this state is reserved for builtin_die + builtin_die_state=0; + this->error=0; this->function_returned_address=-1; @@ -582,14 +505,14 @@ int nasal_runtime::call_scalar(nasal_ast& node,int local_scope_addr) value_address=call_builtin_function(val_name,local_scope_addr); if(value_address>=0) return value_address; - } - if(value_address<0) - { - 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; + { + 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); } @@ -1042,7 +965,10 @@ int nasal_runtime::call_builtin_function(std::string val_name,int local_scope_ad int ret_value_addr=-1; int builtin_func_num=-1; if(builtin_func_hashmap.find(val_name)!=builtin_func_hashmap.end()) - ret_value_addr=(this->*builtin_func_hashmap[val_name])(local_scope_addr); + { + ret_value_addr=(*builtin_func_hashmap[val_name])(local_scope_addr); + error+=builtin_die_state; + } return ret_value_addr; } int nasal_runtime::call_scalar_mem(nasal_ast& node,int local_scope_addr) @@ -1468,11 +1394,6 @@ 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 && value_node.get_type()==ast_multi_scalar) - { - die(value_node.get_line(),"one identifier cannot accept too many values"); - return; - } if(define_node.get_type()==ast_identifier) { std::string new_name=define_node.get_str(); @@ -1535,11 +1456,6 @@ void nasal_runtime::multi_assignment(nasal_ast& node,int local_scope_addr) for(int i=0;i