gc changed to mark-sweep

This commit is contained in:
Valk Richard Li 2021-03-27 01:08:05 +08:00
parent 569d5c6c6a
commit 144e6f45da
15 changed files with 1678 additions and 2000 deletions

View File

@ -342,7 +342,7 @@ struct FUNC_TABLE
nasal_val* (*func_pointer)(nasal_val* x,nasal_gc& gc); nasal_val* (*func_pointer)(nasal_val* x,nasal_gc& gc);
} builtin_func_table[]= } builtin_func_table[]=
{ {
{"nasal_call_builtin_std_cout",builtin_print}, {"__builtin_std_cout",builtin_print},
{"",NULL} {"",NULL}
}; };
``` ```

84
lib.nas
View File

@ -1,157 +1,157 @@
var import=func(filename) var import=func(filename)
{ {
nasal_call_import(filename); __builtin_import(filename);
return nil; return nil;
} }
var print=func(elements...) var print=func(elements...)
{ {
nasal_call_builtin_std_cout(elements); __builtin_std_cout(elements);
return nil; return nil;
}; };
var println=func(elements...) var println=func(elements...)
{ {
nasal_call_builtin_std_cout(elements); __builtin_std_cout(elements);
print('\n'); print('\n');
return nil; return nil;
} }
var append=func(vector,elements...) var append=func(vector,elements...)
{ {
nasal_call_builtin_push_back(vector,elements); __builtin_push_back(vector,elements);
return nil; return nil;
} }
var setsize=func(vector,size) var setsize=func(vector,size)
{ {
nasal_call_builtin_set_size(vector,size); __builtin_set_size(vector,size);
return nil; return nil;
} }
var system=func(str) var system=func(str)
{ {
nasal_call_builtin_system(str); __builtin_system(str);
return; return;
} }
var input=func() var input=func()
{ {
return nasal_call_builtin_input(); return __builtin_input();
} }
var sleep=func(duration) var sleep=func(duration)
{ {
nasal_call_builtin_sleep(duration); __builtin_sleep(duration);
return; return;
} }
var split=func(delimeter,string) var split=func(delimeter,string)
{ {
return nasal_call_builtin_split(delimeter,string); return __builtin_split(delimeter,string);
} }
var rand=func(seed=nil) var rand=func(seed=nil)
{ {
return nasal_call_builtin_rand(seed); return __builtin_rand(seed);
} }
var id=func(thing) var id=func(thing)
{ {
return nasal_call_builtin_get_id(thing); return __builtin_get_id(thing);
} }
var int=func(value) var int=func(value)
{ {
return nasal_call_builtin_trans_int(value); return __builtin_int(value);
} }
var num=func(value) var num=func(value)
{ {
return nasal_call_builtin_trans_num(value); return __builtin_num(value);
} }
var pop=func(vector) var pop=func(vector)
{ {
return nasal_call_builtin_pop_back(vector); return __builtin_pop_back(vector);
} }
var str=func(number) var str=func(number)
{ {
return nasal_call_builtin_trans_str(number); return __builtin_str(number);
} }
var size=func(object) var size=func(object)
{ {
return nasal_call_builtin_size(object); return __builtin_size(object);
} }
var contains=func(hash,key) var contains=func(hash,key)
{ {
return nasal_call_builtin_contains(hash,key); return __builtin_contains(hash,key);
} }
var delete=func(hash,key) var delete=func(hash,key)
{ {
nasal_call_builtin_delete(hash,key); __builtin_delete(hash,key);
return; return;
} }
var keys=func(hash) var keys=func(hash)
{ {
return nasal_call_builtin_get_keys(hash); return __builtin_get_keys(hash);
} }
var time=func(begin_time) var time=func(begin_time)
{ {
return nasal_call_builtin_time(begin_time); return __builtin_time(begin_time);
} }
var die=func(str) var die=func(str)
{ {
nasal_call_builtin_die(str); __builtin_die(str);
return nil; return nil;
} }
var typeof=func(object) var typeof=func(object)
{ {
return nasal_call_builtin_type(object); return __builtin_type(object);
} }
var substr=func(str,begin,length) var substr=func(str,begin,length)
{ {
return nasal_call_builtin_substr(str,begin,length); return __builtin_substr(str,begin,length);
} }
var streq=func(a,b) var streq=func(a,b)
{ {
return nasal_call_builtin_streq(a,b); return __builtin_streq(a,b);
} }
var left=func(string,length) var left=func(string,length)
{ {
return nasal_call_builtin_left(string,length); return __builtin_left(string,length);
} }
var right=func(string,length) var right=func(string,length)
{ {
return nasal_call_builtin_right(string,length); return __builtin_right(string,length);
} }
var cmp=func(a,b) var cmp=func(a,b)
{ {
return nasal_call_builtin_cmp(a,b); return __builtin_cmp(a,b);
} }
var chr=func(code) #//Unlike in FG, this chr does not support Extended ASCII var chr=func(code) #//Unlike in FG, this chr does not support Extended ASCII
{ {
return nasal_call_builtin_chr(code); return __builtin_chr(code);
} }
var io= var io=
{ {
fin:func(filename) fin:func(filename)
{ {
return nasal_call_builtin_finput(filename); return __builtin_fin(filename);
}, },
fout:func(filename,str) fout:func(filename,str)
{ {
nasal_call_builtin_foutput(filename,str); __builtin_fout(filename,str);
return; return;
} }
}; };
var bits= var bits=
{ {
bitxor: func(a,b){return nasal_call_builtin_xor(a,b); }, bitxor: func(a,b){return __builtin_xor(a,b); },
bitand: func(a,b){return nasal_call_builtin_and(a,b); }, bitand: func(a,b){return __builtin_and(a,b); },
bitor: func(a,b){return nasal_call_builtin_or(a,b); }, bitor: func(a,b){return __builtin_or(a,b); },
bitnand: func(a,b){return nasal_call_builtin_nand(a,b);}, bitnand: func(a,b){return __builtin_nand(a,b);},
bitnot: func(a) {return nasal_call_builtin_not(a); } bitnot: func(a) {return __builtin_not(a); }
}; };
var math= var math=
{ {
e: 2.7182818284590452354, e: 2.7182818284590452354,
pi: 3.14159265358979323846264338327950288, pi: 3.14159265358979323846264338327950288,
sin: func(x) {return nasal_call_builtin_sin(x); }, sin: func(x) {return __builtin_sin(x); },
cos: func(x) {return nasal_call_builtin_cos(x); }, cos: func(x) {return __builtin_cos(x); },
tan: func(x) {return nasal_call_builtin_tan(x); }, tan: func(x) {return __builtin_tan(x); },
exp: func(x) {return nasal_call_builtin_exp(x); }, exp: func(x) {return __builtin_exp(x); },
ln: func(x) {return nasal_call_builtin_cpp_math_ln(x); }, ln: func(x) {return __builtin_ln(x); },
sqrt: func(x) {return nasal_call_builtin_cpp_math_sqrt(x);}, sqrt: func(x) {return __builtin_sqrt(x); },
atan2: func(x,y){return nasal_call_builtin_cpp_atan2(x,y); } atan2: func(x,y){return __builtin_atan2(x,y);}
}; };

View File

@ -10,15 +10,15 @@ nasal_vm vm;
void help() void help()
{ {
std::cout std::cout
<<">> [\"file\"] input a file name.\n" <<">> [\"file\"] input a file name. \n"
<<">> [help ] show help.\n" <<">> [help ] show help. \n"
<<">> [clear ] clear the screen.\n" <<">> [clear ] clear the screen. \n"
<<">> [lex ] use lexer to turn code into tokens.\n" <<">> [lex ] use lexer to turn code into tokens. \n"
<<">> [ast ] do parsing and check the abstract syntax tree.\n" <<">> [ast ] do parsing and check the abstract syntax tree.\n"
<<">> [code ] show byte code.\n" <<">> [code ] show byte code. \n"
<<">> [exec ] execute program on bytecode vm.\n" <<">> [exec ] execute program on bytecode vm. \n"
<<">> [logo ] print logo of nasal .\n" <<">> [logo ] print logo of nasal . \n"
<<">> [exit ] quit nasal interpreter.\n"; <<">> [exit ] quit nasal interpreter. \n";
return; return;
} }
@ -90,11 +90,13 @@ void execute(std::string& command)
codegen.print_byte_code(); codegen.print_byte_code();
return; return;
} }
vm.run( vm.init(
codegen.get_string_table(), codegen.get_str_table(),
codegen.get_number_table(), codegen.get_num_table(),
codegen.get_exec_code() codegen.get_exec_code()
); );
vm.run();
vm.clear();
return; return;
} }

13
nasal.h
View File

