gc changed to mark-sweep
This commit is contained in:
parent
569d5c6c6a
commit
144e6f45da
|
@ -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
84
lib.nas
|
@ -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);}
|
||||||
};
|
};
|
||||||
|
|
24
main.cpp
24
main.cpp
|
@ -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
13
nasal.h
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
72
nasal_ast.h
72
nasal_ast.h
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
816
nasal_builtin.h
816
nasal_builtin.h
File diff suppressed because it is too large
Load Diff
580
nasal_codegen.h
580
nasal_codegen.h
File diff suppressed because it is too large
Load Diff
686
nasal_gc.h
686
nasal_gc.h
|
@ -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,184 +12,113 @@ 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&);
|
void print();
|
||||||
~nasal_vec();
|
nasal_val* get_val(int);
|
||||||
int size();
|
nasal_val** get_mem(int);
|
||||||
void add_elem(nasal_val*);
|
|
||||||
void print();
|
|
||||||
nasal_val* del_elem();
|
|
||||||
nasal_val* operator[](const 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();
|
void print();
|
||||||
int size();
|
nasal_val* get_special_para(std::string&);
|
||||||
bool check_contain(std::string);
|
nasal_val* get_val(std::string&);
|
||||||
void add_elem(std::string,nasal_val*);
|
nasal_val** get_mem(std::string&);
|
||||||
void del_elem(std::string);
|
|
||||||
void print();
|
|
||||||
nasal_val* get_special_para(std::string);
|
|
||||||
nasal_val* get_value_address(std::string);
|
|
||||||
nasal_val** get_mem_address(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
|
||||||
{
|
{
|
||||||
double num;
|
double num;
|
||||||
std::string* str;
|
std::string* str;
|
||||||
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(int,nasal_gc&);
|
|
||||||
~nasal_val();
|
|
||||||
void clear();
|
|
||||||
void set_type(int,nasal_gc&);
|
|
||||||
void set_number(double);
|
|
||||||
void set_string(std::string);
|
|
||||||
int get_type();
|
|
||||||
double to_number();
|
|
||||||
double get_number();
|
|
||||||
std::string to_string();
|
|
||||||
std::string get_string();
|
|
||||||
nasal_vec& get_vector();
|
|
||||||
nasal_hash& get_hash();
|
|
||||||
nasal_func& get_func();
|
|
||||||
nasal_scop& get_closure();
|
|
||||||
};
|
|
||||||
|
|
||||||
class nasal_gc
|
nasal_val();
|
||||||
{
|
nasal_val(int);
|
||||||
private:
|
~nasal_val();
|
||||||
std::queue<nasal_val*> free_space;
|
void clear();
|
||||||
std::vector<nasal_val*> memory;
|
void set_type(int);
|
||||||
public:
|
double to_number();
|
||||||
~nasal_gc();
|
std::string to_string();
|
||||||
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,14 +132,14 @@ 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,14 +249,14 @@ 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; break;
|
||||||
case vm_vec: ptr.vec=new nasal_vec(nvm); break;
|
case vm_hash: ptr.hash=new nasal_hash; break;
|
||||||
case vm_hash: ptr.hash=new nasal_hash(nvm); break;
|
case vm_func: ptr.func=new nasal_func; break;
|
||||||
case vm_func: ptr.func=new nasal_func(nvm); break;
|
case vm_scop: ptr.scop=new nasal_scop; break;
|
||||||
case vm_scop: ptr.cls=new nasal_scop(nvm); 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]);
|
||||||
|
}
|
||||||
|
memory[i]->mark=false;
|
||||||
}
|
}
|
||||||
nasal_val* ret=free_space.front();
|
return;
|
||||||
free_space.pop();
|
}
|
||||||
ret->ref_cnt=1;
|
|
||||||
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
|
|
@ -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);
|
||||||
|
|
1093
nasal_vm.h
1093
nasal_vm.h
File diff suppressed because it is too large
Load Diff
15
test/bp.nas
15
test/bp.nas
|
@ -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');
|
||||||
|
|
|
@ -1,19 +1,23 @@
|
||||||
import("lib.nas");
|
import("lib.nas");
|
||||||
|
|
||||||
var student=
|
var student=func(name,age)
|
||||||
{
|
{
|
||||||
new:func(name,age)
|
var val={
|
||||||
{
|
name:name,
|
||||||
return {
|
age:age
|
||||||
parents:[student],
|
};
|
||||||
name:name,
|
return {
|
||||||
age:age
|
print_info:func(){println(val.name,' ',val.age);},
|
||||||
};
|
set_age: func(age){val.age=age;},
|
||||||
},
|
get_age: func(){return val.age;},
|
||||||
print_info:func(){println(me.name,' ',me.age);},
|
set_name: func(name){val.name=name;},
|
||||||
get_age:func(){return me.age;},
|
get_name: func(){return val.name;}
|
||||||
get_name:func(){return me.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());
|
34
test/fib.nas
34
test/fib.nas
|
@ -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');
|
119
test/lexer.nas
119
test/lexer.nas
|
@ -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");
|
||||||
|
|
84
test/lib.nas
84
test/lib.nas
|
@ -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);}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue