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
> 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
@ -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/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
## basic value type
@ -284,7 +315,7 @@ a[-1,1,0:2,0:,:3,:,nil:8,3:nil,nil:nil];
## 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
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:
```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++:
```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
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
// 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();
@ -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
// generate return value,use gc::gc_alloc(type) to make a new value
// or use reserved reference nil_addr/one_addr/zero_addr
return nil_addr;
// or use reserved reference gc.nil_addr/gc.one_addr/gc.zero_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
{
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_std_cout",builtin_print},

View File

@ -10,54 +10,50 @@
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
// 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_append(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_setsize(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_system(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_input(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_sleep(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_fin(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_fout(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_split(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_rand(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_id(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_int(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_num(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_pop(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_str(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_size(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_xor(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_and(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_or(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_nand(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_not(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_sin(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_cos(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_tan(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_exp(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_ln(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_sqrt(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_atan2(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_time(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_contains(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_delete(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_getkeys(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_import(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_die(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_type(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_substr(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_streq(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_left(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_right(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_cmp(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_chr(std::unordered_map<int,nasal_val*>&,nasal_gc&);
nasal_val* builtin_print(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_append(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_setsize(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_system(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_input(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_sleep(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_fin(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_fout(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_split(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_rand(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_id(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_int(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_num(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_pop(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_str(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_size(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_xor(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_and(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_or(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_nand(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_not(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_sin(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_cos(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_tan(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_exp(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_ln(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_sqrt(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_atan2(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_time(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_contains(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_delete(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_getkeys(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_import(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_die(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_type(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_substr(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_streq(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_left(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_right(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_cmp(std::vector<nasal_val*>&,nasal_gc&);
nasal_val* builtin_chr(std::vector<nasal_val*>&,nasal_gc&);
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
{
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_std_cout", builtin_print },
@ -117,12 +113,13 @@ struct FUNC_TABLE
{"", 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
nasal_val* vector_val_addr=builtin_find("elements");
// local_scope[0] is reserved for 'me'
nasal_val* vec_addr=local_scope[1];
// 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();
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
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* elem_addr=builtin_find("elements");
nasal_val* vec_addr=local_scope[1];
nasal_val* elem_addr=local_scope[2];
if(vec_addr->type!=vm_vec)
{
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]);
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* size_addr=builtin_find("size");
nasal_val* vec_addr=local_scope[1];
nasal_val* size_addr=local_scope[2];
if(vec_addr->type!=vm_vec)
{
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;
}
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)
{
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;
}
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);
std::cin>>*ret_addr->ptr.str;
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)
{
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;
}
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)
{
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;
}
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* str_addr=builtin_find("str");
nasal_val* val_addr=local_scope[1];
nasal_val* str_addr=local_scope[2];
if(val_addr->type!=vm_str)
{
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;
}
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* string_val_addr=builtin_find("string");
nasal_val* delimeter_val_addr=local_scope[1];
nasal_val* string_val_addr=local_scope[2];
if(delimeter_val_addr->type!=vm_str)
{
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;
}
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)
{
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;
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);
char buf[32];
sprintf(buf,"0x%p",val_addr);
*ret_addr->ptr.str=buf;
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)
{
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;
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)
{
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();
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)
{
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;
}
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)
{
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();
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);
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;
}
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* b_addr=builtin_find("b");
nasal_val* a_addr=local_scope[1];
nasal_val* b_addr=local_scope[2];
if(a_addr->type!=vm_num)
{
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);
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* b_addr=builtin_find("b");
nasal_val* a_addr=local_scope[1];
nasal_val* b_addr=local_scope[2];
if(a_addr->type!=vm_num)
{
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);
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* b_addr=builtin_find("b");
nasal_val* a_addr=local_scope[1];
nasal_val* b_addr=local_scope[2];
if(a_addr->type!=vm_num)
{
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);
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* b_addr=builtin_find("b");
nasal_val* a_addr=local_scope[1];
nasal_val* b_addr=local_scope[2];
if(a_addr->type!=vm_num)
{
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));
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)
{
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);
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)
{
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);
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)
{
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);
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)
{
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);
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)
{
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);
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)
{
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));
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)
{
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);
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* y_val_addr=builtin_find("y");
nasal_val* x_val_addr=local_scope[1];
nasal_val* y_val_addr=local_scope[1];
if(x_val_addr->type!=vm_num)
{
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);
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)
{
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);
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* key_addr=builtin_find("key");
nasal_val* hash_addr=local_scope[1];
nasal_val* key_addr=local_scope[2];
if(hash_addr->type!=vm_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);
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* key_addr=builtin_find("key");
nasal_val* hash_addr=local_scope[1];
nasal_val* key_addr=local_scope[2];
if(hash_addr->type!=vm_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);
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)
{
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;
}
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 will return nothing when running.
builtin_err("import","cannot use import when running");
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)
{
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';
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);
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;
}
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* beg_addr=builtin_find("begin");
nasal_val* len_addr=builtin_find("length");
nasal_val* str_addr=local_scope[1];
nasal_val* beg_addr=local_scope[2];
nasal_val* len_addr=local_scope[3];
if(str_addr->type!=vm_str)
{
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);
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* b_addr=builtin_find("b");
nasal_val* a_addr=local_scope[1];
nasal_val* b_addr=local_scope[2];
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);
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* len_addr=builtin_find("length");
nasal_val* str_addr=local_scope[1];
nasal_val* len_addr=local_scope[2];
if(str_addr->type!=vm_str)
{
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);
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* len_addr=builtin_find("length");
nasal_val* str_addr=local_scope[1];
nasal_val* len_addr=local_scope[2];
if(str_addr->type!=vm_str)
{
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);
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* b_addr=builtin_find("b");
nasal_val* a_addr=local_scope[1];
nasal_val* b_addr=local_scope[2];
if(a_addr->type!=vm_str)
{
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());
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)
{
builtin_err("chr","\"code\" must be number");

View File

@ -4,6 +4,8 @@
enum op_code
{
op_nop,
op_intg,
op_intl,
op_loadg,
op_loadl,
op_pnum,
@ -71,6 +73,8 @@ struct
}code_table[]=
{
{op_nop, "nop "},
{op_intg, "intg "},
{op_intl, "intl "},
{op_loadg, "loadg "},
{op_loadl, "loadl "},
{op_pnum, "pnum "},
@ -97,7 +101,7 @@ struct
{op_subeq, "subeq "},
{op_muleq, "muleq "},
{op_diveq, "diveq "},
{op_lnkeq, "linkeq"},
{op_lnkeq, "lnkeq "},
{op_meq, "meq "},
{op_eq, "eq "},
{op_neq, "neq "},
@ -170,8 +174,8 @@ private:
void regist_number(double);
void regist_string(std::string&);
void add_sym(std::string);
bool local_find(std::string&);
bool global_find(std::string&);
int local_find(std::string&);
int global_find(std::string&);
void gen(unsigned char,unsigned int);
void pop_gen();
void nil_gen();
@ -255,36 +259,38 @@ void nasal_codegen::add_sym(std::string name)
for(int i=0;i<global.size();++i)
if(global[i]==name)
return;
regist_string(name);
global.push_back(name);
}
else
{
for(auto i=local.begin();i!=local.end();++i)
for(int j=0;j<i->size();++j)
if((*i)[j]==name)
return;
regist_string(name);
local.front().push_back(name);
for(int i=0;i<local.back().size();++i)
if(local.back()[i]==name)
return;
local.back().push_back(name);
}
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(int j=0;j<i->size();++j)
if((*i)[j]==name)
return true;
return false;
index=cnt+j;
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)
if(global[i]==name)
return true;
return false;
return i;
return -1;
}
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();
gen(op_newf,0);
int local_label=exec_code.size();
gen(op_intl,0);
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
// this symbol is only used in local scope(function's scope)
// this keyword is set to nil as default value
// 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];
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)
{
std::string str=tmp.get_str();
regist_string(str);
add_sym(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]);
std::string str=tmp.get_children()[0].get_str();
regist_string(str);
add_sym(str);
gen(op_defpara,string_table[str]);
}
else if(tmp.get_type()==ast_dynamic_id)
{
std::string str=tmp.get_str();
regist_string(str);
add_sym(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];
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)
{
@ -431,19 +445,25 @@ void nasal_codegen::call_gen(nasal_ast& ast)
void nasal_codegen::call_id(nasal_ast& ast)
{
std::string str=ast.get_str();
regist_string(str);
for(int i=0;builtin_func[i].func;++i)
if(builtin_func[i].name==str)
{
gen(op_callb,i);
return;
}
if(local_find(str))
gen(op_calll,string_table[str]);
else if(global_find(str))
gen(op_callg,string_table[str]);
else
die("cannot find symbol named \""+str+"\".",ast.get_line());
int index=local_find(str);
if(index>=0)
{
gen(op_calll,index);
return;
}
index=global_find(str);
if(index>=0)
{
gen(op_callg,index);
return;
}
die("cannot find symbol named \""+str+"\".",ast.get_line());
return;
}
@ -517,13 +537,19 @@ void nasal_codegen::mcall(nasal_ast& ast)
void nasal_codegen::mcall_id(nasal_ast& ast)
{
std::string str=ast.get_str();
regist_string(str);
if(local_find(str))
gen(op_mcalll,string_table[str]);
else if(global_find(str))
gen(op_mcallg,string_table[str]);
else
die("cannot find symbol named \""+str+"\".",ast.get_line());
int index=local_find(str);
if(index>=0)
{
gen(op_mcalll,index);
return;
}
index=global_find(str);
if(index>=0)
{
gen(op_mcallg,index);
return;
}
die("cannot find symbol named \""+str+"\".",ast.get_line());
return;
}
@ -547,7 +573,10 @@ void nasal_codegen::single_def(nasal_ast& ast)
std::string str=ast.get_children()[0].get_str();
add_sym(str);
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;
}
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();
add_sym(str);
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
@ -571,7 +603,10 @@ void nasal_codegen::multi_def(nasal_ast& ast)
gen(op_callvi,i);
std::string str=ast.get_children()[0].get_children()[i].get_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();
}
@ -762,7 +797,10 @@ void nasal_codegen::forindex_gen(nasal_ast& ast)
{
std::string str=ast.get_children()[0].get_children()[0].get_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
{
@ -789,7 +827,10 @@ void nasal_codegen::foreach_gen(nasal_ast& ast)
{
std::string str=ast.get_children()[0].get_children()[0].get_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
{
@ -997,7 +1038,7 @@ void nasal_codegen::main_progress(nasal_ast& ast)
global.clear();
local.clear();
gen(op_intg,0);
int size=ast.get_children().size();
for(int i=0;i<size;++i)
{
@ -1041,6 +1082,7 @@ void nasal_codegen::main_progress(nasal_ast& ast)
}
}
gen(op_nop,0);
exec_code[0].num=global.size();
num_res_table.resize(number_table.size());
str_res_table.resize(string_table.size());
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_callb:std::cout<<'('<<builtin_func[exec_code[index].num].name<<')';break;
case op_happ:
case op_callg:
case op_calll:
case op_mcallg:
case op_mcalll:
case op_pstr:
case op_callh:
case op_mcallh:
case op_para:
case op_defpara:
case op_dynpara:
case op_loadg:
case op_loadl:std::cout<<'('<<str_res_table[exec_code[index].num]<<')';break;
case op_dynpara:std::cout<<'('<<str_res_table[exec_code[index].num]<<')';break;
}
std::cout<<'\n';
return;

View File

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

View File

@ -8,7 +8,6 @@ private:
nasal_val**& stack_top; // stack top
/* values of nasal_vm */
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
std::stack<int> ret; // ptr stack stores address for function to return
std::stack<int> counter; // iterator stack for forindex/foreach
@ -20,6 +19,8 @@ private:
void die(std::string);
bool condition(nasal_val*);
void opr_nop();
void opr_intg();
void opr_intl();
void opr_loadg();
void opr_loadl();
void opr_pnum();
@ -101,12 +102,6 @@ void nasal_vm::init(
gc.gc_init(nums,strs);
str_table=strs; // get constant strings & symbols
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
return;
}
@ -150,6 +145,17 @@ void nasal_vm::opr_nop()
loop_mark=false;
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()
{
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;
if(!gc.local.empty())
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;
return;
}
@ -223,14 +231,16 @@ void nasal_vm::opr_happ()
}
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);
return;
}
void nasal_vm::opr_defpara()
{
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);
return;
}
@ -564,7 +574,7 @@ void nasal_vm::opr_callv()
return;
}
if(res->type==vm_func)
res->ptr.func->closure[me]=val;
res->ptr.func->closure[0]=val;// me
*stack_top=res;
}
else if(type==vm_str)
@ -618,7 +628,7 @@ void nasal_vm::opr_callh()
return;
}
if(res->type==vm_func)
res->ptr.func->closure[me]=val;
res->ptr.func->closure[0]=val;// me
*stack_top=res;
return;
}
@ -635,36 +645,36 @@ void nasal_vm::opr_callf()
// push new local scope
gc.local.push_back(func_addr->ptr.func->closure);
// load parameters
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::unordered_map<int,nasal_val*>& ref_closure=gc.local.back();
nasal_func& ref_func=*func_addr->ptr.func;
std::vector<nasal_val*>& ref_default=ref_func.default_para;
std::vector<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)
{
std::vector<nasal_val*>& ref_vec=para_addr->ptr.vec->elems;
int vec_size=ref_vec.size();
int para_size=ref_para.size();
std::vector<nasal_val*>& args=para_addr->ptr.vec->elems;
int args_size=args.size();
int para_size=ref_keys.size();
for(int i=0;i<para_size;++i)
{
if(i>=vec_size)
if(i>=args_size)
{
if(!ref_default[i])
{
die("callf: lack argument(s)");
return;
}
ref_closure[ref_para[i]]=ref_default[i];
ref_closure[i+ref_func.offset]=ref_default[i];
}
else
ref_closure[ref_para[i]]=ref_vec[i];
ref_closure[i+ref_func.offset]=args[i];
}
if(ref_func.dynpara>=0)
{
nasal_val* vec_addr=gc.gc_alloc(vm_vec);
for(int i=para_size;i<vec_size;++i)
vec_addr->ptr.vec->elems.push_back(ref_vec[i]);
ref_closure[ref_func.dynpara]=vec_addr;
for(int i=para_size;i<args_size;++i)
vec_addr->ptr.vec->elems.push_back(args[i]);
ref_closure[para_size+ref_func.offset]=vec_addr;
}
}
else
@ -672,20 +682,18 @@ void nasal_vm::opr_callf()
std::unordered_map<std::string,nasal_val*>& ref_hash=para_addr->ptr.hash->elems;
if(ref_func.dynpara>=0)
{
die("callf: special call cannot use dynamic parameter");
die("callf: special call cannot use dynamic argument");
return;
}
int para_size=ref_para.size();
for(int i=0;i<para_size;++i)
for(auto i=ref_keys.begin();i!=ref_keys.end();++i)
{
std::string& sym=str_table[ref_para[i]];
if(ref_hash.count(sym))
ref_closure[ref_para[i]]=ref_hash[sym];
else if(ref_default[i])
ref_closure[ref_para[i]]=ref_default[i];
if(ref_hash.count(i->first))
ref_closure[i->second+ref_func.offset]=ref_hash[i->first];
else if(ref_default[i->second])
ref_closure[i->second+ref_func.offset]=ref_default[i->second];
else
{
die("callf: lack argument(s)");
die("callf: lack argument(s): \""+i->first+"\"");
return;
}
}
@ -859,6 +867,8 @@ void nasal_vm::run()
static void (nasal_vm::*opr_table[])()=
{
&nasal_vm::opr_nop,
&nasal_vm::opr_intg,
&nasal_vm::opr_intl,
&nasal_vm::opr_loadg,
&nasal_vm::opr_loadl,
&nasal_vm::opr_pnum,

View File

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

View File

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