@ -25,7 +25,7 @@
check if a string can be converted to a number check if a string can be converted to a number
if this string cannot be converted to a number,it will return nan if this string cannot be converted to a number,it will return nan
*/ */
inline double hex_to_double(std::string str) inline double hex_to_double(std::string& str)
{ {
double ret=0; double ret=0;
for(int i=2;str[i];++i) for(int i=2;str[i];++i)
@ -42,7 +42,7 @@ inline double hex_to_double(std::string str)
} }
return ret; return ret;
} }
inline double oct_to_double(std::string str) inline double oct_to_double(std::string& str)
{ {
double ret=0; double ret=0;
for(int i=2;str[i];++i) for(int i=2;str[i];++i)
@ -55,7 +55,7 @@ inline double oct_to_double(std::string str)
} }
return ret; return ret;
} }
inline double dec_to_double(std::string str,int len) inline double dec_to_double(std::string& str,int len)
{ {
double ret=0; double ret=0;
int i=0; int i=0;
@ -96,14 +96,13 @@ inline double dec_to_double(std::string str,int len)
} }
double trans_string_to_number(std::string str) double trans_string_to_number(std::string str)
{ {
double is_negative=1; bool is_negative=false;
int len=str.length(); int len=str.length();
double ret_num=0; double ret_num=0;
if(!len) return std::nan("");
if(str[0]=='-' || str[0]=='+') if(str[0]=='-' || str[0]=='+')
{ {
if(len==1) return std::nan(""); if(len==1) return std::nan("");
is_negative=(str[0]=='-'?-1:1); is_negative=(str[0]=='-');
str=str.substr(1,len--); str=str.substr(1,len--);
} }
if(len>1 && str[0]=='0' && str[1]=='x') if(len>1 && str[0]=='0' && str[1]=='x')
@ -112,7 +111,7 @@ double trans_string_to_number(std::string str)
ret_num=oct_to_double(str); ret_num=oct_to_double(str);
else else
ret_num=dec_to_double(str,len); ret_num=dec_to_double(str,len);
return is_negative*ret_num; return is_negative?-ret_num:ret_num;
} }
/* /*

View File

@ -3,7 +3,9 @@
enum ast_node enum ast_node
{ {
ast_null=0,ast_root,ast_block, ast_null=0,
ast_root,
ast_block,
ast_nil,ast_num,ast_str,ast_id,ast_func,ast_hash,ast_vec, ast_nil,ast_num,ast_str,ast_id,ast_func,ast_hash,ast_vec,
ast_hashmember,ast_call,ast_callh,ast_callv,ast_callf,ast_subvec, ast_hashmember,ast_call,ast_callh,ast_callv,ast_callf,ast_subvec,
ast_args,ast_default_arg,ast_dynamic_id, ast_args,ast_default_arg,ast_dynamic_id,
@ -116,68 +118,68 @@ public:
nasal_ast::nasal_ast(int init_line=0,int init_type=ast_null) nasal_ast::nasal_ast(int init_line=0,int init_type=ast_null)
{ {
this->line=init_line; line=init_line;
this->type=init_type; type=init_type;
return; return;
} }
nasal_ast::nasal_ast(const nasal_ast& tmp) nasal_ast::nasal_ast(const nasal_ast& tmp)
{ {
this->line=tmp.line; line=tmp.line;
this->type=tmp.type; type=tmp.type;
this->str=tmp.str; str=tmp.str;
this->num=tmp.num; num=tmp.num;
this->children=tmp.children; children=tmp.children;
return; return;
} }
nasal_ast::~nasal_ast() nasal_ast::~nasal_ast()
{ {
this->children.clear(); children.clear();
return; return;
} }
nasal_ast& nasal_ast::operator=(const nasal_ast& tmp) nasal_ast& nasal_ast::operator=(const nasal_ast& tmp)
{ {
this->line=tmp.line; line=tmp.line;
this->type=tmp.type; type=tmp.type;
this->str=tmp.str; str=tmp.str;
this->num=tmp.num; num=tmp.num;
this->children=tmp.children; children=tmp.children;
return *this; return *this;
} }
void nasal_ast::clear() void nasal_ast::clear()
{ {
this->line=0; line=0;
this->str=""; str="";
this->num=0; num=0;
this->type=ast_null; type=ast_null;
this->children.clear(); children.clear();
return; return;
} }
void nasal_ast::set_line(int l) void nasal_ast::set_line(int l)
{ {
this->line=l; line=l;
return; return;
} }
void nasal_ast::set_type(int t) void nasal_ast::set_type(int t)
{ {
this->type=t; type=t;
return; return;
} }
void nasal_ast::set_str(std::string& s) void nasal_ast::set_str(std::string& s)
{ {
this->str=s; str=s;
return; return;
} }
void nasal_ast::set_num(double n) void nasal_ast::set_num(double n)
{ {
this->num=n; num=n;
return; return;
} }
@ -189,43 +191,43 @@ void nasal_ast::add_child(nasal_ast ast)
int nasal_ast::get_line() int nasal_ast::get_line()
{ {
return this->line; return line;
} }
int nasal_ast::get_type() int nasal_ast::get_type()
{ {
return this->type; return type;
} }
std::string nasal_ast::get_str() std::string nasal_ast::get_str()
{ {
return this->str; return str;
} }
double nasal_ast::get_num() double nasal_ast::get_num()
{ {
return this->num; return num;
} }
std::vector<nasal_ast>& nasal_ast::get_children() std::vector<nasal_ast>& nasal_ast::get_children()
{ {
return this->children; return children;
} }
void nasal_ast::print_ast(int depth) void nasal_ast::print_ast(int depth)
{ {
std::string indentation=""; std::string indentation="";
for(int i=0;i<depth;++i) indentation+="| "; for(int i=0;i<depth;++i) indentation+="| ";
indentation+=ast_name(this->type); indentation+=ast_name(type);
std::cout<<indentation; std::cout<<indentation;
if(this->type==ast_str || this->type==ast_id || this->type==ast_dynamic_id || this->type==ast_callh) if(type==ast_str || type==ast_id || type==ast_dynamic_id || type==ast_callh)
std::cout<<":"<<this->str; std::cout<<":"<<str;
else if(this->type==ast_num) else if(type==ast_num)
std::cout<<":"<<this->num; std::cout<<":"<<num;
std::cout<<'\n'; std::cout<<'\n';
int child_size=this->children.size(); int child_size=children.size();
for(int i=0;i<child_size;++i) for(int i=0;i<child_size;++i)
this->children[i].print_ast(depth+1); children[i].print_ast(depth+1);
return; return;
} }

File diff suppressed because it is too large Load Diff

View File

@ -5,40 +5,62 @@ enum op_code
{ {
op_nop, op_nop,
op_load,// load value in value_stack to identifier op_load,// load value in value_stack to identifier
op_pushnum, op_loadg,
op_pushone, op_loadl,
op_pushzero, op_pnum,
op_pushnil, op_pone,
op_pushstr, op_pzero,
op_newvec,op_newhash,op_newfunc, op_pnil,
op_vecapp,op_hashapp, op_pstr,
op_para,op_defpara,op_dynpara, op_newv,
op_unot,op_usub, op_newh,
op_add,op_sub,op_mul,op_div,op_lnk, op_newf,
op_addeq,op_subeq,op_muleq,op_diveq,op_lnkeq,op_meq, op_vapp,
op_eq,op_neq,op_less,op_leq,op_grt,op_geq, op_happ,
op_para,
op_defpara,
op_dynpara,
op_unot,
op_usub,
op_add,
op_sub,
op_mul,
op_div,
op_lnk,
op_addeq,
op_subeq,
op_muleq,
op_diveq,
op_lnkeq,
op_meq,
op_eq,
op_neq,
op_less,
op_leq,
op_grt,
op_geq,
op_pop, op_pop,
op_jmp, // jump with no condition op_jmp, // jump with no condition
op_jmptrue, // used in operator and/or,jmp when condition is true and DO NOT POP op_jt, // used in operator and/or,jmp when condition is true and DO NOT POP
op_jmpfalse, // used in conditional/loop,jmp when condition is false and POP STACK op_jf, // used in conditional/loop,jmp when condition is false and POP STACK
op_counter, // add counter for forindex/foreach op_counter, // add counter for forindex/foreach
op_cntpop, // pop counter op_cntpop, // pop counter
op_forindex, // index counter on the top of forindex_stack plus 1 op_findex, // index counter on the top of forindex_stack plus 1
op_foreach, // index counter on the top of forindex_stack plus 1 and get the value in vector op_feach, // index counter on the top of forindex_stack plus 1 and get the value in vector
op_call, // call identifier op_call, // call identifier
op_callv, // call vec[index] op_callv, // call vec[index]
op_callvi, // call vec[immediate] (used in multi-assign/multi-define) op_callvi, // call vec[immediate] (used in multi-assign/multi-define)
op_callh, // call hash.label op_callh, // call hash.label
op_callf, // call function(parameters) op_callf, // call function(parameters)
op_builtincall,// call builtin-function op_callb, // call builtin-function
op_slicebegin, // begin of slice like: vec[1,2,3:6,0,-1] op_slcbegin, // begin of slice like: vec[1,2,3:6,0,-1]
op_sliceend, // end of slice op_slcend, // end of slice
op_slice, // slice like vec[1] op_slc, // slice like vec[1]
op_slice2, // slice like vec[nil:10] op_slc2, // slice like vec[nil:10]
op_mcall, // get memory of identifier op_mcall, // get memory of identifier
op_mcallv, // get memory of vec[index] op_mcallv, // get memory of vec[index]
op_mcallh, // get memory of hash.label op_mcallh, // get memory of hash.label
op_return // return op_ret // return
}; };
struct struct
@ -49,18 +71,20 @@ struct
{ {
{op_nop, "nop "}, {op_nop, "nop "},
{op_load, "load "}, {op_load, "load "},
{op_pushnum, "pnum "}, {op_loadg, "loadg "},
{op_pushone, "pone "}, {op_loadl, "loadl "},
{op_pushzero, "pzero "}, {op_pnum, "pnum "},
{op_pushnil, "pnil "}, {op_pone, "pone "},
{op_pushstr, "pstr "}, {op_pzero, "pzero "},
{op_newvec, "newv "}, {op_pnil, "pnil "},
{op_newhash, "newh "}, {op_pstr, "pstr "},
{op_newfunc, "newf "}, {op_newv, "newv "},
{op_vecapp, "vapp "}, {op_newh, "newh "},
{op_hashapp, "happ "}, {op_newf, "newf "},
{op_vapp, "vapp "},
{op_happ, "happ "},
{op_para, "para "}, {op_para, "para "},
{op_defpara, "deflt "}, {op_defpara, "def "},
{op_dynpara, "dyn "}, {op_dynpara, "dyn "},
{op_unot, "not "}, {op_unot, "not "},
{op_usub, "usub "}, {op_usub, "usub "},
@ -74,7 +98,7 @@ struct
{op_muleq, "muleq "}, {op_muleq, "muleq "},
{op_diveq, "diveq "}, {op_diveq, "diveq "},
{op_lnkeq, "linkeq"}, {op_lnkeq, "linkeq"},
{op_meq, "memeq "}, {op_meq, "meq "},
{op_eq, "eq "}, {op_eq, "eq "},
{op_neq, "neq "}, {op_neq, "neq "},
{op_less, "less "}, {op_less, "less "},
@ -83,43 +107,43 @@ struct
{op_geq, "geq "}, {op_geq, "geq "},
{op_pop, "pop "}, {op_pop, "pop "},
{op_jmp, "jmp "}, {op_jmp, "jmp "},
{op_jmptrue, "jt "}, {op_jt, "jt "},
{op_jmpfalse, "jf "}, {op_jf, "jf "},
{op_counter, "cnt "}, {op_counter, "cnt "},
{op_cntpop, "cntpop"}, {op_cntpop, "cntpop"},
{op_forindex, "findx "}, {op_findex, "findx "},
{op_foreach, "feach "}, {op_feach, "feach "},
{op_call, "call "}, {op_call, "call "},
{op_callv, "callv "}, {op_callv, "callv "},
{op_callvi, "callvi"}, {op_callvi, "callvi"},
{op_callh, "callh "}, {op_callh, "callh "},
{op_callf, "callf "}, {op_callf, "callf "},
{op_builtincall, "callb "}, {op_callb, "callb "},
{op_slicebegin, "slcbeg"}, {op_slcbegin, "slcbeg"},
{op_sliceend, "slcend"}, {op_slcend, "slcend"},
{op_slice, "slc "}, {op_slc, "slc "},
{op_slice2, "slc2 "}, {op_slc2, "slc2 "},
{op_mcall, "mcall "}, {op_mcall, "mcall "},
{op_mcallv, "mcallv"}, {op_mcallv, "mcallv"},
{op_mcallh, "mcallh"}, {op_mcallh, "mcallh"},
{op_return, "ret "}, {op_ret, "ret "},
{-1, NULL }, {-1, NULL },
}; };
struct opcode struct opcode
{ {
unsigned char op; unsigned char op;
unsigned int index; unsigned int num;
opcode(unsigned char _op=op_nop,unsigned int _index=0) opcode(unsigned char _op=op_nop,unsigned int _num=0)
{ {
op=_op; op=_op;
index=_index; num=_num;
return; return;
} }
opcode& operator=(const opcode& tmp) opcode& operator=(const opcode& tmp)
{ {
op=tmp.op; op=tmp.op;
index=tmp.index; num=tmp.num;
return *this; return *this;
} }
}; };
@ -127,39 +151,40 @@ struct opcode
class nasal_codegen class nasal_codegen
{ {
private: private:
std::unordered_map<double,int> number_table;
std::unordered_map<std::string,int> string_table;
std::vector<double> number_result_table;
std::vector<std::string> string_result_table;
std::vector<opcode> exec_code;
std::list<std::vector<int> > continue_ptr;
std::list<std::vector<int> > break_ptr;
int error; int error;
int in_forindex; int in_forindex;
int in_foreach; int in_foreach;
std::unordered_map<double,int> number_table;
std::unordered_map<std::string,int> string_table;
std::vector<double> num_res_table;
std::vector<std::string> str_res_table;
std::vector<opcode> exec_code;
std::list<std::vector<int> > continue_ptr;
std::list<std::vector<int> > break_ptr;
void regist_number(double); void regist_number(double);
void regist_string(std::string); void regist_string(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();
void number_gen(nasal_ast&); void num_gen(nasal_ast&);
void string_gen(nasal_ast&); void str_gen(nasal_ast&);
void vector_gen(nasal_ast&); void vec_gen(nasal_ast&);
void hash_gen(nasal_ast&); void hash_gen(nasal_ast&);
void function_gen(nasal_ast&); void func_gen(nasal_ast&);
void call_gen(nasal_ast&); void call_gen(nasal_ast&);
void call_id(nasal_ast&); void call_id(nasal_ast&);
void call_hash(nasal_ast&); void call_hash(nasal_ast&);
void call_vec(nasal_ast&); void call_vec(nasal_ast&);
void call_func(nasal_ast&); void call_func(nasal_ast&);
void mem_call(nasal_ast&); void mcall(nasal_ast&);
void mem_call_id(nasal_ast&); void mcall_id(nasal_ast&);
void mem_call_vec(nasal_ast&); void mcall_vec(nasal_ast&);
void mem_call_hash(nasal_ast&); void mcall_hash(nasal_ast&);
void multi_def(nasal_ast&); void multi_def(nasal_ast&);
void single_def(nasal_ast&); void single_def(nasal_ast&);
void definition_gen(nasal_ast&); void def_gen(nasal_ast&);
void multi_assignment_gen(nasal_ast&); void multi_assign_gen(nasal_ast&);
void conditional_gen(nasal_ast&); void conditional_gen(nasal_ast&);
void loop_gen(nasal_ast&); void loop_gen(nasal_ast&);
void load_continue_break(int,int); void load_continue_break(int,int);
@ -170,16 +195,16 @@ private:
void or_gen(nasal_ast&); void or_gen(nasal_ast&);
void and_gen(nasal_ast&); void and_gen(nasal_ast&);
void trino_gen(nasal_ast&); void trino_gen(nasal_ast&);
void calculation_gen(nasal_ast&); void calc_gen(nasal_ast&);
void block_gen(nasal_ast&); void block_gen(nasal_ast&);
void return_gen(nasal_ast&); void ret_gen(nasal_ast&);
public: public:
nasal_codegen(); nasal_codegen();
void main_progress(nasal_ast&); void main_progress(nasal_ast&);
void print_op(int); void print_op(int);
void print_byte_code(); void print_byte_code();
std::vector<std::string>& get_string_table(); std::vector<std::string>& get_str_table();
std::vector<double>& get_number_table(); std::vector<double>& get_num_table();
std::vector<opcode>& get_exec_code(); std::vector<opcode>& get_exec_code();
}; };
@ -223,40 +248,40 @@ void nasal_codegen::pop_gen()
void nasal_codegen::nil_gen() void nasal_codegen::nil_gen()
{ {
opcode op(op_pushnil,0); opcode op(op_pnil,0);
exec_code.push_back(op); exec_code.push_back(op);
return; return;
} }
void nasal_codegen::number_gen(nasal_ast& ast) void nasal_codegen::num_gen(nasal_ast& ast)
{ {
double num=ast.get_num(); double num=ast.get_num();
if(num==1) gen(op_pushone,0); if(num==1) gen(op_pone,0);
else if(num==0) gen(op_pushzero,0); else if(num==0) gen(op_pzero,0);
else else
{ {
regist_number(num); regist_number(num);
gen(op_pushnum,number_table[num]); gen(op_pnum,number_table[num]);
} }
return; return;
} }
void nasal_codegen::string_gen(nasal_ast& ast) void nasal_codegen::str_gen(nasal_ast& ast)
{ {
std::string str=ast.get_str(); std::string str=ast.get_str();
regist_string(str); regist_string(str);
gen(op_pushstr,string_table[str]); gen(op_pstr,string_table[str]);
return; return;
} }
void nasal_codegen::vector_gen(nasal_ast& ast) void nasal_codegen::vec_gen(nasal_ast& ast)
{ {
int size=ast.get_children().size(); int size=ast.get_children().size();
gen(op_newvec,0); gen(op_newv,0);
for(int i=0;i<size;++i) for(int i=0;i<size;++i)
{ {
calculation_gen(ast.get_children()[i]); calc_gen(ast.get_children()[i]);
gen(op_vecapp,0); gen(op_vapp,0);
} }
return; return;
} }
@ -264,21 +289,21 @@ void nasal_codegen::vector_gen(nasal_ast& ast)
void nasal_codegen::hash_gen(nasal_ast& ast) void nasal_codegen::hash_gen(nasal_ast& ast)
{ {
int size=ast.get_children().size(); int size=ast.get_children().size();
gen(op_newhash,0); gen(op_newh,0);
for(int i=0;i<size;++i) for(int i=0;i<size;++i)
{ {
calculation_gen(ast.get_children()[i].get_children()[1]); calc_gen(ast.get_children()[i].get_children()[1]);
std::string str=ast.get_children()[i].get_children()[0].get_str(); std::string str=ast.get_children()[i].get_children()[0].get_str();
regist_string(str); regist_string(str);
gen(op_hashapp,string_table[str]); gen(op_happ,string_table[str]);
} }
return; return;
} }
void nasal_codegen::function_gen(nasal_ast& ast) void nasal_codegen::func_gen(nasal_ast& ast)
{ {
int newfunc_label=exec_code.size(); int newfunc_label=exec_code.size();
gen(op_newfunc,0); gen(op_newf,0);
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();
@ -293,7 +318,7 @@ void nasal_codegen::function_gen(nasal_ast& ast)
} }
else if(tmp.get_type()==ast_default_arg) else if(tmp.get_type()==ast_default_arg)
{ {
calculation_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); regist_string(str);
gen(op_defpara,string_table[str]); gen(op_defpara,string_table[str]);
@ -305,7 +330,7 @@ void nasal_codegen::function_gen(nasal_ast& ast)
gen(op_dynpara,string_table[str]); gen(op_dynpara,string_table[str]);
} }
} }
exec_code[newfunc_label].index=exec_code.size()+1; exec_code[newfunc_label].num=exec_code.size()+1;
int ptr=exec_code.size(); int ptr=exec_code.size();
gen(op_jmp,0); gen(op_jmp,0);
nasal_ast& block=ast.get_children()[1]; nasal_ast& block=ast.get_children()[1];
@ -313,16 +338,16 @@ void nasal_codegen::function_gen(nasal_ast& ast)
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)
{ {
nil_gen(); nil_gen();
gen(op_return,0); gen(op_ret,0);
} }
exec_code[ptr].index=exec_code.size(); exec_code[ptr].num=exec_code.size();
return; return;
} }
void nasal_codegen::call_gen(nasal_ast& ast) void nasal_codegen::call_gen(nasal_ast& ast)
{ {
calculation_gen(ast.get_children()[0]); calc_gen(ast.get_children()[0]);
if(exec_code.back().op==op_builtincall) if(exec_code.back().op==op_callb)
return; return;
int child_size=ast.get_children().size(); int child_size=ast.get_children().size();
for(int i=1;i<child_size;++i) for(int i=1;i<child_size;++i)
@ -342,10 +367,10 @@ void nasal_codegen::call_id(nasal_ast& ast)
{ {
std::string str=ast.get_str(); std::string str=ast.get_str();
regist_string(str); regist_string(str);
for(int i=0;builtin_func_table[i].func_pointer;++i) for(int i=0;builtin_func[i].func;++i)
if(builtin_func_table[i].func_name==str) if(builtin_func[i].name==str)
{ {
gen(op_builtincall,i); gen(op_callb,i);
return; return;
} }
gen(op_call,string_table[str]); gen(op_call,string_table[str]);
@ -364,62 +389,62 @@ void nasal_codegen::call_vec(nasal_ast& ast)
{ {
if(ast.get_children().size()==1 && ast.get_children()[0].get_type()!=ast_subvec) if(ast.get_children().size()==1 && ast.get_children()[0].get_type()!=ast_subvec)
{ {
calculation_gen(ast.get_children()[0]); calc_gen(ast.get_children()[0]);
gen(op_callv,0); gen(op_callv,0);
return; return;
} }
gen(op_slicebegin,0); gen(op_slcbegin,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)
{ {
nasal_ast& tmp=ast.get_children()[i]; nasal_ast& tmp=ast.get_children()[i];
if(tmp.get_type()!=ast_subvec) if(tmp.get_type()!=ast_subvec)
{ {
calculation_gen(tmp); calc_gen(tmp);
gen(op_slice,0); gen(op_slc,0);
} }
else else
{ {
calculation_gen(tmp.get_children()[0]); calc_gen(tmp.get_children()[0]);
calculation_gen(tmp.get_children()[1]); calc_gen(tmp.get_children()[1]);
gen(op_slice2,0); gen(op_slc2,0);
} }
} }
gen(op_sliceend,0); gen(op_slcend,0);
return; return;
} }
void nasal_codegen::call_func(nasal_ast& ast) void nasal_codegen::call_func(nasal_ast& ast)
{ {
if(!ast.get_children().size()) if(!ast.get_children().size())
gen(op_newvec,0); gen(op_newv,0);
else if(ast.get_children()[0].get_type()==ast_hashmember) else if(ast.get_children()[0].get_type()==ast_hashmember)
hash_gen(ast); hash_gen(ast);
else else
vector_gen(ast); vec_gen(ast);
gen(op_callf,0); gen(op_callf,0);
return; return;
} }
void nasal_codegen::mem_call(nasal_ast& ast) void nasal_codegen::mcall(nasal_ast& ast)
{ {
if(ast.get_type()==ast_id) if(ast.get_type()==ast_id)
mem_call_id(ast); mcall_id(ast);
else else
mem_call_id(ast.get_children()[0]); mcall_id(ast.get_children()[0]);
int child_size=ast.get_children().size(); int child_size=ast.get_children().size();
for(int i=1;i<child_size;++i) for(int i=1;i<child_size;++i)
{ {
nasal_ast& tmp=ast.get_children()[i]; nasal_ast& tmp=ast.get_children()[i];
if(tmp.get_type()==ast_callh) if(tmp.get_type()==ast_callh)
mem_call_hash(tmp); mcall_hash(tmp);
else if(tmp.get_type()==ast_callv) else if(tmp.get_type()==ast_callv)
mem_call_vec(tmp); mcall_vec(tmp);
} }
return; return;
} }
void nasal_codegen::mem_call_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); regist_string(str);
@ -427,14 +452,14 @@ void nasal_codegen::mem_call_id(nasal_ast& ast)
return; return;
} }
void nasal_codegen::mem_call_vec(nasal_ast& ast) void nasal_codegen::mcall_vec(nasal_ast& ast)
{ {
calculation_gen(ast.get_children()[0]); calc_gen(ast.get_children()[0]);
gen(op_mcallv,0); gen(op_mcallv,0);
return; return;
} }
void nasal_codegen::mem_call_hash(nasal_ast& ast) void nasal_codegen::mcall_hash(nasal_ast& ast)
{ {
std::string str=ast.get_str(); std::string str=ast.get_str();
regist_string(str); regist_string(str);
@ -444,7 +469,7 @@ void nasal_codegen::mem_call_hash(nasal_ast& ast)
void nasal_codegen::single_def(nasal_ast& ast) void nasal_codegen::single_def(nasal_ast& ast)
{ {
calculation_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
std::string str=ast.get_children()[0].get_str(); std::string str=ast.get_children()[0].get_str();
regist_string(str); regist_string(str);
gen(op_load,string_table[str]); gen(op_load,string_table[str]);
@ -457,7 +482,7 @@ void nasal_codegen::multi_def(nasal_ast& ast)
{ {
for(int i=0;i<size;++i) for(int i=0;i<size;++i)
{ {
calculation_gen(ast.get_children()[1].get_children()[i]); calc_gen(ast.get_children()[1].get_children()[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();
regist_string(str); regist_string(str);
gen(op_load,string_table[str]); gen(op_load,string_table[str]);
@ -465,7 +490,7 @@ void nasal_codegen::multi_def(nasal_ast& ast)
} }
else else
{ {
calculation_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
for(int i=0;i<size;++i) for(int i=0;i<size;++i)
{ {
gen(op_callvi,i); gen(op_callvi,i);
@ -478,7 +503,7 @@ void nasal_codegen::multi_def(nasal_ast& ast)
return; return;
} }
void nasal_codegen::definition_gen(nasal_ast& ast) void nasal_codegen::def_gen(nasal_ast& ast)
{ {
if(ast.get_children()[0].get_type()==ast_id) if(ast.get_children()[0].get_type()==ast_id)
single_def(ast); single_def(ast);
@ -487,27 +512,27 @@ void nasal_codegen::definition_gen(nasal_ast& ast)
return; return;
} }
void nasal_codegen::multi_assignment_gen(nasal_ast& ast) void nasal_codegen::multi_assign_gen(nasal_ast& ast)
{ {
int size=ast.get_children()[0].get_children().size(); int size=ast.get_children()[0].get_children().size();
if(ast.get_children()[1].get_type()==ast_multi_scalar) if(ast.get_children()[1].get_type()==ast_multi_scalar)
{ {
for(int i=size-1;i>=0;--i) for(int i=size-1;i>=0;--i)
calculation_gen(ast.get_children()[1].get_children()[i]); calc_gen(ast.get_children()[1].get_children()[i]);
for(int i=0;i<size;++i) for(int i=0;i<size;++i)
{ {
mem_call(ast.get_children()[0].get_children()[i]); mcall(ast.get_children()[0].get_children()[i]);
gen(op_meq,0); gen(op_meq,0);
pop_gen(); pop_gen();
} }
} }
else else
{ {
calculation_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
for(int i=0;i<size;++i) for(int i=0;i<size;++i)
{ {
gen(op_callvi,i); gen(op_callvi,i);
mem_call(ast.get_children()[0].get_children()[i]); mcall(ast.get_children()[0].get_children()[i]);
gen(op_meq,0); gen(op_meq,0);
pop_gen(); pop_gen();
} }
@ -525,15 +550,15 @@ void nasal_codegen::conditional_gen(nasal_ast& ast)
nasal_ast& tmp=ast.get_children()[i]; nasal_ast& tmp=ast.get_children()[i];
if(tmp.get_type()==ast_if || tmp.get_type()==ast_elsif) if(tmp.get_type()==ast_if || tmp.get_type()==ast_elsif)
{ {
calculation_gen(tmp.get_children()[0]); calc_gen(tmp.get_children()[0]);
int ptr=exec_code.size(); int ptr=exec_code.size();
gen(op_jmpfalse,0); gen(op_jf,0);
block_gen(tmp.get_children()[1]); block_gen(tmp.get_children()[1]);
jmp_label.push_back(exec_code.size()); jmp_label.push_back(exec_code.size());
// without 'else' the last condition doesn't need to jmp // without 'else' the last condition doesn't need to jmp
if(i!=size-1) if(i!=size-1)
gen(op_jmp,0); gen(op_jmp,0);
exec_code[ptr].index=exec_code.size(); exec_code[ptr].num=exec_code.size();
} }
else else
{ {
@ -542,7 +567,7 @@ void nasal_codegen::conditional_gen(nasal_ast& ast)
} }
} }
for(std::vector<int>::iterator i=jmp_label.begin();i!=jmp_label.end();++i) for(std::vector<int>::iterator i=jmp_label.begin();i!=jmp_label.end();++i)
exec_code[*i].index=exec_code.size(); exec_code[*i].num=exec_code.size();
return; return;
} }
@ -564,9 +589,9 @@ void nasal_codegen::loop_gen(nasal_ast& ast)
void nasal_codegen::load_continue_break(int continue_place,int break_place) void nasal_codegen::load_continue_break(int continue_place,int break_place)
{ {
for(int i=0;i<continue_ptr.front().size();++i) for(int i=0;i<continue_ptr.front().size();++i)
exec_code[continue_ptr.front()[i]].index=continue_place; exec_code[continue_ptr.front()[i]].num=continue_place;
for(int i=0;i<break_ptr.front().size();++i) for(int i=0;i<break_ptr.front().size();++i)
exec_code[break_ptr.front()[i]].index=break_place; exec_code[break_ptr.front()[i]].num=break_place;
continue_ptr.pop_front(); continue_ptr.pop_front();
break_ptr.pop_front(); break_ptr.pop_front();
return; return;
@ -575,13 +600,13 @@ void nasal_codegen::load_continue_break(int continue_place,int break_place)
void nasal_codegen::while_gen(nasal_ast& ast) void nasal_codegen::while_gen(nasal_ast& ast)
{ {
int loop_ptr=exec_code.size(); int loop_ptr=exec_code.size();
calculation_gen(ast.get_children()[0]); calc_gen(ast.get_children()[0]);
int condition_ptr=exec_code.size(); int condition_ptr=exec_code.size();
gen(op_jmpfalse,0); gen(op_jf,0);
block_gen(ast.get_children()[1]); block_gen(ast.get_children()[1]);
gen(op_jmp,loop_ptr); gen(op_jmp,loop_ptr);
exec_code[condition_ptr].index=exec_code.size(); exec_code[condition_ptr].num=exec_code.size();
load_continue_break(exec_code.size()-1,exec_code.size()); load_continue_break(exec_code.size()-1,exec_code.size());
return; return;
} }
@ -592,32 +617,51 @@ void nasal_codegen::for_gen(nasal_ast& ast)
switch(ast.get_children()[0].get_type()) switch(ast.get_children()[0].get_type())
{ {
case ast_null:break; case ast_null:break;
case ast_definition:definition_gen(ast.get_children()[0]);break; case ast_definition:def_gen(ast.get_children()[0]);break;
case ast_multi_assign:multi_assignment_gen(ast.get_children()[0]);break; case ast_multi_assign:multi_assign_gen(ast.get_children()[0]);break;
case ast_nil:case ast_num:case ast_str:case ast_func:break; case ast_nil:
case ast_vec:case ast_hash: case ast_num:
case ast_str:
case ast_func:break;
case ast_vec:
case ast_hash:
case ast_call: case ast_call:
case ast_equal:case ast_addeq:case ast_subeq:case ast_multeq:case ast_diveq:case ast_lnkeq: case ast_equal:
case ast_neg:case ast_not: case ast_addeq:
case ast_add:case ast_sub:case ast_mult:case ast_div:case ast_link: case ast_subeq:
case ast_cmpeq:case ast_neq:case ast_leq:case ast_less:case ast_geq:case ast_grt: case ast_multeq:
case ast_trino:calculation_gen(ast.get_children()[0]);pop_gen();break; case ast_diveq:
case ast_lnkeq:
case ast_neg:
case ast_not:
case ast_add:
case ast_sub:
case ast_mult:
case ast_div:
case ast_link:
case ast_cmpeq:
case ast_neq:
case ast_leq:
case ast_less:
case ast_geq:
case ast_grt:
case ast_trino:calc_gen(ast.get_children()[0]);pop_gen();break;
} }
int jmp_place=exec_code.size(); int jmp_place=exec_code.size();
if(ast.get_children()[1].get_type()==ast_null) if(ast.get_children()[1].get_type()==ast_null)
gen(op_pushone,0); gen(op_pone,0);
else else
calculation_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
int label_exit=exec_code.size(); int label_exit=exec_code.size();
gen(op_jmpfalse,0); gen(op_jf,0);
block_gen(ast.get_children()[3]); block_gen(ast.get_children()[3]);
int continue_place=exec_code.size(); int continue_place=exec_code.size();
switch(ast.get_children()[2].get_type()) switch(ast.get_children()[2].get_type())
{ {
case ast_null:break; case ast_null:break;
case ast_definition:definition_gen(ast.get_children()[2]);break; case ast_definition:def_gen(ast.get_children()[2]);break;
case ast_multi_assign:multi_assignment_gen(ast.get_children()[2]);break; case ast_multi_assign:multi_assign_gen(ast.get_children()[2]);break;
case ast_nil:case ast_num:case ast_str:case ast_func:break; case ast_nil:case ast_num:case ast_str:case ast_func:break;
case ast_vec:case ast_hash: case ast_vec:case ast_hash:
case ast_call: case ast_call:
@ -625,20 +669,20 @@ void nasal_codegen::for_gen(nasal_ast& ast)
case ast_neg:case ast_not: case ast_neg:case ast_not:
case ast_add:case ast_sub:case ast_mult:case ast_div:case ast_link: case ast_add:case ast_sub:case ast_mult:case ast_div:case ast_link:
case ast_cmpeq:case ast_neq:case ast_leq:case ast_less:case ast_geq:case ast_grt: case ast_cmpeq:case ast_neq:case ast_leq:case ast_less:case ast_geq:case ast_grt:
case ast_trino:calculation_gen(ast.get_children()[2]);pop_gen();break; case ast_trino:calc_gen(ast.get_children()[2]);pop_gen();break;
} }
gen(op_jmp,jmp_place); gen(op_jmp,jmp_place);
exec_code[label_exit].index=exec_code.size(); exec_code[label_exit].num=exec_code.size();
load_continue_break(continue_place,exec_code.size()); load_continue_break(continue_place,exec_code.size());
return; return;
} }
void nasal_codegen::forindex_gen(nasal_ast& ast) void nasal_codegen::forindex_gen(nasal_ast& ast)
{ {
calculation_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
gen(op_counter,0); gen(op_counter,0);
int ptr=exec_code.size(); int ptr=exec_code.size();
gen(op_forindex,0); gen(op_findex,0);
if(ast.get_children()[0].get_type()==ast_new_iter) if(ast.get_children()[0].get_type()==ast_new_iter)
{ {
std::string str=ast.get_children()[0].get_children()[0].get_str(); std::string str=ast.get_children()[0].get_children()[0].get_str();
@ -647,14 +691,14 @@ void nasal_codegen::forindex_gen(nasal_ast& ast)
} }
else else
{ {
mem_call(ast.get_children()[0]); mcall(ast.get_children()[0]);
gen(op_meq,0); gen(op_meq,0);
pop_gen(); pop_gen();
} }
block_gen(ast.get_children()[2]); block_gen(ast.get_children()[2]);
gen(op_jmp,ptr); gen(op_jmp,ptr);
exec_code[ptr].index=exec_code.size(); exec_code[ptr].num=exec_code.size();
load_continue_break(exec_code.size()-1,exec_code.size()); load_continue_break(exec_code.size()-1,exec_code.size());
pop_gen();// pop vector pop_gen();// pop vector
gen(op_cntpop,0); gen(op_cntpop,0);
@ -662,10 +706,10 @@ void nasal_codegen::forindex_gen(nasal_ast& ast)
} }
void nasal_codegen::foreach_gen(nasal_ast& ast) void nasal_codegen::foreach_gen(nasal_ast& ast)
{ {
calculation_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
gen(op_counter,0); gen(op_counter,0);
int ptr=exec_code.size(); int ptr=exec_code.size();
gen(op_foreach,0); gen(op_feach,0);
if(ast.get_children()[0].get_type()==ast_new_iter) if(ast.get_children()[0].get_type()==ast_new_iter)
{ {
std::string str=ast.get_children()[0].get_children()[0].get_str(); std::string str=ast.get_children()[0].get_children()[0].get_str();
@ -674,14 +718,14 @@ void nasal_codegen::foreach_gen(nasal_ast& ast)
} }
else else
{ {
mem_call(ast.get_children()[0]); mcall(ast.get_children()[0]);
gen(op_meq,0); gen(op_meq,0);
pop_gen(); pop_gen();
} }
block_gen(ast.get_children()[2]); block_gen(ast.get_children()[2]);
gen(op_jmp,ptr); gen(op_jmp,ptr);
exec_code[ptr].index=exec_code.size(); exec_code[ptr].num=exec_code.size();
load_continue_break(exec_code.size()-1,exec_code.size()); load_continue_break(exec_code.size()-1,exec_code.size());
pop_gen();// pop vector pop_gen();// pop vector
gen(op_cntpop,0); gen(op_cntpop,0);
@ -690,35 +734,35 @@ void nasal_codegen::foreach_gen(nasal_ast& ast)
void nasal_codegen::or_gen(nasal_ast& ast) void nasal_codegen::or_gen(nasal_ast& ast)
{ {
calculation_gen(ast.get_children()[0]); calc_gen(ast.get_children()[0]);
int l1=exec_code.size(); int l1=exec_code.size();
gen(op_jmptrue,0); gen(op_jt,0);
pop_gen(); pop_gen();
calculation_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
int l2=exec_code.size(); int l2=exec_code.size();
gen(op_jmptrue,0); gen(op_jt,0);
pop_gen(); pop_gen();
nil_gen(); nil_gen();
exec_code[l1].index=exec_code[l2].index=exec_code.size(); exec_code[l1].num=exec_code[l2].num=exec_code.size();
return; return;
} }
void nasal_codegen::and_gen(nasal_ast& ast) void nasal_codegen::and_gen(nasal_ast& ast)
{ {
calculation_gen(ast.get_children()[0]); calc_gen(ast.get_children()[0]);
gen(op_jmptrue,exec_code.size()+2); gen(op_jt,exec_code.size()+2);
int lfalse=exec_code.size(); int lfalse=exec_code.size();
gen(op_jmp,0); gen(op_jmp,0);
pop_gen();// jt jumps here pop_gen();// jt jumps here
calculation_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
gen(op_jmptrue,exec_code.size()+3); gen(op_jt,exec_code.size()+3);
exec_code[lfalse].index=exec_code.size(); exec_code[lfalse].num=exec_code.size();
pop_gen(); pop_gen();
nil_gen(); nil_gen();
//jt jumps here //jt jumps here
@ -727,62 +771,62 @@ void nasal_codegen::and_gen(nasal_ast& ast)
void nasal_codegen::trino_gen(nasal_ast& ast) void nasal_codegen::trino_gen(nasal_ast& ast)
{ {
calculation_gen(ast.get_children()[0]); calc_gen(ast.get_children()[0]);
int lfalse=exec_code.size(); int lfalse=exec_code.size();
gen(op_jmpfalse,0); gen(op_jf,0);
calculation_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
int lexit=exec_code.size(); int lexit=exec_code.size();
gen(op_jmp,0); gen(op_jmp,0);
exec_code[lfalse].index=exec_code.size(); exec_code[lfalse].num=exec_code.size();
calculation_gen(ast.get_children()[2]); calc_gen(ast.get_children()[2]);
exec_code[lexit].index=exec_code.size(); exec_code[lexit].num=exec_code.size();
return; return;
} }
void nasal_codegen::calculation_gen(nasal_ast& ast) void nasal_codegen::calc_gen(nasal_ast& ast)
{ {
switch(ast.get_type()) switch(ast.get_type())
{ {
case ast_nil: nil_gen(); break; case ast_nil: nil_gen(); break;
case ast_num: number_gen(ast); break; case ast_num: num_gen(ast); break;
case ast_str: string_gen(ast); break; case ast_str: str_gen(ast); break;
case ast_id: call_id(ast); break; case ast_id: call_id(ast); break;
case ast_vec: vector_gen(ast); break; case ast_vec: vec_gen(ast); break;
case ast_hash: hash_gen(ast); break; case ast_hash: hash_gen(ast);break;
case ast_func: function_gen(ast); break; case ast_func: func_gen(ast);break;
case ast_call: call_gen(ast); break; case ast_call: call_gen(ast);break;
case ast_equal: case ast_equal:
calculation_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
mem_call(ast.get_children()[0]); mcall(ast.get_children()[0]);
gen(op_meq,0); gen(op_meq,0);
break; break;
// ast_addeq(22)~ast_lnkeq(26) op_addeq(23)~op_lnkeq(27) // ast_addeq(22)~ast_lnkeq(26) op_addeq(23)~op_lnkeq(27)
case ast_addeq:case ast_subeq:case ast_multeq:case ast_diveq:case ast_lnkeq: case ast_addeq:case ast_subeq:case ast_multeq:case ast_diveq:case ast_lnkeq:
calculation_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
mem_call(ast.get_children()[0]); mcall(ast.get_children()[0]);
gen(ast.get_type()-ast_addeq+op_addeq,0); gen(ast.get_type()-ast_addeq+op_addeq,0);
break; break;
case ast_or:or_gen(ast);break; case ast_or:or_gen(ast);break;
case ast_and:and_gen(ast);break; case ast_and:and_gen(ast);break;
// ast_add(33)~ast_link(37) op_add(18)~op_lnk(22) // ast_add(33)~ast_link(37) op_add(18)~op_lnk(22)
case ast_add:case ast_sub:case ast_mult:case ast_div:case ast_link: case ast_add:case ast_sub:case ast_mult:case ast_div:case ast_link:
calculation_gen(ast.get_children()[0]); calc_gen(ast.get_children()[0]);
calculation_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
gen(ast.get_type()-ast_add+op_add,0); gen(ast.get_type()-ast_add+op_add,0);
break; break;
// ast_cmpeq(27)~ast_geq(32) op_eq(29)~op_geq(34) // ast_cmpeq(27)~ast_geq(32) op_eq(29)~op_geq(34)
case ast_cmpeq:case ast_neq:case ast_less:case ast_leq:case ast_grt:case ast_geq: case ast_cmpeq:case ast_neq:case ast_less:case ast_leq:case ast_grt:case ast_geq:
calculation_gen(ast.get_children()[0]); calc_gen(ast.get_children()[0]);
calculation_gen(ast.get_children()[1]); calc_gen(ast.get_children()[1]);
gen(ast.get_type()-ast_cmpeq+op_eq,0); gen(ast.get_type()-ast_cmpeq+op_eq,0);
break; break;
case ast_trino:trino_gen(ast);break; case ast_trino:trino_gen(ast);break;
case ast_neg: case ast_neg:
calculation_gen(ast.get_children()[0]); calc_gen(ast.get_children()[0]);
gen(op_usub,0); gen(op_usub,0);
break; break;
case ast_not: case ast_not:
calculation_gen(ast.get_children()[0]); calc_gen(ast.get_children()[0]);
gen(op_unot,0); gen(op_unot,0);
break; break;
case ast_definition: case ast_definition:
@ -802,8 +846,8 @@ void nasal_codegen::block_gen(nasal_ast& ast)
switch(tmp.get_type()) switch(tmp.get_type())
{ {
case ast_null:case ast_nil:case ast_num:case ast_str:case ast_func:break; case ast_null:case ast_nil:case ast_num:case ast_str:case ast_func:break;
case ast_definition:definition_gen(tmp);break; case ast_definition:def_gen(tmp);break;
case ast_multi_assign:multi_assignment_gen(tmp);break; case ast_multi_assign:multi_assign_gen(tmp);break;
case ast_conditional:conditional_gen(tmp);break; case ast_conditional:conditional_gen(tmp);break;
case ast_continue: case ast_continue:
continue_ptr.front().push_back(exec_code.size()); continue_ptr.front().push_back(exec_code.size());
@ -842,14 +886,14 @@ void nasal_codegen::block_gen(nasal_ast& ast)
case ast_grt: case ast_grt:
case ast_or: case ast_or:
case ast_and: case ast_and:
case ast_trino:calculation_gen(tmp);pop_gen();break; case ast_trino:calc_gen(tmp);pop_gen();break;
case ast_return:return_gen(tmp);break; case ast_return:ret_gen(tmp);break;
} }
} }
return; return;
} }
void nasal_codegen::return_gen(nasal_ast& ast) void nasal_codegen::ret_gen(nasal_ast& ast)
{ {
for(int i=0;i<in_foreach;++i) for(int i=0;i<in_foreach;++i)
{ {
@ -862,10 +906,10 @@ void nasal_codegen::return_gen(nasal_ast& ast)
gen(op_cntpop,0); gen(op_cntpop,0);
} }
if(ast.get_children().size()) if(ast.get_children().size())
calculation_gen(ast.get_children()[0]); calc_gen(ast.get_children()[0]);
else else
nil_gen(); nil_gen();
gen(op_return,0); gen(op_ret,0);
return; return;
} }
@ -883,8 +927,8 @@ void nasal_codegen::main_progress(nasal_ast& ast)
switch(tmp.get_type()) switch(tmp.get_type())
{ {
case ast_null:case ast_nil:case ast_num:case ast_str:case ast_func:break; case ast_null:case ast_nil:case ast_num:case ast_str:case ast_func:break;
case ast_definition:definition_gen(tmp);break; case ast_definition:def_gen(tmp);break;
case ast_multi_assign:multi_assignment_gen(tmp);break; case ast_multi_assign:multi_assign_gen(tmp);break;
case ast_conditional:conditional_gen(tmp);break; case ast_conditional:conditional_gen(tmp);break;
case ast_while: case ast_while:
case ast_for: case ast_for:
@ -915,16 +959,16 @@ void nasal_codegen::main_progress(nasal_ast& ast)
case ast_grt: case ast_grt:
case ast_or: case ast_or:
case ast_and: case ast_and:
case ast_trino:calculation_gen(tmp);pop_gen();break; case ast_trino:calc_gen(tmp);pop_gen();break;
} }
} }
gen(op_nop,0); gen(op_nop,0);
number_result_table.resize(number_table.size()); num_res_table.resize(number_table.size());
string_result_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)
number_result_table[i->second]=i->first; num_res_table[i->second]=i->first;
for(auto i=string_table.begin();i!=string_table.end();++i) for(auto i=string_table.begin();i!=string_table.end();++i)
string_result_table[i->second]=i->first; str_res_table[i->second]=i->first;
return; return;
} }
@ -940,22 +984,22 @@ void nasal_codegen::print_op(int index)
break; break;
} }
// print opcode index // print opcode index
printf("0x%.8x ",exec_code[index].index); printf("0x%.8x ",exec_code[index].num);
// print detail info // print detail info
switch(exec_code[index].op) switch(exec_code[index].op)
{ {
case op_pushnum:std::cout<<'('<<number_result_table[exec_code[index].index]<<')';break; case op_pnum:std::cout<<'('<<num_res_table[exec_code[index].num]<<')';break;
case op_builtincall:std::cout<<'('<<builtin_func_table[exec_code[index].index].func_name<<')';break; case op_callb:std::cout<<'('<<builtin_func[exec_code[index].num].name<<')';break;
case op_hashapp: case op_happ:
case op_call: case op_call:
case op_mcall: case op_mcall:
case op_pushstr: 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:
case op_load:std::cout<<'('<<string_result_table[exec_code[index].index]<<')';break; case op_load:std::cout<<'('<<str_res_table[exec_code[index].num]<<')';break;
} }
std::cout<<'\n'; std::cout<<'\n';
return; return;
@ -963,24 +1007,24 @@ void nasal_codegen::print_op(int index)
void nasal_codegen::print_byte_code() void nasal_codegen::print_byte_code()
{ {
for(int i=0;i<number_result_table.size();++i) for(int i=0;i<num_res_table.size();++i)
std::cout<<".number "<<number_result_table[i]<<'\n'; std::cout<<".number "<<num_res_table[i]<<'\n';
for(int i=0;i<string_result_table.size();++i) for(int i=0;i<str_res_table.size();++i)
std::cout<<".symbol "<<string_result_table[i]<<'\n'; std::cout<<".symbol "<<str_res_table[i]<<'\n';
int size=exec_code.size(); int size=exec_code.size();
for(int i=0;i<size;++i) for(int i=0;i<size;++i)
print_op(i); print_op(i);
return; return;
} }
std::vector<std::string>& nasal_codegen::get_string_table() std::vector<std::string>& nasal_codegen::get_str_table()
{ {
return string_result_table; return str_res_table;
} }
std::vector<double>& nasal_codegen::get_number_table() std::vector<double>& nasal_codegen::get_num_table()
{ {
return number_result_table; return num_res_table;
} }
std::vector<opcode>& nasal_codegen::get_exec_code() std::vector<opcode>& nasal_codegen::get_exec_code()

View File

@ -1,7 +1,7 @@
#ifndef __NASAL_GC_H__ #ifndef __NASAL_GC_H__
#define __NASAL_GC_H__ #define __NASAL_GC_H__
enum runtime_scalar_type enum nasal_type
{ {
vm_nil=0, vm_nil=0,
vm_num, vm_num,
@ -12,89 +12,74 @@ enum runtime_scalar_type
vm_hash vm_hash
}; };
class nasal_gc; struct nasal_vec;
class nasal_vec; struct nasal_hash;
class nasal_hash; struct nasal_func;
class nasal_func; struct nasal_scop;
class nasal_scop; struct nasal_val;
class nasal_val;
class nasal_vec 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* global; // global scope address,type vm_scop
nasal_val** val_stack; // main stack
nasal_val** stack_top; // stack top
std::vector<nasal_val*> num_addrs; // reserved address for const vm_num
std::vector<nasal_val*> local; // local scope for function block
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
/* gc functions */
void mark();
void sweep();
void gc_init();
void gc_clear();
nasal_val* gc_alloc(int);
struct nasal_vec
{ {
private:
nasal_gc& gc;
std::vector<nasal_val*> elems; std::vector<nasal_val*> elems;
public:
nasal_vec(nasal_gc&);
~nasal_vec();
int size();
void add_elem(nasal_val*);
void print(); void print();
nasal_val* del_elem(); nasal_val* get_val(int);
nasal_val* operator[](const int); nasal_val** get_mem(int);
nasal_val* get_value_address(int);
nasal_val** get_mem_address(int);
}; };
class nasal_hash struct nasal_hash
{ {
private:
nasal_gc& gc;
std::unordered_map<std::string,nasal_val*> elems; std::unordered_map<std::string,nasal_val*> elems;
public:
nasal_hash(nasal_gc&); bool check_contain(std::string&);
~nasal_hash();
int size();
bool check_contain(std::string);
void add_elem(std::string,nasal_val*);
void del_elem(std::string);
void print(); void print();
nasal_val* get_special_para(std::string); nasal_val* get_special_para(std::string&);
nasal_val* get_value_address(std::string); nasal_val* get_val(std::string&);
nasal_val** get_mem_address(std::string); nasal_val** get_mem(std::string&);
nasal_val* get_keys(); nasal_val* get_keys();
}; };
class nasal_func struct nasal_func
{ {
private:
nasal_gc& gc;
int entry;
nasal_val* closure_addr;
std::vector<int> para;
int dynpara; int dynpara;
std::vector<nasal_val*> default_para_addr; int entry;
public: std::vector<int> para;
nasal_func(nasal_gc&); std::vector<nasal_val*> default_para;
~nasal_func(); std::unordered_map<int,nasal_val*> closure;
int get_entry();
int get_dynamic_para(); nasal_func();
void set_entry(int);
void add_para(int,nasal_val*,bool);
void set_closure_addr(nasal_val*);
void set_new_closure();
nasal_val* get_closure_addr();
std::vector<int>& get_para();
std::vector<nasal_val*>& get_default();
}; };
class nasal_scop struct nasal_scop
{ {
private:
nasal_gc& gc;
std::unordered_map<int,nasal_val*> elems; std::unordered_map<int,nasal_val*> elems;
public:
nasal_scop(nasal_gc&); nasal_val* get_val(int);
~nasal_scop(); nasal_val** get_mem(int);
void set_closure(nasal_scop&);
void add_new_value(int,nasal_val*);
nasal_val* get_value_address(int);
nasal_val** get_mem_address(int);
}; };
class nasal_val struct nasal_val
{ {
protected: bool mark;
int type; int type;
union union
{ {
@ -103,93 +88,37 @@ protected:
nasal_vec* vec; nasal_vec* vec;
nasal_hash* hash; nasal_hash* hash;
nasal_func* func; nasal_func* func;
nasal_scop* cls; nasal_scop* scop;
}ptr; }ptr;
public:
int ref_cnt;
nasal_val(); nasal_val();
nasal_val(int,nasal_gc&); nasal_val(int);
~nasal_val(); ~nasal_val();
void clear(); void clear();
void set_type(int,nasal_gc&); void set_type(int);
void set_number(double);
void set_string(std::string);
int get_type();
double to_number(); double to_number();
double get_number();
std::string to_string(); std::string to_string();
std::string get_string();
nasal_vec& get_vector();
nasal_hash& get_hash();
nasal_func& get_func();
nasal_scop& get_closure();
};
class nasal_gc
{
private:
std::queue<nasal_val*> free_space;
std::vector<nasal_val*> memory;
public:
~nasal_gc();
void clear();
nasal_val* gc_alloc(int);
void add_reference(nasal_val*);
void del_reference(nasal_val*);
}; };
/*functions of nasal_vec*/ /*functions of nasal_vec*/
nasal_vec::nasal_vec(nasal_gc& ngc):gc(ngc) nasal_val* nasal_vec::get_val(int index)
{
return;
}
nasal_vec::~nasal_vec()
{
int size=elems.size();
for(int i=0;i<size;++i)
gc.del_reference(elems[i]);
return;
}
void nasal_vec::add_elem(nasal_val* value_address)
{
elems.push_back(value_address);
return;
}
nasal_val* nasal_vec::del_elem()
{
// pop back
if(!elems.size())
return NULL;
nasal_val* ret=elems.back();
elems.pop_back();
return ret;
}
int nasal_vec::size()
{
return elems.size();
}
nasal_val* nasal_vec::operator[](const int index)
{
return elems[index];
}
nasal_val* nasal_vec::get_value_address(int index)
{ {
int vec_size=elems.size(); int vec_size=elems.size();
if(index<-vec_size || index>=vec_size) if(index<-vec_size || index>=vec_size)
{ {
std::cout<<">> [gc] nasal_vec::get_value_address: index out of range: "<<index<<"\n"; std::cout<<">> [gc] nasal_vec::get_val: index out of range: "<<index<<"\n";
return NULL; return nullptr;
} }
int idx[2]={index+vec_size,index}; int idx[2]={index+vec_size,index};
return elems[idx[index>=0]]; return elems[idx[index>=0]];
} }
nasal_val** nasal_vec::get_mem_address(int index) nasal_val** nasal_vec::get_mem(int index)
{ {
int vec_size=elems.size(); int vec_size=elems.size();
if(index<-vec_size || index>=vec_size) if(index<-vec_size || index>=vec_size)
{ {
std::cout<<">> [gc] nasal_vec::get_mem_address: index out of range: "<<index<<"\n"; std::cout<<">> [gc] nasal_vec::get_mem: index out of range: "<<index<<"\n";
return NULL; return nullptr;
} }
int idx[2]={index+vec_size,index}; int idx[2]={index+vec_size,index};
return &elems[idx[index>=0]]; return &elems[idx[index>=0]];
@ -203,13 +132,13 @@ void nasal_vec::print()
for(int i=0;i<size;++i) for(int i=0;i<size;++i)
{ {
nasal_val* tmp=elems[i]; nasal_val* tmp=elems[i];
switch(tmp->get_type()) switch(tmp->type)
{ {
case vm_nil: std::cout<<"nil"; break; case vm_nil: std::cout<<"nil"; break;
case vm_num: std::cout<<tmp->get_number(); break; case vm_num: std::cout<<tmp->ptr.num; break;
case vm_str: std::cout<<tmp->get_string(); break; case vm_str: std::cout<<*tmp->ptr.str; break;
case vm_vec: tmp->get_vector().print(); break; case vm_vec: tmp->ptr.vec->print(); break;
case vm_hash: tmp->get_hash().print(); break; case vm_hash: tmp->ptr.hash->print(); break;
case vm_func: std::cout<<"func(...){...}"; break; case vm_func: std::cout<<"func(...){...}"; break;
} }
std::cout<<",]"[i==size-1]; std::cout<<",]"[i==size-1];
@ -218,123 +147,93 @@ void nasal_vec::print()
} }
/*functions of nasal_hash*/ /*functions of nasal_hash*/
nasal_hash::nasal_hash(nasal_gc& ngc):gc(ngc) nasal_val* nasal_hash::get_special_para(std::string& key)
{
return;
}
nasal_hash::~nasal_hash()
{
for(auto iter=elems.begin();iter!=elems.end();++iter)
gc.del_reference(iter->second);
return;
}
void nasal_hash::add_elem(std::string key,nasal_val* value_address)
{
if(!elems.count(key))
elems[key]=value_address;
return;
}
void nasal_hash::del_elem(std::string key)
{
if(!elems.count(key))
{
gc.del_reference(elems[key]);
elems.erase(key);
}
return;
}
int nasal_hash::size()
{
return elems.size();
}
nasal_val* nasal_hash::get_special_para(std::string key)
{ {
if(elems.count(key)) if(elems.count(key))
return elems[key]; return elems[key];
return NULL; return nullptr;
} }
nasal_val* nasal_hash::get_value_address(std::string key) nasal_val* nasal_hash::get_val(std::string& key)
{ {
nasal_val* ret_value_addr=NULL; nasal_val* ret_addr=nullptr;
if(elems.count(key)) if(elems.count(key))
return elems[key]; return elems[key];
else if(elems.count("parents")) else if(elems.count("parents"))
{ {
nasal_val* val_addr=elems["parents"]; nasal_val* val_addr=elems["parents"];
if(val_addr->get_type()==vm_vec) if(val_addr->type==vm_vec)
{ {
nasal_vec& vec_ref=val_addr->get_vector(); std::vector<nasal_val*>& vec_ref=val_addr->ptr.vec->elems;
int size=vec_ref.size(); int size=vec_ref.size();
for(int i=0;i<size;++i) for(int i=0;i<size;++i)
{ {
nasal_val* tmp_val_addr=vec_ref.get_value_address(i); nasal_val* tmp=vec_ref[i];
if(tmp_val_addr->get_type()==vm_hash) if(tmp->type==vm_hash)
ret_value_addr=tmp_val_addr->get_hash().get_value_address(key); ret_addr=tmp->ptr.hash->get_val(key);
if(ret_value_addr) if(ret_addr)
break; return ret_addr;
} }
} }
} }
return ret_value_addr; return ret_addr;
} }
nasal_val** nasal_hash::get_mem_address(std::string key) nasal_val** nasal_hash::get_mem(std::string& key)
{ {
nasal_val** mem_addr=NULL; nasal_val** mem_addr=nullptr;
if(elems.count(key)) if(elems.count(key))
return &elems[key]; return &elems[key];
else if(elems.count("parents")) else if(elems.count("parents"))
{ {
nasal_val* val_addr=elems["parents"]; nasal_val* val_addr=elems["parents"];
if(val_addr->get_type()==vm_vec) if(val_addr->type==vm_vec)
{ {
nasal_vec& vec_ref=val_addr->get_vector(); std::vector<nasal_val*>& vec_ref=val_addr->ptr.vec->elems;
int size=vec_ref.size(); int size=vec_ref.size();
for(int i=0;i<size;++i) for(int i=0;i<size;++i)
{ {
nasal_val* tmp_val_addr=vec_ref.get_value_address(i); nasal_val* tmp_val_addr=vec_ref[i];
if(tmp_val_addr->get_type()==vm_hash) if(tmp_val_addr->type==vm_hash)
mem_addr=tmp_val_addr->get_hash().get_mem_address(key); mem_addr=tmp_val_addr->ptr.hash->get_mem(key);
if(mem_addr) if(mem_addr)
break; return mem_addr;
} }
} }
} }
return mem_addr; return mem_addr;
} }
bool nasal_hash::check_contain(std::string key) bool nasal_hash::check_contain(std::string& key)
{ {
if(elems.count(key)) if(elems.count(key))
return true; return true;
if(elems.count("parents")) if(elems.count("parents"))
{ {
bool result=false;
nasal_val* val_addr=elems["parents"]; nasal_val* val_addr=elems["parents"];
if(val_addr->get_type()==vm_vec) if(val_addr->type==vm_vec)
{ {
nasal_vec& vec_ref=val_addr->get_vector(); bool result=false;
std::vector<nasal_val*>& vec_ref=val_addr->ptr.vec->elems;
int size=vec_ref.size(); int size=vec_ref.size();
for(int i=0;i<size;++i) for(int i=0;i<size;++i)
{ {
nasal_val* tmp_val_addr=vec_ref.get_value_address(i); nasal_val* tmp=vec_ref[i];
if(tmp_val_addr->get_type()==vm_hash) if(tmp->type==vm_hash)
result=tmp_val_addr->get_hash().check_contain(key); result=tmp->ptr.hash->check_contain(key);
if(result) if(result)
break; return true;
} }
} }
return result;
} }
return false; return false;
} }
nasal_val* nasal_hash::get_keys() nasal_val* nasal_hash::get_keys()
{ {
nasal_val* ret_addr=gc.gc_alloc(vm_vec); nasal_val* ret_addr=gc_alloc(vm_vec);
nasal_vec& ref_vec=ret_addr->get_vector(); std::vector<nasal_val*>& ref_vec=ret_addr->ptr.vec->elems;
for(auto iter=elems.begin();iter!=elems.end();++iter) for(auto iter=elems.begin();iter!=elems.end();++iter)
{ {
nasal_val* str_addr=gc.gc_alloc(vm_str); nasal_val* str_addr=gc_alloc(vm_str);
str_addr->set_string(iter->first); *str_addr->ptr.str=iter->first;
ref_vec.add_elem(str_addr); ref_vec.push_back(str_addr);
} }
return ret_addr; return ret_addr;
} }
@ -350,13 +249,13 @@ void nasal_hash::print()
{ {
std::cout<<i->first<<':'; std::cout<<i->first<<':';
nasal_val* tmp=i->second; nasal_val* tmp=i->second;
switch(tmp->get_type()) switch(tmp->type)
{ {
case vm_nil: std::cout<<"nil"; break; case vm_nil: std::cout<<"nil"; break;
case vm_num: std::cout<<tmp->get_number(); break; case vm_num: std::cout<<tmp->ptr.num; break;
case vm_str: std::cout<<tmp->get_string(); break; case vm_str: std::cout<<*tmp->ptr.str; break;
case vm_vec: tmp->get_vector().print(); break; case vm_vec: tmp->ptr.vec->print(); break;
case vm_hash: tmp->get_hash().print(); break; case vm_hash: tmp->ptr.hash->print(); break;
case vm_func: std::cout<<"func(...){...}"; break; case vm_func: std::cout<<"func(...){...}"; break;
} }
std::cout<<','; std::cout<<',';
@ -366,161 +265,64 @@ void nasal_hash::print()
} }
/*functions of nasal_func*/ /*functions of nasal_func*/
nasal_func::nasal_func(nasal_gc& ngc):gc(ngc) nasal_func::nasal_func()
{ {
closure_addr=NULL;
dynpara=-1; dynpara=-1;
return; return;
} }
nasal_func::~nasal_func()
{
if(closure_addr)
gc.del_reference(closure_addr);
for(int i=0;i<default_para_addr.size();++i)
if(default_para_addr[i])
gc.del_reference(default_para_addr[i]);
return;
}
void nasal_func::set_entry(int etr)
{
entry=etr;
return;
}
int nasal_func::get_entry()
{
return entry;
}
void nasal_func::add_para(int name_index,nasal_val* val_addr=NULL,bool is_dynamic=false)
{
if(is_dynamic)
{
dynpara=name_index;
return;
}
para.push_back(name_index);
default_para_addr.push_back(val_addr);
return;
}
std::vector<int>& nasal_func::get_para()
{
return para;
}
int nasal_func::get_dynamic_para()
{
return dynpara;
}
std::vector<nasal_val*>& nasal_func::get_default()
{
return default_para_addr;
}
void nasal_func::set_closure_addr(nasal_val* value_address)
{
nasal_val* new_closure=gc.gc_alloc(vm_scop);
new_closure->get_closure().set_closure(value_address->get_closure());
closure_addr=new_closure;
return;
}
void nasal_func::set_new_closure()
{
closure_addr=gc.gc_alloc(vm_scop);
return;
}
nasal_val* nasal_func::get_closure_addr()
{
return closure_addr;
}
/*functions of nasal_scop*/ /*functions of nasal_scop*/
nasal_scop::nasal_scop(nasal_gc& ngc):gc(ngc) nasal_val* nasal_scop::get_val(int key)
{
return;
}
nasal_scop::~nasal_scop()
{
for(auto i=elems.begin();i!=elems.end();++i)
gc.del_reference(i->second);
return;
}
void nasal_scop::add_new_value(int key,nasal_val* value_address)
{
if(elems.count(key))
{
// if this value already exists,delete the old value and update a new value
gc.del_reference(elems[key]);
}
elems[key]=value_address;
return;
}
nasal_val* nasal_scop::get_value_address(int key)
{ {
if(elems.count(key)) if(elems.count(key))
return elems[key]; return elems[key];
return NULL; return nullptr;
} }
nasal_val** nasal_scop::get_mem_address(int key) nasal_val** nasal_scop::get_mem(int key)
{ {
if(elems.count(key)) if(elems.count(key))
return &(elems[key]); return &(elems[key]);
return NULL; return nullptr;
}
void nasal_scop::set_closure(nasal_scop& tmp)
{
elems=tmp.elems;
for(auto i=elems.begin();i!=elems.end();++i)
gc.add_reference(i->second);
return;
} }
/*functions of nasal_val*/ /*functions of nasal_val*/
nasal_val::nasal_val() nasal_val::nasal_val()
{ {
ref_cnt=1; mark=false;
type=vm_nil; type=vm_nil;
return; return;
} }
nasal_val::nasal_val(int nasal_val_type,nasal_gc& nvm) nasal_val::nasal_val(int val_type)
{ {
ref_cnt=1; mark=false;
type=nasal_val_type; type=val_type;
switch(nasal_val_type) switch(type)
{ {
case vm_nil: break;
case vm_num: ptr.num=0; break; case vm_num: ptr.num=0; break;
case vm_str: ptr.str=new std::string; break; case vm_str: ptr.str=new std::string; break;
case vm_vec: ptr.vec=new nasal_vec(nvm); break; case vm_vec: ptr.vec=new nasal_vec; break;
case vm_hash: ptr.hash=new nasal_hash(nvm); break; case vm_hash: ptr.hash=new nasal_hash; break;
case vm_func: ptr.func=new nasal_func(nvm); break; case vm_func: ptr.func=new nasal_func; break;
case vm_scop: ptr.cls=new nasal_scop(nvm); break; case vm_scop: ptr.scop=new nasal_scop; break;
} }
return; return;
} }
nasal_val::~nasal_val() nasal_val::~nasal_val()
{ {
// must set type and scalar_ptr to default first switch(type)
// this operation will avoid SIGTRAP caused by circular reference
// circular reference will cause using destructor repeatedly
int tmp_type=type;
type=vm_nil;
switch(tmp_type)
{ {
case vm_nil: break;
case vm_num: break;
case vm_str: delete ptr.str; break; case vm_str: delete ptr.str; break;
case vm_vec: delete ptr.vec; break; case vm_vec: delete ptr.vec; break;
case vm_hash: delete ptr.hash; break; case vm_hash: delete ptr.hash; break;
case vm_func: delete ptr.func; break; case vm_func: delete ptr.func; break;
case vm_scop: delete ptr.cls; break; case vm_scop: delete ptr.scop; break;
} }
type=vm_nil;
return; return;
} }
void nasal_val::clear() void nasal_val::clear()
{ {
// must set type and scalar_ptr to default first switch(type)
// this operation will avoid SIGTRAP caused by circular reference
// circular reference will cause using destructor repeatedly
int tmp_type=type;
type=vm_nil;
switch(tmp_type)
{ {
case vm_nil: break; case vm_nil: break;
case vm_num: break; case vm_num: break;
@ -528,49 +330,30 @@ void nasal_val::clear()
case vm_vec: delete ptr.vec; break; case vm_vec: delete ptr.vec; break;
case vm_hash: delete ptr.hash; break; case vm_hash: delete ptr.hash; break;
case vm_func: delete ptr.func; break; case vm_func: delete ptr.func; break;
case vm_scop: delete ptr.cls; break; case vm_scop: delete ptr.scop; break;
} }
type=vm_nil;
return; return;
} }
void nasal_val::set_type(int nasal_val_type,nasal_gc& nvm) void nasal_val::set_type(int val_type)
{ {
type=nasal_val_type; type=val_type;
switch(nasal_val_type) switch(type)
{ {
case vm_nil: break; case vm_nil: break;
case vm_num: ptr.num=0; break; case vm_num: ptr.num=0; break;
case vm_str: ptr.str=new std::string; break; case vm_str: ptr.str=new std::string; break;
case vm_vec: ptr.vec=new nasal_vec(nvm); break; case vm_vec: ptr.vec=new nasal_vec; break;
case vm_hash: ptr.hash=new nasal_hash(nvm); break; case vm_hash: ptr.hash=new nasal_hash; break;
case vm_func: ptr.func=new nasal_func(nvm); break; case vm_func: ptr.func=new nasal_func; break;
case vm_scop: ptr.cls=new nasal_scop(nvm); break; case vm_scop: ptr.scop=new nasal_scop; break;
} }
return; return;
} }
void nasal_val::set_number(double num)
{
ptr.num=num;
return;
}
void nasal_val::set_string(std::string str)
{
*ptr.str=str;
return;
}
int nasal_val::get_type()
{
return type;
}
double nasal_val::to_number() double nasal_val::to_number()
{ {
if(type==vm_num) if(type==vm_str)
return ptr.num;
else if(type==vm_str)
return trans_string_to_number(*ptr.str); return trans_string_to_number(*ptr.str);
return 0;
}
double nasal_val::get_number()
{
return ptr.num; return ptr.num;
} }
std::string nasal_val::to_string() std::string nasal_val::to_string()
@ -581,79 +364,126 @@ std::string nasal_val::to_string()
return trans_number_to_string(ptr.num); return trans_number_to_string(ptr.num);
return ""; return "";
} }
std::string nasal_val::get_string()
void mark()
{ {
return *ptr.str; int size;
} std::queue<nasal_val*> bfs;
nasal_vec& nasal_val::get_vector() bfs.push(zero_addr);
{ bfs.push(one_addr);
return *ptr.vec; bfs.push(nil_addr);
} bfs.push(global);
nasal_hash& nasal_val::get_hash()
{ size=num_addrs.size();
return *ptr.hash; for(int i=0;i<size;++i)
} bfs.push(num_addrs[i]);
nasal_func& nasal_val::get_func() size=local.size();
{ for(int i=0;i<size;++i)
return *ptr.func; bfs.push(local[i]);
} size=slice_stack.size();
nasal_scop& nasal_val::get_closure() for(int i=0;i<size;++i)
{ bfs.push(slice_stack[i]);
return *ptr.cls; for(nasal_val** i=val_stack;i<=stack_top;++i)
bfs.push(*i);
while(!bfs.empty())
{
nasal_val* tmp=bfs.front();
bfs.pop();
if(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);
}
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);
}
else if(tmp->type==vm_func)
{
std::unordered_map<int,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);
for(auto i=def.begin();i!=def.end();++i)
if(*i && !(*i)->mark)
bfs.push(*i);
}
else if(tmp->type==vm_scop)
{
std::unordered_map<int,nasal_val*>& scop=tmp->ptr.scop->elems;
for(auto i=scop.begin();i!=scop.end();++i)
if(!i->second->mark)
bfs.push(i->second);
}
}
return;
} }
/*functions of nasal_gc*/ void sweep()
nasal_gc::~nasal_gc()
{ {
int gc_mem_size=memory.size(); int size=memory.size();
for(int i=0;i<gc_mem_size;++i) for(int i=0;i<size;++i)
memory[i]->clear();
for(int i=0;i<gc_mem_size;++i)
delete memory[i];
while(!free_space.empty())
free_space.pop();
return;
}
void nasal_gc::clear()
{
int gc_mem_size=memory.size();
for(int i=0;i<gc_mem_size;++i)
memory[i]->clear();
for(int i=0;i<gc_mem_size;++i)
delete memory[i];
while(!free_space.empty())
free_space.pop();
memory.clear();
return;
}
nasal_val* nasal_gc::gc_alloc(int val_type)
{
if(free_space.empty())
{ {
nasal_val* new_unit=new nasal_val(val_type,*this); if(!memory[i]->mark)
memory.push_back(new_unit); {
return new_unit; memory[i]->clear();
free_list.push(memory[i]);
} }
nasal_val* ret=free_space.front(); memory[i]->mark=false;
free_space.pop(); }
ret->ref_cnt=1; return;
ret->set_type(val_type,*this); }
void gc_init()
{
for(int i=0;i<65536;++i)
{
nasal_val* tmp=new nasal_val;
memory.push_back(tmp);
free_list.push(tmp);
}
return;
}
void gc_clear()
{
int size=memory.size();
for(int i=0;i<size;++i)
{
memory[i]->clear();
delete memory[i];
}
memory.clear();
while(!free_list.empty())
free_list.pop();
return;
}
nasal_val* gc_alloc(int type)
{
if(free_list.empty())
{
mark();
sweep();
}
if(free_list.empty())
for(int i=0;i<65536;++i)
{
nasal_val* tmp=new nasal_val;
memory.push_back(tmp);
free_list.push(tmp);
}
nasal_val* ret=free_list.front();
free_list.pop();
ret->set_type(type);
return ret; return ret;
} }
void nasal_gc::add_reference(nasal_val* value_address)
{
++value_address->ref_cnt;
return;
}
void nasal_gc::del_reference(nasal_val* value_address)
{
--value_address->ref_cnt;
if(!value_address->ref_cnt)
{
value_address->clear();
free_space.push(value_address);
}
return;
}
#endif #endif

