change scope from unordered_map to vector

This commit is contained in:
Valk Richard Li 2021-04-19 19:12:41 +08:00
parent 1a233fbe15
commit c5f4736984
8 changed files with 335 additions and 325 deletions

View File

@ -20,7 +20,11 @@ They found it easier for them to check errors before copying nasal-codes in nasa
# How to Compile # How to Compile
> g++ -std=c++11 main.cpp -o main.exe MUST USE -O2 !
pragma gcc optimize(2) seems useless when using g++
> g++ -std=c++11 -O2 main.cpp -o main.exe
# Parser # Parser
@ -121,6 +125,33 @@ Vapp and newf operand use .num to reduce the size of exec_code.
2021/4/3 update: Now it can count from 0 to 4000000-1 in 0.8s. 2021/4/3 update: Now it can count from 0 to 4000000-1 in 0.8s.
2021/4/19 update: Now it can count from 0 to 4e6-1 in 0.4s.
In this update i changed global and local scope from unordered_map to vector.
So the bytecode generator changed a lot.
```javascript
for(var i=0;i<4000000;i+=1);
```
```asm
.number 4e+006
0x00000000: intg 0x00000001
0x00000001: pzero 0x00000000
0x00000002: loadg 0x00000000
0x00000003: callg 0x00000000
0x00000004: pnum 0x00000000 (4e+006)
0x00000005: less 0x00000000
0x00000006: jf 0x0000000c
0x00000007: pone 0x00000000
0x00000008: mcallg 0x00000000
0x00000009: addeq 0x00000000
0x0000000a: pop 0x00000000
0x0000000b: jmp 0x00000003
0x0000000c: nop 0x00000000
```
# How to Use Nasal to Program # How to Use Nasal to Program
## basic value type ## basic value type
@ -284,7 +315,7 @@ a[-1,1,0:2,0:,:3,:,nil:8,3:nil,nil:nil];
## special function call ## special function call
This is of great use but is not very efficient. This is of great use but is not very efficient(because hashmap use string as the key to compare).
```javascript ```javascript
a(x:0,y:1,z:2); a(x:0,y:1,z:2);
@ -331,16 +362,18 @@ If you want to add your own built-in functions,define the function in nasal_buil
Definition: Definition:
```C++ ```C++
nasal_val* builtin_chr(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_chr(std::vector<nasal_val*>&,nasal_gc&);
``` ```
Then complete this function using C++: Then complete this function using C++:
```C++ ```C++
nasal_val* builtin_print(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_print(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
// get arguments by using builtin_find // get arguments by using builtin_find
nasal_val* vector_value=builtin_find("elements"); // find value with index begin from 1
// because local_scope[0] is reserved for value 'me'
nasal_val* vector_value=local_scope[1];
// main process // main process
// also check number of arguments and type here,if get a type error,use builtin_err and return nullptr // also check number of arguments and type here,if get a type error,use builtin_err and return nullptr
nasal_vec& ref_vec=vector_value->get_vector(); nasal_vec& ref_vec=vector_value->get_vector();
@ -360,8 +393,8 @@ nasal_val* builtin_print(std::unordered_map<int,nasal_val*>& local_scope,nasal_g
} }
// if a nasal value is not in use,use gc::del_reference to delete it // if a nasal value is not in use,use gc::del_reference to delete it
// generate return value,use gc::gc_alloc(type) to make a new value // generate return value,use gc::gc_alloc(type) to make a new value
// or use reserved reference nil_addr/one_addr/zero_addr // or use reserved reference gc.nil_addr/gc.one_addr/gc.zero_addr
return nil_addr; return gc.nil_addr;
} }
``` ```
@ -371,7 +404,7 @@ After that, write the built-in function's name(in nasal) and the function's poin
struct FUNC_TABLE struct FUNC_TABLE
{ {
std::string name; std::string name;
nasal_val* (*func)(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* (*func)(std::vector<nasal_val*>&,nasal_gc&);
} builtin_func[]= } builtin_func[]=
{ {
{"__builtin_std_cout",builtin_print}, {"__builtin_std_cout",builtin_print},

View File

@ -10,54 +10,50 @@
builtin function __builtin_std_cout is wrapped up by print builtin function __builtin_std_cout is wrapped up by print
*/ */
std::unordered_map<std::string,int> builtin_use_str;
// used to find values that builtin function uses
#define builtin_find(name) (local_scope[builtin_use_str[name]])
// declaration of builtin functions // declaration of builtin functions
// to add new builtin function,declare it here and write the definition below // to add new builtin function,declare it here and write the definition below
nasal_val* builtin_print(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_print(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_append(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_append(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_setsize(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_setsize(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_system(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_system(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_input(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_input(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_sleep(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_sleep(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_fin(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_fin(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_fout(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_fout(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_split(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_split(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_rand(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_rand(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_id(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_id(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_int(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_int(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_num(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_num(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_pop(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_pop(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_str(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_str(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_size(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_size(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_xor(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_xor(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_and(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_and(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_or(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_or(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_nand(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_nand(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_not(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_not(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_sin(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_sin(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_cos(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_cos(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_tan(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_tan(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_exp(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_exp(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_ln(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_ln(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_sqrt(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_sqrt(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_atan2(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_atan2(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_time(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_time(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_contains(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_contains(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_delete(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_delete(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_getkeys(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_getkeys(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_import(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_import(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_die(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_die(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_type(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_type(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_substr(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_substr(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_streq(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_streq(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_left(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_left(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_right(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_right(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_cmp(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_cmp(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_chr(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* builtin_chr(std::vector<nasal_val*>&,nasal_gc&);
void builtin_err(std::string func_name,std::string info) void builtin_err(std::string func_name,std::string info)
{ {
@ -70,7 +66,7 @@ void builtin_err(std::string func_name,std::string info)
struct FUNC_TABLE struct FUNC_TABLE
{ {
std::string name; std::string name;
nasal_val* (*func)(std::unordered_map<int,nasal_val*>&,nasal_gc&); nasal_val* (*func)(std::vector<nasal_val*>&,nasal_gc&);
} builtin_func[]= } builtin_func[]=
{ {
{"__builtin_std_cout", builtin_print }, {"__builtin_std_cout", builtin_print },
@ -117,12 +113,13 @@ struct FUNC_TABLE
{"", nullptr } {"", nullptr }
}; };
nasal_val* builtin_print(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_print(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
// get arguments // get arguments
nasal_val* vector_val_addr=builtin_find("elements"); // local_scope[0] is reserved for 'me'
nasal_val* vec_addr=local_scope[1];
// main process // main process
std::vector<nasal_val*>& ref_vec=vector_val_addr->ptr.vec->elems; std::vector<nasal_val*>& ref_vec=vec_addr->ptr.vec->elems;
int size=ref_vec.size(); int size=ref_vec.size();
for(int i=0;i<size;++i) for(int i=0;i<size;++i)
{ {
@ -140,10 +137,10 @@ nasal_val* builtin_print(std::unordered_map<int,nasal_val*>& local_scope,nasal_g
// generate return value // generate return value
return gc.nil_addr; return gc.nil_addr;
} }
nasal_val* builtin_append(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_append(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* vec_addr=builtin_find("vector"); nasal_val* vec_addr=local_scope[1];
nasal_val* elem_addr=builtin_find("elements"); nasal_val* elem_addr=local_scope[2];
if(vec_addr->type!=vm_vec) if(vec_addr->type!=vm_vec)
{ {
builtin_err("append","\"vector\" must be vector"); builtin_err("append","\"vector\" must be vector");
@ -156,10 +153,10 @@ nasal_val* builtin_append(std::unordered_map<int,nasal_val*>& local_scope,nasal_
ref_vec.push_back(ref_elems[i]); ref_vec.push_back(ref_elems[i]);
return gc.nil_addr; return gc.nil_addr;
} }
nasal_val* builtin_setsize(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_setsize(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* vec_addr=builtin_find("vector"); nasal_val* vec_addr=local_scope[1];
nasal_val* size_addr=builtin_find("size"); nasal_val* size_addr=local_scope[2];
if(vec_addr->type!=vm_vec) if(vec_addr->type!=vm_vec)
{ {
builtin_err("setsize","\"vector\" must be vector"); builtin_err("setsize","\"vector\" must be vector");
@ -187,9 +184,9 @@ nasal_val* builtin_setsize(std::unordered_map<int,nasal_val*>& local_scope,nasal
return gc.nil_addr; return gc.nil_addr;
} }
nasal_val* builtin_system(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_system(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* str_addr=builtin_find("str"); nasal_val* str_addr=local_scope[1];
if(str_addr->type!=vm_str) if(str_addr->type!=vm_str)
{ {
builtin_err("system","\"str\" must be string"); builtin_err("system","\"str\" must be string");
@ -199,16 +196,16 @@ nasal_val* builtin_system(std::unordered_map<int,nasal_val*>& local_scope,nasal_
return gc.nil_addr; return gc.nil_addr;
} }
nasal_val* builtin_input(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_input(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* ret_addr=gc.gc_alloc(vm_str); nasal_val* ret_addr=gc.gc_alloc(vm_str);
std::cin>>*ret_addr->ptr.str; std::cin>>*ret_addr->ptr.str;
return ret_addr; return ret_addr;
} }
nasal_val* builtin_sleep(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_sleep(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* val_addr=builtin_find("duration"); nasal_val* val_addr=local_scope[1];
if(val_addr->type!=vm_num) if(val_addr->type!=vm_num)
{ {
builtin_err("sleep","\"duration\" must be number"); builtin_err("sleep","\"duration\" must be number");
@ -219,9 +216,9 @@ nasal_val* builtin_sleep(std::unordered_map<int,nasal_val*>& local_scope,nasal_g
return gc.nil_addr; return gc.nil_addr;
} }
nasal_val* builtin_fin(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_fin(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* val_addr=builtin_find("filename"); nasal_val* val_addr=local_scope[1];
if(val_addr->type!=vm_str) if(val_addr->type!=vm_str)
{ {
builtin_err("io.fin","\"filename\" must be string"); builtin_err("io.fin","\"filename\" must be string");
@ -245,10 +242,10 @@ nasal_val* builtin_fin(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc&
return ret_addr; return ret_addr;
} }
nasal_val* builtin_fout(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_fout(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* val_addr=builtin_find("filename"); nasal_val* val_addr=local_scope[1];
nasal_val* str_addr=builtin_find("str"); nasal_val* str_addr=local_scope[2];
if(val_addr->type!=vm_str) if(val_addr->type!=vm_str)
{ {
builtin_err("io.fout","\"filename\" must be string"); builtin_err("io.fout","\"filename\" must be string");
@ -270,10 +267,10 @@ nasal_val* builtin_fout(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc
return gc.nil_addr; return gc.nil_addr;
} }
nasal_val* builtin_split(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_split(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* delimeter_val_addr=builtin_find("delimeter"); nasal_val* delimeter_val_addr=local_scope[1];
nasal_val* string_val_addr=builtin_find("string"); nasal_val* string_val_addr=local_scope[2];
if(delimeter_val_addr->type!=vm_str) if(delimeter_val_addr->type!=vm_str)
{ {
builtin_err("split","\"delimeter\" must be string"); builtin_err("split","\"delimeter\" must be string");
@ -338,9 +335,9 @@ nasal_val* builtin_split(std::unordered_map<int,nasal_val*>& local_scope,nasal_g
} }
return ret_addr; return ret_addr;
} }
nasal_val* builtin_rand(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_rand(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* val_addr=builtin_find("seed"); nasal_val* val_addr=local_scope[1];
if(val_addr->type!=vm_num && val_addr->type!=vm_nil) if(val_addr->type!=vm_num && val_addr->type!=vm_nil)
{ {
builtin_err("rand","\"seed\" must be nil or number"); builtin_err("rand","\"seed\" must be nil or number");
@ -358,18 +355,18 @@ nasal_val* builtin_rand(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc
ret_addr->ptr.num=num; ret_addr->ptr.num=num;
return ret_addr; return ret_addr;
} }
nasal_val* builtin_id(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_id(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* val_addr=builtin_find("thing"); nasal_val* val_addr=local_scope[1];
nasal_val* ret_addr=gc.gc_alloc(vm_str); nasal_val* ret_addr=gc.gc_alloc(vm_str);
char buf[32]; char buf[32];
sprintf(buf,"0x%p",val_addr); sprintf(buf,"0x%p",val_addr);
*ret_addr->ptr.str=buf; *ret_addr->ptr.str=buf;
return ret_addr; return ret_addr;
} }
nasal_val* builtin_int(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_int(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* val_addr=builtin_find("value"); nasal_val* val_addr=local_scope[1];
if(val_addr->type!=vm_num) if(val_addr->type!=vm_num)
{ {
builtin_err("int","\"value\" must be number"); builtin_err("int","\"value\" must be number");
@ -380,9 +377,9 @@ nasal_val* builtin_int(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc&
ret_addr->ptr.num=(double)number; ret_addr->ptr.num=(double)number;
return ret_addr; return ret_addr;
} }
nasal_val* builtin_num(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_num(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* val_addr=builtin_find("value"); nasal_val* val_addr=local_scope[1];
if(val_addr->type!=vm_str) if(val_addr->type!=vm_str)
{ {
builtin_err("num","\"value\" must be string"); builtin_err("num","\"value\" must be string");
@ -392,9 +389,9 @@ nasal_val* builtin_num(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc&
ret_addr->ptr.num=val_addr->to_number(); ret_addr->ptr.num=val_addr->to_number();
return ret_addr; return ret_addr;
} }
nasal_val* builtin_pop(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_pop(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* val_addr=builtin_find("vector"); nasal_val* val_addr=local_scope[1];
if(val_addr->type!=vm_vec) if(val_addr->type!=vm_vec)
{ {
builtin_err("pop","\"vector\" must be vector"); builtin_err("pop","\"vector\" must be vector");
@ -408,9 +405,9 @@ nasal_val* builtin_pop(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc&
} }
return gc.nil_addr; return gc.nil_addr;
} }
nasal_val* builtin_str(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_str(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* val_addr=builtin_find("number"); nasal_val* val_addr=local_scope[1];
if(val_addr->type!=vm_num) if(val_addr->type!=vm_num)
{ {
builtin_err("str","\"number\" must be number"); builtin_err("str","\"number\" must be number");
@ -420,9 +417,9 @@ nasal_val* builtin_str(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc&
*ret_addr->ptr.str=val_addr->to_string(); *ret_addr->ptr.str=val_addr->to_string();
return ret_addr; return ret_addr;
} }
nasal_val* builtin_size(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_size(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* val_addr=builtin_find("object"); nasal_val* val_addr=local_scope[1];
nasal_val* ret_addr=gc.gc_alloc(vm_num); nasal_val* ret_addr=gc.gc_alloc(vm_num);
switch(val_addr->type) switch(val_addr->type)
{ {
@ -435,10 +432,10 @@ nasal_val* builtin_size(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc
} }
return ret_addr; return ret_addr;
} }
nasal_val* builtin_xor(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_xor(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* a_addr=builtin_find("a"); nasal_val* a_addr=local_scope[1];
nasal_val* b_addr=builtin_find("b"); nasal_val* b_addr=local_scope[2];
if(a_addr->type!=vm_num) if(a_addr->type!=vm_num)
{ {
builtin_err("xor","\"a\" must be number"); builtin_err("xor","\"a\" must be number");
@ -455,10 +452,10 @@ nasal_val* builtin_xor(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc&
ret_addr->ptr.num=(number_a^number_b); ret_addr->ptr.num=(number_a^number_b);
return ret_addr; return ret_addr;
} }
nasal_val* builtin_and(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_and(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* a_addr=builtin_find("a"); nasal_val* a_addr=local_scope[1];
nasal_val* b_addr=builtin_find("b"); nasal_val* b_addr=local_scope[2];
if(a_addr->type!=vm_num) if(a_addr->type!=vm_num)
{ {
builtin_err("and","\"a\" must be number"); builtin_err("and","\"a\" must be number");
@ -475,10 +472,10 @@ nasal_val* builtin_and(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc&
ret_addr->ptr.num=(number_a&number_b); ret_addr->ptr.num=(number_a&number_b);
return ret_addr; return ret_addr;
} }
nasal_val* builtin_or(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_or(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* a_addr=builtin_find("a"); nasal_val* a_addr=local_scope[1];
nasal_val* b_addr=builtin_find("b"); nasal_val* b_addr=local_scope[2];
if(a_addr->type!=vm_num) if(a_addr->type!=vm_num)
{ {
builtin_err("or","\"a\" must be number"); builtin_err("or","\"a\" must be number");
@ -495,10 +492,10 @@ nasal_val* builtin_or(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc&
ret_addr->ptr.num=(number_a|number_b); ret_addr->ptr.num=(number_a|number_b);
return ret_addr; return ret_addr;
} }
nasal_val* builtin_nand(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_nand(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* a_addr=builtin_find("a"); nasal_val* a_addr=local_scope[1];
nasal_val* b_addr=builtin_find("b"); nasal_val* b_addr=local_scope[2];
if(a_addr->type!=vm_num) if(a_addr->type!=vm_num)
{ {
builtin_err("nand","\"a\" must be number"); builtin_err("nand","\"a\" must be number");
@ -515,9 +512,9 @@ nasal_val* builtin_nand(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc
ret_addr->ptr.num=(~(number_a&number_b)); ret_addr->ptr.num=(~(number_a&number_b));
return ret_addr; return ret_addr;
} }
nasal_val* builtin_not(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_not(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* a_addr=builtin_find("a"); nasal_val* a_addr=local_scope[1];
if(a_addr->type!=vm_num) if(a_addr->type!=vm_num)
{ {
builtin_err("not","\"a\" must be number"); builtin_err("not","\"a\" must be number");
@ -528,9 +525,9 @@ nasal_val* builtin_not(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc&
ret_addr->ptr.num=(~number); ret_addr->ptr.num=(~number);
return ret_addr; return ret_addr;
} }
nasal_val* builtin_sin(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_sin(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* val_addr=builtin_find("x"); nasal_val* val_addr=local_scope[1];
if(val_addr->type!=vm_num) if(val_addr->type!=vm_num)
{ {
builtin_err("sin","\"x\" must be number"); builtin_err("sin","\"x\" must be number");
@ -540,9 +537,9 @@ nasal_val* builtin_sin(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc&
ret_addr->ptr.num=sin(val_addr->ptr.num); ret_addr->ptr.num=sin(val_addr->ptr.num);
return ret_addr; return ret_addr;
} }
nasal_val* builtin_cos(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_cos(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* val_addr=builtin_find("x"); nasal_val* val_addr=local_scope[1];
if(val_addr->type!=vm_num) if(val_addr->type!=vm_num)
{ {
builtin_err("cos","\"x\" must be number"); builtin_err("cos","\"x\" must be number");
@ -552,9 +549,9 @@ nasal_val* builtin_cos(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc&
ret_addr->ptr.num=cos(val_addr->ptr.num); ret_addr->ptr.num=cos(val_addr->ptr.num);
return ret_addr; return ret_addr;
} }
nasal_val* builtin_tan(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_tan(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* val_addr=builtin_find("x"); nasal_val* val_addr=local_scope[1];
if(val_addr->type!=vm_num) if(val_addr->type!=vm_num)
{ {
builtin_err("tan","\"x\" must be number"); builtin_err("tan","\"x\" must be number");
@ -564,9 +561,9 @@ nasal_val* builtin_tan(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc&
ret_addr->ptr.num=tan(val_addr->ptr.num); ret_addr->ptr.num=tan(val_addr->ptr.num);
return ret_addr; return ret_addr;
} }
nasal_val* builtin_exp(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_exp(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* val_addr=builtin_find("x"); nasal_val* val_addr=local_scope[1];
if(val_addr->type!=vm_num) if(val_addr->type!=vm_num)
{ {
builtin_err("exp","\"x\" must be number"); builtin_err("exp","\"x\" must be number");
@ -576,9 +573,9 @@ nasal_val* builtin_exp(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc&
ret_addr->ptr.num=exp(val_addr->ptr.num); ret_addr->ptr.num=exp(val_addr->ptr.num);
return ret_addr; return ret_addr;
} }
nasal_val* builtin_ln(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_ln(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* val_addr=builtin_find("x"); nasal_val* val_addr=local_scope[1];
if(val_addr->type!=vm_num) if(val_addr->type!=vm_num)
{ {
builtin_err("ln","\"x\" must be number"); builtin_err("ln","\"x\" must be number");
@ -588,9 +585,9 @@ nasal_val* builtin_ln(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc&
ret_addr->ptr.num=(log(val_addr->ptr.num)/log(2.7182818284590452354)); ret_addr->ptr.num=(log(val_addr->ptr.num)/log(2.7182818284590452354));
return ret_addr; return ret_addr;
} }
nasal_val* builtin_sqrt(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_sqrt(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* val_addr=builtin_find("x"); nasal_val* val_addr=local_scope[1];
if(val_addr->type!=vm_num) if(val_addr->type!=vm_num)
{ {
builtin_err("sqrt","\"x\" must be number"); builtin_err("sqrt","\"x\" must be number");
@ -600,10 +597,10 @@ nasal_val* builtin_sqrt(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc
ret_addr->ptr.num=sqrt(val_addr->ptr.num); ret_addr->ptr.num=sqrt(val_addr->ptr.num);
return ret_addr; return ret_addr;
} }
nasal_val* builtin_atan2(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_atan2(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* x_val_addr=builtin_find("x"); nasal_val* x_val_addr=local_scope[1];
nasal_val* y_val_addr=builtin_find("y"); nasal_val* y_val_addr=local_scope[1];
if(x_val_addr->type!=vm_num) if(x_val_addr->type!=vm_num)
{ {
builtin_err("atan2","\"x\" must be number"); builtin_err("atan2","\"x\" must be number");
@ -618,9 +615,9 @@ nasal_val* builtin_atan2(std::unordered_map<int,nasal_val*>& local_scope,nasal_g
ret_addr->ptr.num=atan2(y_val_addr->ptr.num,x_val_addr->ptr.num); ret_addr->ptr.num=atan2(y_val_addr->ptr.num,x_val_addr->ptr.num);
return ret_addr; return ret_addr;
} }
nasal_val* builtin_time(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_time(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* val_addr=builtin_find("begin_time"); nasal_val* val_addr=local_scope[1];
if(val_addr->type!=vm_num) if(val_addr->type!=vm_num)
{ {
builtin_err("time","\"begin_time\" must be number"); builtin_err("time","\"begin_time\" must be number");
@ -631,10 +628,10 @@ nasal_val* builtin_time(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc
ret_addr->ptr.num=time(&begin_time); ret_addr->ptr.num=time(&begin_time);
return ret_addr; return ret_addr;
} }
nasal_val* builtin_contains(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_contains(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* hash_addr=builtin_find("hash"); nasal_val* hash_addr=local_scope[1];
nasal_val* key_addr=builtin_find("key"); nasal_val* key_addr=local_scope[2];
if(hash_addr->type!=vm_hash) if(hash_addr->type!=vm_hash)
{ {
builtin_err("contains","\"hash\" must be hash"); builtin_err("contains","\"hash\" must be hash");
@ -649,10 +646,10 @@ nasal_val* builtin_contains(std::unordered_map<int,nasal_val*>& local_scope,nasa
ret_addr->ptr.num=hash_addr->ptr.hash->check_contain(*key_addr->ptr.str); ret_addr->ptr.num=hash_addr->ptr.hash->check_contain(*key_addr->ptr.str);
return ret_addr; return ret_addr;
} }
nasal_val* builtin_delete(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_delete(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* hash_addr=builtin_find("hash"); nasal_val* hash_addr=local_scope[1];
nasal_val* key_addr=builtin_find("key"); nasal_val* key_addr=local_scope[2];
if(hash_addr->type!=vm_hash) if(hash_addr->type!=vm_hash)
{ {
builtin_err("delete","\"hash\" must be hash"); builtin_err("delete","\"hash\" must be hash");
@ -667,9 +664,9 @@ nasal_val* builtin_delete(std::unordered_map<int,nasal_val*>& local_scope,nasal_
hash_addr->ptr.hash->elems.erase(*key_addr->ptr.str); hash_addr->ptr.hash->elems.erase(*key_addr->ptr.str);
return gc.nil_addr; return gc.nil_addr;
} }
nasal_val* builtin_getkeys(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_getkeys(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* hash_addr=builtin_find("hash"); nasal_val* hash_addr=local_scope[1];
if(hash_addr->type!=vm_hash) if(hash_addr->type!=vm_hash)
{ {
builtin_err("keys","\"hash\" must be hash"); builtin_err("keys","\"hash\" must be hash");
@ -686,16 +683,16 @@ nasal_val* builtin_getkeys(std::unordered_map<int,nasal_val*>& local_scope,nasal
} }
return ret_addr; return ret_addr;
} }
nasal_val* builtin_import(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_import(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
// this function is used in preprocessing. // this function is used in preprocessing.
// this function will return nothing when running. // this function will return nothing when running.
builtin_err("import","cannot use import when running"); builtin_err("import","cannot use import when running");
return nullptr; return nullptr;
} }
nasal_val* builtin_die(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_die(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* str_addr=builtin_find("str"); nasal_val* str_addr=local_scope[1];
if(str_addr->type!=vm_str) if(str_addr->type!=vm_str)
{ {
builtin_err("die","\"str\" must be string"); builtin_err("die","\"str\" must be string");
@ -704,9 +701,9 @@ nasal_val* builtin_die(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc&
std::cout<<">> [vm] error: "<<*str_addr->ptr.str<<'\n'; std::cout<<">> [vm] error: "<<*str_addr->ptr.str<<'\n';
return nullptr; return nullptr;
} }
nasal_val* builtin_type(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_type(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* val_addr=builtin_find("object"); nasal_val* val_addr=local_scope[1];
nasal_val* ret_addr=gc.gc_alloc(vm_str); nasal_val* ret_addr=gc.gc_alloc(vm_str);
switch(val_addr->type) switch(val_addr->type)
{ {
@ -719,11 +716,11 @@ nasal_val* builtin_type(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc
} }
return ret_addr; return ret_addr;
} }
nasal_val* builtin_substr(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_substr(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* str_addr=builtin_find("str"); nasal_val* str_addr=local_scope[1];
nasal_val* beg_addr=builtin_find("begin"); nasal_val* beg_addr=local_scope[2];
nasal_val* len_addr=builtin_find("length"); nasal_val* len_addr=local_scope[3];
if(str_addr->type!=vm_str) if(str_addr->type!=vm_str)
{ {
builtin_err("substr","\"str\" must be string"); builtin_err("substr","\"str\" must be string");
@ -753,18 +750,18 @@ nasal_val* builtin_substr(std::unordered_map<int,nasal_val*>& local_scope,nasal_
*ret_addr->ptr.str=str.substr(beg,len); *ret_addr->ptr.str=str.substr(beg,len);
return ret_addr; return ret_addr;
} }
nasal_val* builtin_streq(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_streq(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* a_addr=builtin_find("a"); nasal_val* a_addr=local_scope[1];
nasal_val* b_addr=builtin_find("b"); nasal_val* b_addr=local_scope[2];
nasal_val* ret_addr=gc.gc_alloc(vm_num); nasal_val* ret_addr=gc.gc_alloc(vm_num);
ret_addr->ptr.num=(a_addr->type!=vm_str || b_addr->type!=vm_str)?0:(*a_addr->ptr.str==*b_addr->ptr.str); ret_addr->ptr.num=(a_addr->type!=vm_str || b_addr->type!=vm_str)?0:(*a_addr->ptr.str==*b_addr->ptr.str);
return ret_addr; return ret_addr;
} }
nasal_val* builtin_left(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_left(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* str_addr=builtin_find("string"); nasal_val* str_addr=local_scope[1];
nasal_val* len_addr=builtin_find("length"); nasal_val* len_addr=local_scope[2];
if(str_addr->type!=vm_str) if(str_addr->type!=vm_str)
{ {
builtin_err("left","\"string\" must be string"); builtin_err("left","\"string\" must be string");
@ -783,10 +780,10 @@ nasal_val* builtin_left(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc
*ret_addr->ptr.str=str.substr(0, len); *ret_addr->ptr.str=str.substr(0, len);
return ret_addr; return ret_addr;
} }
nasal_val* builtin_right(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_right(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* str_addr=builtin_find("string"); nasal_val* str_addr=local_scope[1];
nasal_val* len_addr=builtin_find("length"); nasal_val* len_addr=local_scope[2];
if(str_addr->type!=vm_str) if(str_addr->type!=vm_str)
{ {
builtin_err("right","\"string\" must be string"); builtin_err("right","\"string\" must be string");
@ -808,10 +805,10 @@ nasal_val* builtin_right(std::unordered_map<int,nasal_val*>& local_scope,nasal_g
*ret_addr->ptr.str=str.substr(srclen-len, srclen); *ret_addr->ptr.str=str.substr(srclen-len, srclen);
return ret_addr; return ret_addr;
} }
nasal_val* builtin_cmp(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_cmp(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* a_addr=builtin_find("a"); nasal_val* a_addr=local_scope[1];
nasal_val* b_addr=builtin_find("b"); nasal_val* b_addr=local_scope[2];
if(a_addr->type!=vm_str) if(a_addr->type!=vm_str)
{ {
builtin_err("cmp","\"a\" must be string"); builtin_err("cmp","\"a\" must be string");
@ -826,9 +823,9 @@ nasal_val* builtin_cmp(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc&
ret_addr->ptr.num=strcmp(a_addr->ptr.str->data(),b_addr->ptr.str->data()); ret_addr->ptr.num=strcmp(a_addr->ptr.str->data(),b_addr->ptr.str->data());
return ret_addr; return ret_addr;
} }
nasal_val* builtin_chr(std::unordered_map<int,nasal_val*>& local_scope,nasal_gc& gc) nasal_val* builtin_chr(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
{ {
nasal_val* code_addr=builtin_find("code"); nasal_val* code_addr=local_scope[1];
if(code_addr->type!=vm_num) if(code_addr->type!=vm_num)
{ {
builtin_err("chr","\"code\" must be number"); builtin_err("chr","\"code\" must be number");

View File

@ -4,6 +4,8 @@
enum op_code enum op_code
{ {
op_nop, op_nop,
op_intg,
op_intl,
op_loadg, op_loadg,
op_loadl, op_loadl,
op_pnum, op_pnum,
@ -71,6 +73,8 @@ struct
}code_table[]= }code_table[]=
{ {
{op_nop, "nop "}, {op_nop, "nop "},
{op_intg, "intg "},
{op_intl, "intl "},
{op_loadg, "loadg "}, {op_loadg, "loadg "},
{op_loadl, "loadl "}, {op_loadl, "loadl "},
{op_pnum, "pnum "}, {op_pnum, "pnum "},
@ -97,7 +101,7 @@ struct
{op_subeq, "subeq "}, {op_subeq, "subeq "},
{op_muleq, "muleq "}, {op_muleq, "muleq "},
{op_diveq, "diveq "}, {op_diveq, "diveq "},
{op_lnkeq, "linkeq"}, {op_lnkeq, "lnkeq "},
{op_meq, "meq "}, {op_meq, "meq "},
{op_eq, "eq "}, {op_eq, "eq "},
{op_neq, "neq "}, {op_neq, "neq "},
@ -170,8 +174,8 @@ private:
void regist_number(double); void regist_number(double);
void regist_string(std::string&); void regist_string(std::string&);
void add_sym(std::string); void add_sym(std::string);
bool local_find(std::string&); int local_find(std::string&);
bool global_find(std::string&); int global_find(std::string&);
void gen(unsigned char,unsigned int); void gen(unsigned char,unsigned int);
void pop_gen(); void pop_gen();
void nil_gen(); void nil_gen();
@ -255,36 +259,38 @@ void nasal_codegen::add_sym(std::string name)
for(int i=0;i<global.size();++i) for(int i=0;i<global.size();++i)
if(global[i]==name) if(global[i]==name)
return; return;
regist_string(name);
global.push_back(name); global.push_back(name);
} }
else else
{ {
for(auto i=local.begin();i!=local.end();++i) for(int i=0;i<local.back().size();++i)
for(int j=0;j<i->size();++j) if(local.back()[i]==name)
if((*i)[j]==name) return;
return; local.back().push_back(name);
regist_string(name);
local.front().push_back(name);
} }
return; return;
} }
bool nasal_codegen::local_find(std::string& name) int nasal_codegen::local_find(std::string& name)
{ {
int index=-1;
int cnt=0;
for(auto i=local.begin();i!=local.end();++i) for(auto i=local.begin();i!=local.end();++i)
{
for(int j=0;j<i->size();++j) for(int j=0;j<i->size();++j)
if((*i)[j]==name) if((*i)[j]==name)
return true; index=cnt+j;
return false; cnt+=i->size();
}
return index;
} }
bool nasal_codegen::global_find(std::string& name) int nasal_codegen::global_find(std::string& name)
{ {
for(int i=0;i<global.size();++i) for(int i=0;i<global.size();++i)
if(global[i]==name) if(global[i]==name)
return true; return i;
return false; return -1;
} }
void nasal_codegen::gen(unsigned char op,unsigned int index) void nasal_codegen::gen(unsigned char op,unsigned int index)
@ -357,15 +363,18 @@ void nasal_codegen::func_gen(nasal_ast& ast)
{ {
int newfunc_label=exec_code.size(); int newfunc_label=exec_code.size();
gen(op_newf,0); gen(op_newf,0);
int local_label=exec_code.size();
gen(op_intl,0);
std::vector<std::string> new_scope; std::vector<std::string> new_scope;
local.push_front(new_scope); // symbol table push front local.push_back(new_scope);
// add special keyword 'me' into symbol table // add special keyword 'me' into symbol table
// this symbol is only used in local scope(function's scope) // this symbol is only used in local scope(function's scope)
// this keyword is set to nil as default value // this keyword is set to nil as default value
// after calling a hash, this keyword is set to this hash // after calling a hash, this keyword is set to this hash
add_sym("me"); // this symbol's index will be 0
if(local.size()==1)
add_sym("me");
nasal_ast& ref_arg=ast.get_children()[0]; nasal_ast& ref_arg=ast.get_children()[0];
int arg_size=ref_arg.get_children().size(); int arg_size=ref_arg.get_children().size();
@ -375,6 +384,7 @@ void nasal_codegen::func_gen(nasal_ast& ast)
if(tmp.get_type()==ast_id) if(tmp.get_type()==ast_id)
{ {
std::string str=tmp.get_str(); std::string str=tmp.get_str();
regist_string(str);
add_sym(str); add_sym(str);
gen(op_para,string_table[str]); gen(op_para,string_table[str]);
} }
@ -382,12 +392,14 @@ void nasal_codegen::func_gen(nasal_ast& ast)
{ {
calc_gen(tmp.get_children()[1]); calc_gen(tmp.get_children()[1]);
std::string str=tmp.get_children()[0].get_str(); std::string str=tmp.get_children()[0].get_str();
regist_string(str);
add_sym(str); add_sym(str);
gen(op_defpara,string_table[str]); gen(op_defpara,string_table[str]);
} }
else if(tmp.get_type()==ast_dynamic_id) else if(tmp.get_type()==ast_dynamic_id)
{ {
std::string str=tmp.get_str(); std::string str=tmp.get_str();
regist_string(str);
add_sym(str); add_sym(str);
gen(op_dynpara,string_table[str]); gen(op_dynpara,string_table[str]);
} }
@ -398,7 +410,9 @@ void nasal_codegen::func_gen(nasal_ast& ast)
nasal_ast& block=ast.get_children()[1]; nasal_ast& block=ast.get_children()[1];
block_gen(block); block_gen(block);
local.pop_front(); // symbol table pop front for(auto i=local.begin();i!=local.end();++i)
exec_code[local_label].num+=i->size();
local.pop_back();
if(!block.get_children().size() || block.get_children().back().get_type()!=ast_return) if(!block.get_children().size() || block.get_children().back().get_type()!=ast_return)
{ {
@ -431,19 +445,25 @@ void nasal_codegen::call_gen(nasal_ast& ast)
void nasal_codegen::call_id(nasal_ast& ast) void nasal_codegen::call_id(nasal_ast& ast)
{ {
std::string str=ast.get_str(); std::string str=ast.get_str();
regist_string(str);
for(int i=0;builtin_func[i].func;++i) for(int i=0;builtin_func[i].func;++i)
if(builtin_func[i].name==str) if(builtin_func[i].name==str)
{ {
gen(op_callb,i); gen(op_callb,i);
return; return;
} }
if(local_find(str)) int index=local_find(str);
gen(op_calll,string_table[str]); if(index>=0)
else if(global_find(str)) {
gen(op_callg,string_table[str]); gen(op_calll,index);
else return;
die("cannot find symbol named \""+str+"\".",ast.get_line()); }
index=global_find(str);
if(index>=0)
{
gen(op_callg,index);
return;
}
die("cannot find symbol named \""+str+"\".",ast.get_line());
return; return;
} }
@ -517,13 +537,19 @@ void nasal_codegen::mcall(nasal_ast& ast)
void nasal_codegen::mcall_id(nasal_ast& ast) void nasal_codegen::mcall_id(nasal_ast& ast)
{ {
std::string str=ast.get_str(); std::string str=ast.get_str();
regist_string(str); int index=local_find(str);
if(local_find(str)) if(index>=0)
gen(op_mcalll,string_table[str]); {
else if(global_find(str)) gen(op_mcalll,index);
gen(op_mcallg,string_table[str]); return;
else }
die("cannot find symbol named \""+str+"\".",ast.get_line()); index=global_find(str);
if(index>=0)
{
gen(op_mcallg,index);
return;
}
die("cannot find symbol named \""+str+"\".",ast.get_line());
return; return;
} }
@ -547,7 +573,10 @@ void nasal_codegen::single_def(nasal_ast& ast)
std::string str=ast.get_children()[0].get_str(); std::string str=ast.get_children()[0].get_str();
add_sym(str); add_sym(str);
calc_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
gen(local.empty()?op_loadg:op_loadl,string_table[str]); if(local.empty())
gen(op_loadg,global_find(str));
else
gen(op_loadl,local_find(str));
return; return;
} }
void nasal_codegen::multi_def(nasal_ast& ast) void nasal_codegen::multi_def(nasal_ast& ast)
@ -560,7 +589,10 @@ void nasal_codegen::multi_def(nasal_ast& ast)
std::string str=ast.get_children()[0].get_children()[i].get_str(); std::string str=ast.get_children()[0].get_children()[i].get_str();
add_sym(str); add_sym(str);
calc_gen(ast.get_children()[1].get_children()[i]); calc_gen(ast.get_children()[1].get_children()[i]);
gen(local.empty()?op_loadg:op_loadl,string_table[str]); if(local.empty())
gen(op_loadg,global_find(str));
else
gen(op_loadl,local_find(str));
} }
} }
else else
@ -571,7 +603,10 @@ void nasal_codegen::multi_def(nasal_ast& ast)
gen(op_callvi,i); gen(op_callvi,i);
std::string str=ast.get_children()[0].get_children()[i].get_str(); std::string str=ast.get_children()[0].get_children()[i].get_str();
add_sym(str); add_sym(str);
gen(local.empty()?op_loadg:op_loadl,string_table[str]); if(local.empty())
gen(op_loadg,global_find(str));
else
gen(op_loadl,local_find(str));
} }
pop_gen(); pop_gen();
} }
@ -762,7 +797,10 @@ void nasal_codegen::forindex_gen(nasal_ast& ast)
{ {
std::string str=ast.get_children()[0].get_children()[0].get_str(); std::string str=ast.get_children()[0].get_children()[0].get_str();
add_sym(str); add_sym(str);
gen(local.empty()?op_loadg:op_loadl,string_table[str]); if(local.empty())
gen(op_loadg,global_find(str));
else
gen(op_loadl,local_find(str));
} }
else else
{ {
@ -789,7 +827,10 @@ void nasal_codegen::foreach_gen(nasal_ast& ast)
{ {
std::string str=ast.get_children()[0].get_children()[0].get_str(); std::string str=ast.get_children()[0].get_children()[0].get_str();
add_sym(str); add_sym(str);
gen(local.empty()?op_loadg:op_loadl,string_table[str]); if(local.empty())
gen(op_loadg,global_find(str));
else
gen(op_loadl,local_find(str));
} }
else else
{ {
@ -997,7 +1038,7 @@ void nasal_codegen::main_progress(nasal_ast& ast)
global.clear(); global.clear();
local.clear(); local.clear();
gen(op_intg,0);
int size=ast.get_children().size(); int size=ast.get_children().size();
for(int i=0;i<size;++i) for(int i=0;i<size;++i)
{ {
@ -1041,6 +1082,7 @@ void nasal_codegen::main_progress(nasal_ast& ast)
} }
} }
gen(op_nop,0); gen(op_nop,0);
exec_code[0].num=global.size();
num_res_table.resize(number_table.size()); num_res_table.resize(number_table.size());
str_res_table.resize(string_table.size()); str_res_table.resize(string_table.size());
for(auto i=number_table.begin();i!=number_table.end();++i) for(auto i=number_table.begin();i!=number_table.end();++i)
@ -1069,18 +1111,12 @@ void nasal_codegen::print_op(int index)
case op_pnum:std::cout<<'('<<num_res_table[exec_code[index].num]<<')';break; case op_pnum:std::cout<<'('<<num_res_table[exec_code[index].num]<<')';break;
case op_callb:std::cout<<'('<<builtin_func[exec_code[index].num].name<<')';break; case op_callb:std::cout<<'('<<builtin_func[exec_code[index].num].name<<')';break;
case op_happ: case op_happ:
case op_callg:
case op_calll:
case op_mcallg:
case op_mcalll:
case op_pstr: case op_pstr:
case op_callh: case op_callh:
case op_mcallh: case op_mcallh:
case op_para: case op_para:
case op_defpara: case op_defpara:
case op_dynpara: case op_dynpara:std::cout<<'('<<str_res_table[exec_code[index].num]<<')';break;
case op_loadg:
case op_loadl:std::cout<<'('<<str_res_table[exec_code[index].num]<<')';break;
} }
std::cout<<'\n'; std::cout<<'\n';
return; return;

View File

@ -38,11 +38,12 @@ struct nasal_hash
struct nasal_func struct nasal_func
{ {
int dynpara; int dynpara;// dynamic parameter name index in hash
int offset;
int entry; int entry;
std::vector<int> para;
std::vector<nasal_val*> default_para; std::vector<nasal_val*> default_para;
std::unordered_map<int,nasal_val*> closure; std::unordered_map<std::string,int> key_table;// parameter name hash
std::vector<nasal_val*> closure;
nasal_func(); nasal_func();
}; };
@ -298,18 +299,18 @@ std::string nasal_val::to_string()
struct nasal_gc struct nasal_gc
{ {
#define STACK_MAX_DEPTH (65536<<4) #define STACK_MAX_DEPTH (65536<<4)
nasal_val* zero_addr; // reserved address of nasal_val,type vm_num, 0 nasal_val* zero_addr; // reserved address of nasal_val,type vm_num, 0
nasal_val* one_addr; // reserved address of nasal_val,type vm_num, 1 nasal_val* one_addr; // reserved address of nasal_val,type vm_num, 1
nasal_val* nil_addr; // reserved address of nasal_val,type vm_nil nasal_val* nil_addr; // reserved address of nasal_val,type vm_nil
nasal_val* val_stack[STACK_MAX_DEPTH]; nasal_val* val_stack[STACK_MAX_DEPTH];
nasal_val** stack_top; // stack top nasal_val** stack_top; // stack top
std::vector<nasal_val*> num_addrs; // reserved address for const vm_num std::vector<nasal_val*> num_addrs; // reserved address for const vm_num
std::vector<nasal_val*> str_addrs; // reserved address for const vm_str std::vector<nasal_val*> str_addrs; // reserved address for const vm_str
std::vector<nasal_val*> slice_stack; // slice stack for vec[val,val,val:val] std::vector<nasal_val*> slice_stack; // slice stack for vec[val,val,val:val]
std::vector<nasal_val*> memory; // gc memory std::vector<nasal_val*> memory; // gc memory
std::queue <nasal_val*> free_list; // gc free list std::queue <nasal_val*> free_list; // gc free list
std::unordered_map<int,nasal_val*> global; std::vector<nasal_val*> global;
std::vector<std::unordered_map<int,nasal_val*> > local; std::list<std::vector<nasal_val*> > local;
void mark(); void mark();
void sweep(); void sweep();
void gc_init(std::vector<double>&,std::vector<std::string>&); void gc_init(std::vector<double>&,std::vector<std::string>&);
@ -325,15 +326,14 @@ void nasal_gc::mark()
one_addr->mark=true; one_addr->mark=true;
nil_addr->mark=true; nil_addr->mark=true;
for(auto i=global.begin();i!=global.end();++i) for(auto i=global.begin();i!=global.end();++i)
bfs.push(i->second); bfs.push(*i);
int size=num_addrs.size(); int size=num_addrs.size();
for(int i=0;i<size;++i) for(int i=0;i<size;++i)
bfs.push(num_addrs[i]); bfs.push(num_addrs[i]);
size=local.size(); size=local.size();
for(auto i=local.begin();i!=local.end();++i) for(auto i=local.begin();i!=local.end();++i)
for(auto j=i->begin();j!=i->end();++j) for(auto j=i->begin();j!=i->end();++j)
bfs.push(j->second); bfs.push(*j);
size=slice_stack.size(); size=slice_stack.size();
for(int i=0;i<size;++i) for(int i=0;i<size;++i)
bfs.push(slice_stack[i]); bfs.push(slice_stack[i]);
@ -343,32 +343,28 @@ void nasal_gc::mark()
{ {
nasal_val* tmp=bfs.front(); nasal_val* tmp=bfs.front();
bfs.pop(); bfs.pop();
if(tmp->mark) continue; if(!tmp || tmp->mark) continue;
tmp->mark=true; tmp->mark=true;
if(tmp->type==vm_vec) if(tmp->type==vm_vec)
{ {
std::vector<nasal_val*>& vec=tmp->ptr.vec->elems; std::vector<nasal_val*>& vec=tmp->ptr.vec->elems;
for(auto i=vec.begin();i!=vec.end();++i) for(auto i=vec.begin();i!=vec.end();++i)
if(!(*i)->mark) bfs.push(*i);
bfs.push(*i);
} }
else if(tmp->type==vm_hash) else if(tmp->type==vm_hash)
{ {
std::unordered_map<std::string,nasal_val*>& hash=tmp->ptr.hash->elems; std::unordered_map<std::string,nasal_val*>& hash=tmp->ptr.hash->elems;
for(auto i=hash.begin();i!=hash.end();++i) for(auto i=hash.begin();i!=hash.end();++i)
if(!i->second->mark) bfs.push(i->second);
bfs.push(i->second);
} }
else if(tmp->type==vm_func) else if(tmp->type==vm_func)
{ {
std::unordered_map<int,nasal_val*>& cls=tmp->ptr.func->closure; std::vector<nasal_val*>& cls=tmp->ptr.func->closure;
std::vector<nasal_val*>& def=tmp->ptr.func->default_para; std::vector<nasal_val*>& def=tmp->ptr.func->default_para;
for(auto i=cls.begin();i!=cls.end();++i) for(auto i=cls.begin();i!=cls.end();++i)
if(!i->second->mark) bfs.push(*i);
bfs.push(i->second);
for(auto i=def.begin();i!=def.end();++i) for(auto i=def.begin();i!=def.end();++i)
if(*i && !(*i)->mark) bfs.push(*i);
bfs.push(*i);
} }
} }
return; return;

View File

@ -8,7 +8,6 @@ private:
nasal_val**& stack_top; // stack top nasal_val**& stack_top; // stack top
/* values of nasal_vm */ /* values of nasal_vm */
int pc; // program counter int pc; // program counter
int me; // this is the index of "me" in str_table
bool loop_mark; // when mark is false,break the main loop bool loop_mark; // when mark is false,break the main loop
std::stack<int> ret; // ptr stack stores address for function to return std::stack<int> ret; // ptr stack stores address for function to return
std::stack<int> counter; // iterator stack for forindex/foreach std::stack<int> counter; // iterator stack for forindex/foreach
@ -20,6 +19,8 @@ private:
void die(std::string); void die(std::string);
bool condition(nasal_val*); bool condition(nasal_val*);
void opr_nop(); void opr_nop();
void opr_intg();
void opr_intl();
void opr_loadg(); void opr_loadg();
void opr_loadl(); void opr_loadl();
void opr_pnum(); void opr_pnum();
@ -101,12 +102,6 @@ void nasal_vm::init(
gc.gc_init(nums,strs); gc.gc_init(nums,strs);
str_table=strs; // get constant strings & symbols str_table=strs; // get constant strings & symbols
exec_code=exec; // get bytecodes exec_code=exec; // get bytecodes
builtin_use_str.clear(); // create map that builtin functions use
for(int i=0;i<str_table.size();++i)
builtin_use_str[str_table[i]]=i;
me=builtin_use_str.count("me")?builtin_use_str["me"]:-1; // get symbol index of 'me'
loop_mark=true; // set loop mark to true loop_mark=true; // set loop mark to true
return; return;
} }
@ -150,6 +145,17 @@ void nasal_vm::opr_nop()
loop_mark=false; loop_mark=false;
return; return;
} }
void nasal_vm::opr_intg()
{
gc.global.resize(exec_code[pc].num);
return;
}
void nasal_vm::opr_intl()
{
(*stack_top)->ptr.func->closure.resize(exec_code[pc].num);
(*stack_top)->ptr.func->closure[0]=gc.nil_addr;// me
return;
}
void nasal_vm::opr_loadg() void nasal_vm::opr_loadg()
{ {
gc.global[exec_code[pc].num]=*stack_top--; gc.global[exec_code[pc].num]=*stack_top--;
@ -203,7 +209,9 @@ void nasal_vm::opr_newf()
val->ptr.func->entry=exec_code[pc].num; val->ptr.func->entry=exec_code[pc].num;
if(!gc.local.empty()) if(!gc.local.empty())
val->ptr.func->closure=gc.local.back(); val->ptr.func->closure=gc.local.back();
val->ptr.func->closure[me]=gc.nil_addr; else
val->ptr.func->closure.push_back(gc.nil_addr);
val->ptr.func->offset=val->ptr.func->closure.size();
*(++stack_top)=val; *(++stack_top)=val;
return; return;
} }
@ -223,14 +231,16 @@ void nasal_vm::opr_happ()
} }
void nasal_vm::opr_para() void nasal_vm::opr_para()
{ {
(*stack_top)->ptr.func->para.push_back(exec_code[pc].num); int size=(*stack_top)->ptr.func->key_table.size();
(*stack_top)->ptr.func->key_table[str_table[exec_code[pc].num]]=size;
(*stack_top)->ptr.func->default_para.push_back(nullptr); (*stack_top)->ptr.func->default_para.push_back(nullptr);
return; return;
} }
void nasal_vm::opr_defpara() void nasal_vm::opr_defpara()
{ {
nasal_val* def_val=*stack_top--; nasal_val* def_val=*stack_top--;
(*stack_top)->ptr.func->para.push_back(exec_code[pc].num); int size=(*stack_top)->ptr.func->key_table.size();
(*stack_top)->ptr.func->key_table[str_table[exec_code[pc].num]]=size;
(*stack_top)->ptr.func->default_para.push_back(def_val); (*stack_top)->ptr.func->default_para.push_back(def_val);
return; return;
} }
@ -564,7 +574,7 @@ void nasal_vm::opr_callv()
return; return;
} }
if(res->type==vm_func) if(res->type==vm_func)
res->ptr.func->closure[me]=val; res->ptr.func->closure[0]=val;// me
*stack_top=res; *stack_top=res;
} }
else if(type==vm_str) else if(type==vm_str)
@ -618,7 +628,7 @@ void nasal_vm::opr_callh()
return; return;
} }
if(res->type==vm_func) if(res->type==vm_func)
res->ptr.func->closure[me]=val; res->ptr.func->closure[0]=val;// me
*stack_top=res; *stack_top=res;
return; return;
} }
@ -635,36 +645,36 @@ void nasal_vm::opr_callf()
// push new local scope // push new local scope
gc.local.push_back(func_addr->ptr.func->closure); gc.local.push_back(func_addr->ptr.func->closure);
// load parameters // load parameters
nasal_func& ref_func=*func_addr->ptr.func; nasal_func& ref_func=*func_addr->ptr.func;
std::vector<int>& ref_para=ref_func.para; std::vector<nasal_val*>& ref_default=ref_func.default_para;
std::vector<nasal_val*>& ref_default=ref_func.default_para; std::vector<nasal_val*>& ref_closure=gc.local.back();
std::unordered_map<int,nasal_val*>& ref_closure=gc.local.back(); std::unordered_map<std::string,int>& ref_keys=ref_func.key_table;
if(para_addr->type==vm_vec) if(para_addr->type==vm_vec)
{ {
std::vector<nasal_val*>& ref_vec=para_addr->ptr.vec->elems; std::vector<nasal_val*>& args=para_addr->ptr.vec->elems;
int vec_size=ref_vec.size(); int args_size=args.size();
int para_size=ref_para.size(); int para_size=ref_keys.size();
for(int i=0;i<para_size;++i) for(int i=0;i<para_size;++i)
{ {
if(i>=vec_size) if(i>=args_size)
{ {
if(!ref_default[i]) if(!ref_default[i])
{ {
die("callf: lack argument(s)"); die("callf: lack argument(s)");
return; return;
} }
ref_closure[ref_para[i]]=ref_default[i]; ref_closure[i+ref_func.offset]=ref_default[i];
} }
else else
ref_closure[ref_para[i]]=ref_vec[i]; ref_closure[i+ref_func.offset]=args[i];
} }
if(ref_func.dynpara>=0) if(ref_func.dynpara>=0)
{ {
nasal_val* vec_addr=gc.gc_alloc(vm_vec); nasal_val* vec_addr=gc.gc_alloc(vm_vec);
for(int i=para_size;i<vec_size;++i) for(int i=para_size;i<args_size;++i)
vec_addr->ptr.vec->elems.push_back(ref_vec[i]); vec_addr->ptr.vec->elems.push_back(args[i]);
ref_closure[ref_func.dynpara]=vec_addr; ref_closure[para_size+ref_func.offset]=vec_addr;
} }
} }
else else
@ -672,20 +682,18 @@ void nasal_vm::opr_callf()
std::unordered_map<std::string,nasal_val*>& ref_hash=para_addr->ptr.hash->elems; std::unordered_map<std::string,nasal_val*>& ref_hash=para_addr->ptr.hash->elems;
if(ref_func.dynpara>=0) if(ref_func.dynpara>=0)
{ {
die("callf: special call cannot use dynamic parameter"); die("callf: special call cannot use dynamic argument");
return; return;
} }
int para_size=ref_para.size(); for(auto i=ref_keys.begin();i!=ref_keys.end();++i)
for(int i=0;i<para_size;++i)
{ {
std::string& sym=str_table[ref_para[i]]; if(ref_hash.count(i->first))
if(ref_hash.count(sym)) ref_closure[i->second+ref_func.offset]=ref_hash[i->first];
ref_closure[ref_para[i]]=ref_hash[sym]; else if(ref_default[i->second])
else if(ref_default[i]) ref_closure[i->second+ref_func.offset]=ref_default[i->second];
ref_closure[ref_para[i]]=ref_default[i];
else else
{ {
die("callf: lack argument(s)"); die("callf: lack argument(s): \""+i->first+"\"");
return; return;
} }
} }
@ -859,6 +867,8 @@ void nasal_vm::run()
static void (nasal_vm::*opr_table[])()= static void (nasal_vm::*opr_table[])()=
{ {
&nasal_vm::opr_nop, &nasal_vm::opr_nop,
&nasal_vm::opr_intg,
&nasal_vm::opr_intl,
&nasal_vm::opr_loadg, &nasal_vm::opr_loadg,
&nasal_vm::opr_loadl, &nasal_vm::opr_loadl,
&nasal_vm::opr_pnum, &nasal_vm::opr_pnum,

View File

@ -137,7 +137,7 @@ while(error>0.001)
} }
cnt+=1; cnt+=1;
show+=1; show+=1;
if(show==250) if(show==300)
{ {
show=0; show=0;
print('epoch ',cnt,':',error,'\r'); print('epoch ',cnt,':',error,'\r');

View File

@ -2,7 +2,7 @@ import("lib.nas");
var t=1; var t=1;
var res=0; var res=0;
for(var m=1;m<1e6;m+=2) for(var m=1;m<4e6;m+=2)
{ {
res+=t*1/m; res+=t*1/m;
t*=-1; t*=-1;

View File

@ -1,62 +0,0 @@
import("lib.nas");
var global_value=0;
var global_hash=
{
var1:1,
var2:2,
var3:func(){return me.var2;}
};
println(global_value);
println(global_hash.var3());
var func1=func()
{
global_value=1;
println(global_value);
var closure_value=1;
var temp_value=1;
println(temp_value);
return func{return closure_value;};
}
var func2=func()
{
for(var temp_value=0;temp_value<100;temp_value+=1)
{
if(temp_value<10)
println(temp_value,"< 10");
elsif(10<=temp_value and temp_value<50)
println(temp_value,"< 50");
}
return;
}
var func3=func()
{
var fake_closure_value=1;
return func()
{
var fake_closure_value=2;
return fake_closure_value;
};
}
println(func1()());
func2();
println(func3()());
if(!global_value)
{
var temp_value=1;
if(temp_value)
{
var temp_value=2;
if(temp_value>=1)
{
var temp_value=3;
print(temp_value);
}
print(temp_value);
}
print(temp_value);
}