View File

@ -77,9 +77,9 @@ private:
nasal_ast unary(); nasal_ast unary();
nasal_ast scalar(); nasal_ast scalar();
nasal_ast call_scalar(); nasal_ast call_scalar();
nasal_ast call_hash(); nasal_ast callh();
nasal_ast call_vec(); nasal_ast callv();
nasal_ast call_func(); nasal_ast callf();
nasal_ast subvec(); nasal_ast subvec();
nasal_ast definition(); nasal_ast definition();
nasal_ast var_incurve_def(); nasal_ast var_incurve_def();
@ -95,7 +95,7 @@ private:
nasal_ast conditional(); nasal_ast conditional();
nasal_ast continue_expr(); nasal_ast continue_expr();
nasal_ast break_expr(); nasal_ast break_expr();
nasal_ast return_expr(); nasal_ast ret_expr();
public: public:
int get_error(); int get_error();
void set_toklist(std::vector<token>&); void set_toklist(std::vector<token>&);
@ -494,7 +494,7 @@ nasal_ast nasal_parse::expr()
case tok_if: node=conditional(); break; case tok_if: node=conditional(); break;
case tok_continue: node=continue_expr(); break; case tok_continue: node=continue_expr(); break;
case tok_break: node=break_expr(); break; case tok_break: node=break_expr(); break;
case tok_ret: node=return_expr(); break; case tok_ret: node=ret_expr(); break;
case tok_semi: break; case tok_semi: break;
default: die(error_line,"error token \""+tok_list[ptr].str+"\"");break; default: die(error_line,"error token \""+tok_list[ptr].str+"\"");break;
} }
@ -714,13 +714,13 @@ nasal_ast nasal_parse::call_scalar()
nasal_ast node; nasal_ast node;
switch(tok_list[ptr].type) switch(tok_list[ptr].type)
{ {
case tok_lcurve: node=call_func(); break; case tok_lcurve: node=callf(); break;
case tok_lbracket: node=call_vec(); break; case tok_lbracket: node=callv(); break;
case tok_dot: node=call_hash(); break; case tok_dot: node=callh(); break;
} }
return node; return node;
} }
nasal_ast nasal_parse::call_hash() nasal_ast nasal_parse::callh()
{ {
nasal_ast node(tok_list[ptr].line,ast_callh); nasal_ast node(tok_list[ptr].line,ast_callh);
match(tok_dot); match(tok_dot);
@ -728,7 +728,7 @@ nasal_ast nasal_parse::call_hash()
match(tok_id); match(tok_id);
return node; return node;
} }
nasal_ast nasal_parse::call_vec() nasal_ast nasal_parse::callv()
{ {
nasal_ast node(tok_list[ptr].line,ast_callv); nasal_ast node(tok_list[ptr].line,ast_callv);
match(tok_lbracket); match(tok_lbracket);
@ -743,7 +743,7 @@ nasal_ast nasal_parse::call_vec()
match(tok_rbracket); match(tok_rbracket);
return node; return node;
} }
nasal_ast nasal_parse::call_func() nasal_ast nasal_parse::callf()
{ {
nasal_ast node(tok_list[ptr].line,ast_callf); nasal_ast node(tok_list[ptr].line,ast_callf);
bool special_call=check_special_call(); bool special_call=check_special_call();
@ -1033,7 +1033,7 @@ nasal_ast nasal_parse::break_expr()
match(tok_break); match(tok_break);
return node; return node;
} }
nasal_ast nasal_parse::return_expr() nasal_ast nasal_parse::ret_expr()
{ {
nasal_ast node(tok_list[ptr].line,ast_return); nasal_ast node(tok_list[ptr].line,ast_return);
match(tok_ret); match(tok_ret);

1083
nasal_vm.h

File diff suppressed because it is too large Load Diff

View File

@ -4,14 +4,13 @@ rand(time(0));
var new_neuron=func() var new_neuron=func()
{ {
var neuron={ return {
in:0, in:0,
out:0, out:0,
w:[], w:[],
bia:0, bia:0,
diff:0 diff:0
}; };
return neuron;
} }
var sigmoid=func(x) var sigmoid=func(x)
@ -126,7 +125,7 @@ var backward=func(x)
var cnt=0; var cnt=0;
var show=0; var show=0;
var error=1e8; var error=100;
while(error>0.001) while(error>0.001)
{ {
error=0; error=0;
@ -138,20 +137,14 @@ while(error>0.001)
} }
cnt+=1; cnt+=1;
show+=1; show+=1;
if(show==200) if(show==150)
{ {
show=0; show=0;
print('epoch ',cnt,':',error,'\r'); print('epoch ',cnt,':',error,'\r');
} }
} }
print('finished after ',cnt,' epoch.\n'); print('finished after ',cnt,' epoch.\n');
var vec=[ foreach(var v;training_set)
[0,0],
[0,1],
[1,0],
[1,1]
];
foreach(var v;vec)
{ {
run(v); run(v);
print(v,': ',output[0].out,'\n'); print(v,': ',output[0].out,'\n');

View File

@ -1,19 +1,23 @@
import("lib.nas"); import("lib.nas");
var student= var student=func(name,age)
{ {
new:func(name,age) var val={
{
return {
parents:[student],
name:name, name:name,
age:age age:age
}; };
}, return {
print_info:func(){println(me.name,' ',me.age);}, print_info:func(){println(val.name,' ',val.age);},
get_age:func(){return me.age;}, set_age: func(age){val.age=age;},
get_name:func(){return me.name;} get_age: func(){return val.age;},
set_name: func(name){val.name=name;},
get_name: func(){return val.name;}
}
}; };
var s=student.new('tiansuohaoer',24); var s=student('valk',24);
s.print_info();
println(s.get_age(),' ',s.get_name());
s.set_age(18);
s.set_name('aluo');
s.print_info(); s.print_info();
println(s.get_age(),' ',s.get_name()); println(s.get_age(),' ',s.get_name());

View File

@ -1,27 +1,19 @@
var print=func(elements...) import("lib.nas");
{
nasal_call_builtin_std_cout(elements);
return nil;
};
var setsize=func(vector,size)
{
nasal_call_builtin_set_size(vector,size);
return nil;
}
var fib=func(x) var fib=func(x)
{ {
if(x<2) return x; if(x<2) return x;
return fib(x-1)+fib(x-2); return fib(x-1)+fib(x-2);
} }
print(fib(30),'\n'); for(var i=0;i<31;i+=1)
print(fib(i),'\n');
var m=[0,1,1,2,3,5,8]; # var m=[0,1,1,2,3,5,8];
setsize(m,101); # setsize(m,101);
var fib=func(n) # var fib=func(n)
{ # {
if(m[n]!=nil) return m[n]; # if(m[n]!=nil) return m[n];
var t=fib(n-1)+fib(n-2); # var t=fib(n-1)+fib(n-2);
m[n]=t; # m[n]=t;
return t; # return t;
} # }
print(fib(100),'\n'); # print(fib(100),'\n');

View File

@ -1,60 +1,60 @@
import("lib.nas"); import("lib.nas");
var s=split('',io.fin(input())); var s=io.fin(input());
var len=size(s); var len=size(s);
var ptr=0; var ptr=0;
var cnt=0;
var token=[];
var jump_note=func() var jump_note=func()
{ {
while(ptr<len and s[ptr]!='\n') while(ptr<len and chr(s[ptr])!='\n')
ptr+=1; ptr+=1;
ptr+=1; ptr+=1;
return; return;
} }
var generate_id=func() var generate_id=func()
{ {
var tmp=""; var tmp="";
while(ptr<len) while(ptr<len)
{ {
if('a'<=s[ptr] and s[ptr]<='z' if('a'<=chr(s[ptr]) and chr(s[ptr])<='z'
or 'A'<=s[ptr] and s[ptr]<='Z' or 'A'<=chr(s[ptr]) and chr(s[ptr])<='Z'
or s[ptr]=='_' or chr(s[ptr])=='_'
or '0'<=s[ptr] and s[ptr]<='9') or '0'<=chr(s[ptr]) and chr(s[ptr])<='9')
tmp~=s[ptr]; tmp~=chr(s[ptr]);
else else
break; break;
ptr+=1; ptr+=1;
} }
return tmp; return tmp;
} }
var generate_str=func() var generate_str=func()
{ {
var tok_str=""; var tok_str="";
var mark=s[ptr]; var mark=chr(s[ptr]);
ptr+=1; ptr+=1;
while(ptr<len and s[ptr]!=mark) while(ptr<len and chr(s[ptr])!=mark)
{ {
if(s[ptr]=='\\') if(chr(s[ptr])=='\\')
{ {
ptr+=1; ptr+=1;
if(s[ptr]=='a') tok_str~='\a'; if(chr(s[ptr])=='a') tok_str~='\a';
elsif(s[ptr]=='b') tok_str~='\b'; elsif(chr(s[ptr])=='b') tok_str~='\b';
elsif(s[ptr]=='f') tok_str~='\f'; elsif(chr(s[ptr])=='f') tok_str~='\f';
elsif(s[ptr]=='n') tok_str~='\n'; elsif(chr(s[ptr])=='n') tok_str~='\n';
elsif(s[ptr]=='r') tok_str~='\r'; elsif(chr(s[ptr])=='r') tok_str~='\r';
elsif(s[ptr]=='t') tok_str~='\t'; elsif(chr(s[ptr])=='t') tok_str~='\t';
elsif(s[ptr]=='v') tok_str~='\v'; elsif(chr(s[ptr])=='v') tok_str~='\v';
elsif(s[ptr]=='?') tok_str~='?'; elsif(chr(s[ptr])=='?') tok_str~='?';
elsif(s[ptr]=='0') tok_str~='\0'; elsif(chr(s[ptr])=='0') tok_str~='\0';
elsif(s[ptr]=='\\') tok_str~='\\'; elsif(chr(s[ptr])=='\\') tok_str~='\\';
elsif(s[ptr]=='\'') tok_str~='\''; elsif(chr(s[ptr])=='\'') tok_str~='\'';
elsif(s[ptr]=='\"') tok_str~='\"'; elsif(chr(s[ptr])=='\"') tok_str~='\"';
else tok_str~=s[ptr]; else tok_str~=chr(s[ptr]);
} }
else else
tok_str~=s[ptr]; tok_str~=chr(s[ptr]);
ptr+=1; ptr+=1;
} }
if(ptr>=len) if(ptr>=len)
@ -62,80 +62,77 @@ var generate_str=func()
ptr+=1; ptr+=1;
return tok_str; return tok_str;
} }
var generate_number=func() var generate_number=func()
{ {
var number=s[ptr]; var number=chr(s[ptr]);
ptr+=1; ptr+=1;
if(s[ptr]=='x') if(chr(s[ptr])=='x')
{ {
ptr+=1; ptr+=1;
while(ptr<len and ('a'<=s[ptr] and s[ptr]<='f' or '0'<=s[ptr] and s[ptr]<='9')) while(ptr<len and ('a'<=chr(s[ptr]) and chr(s[ptr])<='f' or '0'<=chr(s[ptr]) and chr(s[ptr])<='9'))
{ {
number~=s[ptr]; number~=chr(s[ptr]);
ptr+=1; ptr+=1;
} }
return num(number); return num(number);
} }
elsif(s[ptr]=='o') elsif(chr(s[ptr])=='o')
{ {
ptr+=1; ptr+=1;
while(ptr<len and ('0'<=s[ptr] and s[ptr]<='7')) while(ptr<len and ('0'<=chr(s[ptr]) and chr(s[ptr])<='7'))
{ {
number~=s[ptr]; number~=chr(s[ptr]);
ptr+=1; ptr+=1;
} }
return num(number); return num(number);
} }
while(ptr<len and ('0'<=chr(s[ptr]) and chr(s[ptr])<='9'))
while(ptr<len and ('0'<=s[ptr] and s[ptr]<='9'))
{ {
number~=s[ptr]; number~=chr(s[ptr]);
ptr+=1; ptr+=1;
} }
if(s[ptr]=='.') if(chr(s[ptr])=='.')
number~=s[ptr]; number~=chr(s[ptr]);
else else
return num(number); return num(number);
ptr+=1; ptr+=1;
while(ptr<len and ('0'<=s[ptr] and s[ptr]<='9')) while(ptr<len and ('0'<=chr(s[ptr]) and chr(s[ptr])<='9'))
{ {
number~=s[ptr]; number~=chr(s[ptr]);
ptr+=1; ptr+=1;
} }
if(s[ptr]=='e' or s[ptr]=='E') if(chr(s[ptr])=='e' or chr(s[ptr])=='E')
number~=s[ptr]; number~=chr(s[ptr]);
else else
return num(number); return num(number);
ptr+=1; ptr+=1;
if(s[ptr]=='-' or s[ptr]=='+') if(chr(s[ptr])=='-' or chr(s[ptr])=='+')
{ {
number~=s[ptr]; number~=chr(s[ptr]);
ptr+=1; ptr+=1;
} }
while(ptr<len and ('0'<=s[ptr] and s[ptr]<='9')) while(ptr<len and ('0'<=chr(s[ptr]) and chr(s[ptr])<='9'))
{ {
number~=s[ptr]; number~=chr(s[ptr]);
ptr+=1; ptr+=1;
} }
return num(number); return num(number);
} }
var generate_operator=func() var generate_operator=func()
{ {
var tmp=""; var tmp="";
if(s[ptr]=='+' or s[ptr]=='-' or s[ptr]=='~' or s[ptr]=='/' or s[ptr]=='*' or s[ptr]=='>' or s[ptr]=='<' or s[ptr]=='!' or s[ptr]=='=') if(chr(s[ptr])=='+' or chr(s[ptr])=='-' or chr(s[ptr])=='~' or chr(s[ptr])=='/' or chr(s[ptr])=='*' or chr(s[ptr])=='>' or chr(s[ptr])=='<' or chr(s[ptr])=='!' or chr(s[ptr])=='=')
{ {
tmp=s[ptr]; tmp=chr(s[ptr]);
ptr+=1; ptr+=1;
if(ptr<len and s[ptr]=='=') if(ptr<len and chr(s[ptr])=='=')
{ {
tmp~=s[ptr]; tmp~=chr(s[ptr]);
ptr+=1; ptr+=1;
} }
return tmp; return tmp;
} }
elsif(s[ptr]=='.') elsif(chr(s[ptr])=='.')
{ {
if(ptr+2<len and s[ptr+1]=='.' and s[ptr+2]=='.') if(ptr+2<len and s[ptr+1]=='.' and s[ptr+2]=='.')
{ {
@ -149,22 +146,21 @@ var generate_operator=func()
} }
return tmp; return tmp;
} }
elsif(s[ptr]!=' ' and s[ptr]!='\t' and s[ptr]!='\n' and s[ptr]!='\r' and s[ptr][0]>0) elsif(chr(s[ptr])!=' ' and chr(s[ptr])!='\t' and chr(s[ptr])!='\n' and chr(s[ptr])!='\r' and chr(s[ptr])[0]>0)
tmp=s[ptr]; tmp=chr(s[ptr]);
ptr+=1; ptr+=1;
return tmp; return tmp;
} }
var cnt=0;
var token=[];
while(ptr<len) while(ptr<len)
{ {
if(s[ptr]=='#') if(chr(s[ptr])=='#')
jump_note(); jump_note();
elsif('a'<=s[ptr] and s[ptr]<='z' or 'A'<=s[ptr] and s[ptr]<='Z' or s[ptr]=='_') elsif('a'<=chr(s[ptr]) and chr(s[ptr])<='z' or 'A'<=chr(s[ptr]) and chr(s[ptr])<='Z' or chr(s[ptr])=='_')
append(token,generate_id()); append(token,generate_id());
elsif(s[ptr]=='\'' or s[ptr]=='\"') elsif(chr(s[ptr])=='\'' or chr(s[ptr])=='\"')
append(token,generate_str()); append(token,generate_str());
elsif('0'<=s[ptr] and s[ptr]<='9') elsif('0'<=chr(s[ptr]) and chr(s[ptr])<='9')
append(token,generate_number()); append(token,generate_number());
else else
{ {
@ -175,6 +171,7 @@ while(ptr<len)
if(ptr>=len) if(ptr>=len)
break; break;
} }
foreach(var i;token) foreach(var i;token)
{ {
print("(",cnt," | ",i,")\n"); print("(",cnt," | ",i,")\n");

View File

@ -1,157 +1,157 @@
var import=func(filename) var import=func(filename)
{ {
nasal_call_import(filename); __builtin_import(filename);
return nil; return nil;
} }
var print=func(elements...) var print=func(elements...)
{ {
nasal_call_builtin_std_cout(elements); __builtin_std_cout(elements);
return nil; return nil;
}; };
var println=func(elements...) var println=func(elements...)
{ {
nasal_call_builtin_std_cout(elements); __builtin_std_cout(elements);
print('\n'); print('\n');
return nil; return nil;
} }
var append=func(vector,elements...) var append=func(vector,elements...)
{ {
nasal_call_builtin_push_back(vector,elements); __builtin_push_back(vector,elements);
return nil; return nil;
} }
var setsize=func(vector,size) var setsize=func(vector,size)
{ {
nasal_call_builtin_set_size(vector,size); __builtin_set_size(vector,size);
return nil; return nil;
} }
var system=func(str) var system=func(str)
{ {
nasal_call_builtin_system(str); __builtin_system(str);
return; return;
} }
var input=func() var input=func()
{ {
return nasal_call_builtin_input(); return __builtin_input();
} }
var sleep=func(duration) var sleep=func(duration)
{ {
nasal_call_builtin_sleep(duration); __builtin_sleep(duration);
return; return;
} }
var split=func(delimeter,string) var split=func(delimeter,string)
{ {
return nasal_call_builtin_split(delimeter,string); return __builtin_split(delimeter,string);
} }
var rand=func(seed=nil) var rand=func(seed=nil)
{ {
return nasal_call_builtin_rand(seed); return __builtin_rand(seed);
} }
var id=func(thing) var id=func(thing)
{ {
return nasal_call_builtin_get_id(thing); return __builtin_get_id(thing);
} }
var int=func(value) var int=func(value)
{ {
return nasal_call_builtin_trans_int(value); return __builtin_int(value);
} }
var num=func(value) var num=func(value)
{ {
return nasal_call_builtin_trans_num(value); return __builtin_num(value);
} }
var pop=func(vector) var pop=func(vector)
{ {
return nasal_call_builtin_pop_back(vector); return __builtin_pop_back(vector);
} }
var str=func(number) var str=func(number)
{ {
return nasal_call_builtin_trans_str(number); return __builtin_str(number);
} }
var size=func(object) var size=func(object)
{ {
return nasal_call_builtin_size(object); return __builtin_size(object);
} }
var contains=func(hash,key) var contains=func(hash,key)
{ {
return nasal_call_builtin_contains(hash,key); return __builtin_contains(hash,key);
} }
var delete=func(hash,key) var delete=func(hash,key)
{ {
nasal_call_builtin_delete(hash,key); __builtin_delete(hash,key);
return; return;
} }
var keys=func(hash) var keys=func(hash)
{ {
return nasal_call_builtin_get_keys(hash); return __builtin_get_keys(hash);
} }
var time=func(begin_time) var time=func(begin_time)
{ {
return nasal_call_builtin_time(begin_time); return __builtin_time(begin_time);
} }
var die=func(str) var die=func(str)
{ {
nasal_call_builtin_die(str); __builtin_die(str);
return nil; return nil;
} }
var typeof=func(object) var typeof=func(object)
{ {
return nasal_call_builtin_type(object); return __builtin_type(object);
} }
var substr=func(str,begin,length) var substr=func(str,begin,length)
{ {
return nasal_call_builtin_substr(str,begin,length); return __builtin_substr(str,begin,length);
} }
var streq=func(a,b) var streq=func(a,b)
{ {
return nasal_call_builtin_streq(a,b); return __builtin_streq(a,b);
} }
var left=func(string,length) var left=func(string,length)
{ {
return nasal_call_builtin_left(string,length); return __builtin_left(string,length);
} }
var right=func(string,length) var right=func(string,length)
{ {
return nasal_call_builtin_right(string,length); return __builtin_right(string,length);
} }
var cmp=func(a,b) var cmp=func(a,b)
{ {
return nasal_call_builtin_cmp(a,b); return __builtin_cmp(a,b);
} }
var chr=func(code) #//Unlike in FG, this chr does not support Extended ASCII var chr=func(code) #//Unlike in FG, this chr does not support Extended ASCII
{ {
return nasal_call_builtin_chr(code); return __builtin_chr(code);
} }
var io= var io=
{ {
fin:func(filename) fin:func(filename)
{ {
return nasal_call_builtin_finput(filename); return __builtin_fin(filename);
}, },
fout:func(filename,str) fout:func(filename,str)
{ {
nasal_call_builtin_foutput(filename,str); __builtin_fout(filename,str);
return; return;
} }
}; };
var bits= var bits=
{ {
bitxor: func(a,b){return nasal_call_builtin_xor(a,b); }, bitxor: func(a,b){return __builtin_xor(a,b); },
bitand: func(a,b){return nasal_call_builtin_and(a,b); }, bitand: func(a,b){return __builtin_and(a,b); },
bitor: func(a,b){return nasal_call_builtin_or(a,b); }, bitor: func(a,b){return __builtin_or(a,b); },
bitnand: func(a,b){return nasal_call_builtin_nand(a,b);}, bitnand: func(a,b){return __builtin_nand(a,b);},
bitnot: func(a) {return nasal_call_builtin_not(a); } bitnot: func(a) {return __builtin_not(a); }
}; };
var math= var math=
{ {
e: 2.7182818284590452354, e: 2.7182818284590452354,
pi: 3.14159265358979323846264338327950288, pi: 3.14159265358979323846264338327950288,
sin: func(x) {return nasal_call_builtin_sin(x); }, sin: func(x) {return __builtin_sin(x); },
cos: func(x) {return nasal_call_builtin_cos(x); }, cos: func(x) {return __builtin_cos(x); },
tan: func(x) {return nasal_call_builtin_tan(x); }, tan: func(x) {return __builtin_tan(x); },
exp: func(x) {return nasal_call_builtin_exp(x); }, exp: func(x) {return __builtin_exp(x); },
ln: func(x) {return nasal_call_builtin_cpp_math_ln(x); }, ln: func(x) {return __builtin_ln(x); },
sqrt: func(x) {return nasal_call_builtin_cpp_math_sqrt(x);}, sqrt: func(x) {return __builtin_sqrt(x); },
atan2: func(x,y){return nasal_call_builtin_cpp_atan2(x,y); } atan2: func(x,y){return __builtin_atan2(x,y);}
}; };