optimize nasal_ast and fix bug in opr_slc2
This commit is contained in:
parent
4f0acc4d63
commit
540aeb73f4
25
makefile
25
makefile
|
@ -1,14 +1,31 @@
|
|||
.PHONY=test
|
||||
nasal:main.cpp nasal_ast.h nasal_builtin.h nasal_codegen.h nasal_gc.h nasal_import.h nasal_lexer.h nasal_parse.h nasal_vm.h nasal.h
|
||||
clang++ -std=c++11 -O3 main.cpp -o nasal -fno-exceptions
|
||||
clang++ -std=c++11 -O3 main.cpp -o nasal -fno-exceptions -Wshadow
|
||||
test:nasal
|
||||
./nasal test/ascii-art.nas
|
||||
./nasal test/bp.nas
|
||||
./nasal -c test/bf.nas
|
||||
./nasal -c test/bfconvertor.nas
|
||||
./nasal test/bfs.nas
|
||||
./nasal -t test/bigloop.nas
|
||||
./nasal -t test/fib.nas
|
||||
./nasal test/bp.nas
|
||||
./nasal test/calc.nas
|
||||
./nasal test/choice.nas
|
||||
./nasal test/class.nas
|
||||
# ./nasal test/exception.nas
|
||||
./nasal -t test/fib.nas
|
||||
./nasal test/hexdump.nas
|
||||
./nasal test/json.nas
|
||||
./nasal test/leetcode1319.nas
|
||||
./nasal test/lexer.nas
|
||||
./nasal -c test/life.nas
|
||||
./nasal -t test/loop.nas
|
||||
./nasal -c test/mandel.nas
|
||||
./nasal -t test/mandelbrot.nas
|
||||
./nasal test/nasal_test.nas
|
||||
./nasal -t test/pi.nas
|
||||
./nasal -t test/prime.nas
|
||||
./nasal -t test/quick_sort.nas
|
||||
./nasal test/scalar.nas
|
||||
./nasal test/trait.nas
|
||||
./nasal -t test/ycombinator.nas
|
||||
./nasal test/exception.nas
|
||||
|
51
nasal_ast.h
51
nasal_ast.h
|
@ -4,17 +4,25 @@
|
|||
enum ast_node
|
||||
{
|
||||
ast_null=0,
|
||||
ast_root,ast_block,
|
||||
ast_root,
|
||||
ast_block,
|
||||
ast_file, // ast_file is only used to store which file the subtree is on,codegen will generate nothing
|
||||
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_args,ast_default_arg,ast_dynamic_id,
|
||||
ast_hashmember,
|
||||
ast_call,ast_callh,ast_callv,ast_callf,
|
||||
ast_subvec,
|
||||
ast_args,ast_default,ast_dynamic,
|
||||
ast_and,ast_or,
|
||||
ast_equal,ast_addeq,ast_subeq,ast_multeq,ast_diveq,ast_lnkeq,
|
||||
ast_equal,
|
||||
ast_addeq,ast_subeq,
|
||||
ast_multeq,ast_diveq,
|
||||
ast_lnkeq,
|
||||
ast_cmpeq,ast_neq,
|
||||
ast_less,ast_leq,
|
||||
ast_grt,ast_geq,
|
||||
ast_add,ast_sub,ast_mult,ast_div,ast_link,
|
||||
ast_add,ast_sub,
|
||||
ast_mult,ast_div,
|
||||
ast_link,
|
||||
ast_neg,ast_not,
|
||||
ast_trino,
|
||||
ast_for,ast_forindex,ast_foreach,ast_while,ast_new_iter,
|
||||
|
@ -27,17 +35,25 @@ enum ast_node
|
|||
const char* ast_name[]=
|
||||
{
|
||||
"null",
|
||||
"root","block",
|
||||
"root",
|
||||
"block",
|
||||
"file",
|
||||
"nil","node_num","node_str","id","func","hash","vec",
|
||||
"hashmember","call","callh","callv","callf","subvec",
|
||||
"args","deflt_arg","dyn_id",
|
||||
"nil","num","str","id","func","hash","vec",
|
||||
"hashmember",
|
||||
"call","callh","callv","callf",
|
||||
"subvec",
|
||||
"args","default","dynamic",
|
||||
"and","or",
|
||||
"=","+=","-=","*=","/=","~=",
|
||||
"=",
|
||||
"+=","-=",
|
||||
"*=","/=",
|
||||
"~=",
|
||||
"==","!=",
|
||||
"<","<=",
|
||||
">",">=",
|
||||
"+","-","*","/","~",
|
||||
"+","-",
|
||||
"*","/",
|
||||
"~",
|
||||
"unary-","unary!",
|
||||
"trino",
|
||||
"for","forindex","foreach","while","iter",
|
||||
|
@ -59,10 +75,15 @@ public:
|
|||
nasal_ast(const uint32_t l=0,const uint32_t t=ast_null):text_line(l),node_type(t){}
|
||||
nasal_ast(const nasal_ast&);
|
||||
nasal_ast(nasal_ast&&);
|
||||
nasal_ast& operator=(const nasal_ast&);
|
||||
nasal_ast& operator=(nasal_ast&&);
|
||||
void print(const int);
|
||||
void clear();
|
||||
|
||||
nasal_ast& operator=(const nasal_ast&);
|
||||
nasal_ast& operator=(nasal_ast&&);
|
||||
nasal_ast& operator[](const int index){return node_child[index];}
|
||||
const nasal_ast& operator[](const int index) const {return node_child[index];}
|
||||
size_t size() const {return node_child.size();}
|
||||
|
||||
void add(nasal_ast&& ast){node_child.push_back(std::move(ast));}
|
||||
void add(const nasal_ast& ast){node_child.push_back(ast);}
|
||||
void set_line(const uint32_t l){text_line=l;}
|
||||
|
@ -133,8 +154,8 @@ void nasal_ast::print(const int depth)
|
|||
if(
|
||||
node_type==ast_str ||
|
||||
node_type==ast_id ||
|
||||
node_type==ast_default_arg ||
|
||||
node_type==ast_dynamic_id ||
|
||||
node_type==ast_default ||
|
||||
node_type==ast_dynamic ||
|
||||
node_type==ast_callh)
|
||||
std::cout<<":"<<raw_string(node_str);
|
||||
else if(node_type==ast_num || node_type==ast_file)
|
||||
|
|
|
@ -63,11 +63,11 @@ nasal_ref builtin_err(const char* func_name,std::string info)
|
|||
|
||||
// register builtin function's name and it's address here in this table below
|
||||
// this table must end with {nullptr,nullptr}
|
||||
struct func
|
||||
struct
|
||||
{
|
||||
const char* name;
|
||||
nasal_ref (*func)(std::vector<nasal_ref>&,nasal_gc&);
|
||||
} builtin_func[]=
|
||||
} builtin[]=
|
||||
{
|
||||
{"__builtin_print", builtin_print },
|
||||
{"__builtin_append", builtin_append },
|
||||
|
|
575
nasal_codegen.h
575
nasal_codegen.h
File diff suppressed because it is too large
Load Diff
|
@ -106,7 +106,7 @@ struct nasal_hash// 56 bytes
|
|||
|
||||
struct nasal_func// 112 bytes
|
||||
{
|
||||
int32_t dynpara; // dynamic parameter name index in hash.
|
||||
int32_t dynpara; // dynamic parameter name index in hash.
|
||||
uint32_t entry; // pc will set to entry-1 to call this function
|
||||
std::vector<nasal_ref> local; // local scope with default value(nasal_ref)
|
||||
std::vector<nasal_ref> upvalue; // closure
|
||||
|
@ -116,11 +116,11 @@ struct nasal_func// 112 bytes
|
|||
void clear();
|
||||
};
|
||||
|
||||
constexpr uint8_t GC_UNCOLLECTED=0;
|
||||
constexpr uint8_t GC_COLLECTED =1;
|
||||
constexpr uint8_t GC_FOUND =2;
|
||||
struct nasal_val// 16 bytes
|
||||
{
|
||||
#define GC_UNCOLLECTED 0
|
||||
#define GC_COLLECTED 1
|
||||
#define GC_FOUND 2
|
||||
uint8_t mark;
|
||||
uint8_t type;
|
||||
union
|
||||
|
|
|
@ -37,14 +37,13 @@ only this kind of node can be recognized as 'import':
|
|||
*/
|
||||
if(node.type()!=ast_call)
|
||||
return false;
|
||||
const std::vector<nasal_ast>& vec=node.child();
|
||||
if(vec.size()!=2)
|
||||
if(node.size()!=2)
|
||||
return false;
|
||||
if(vec[0].str()!="import")
|
||||
if(node[0].str()!="import")
|
||||
return false;
|
||||
if(vec[1].type()!=ast_callf)
|
||||
if(node[1].type()!=ast_callf)
|
||||
return false;
|
||||
if(vec[1].child().size()!=1 || vec[1].child()[0].type()!=ast_str)
|
||||
if(node[1].size()!=1 || node[1][0].type()!=ast_str)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -69,7 +68,7 @@ void nasal_import::linker(nasal_ast& root,nasal_ast&& add_root)
|
|||
nasal_ast nasal_import::file_import(nasal_ast& node)
|
||||
{
|
||||
// get filename and set node to ast_null
|
||||
std::string filename=node.child()[1].child()[0].str();
|
||||
std::string filename=node[1][0].str();
|
||||
node.clear();
|
||||
|
||||
// avoid infinite loading loop
|
||||
|
|
125
nasal_parse.h
125
nasal_parse.h
|
@ -43,8 +43,8 @@ class nasal_parse
|
|||
private:
|
||||
uint32_t ptr;
|
||||
uint32_t error;
|
||||
uint32_t in_func; // count when generating function block,used to check return-expression
|
||||
uint32_t in_loop; // count when generating loop block,used to check break/continue-expression
|
||||
uint32_t in_func; // count when generating function block
|
||||
uint32_t in_loop; // count when generating loop block
|
||||
nasal_ast root;
|
||||
std::vector<token> tokens;
|
||||
std::vector<token> error_token;
|
||||
|
@ -53,7 +53,7 @@ private:
|
|||
void match(uint32_t type,const char* info=nullptr);
|
||||
bool check_comma(const uint32_t*);
|
||||
bool check_multi_scalar();
|
||||
bool check_function_end(const nasal_ast&);
|
||||
bool check_func_end(const nasal_ast&);
|
||||
bool check_special_call();
|
||||
bool need_semi_check(const nasal_ast&);
|
||||
void check_memory_reachable(const nasal_ast&);
|
||||
|
@ -93,7 +93,7 @@ private:
|
|||
nasal_ast while_loop();
|
||||
nasal_ast for_loop();
|
||||
nasal_ast forei_loop();
|
||||
nasal_ast new_iter_gen();
|
||||
nasal_ast iter_gen();
|
||||
nasal_ast conditional();
|
||||
nasal_ast continue_expr();
|
||||
nasal_ast break_expr();
|
||||
|
@ -197,7 +197,7 @@ bool nasal_parse::check_multi_scalar()
|
|||
}
|
||||
return false;
|
||||
}
|
||||
bool nasal_parse::check_function_end(const nasal_ast& node)
|
||||
bool nasal_parse::check_func_end(const nasal_ast& node)
|
||||
{
|
||||
uint32_t type=node.type();
|
||||
if(type==ast_func)
|
||||
|
@ -218,7 +218,7 @@ bool nasal_parse::check_function_end(const nasal_ast& node)
|
|||
)
|
||||
return false;
|
||||
else
|
||||
return check_function_end(node.child().back());
|
||||
return check_func_end(node.child().back());
|
||||
return false;
|
||||
}
|
||||
bool nasal_parse::check_special_call()
|
||||
|
@ -250,7 +250,7 @@ bool nasal_parse::need_semi_check(const nasal_ast& node)
|
|||
uint32_t type=node.type();
|
||||
if(type==ast_for || type==ast_foreach || type==ast_forindex || type==ast_while || type==ast_conditional)
|
||||
return false;
|
||||
return !check_function_end(node);
|
||||
return !check_func_end(node);
|
||||
}
|
||||
void nasal_parse::check_memory_reachable(const nasal_ast& node)
|
||||
{
|
||||
|
@ -259,7 +259,7 @@ void nasal_parse::check_memory_reachable(const nasal_ast& node)
|
|||
const nasal_ast& tmp=node.child().back();
|
||||
if(tmp.type()==ast_callf)
|
||||
die(tmp.line(),"bad left-value");
|
||||
if(tmp.type()==ast_callv && (tmp.child().size()>1 || tmp.child()[0].type()==ast_subvec))
|
||||
if(tmp.type()==ast_callv && (tmp.size()>1 || tmp[0].type()==ast_subvec))
|
||||
die(tmp.line(),"bad left-value");
|
||||
}
|
||||
else if(node.type()!=ast_id)
|
||||
|
@ -380,14 +380,14 @@ nasal_ast nasal_parse::args()
|
|||
{
|
||||
match(tok_eq);
|
||||
special_arg=std::move(tmp);
|
||||
special_arg.set_type(ast_default_arg);
|
||||
special_arg.set_type(ast_default);
|
||||
special_arg.add(calc());
|
||||
}
|
||||
else
|
||||
{
|
||||
match(tok_ellipsis);
|
||||
special_arg=std::move(tmp);
|
||||
special_arg.set_type(ast_dynamic_id);
|
||||
special_arg.set_type(ast_dynamic);
|
||||
}
|
||||
node.add(std::move(special_arg));
|
||||
}
|
||||
|
@ -405,40 +405,41 @@ nasal_ast nasal_parse::args()
|
|||
std::string format="func(";
|
||||
for(auto& tmp:node.child())
|
||||
{
|
||||
format+=tmp.str();
|
||||
switch(tmp.type())
|
||||
{
|
||||
case ast_id: format+=tmp.str();break;
|
||||
case ast_default_arg: format+=tmp.str()+"=val";break;
|
||||
case ast_dynamic_id: format+=tmp.str()+"...";break;
|
||||
case ast_id: break;
|
||||
case ast_default: format+="=val";break;
|
||||
case ast_dynamic: format+="..."; break;
|
||||
}
|
||||
format+=",)"[&tmp==&node.child().back()];
|
||||
}
|
||||
bool checked_default_val=false,checked_dynamic_ids=false;
|
||||
bool checked_default=false,checked_dynamic=false;
|
||||
for(auto& tmp:node.child())
|
||||
{
|
||||
if(tmp.type()==ast_default_arg)
|
||||
checked_default_val=true;
|
||||
else if(tmp.type()==ast_dynamic_id)
|
||||
checked_dynamic_ids=true;
|
||||
if(checked_default_val && tmp.type()!=ast_default_arg)
|
||||
die(tmp.line(),"must use default paras after using it once: "+format);
|
||||
if(checked_dynamic_ids && &tmp!=&node.child().back())
|
||||
if(tmp.type()==ast_default)
|
||||
checked_default=true;
|
||||
else if(tmp.type()==ast_dynamic)
|
||||
checked_dynamic=true;
|
||||
if(checked_default && tmp.type()!=ast_default)
|
||||
die(tmp.line(),"must use default paras after using once: "+format);
|
||||
if(checked_dynamic && &tmp!=&node.child().back())
|
||||
die(tmp.line(),"dynamic para must be the end: "+format);
|
||||
}
|
||||
std::unordered_map<std::string,bool> argname_table;
|
||||
std::unordered_map<std::string,bool> argname;
|
||||
for(auto& tmp:node.child())
|
||||
{
|
||||
std::string new_name;
|
||||
std::string name;
|
||||
switch(tmp.type())
|
||||
{
|
||||
case ast_dynamic_id:
|
||||
case ast_id: new_name=tmp.str();break;
|
||||
case ast_default_arg:new_name=tmp.str();break;
|
||||
case ast_dynamic:
|
||||
case ast_id: name=tmp.str();break;
|
||||
case ast_default:name=tmp.str();break;
|
||||
}
|
||||
if(argname_table.count(new_name))
|
||||
die(tmp.line(),"parameter's name repeats: "+new_name);
|
||||
if(argname.count(name))
|
||||
die(tmp.line(),"parameter's name repeats: "+name);
|
||||
else
|
||||
argname_table[new_name]=true;
|
||||
argname[name]=true;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
@ -766,9 +767,9 @@ nasal_ast nasal_parse::definition()
|
|||
match(tok_var);
|
||||
switch(tokens[ptr].type)
|
||||
{
|
||||
case tok_id: node.add(id());match(tok_id); break;
|
||||
case tok_lcurve: node.add(var_outcurve_def()); break;
|
||||
default: die(error_line,"expected identifier"); break;
|
||||
case tok_id: node.add(id());match(tok_id);break;
|
||||
case tok_lcurve: node.add(var_outcurve_def());break;
|
||||
default: die(error_line,"expected identifier");break;
|
||||
}
|
||||
}
|
||||
else if(tokens[ptr].type==tok_lcurve)
|
||||
|
@ -778,11 +779,11 @@ nasal_ast nasal_parse::definition()
|
|||
node.add(check_multi_scalar()?multi_scalar(false):calc());
|
||||
else
|
||||
node.add(calc());
|
||||
if(node.child()[0].type()==ast_id && node.child()[1].type()==ast_multi_scalar)
|
||||
die(node.child()[1].line(),"one identifier cannot accept too many values");
|
||||
else if(node.child()[0].type()==ast_multi_id && node.child()[1].type()==ast_multi_scalar)
|
||||
if(node.child()[0].child().size()!=node.child()[1].child().size())
|
||||
die(node.child()[0].line(),"too much or lack values in multi-definition");
|
||||
if(node[0].type()==ast_id && node[1].type()==ast_multi_scalar)
|
||||
die(node[1].line(),"one identifier cannot accept too many values");
|
||||
else if(node[0].type()==ast_multi_id && node[1].type()==ast_multi_scalar)
|
||||
if(node[0].size()!=node[1].size())
|
||||
die(node[0].line(),"too much or lack values in multi-definition");
|
||||
return node;
|
||||
}
|
||||
nasal_ast nasal_parse::var_incurve_def()
|
||||
|
@ -861,9 +862,9 @@ nasal_ast nasal_parse::multi_assgin()
|
|||
node.add(check_multi_scalar()?multi_scalar(false):calc());
|
||||
else
|
||||
node.add(calc());
|
||||
if(node.child()[1].type()==ast_multi_scalar
|
||||
&& node.child()[0].child().size()!=node.child()[1].child().size())
|
||||
die(node.child()[0].line(),"too much or lack values in multi-assignment");
|
||||
if(node[1].type()==ast_multi_scalar
|
||||
&& node[0].size()!=node[1].size())
|
||||
die(node[0].line(),"too much or lack values in multi-assignment");
|
||||
return node;
|
||||
}
|
||||
nasal_ast nasal_parse::loop()
|
||||
|
@ -933,15 +934,15 @@ nasal_ast nasal_parse::forei_loop()
|
|||
nasal_ast node(tokens[ptr].line,ast_null);
|
||||
switch(tokens[ptr].type)
|
||||
{
|
||||
case tok_forindex: node.set_type(ast_forindex);match(tok_forindex); break;
|
||||
case tok_foreach: node.set_type(ast_foreach); match(tok_foreach); break;
|
||||
case tok_forindex:node.set_type(ast_forindex);match(tok_forindex);break;
|
||||
case tok_foreach: node.set_type(ast_foreach); match(tok_foreach); break;
|
||||
}
|
||||
match(tok_lcurve);
|
||||
// first expression
|
||||
// foreach/forindex must have an iterator to loop through
|
||||
if(tokens[ptr].type!=tok_var && tokens[ptr].type!=tok_id)
|
||||
die(error_line,"expected iterator");
|
||||
node.add(new_iter_gen());
|
||||
node.add(iter_gen());
|
||||
// check semi
|
||||
match(tok_semi,"expected \';\' in foreach/forindex(iter;vector)");
|
||||
// check vector
|
||||
|
@ -952,7 +953,7 @@ nasal_ast nasal_parse::forei_loop()
|
|||
node.add(exprs());
|
||||
return node;
|
||||
}
|
||||
nasal_ast nasal_parse::new_iter_gen()
|
||||
nasal_ast nasal_parse::iter_gen()
|
||||
{
|
||||
nasal_ast node(tokens[ptr].line,ast_null);
|
||||
if(tokens[ptr].type==tok_var)
|
||||
|
@ -975,30 +976,29 @@ nasal_ast nasal_parse::new_iter_gen()
|
|||
nasal_ast nasal_parse::conditional()
|
||||
{
|
||||
nasal_ast node(tokens[ptr].line,ast_conditional);
|
||||
nasal_ast tmp(tokens[ptr].line,ast_if);
|
||||
nasal_ast ifnode(tokens[ptr].line,ast_if);
|
||||
match(tok_if);
|
||||
match(tok_lcurve);
|
||||
tmp.add(calc());
|
||||
ifnode.add(calc());
|
||||
match(tok_rcurve);
|
||||
tmp.add(exprs());
|
||||
node.add(std::move(tmp));
|
||||
// end of if-expression
|
||||
ifnode.add(exprs());
|
||||
node.add(std::move(ifnode));
|
||||
while(tokens[ptr].type==tok_elsif)
|
||||
{
|
||||
nasal_ast tmp(tokens[ptr].line,ast_elsif);
|
||||
nasal_ast elsifnode(tokens[ptr].line,ast_elsif);
|
||||
match(tok_elsif);
|
||||
match(tok_lcurve);
|
||||
tmp.add(calc());
|
||||
elsifnode.add(calc());
|
||||
match(tok_rcurve);
|
||||
tmp.add(exprs());
|
||||
node.add(std::move(tmp));
|
||||
elsifnode.add(exprs());
|
||||
node.add(std::move(elsifnode));
|
||||
}
|
||||
if(tokens[ptr].type==tok_else)
|
||||
{
|
||||
nasal_ast tmp(tokens[ptr].line,ast_else);
|
||||
nasal_ast elsenode(tokens[ptr].line,ast_else);
|
||||
match(tok_else);
|
||||
tmp.add(exprs());
|
||||
node.add(std::move(tmp));
|
||||
elsenode.add(exprs());
|
||||
node.add(std::move(elsenode));
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
@ -1019,8 +1019,17 @@ nasal_ast nasal_parse::ret_expr()
|
|||
nasal_ast node(tokens[ptr].line,ast_ret);
|
||||
match(tok_ret);
|
||||
uint32_t type=tokens[ptr].type;
|
||||
if(type==tok_nil || type==tok_num || type==tok_str || type==tok_id || type==tok_func ||
|
||||
type==tok_sub || type==tok_not || type==tok_lcurve || type==tok_lbracket || type==tok_lbrace)
|
||||
if(
|
||||
type==tok_nil ||
|
||||
type==tok_num ||
|
||||
type==tok_str ||
|
||||
type==tok_id ||
|
||||
type==tok_func ||
|
||||
type==tok_sub ||
|
||||
type==tok_not ||
|
||||
type==tok_lcurve ||
|
||||
type==tok_lbracket ||
|
||||
type==tok_lbrace)
|
||||
node.add(calc());
|
||||
return node;
|
||||
}
|
||||
|
|
23
nasal_vm.h
23
nasal_vm.h
|
@ -165,7 +165,7 @@ void nasal_vm::bytecodeinfo(const uint32_t p)
|
|||
const opcode& code=bytecode[p];
|
||||
printf("\t0x%.8x: %s 0x%x",p,code_table[code.op].name,code.num);
|
||||
if(code.op==op_callb)
|
||||
printf(" <%s>",builtin_func[code.num].name);
|
||||
printf(" <%s>",builtin[code.num].name);
|
||||
printf(" (<%s> line %d)\n",files[code.fidx].c_str(),code.line);
|
||||
}
|
||||
void nasal_vm::traceback()
|
||||
|
@ -286,10 +286,9 @@ inline bool nasal_vm::condition(nasal_ref val)
|
|||
return val.value.num;
|
||||
else if(val.type==vm_str)
|
||||
{
|
||||
const std::string& str=*val.str();
|
||||
double num=str2num(str.c_str());
|
||||
double num=str2num(val.str()->c_str());
|
||||
if(std::isnan(num))
|
||||
return str.empty();
|
||||
return val.str()->empty();
|
||||
return num;
|
||||
}
|
||||
return false;
|
||||
|
@ -560,7 +559,7 @@ inline void nasal_vm::opr_findex()
|
|||
pc=imm[pc]-1;
|
||||
return;
|
||||
}
|
||||
(++top)[0]={vm_num,static_cast<double>(counter.top())};
|
||||
(++top)[0]={vm_num,(double)counter.top()};
|
||||
}
|
||||
inline void nasal_vm::opr_feach()
|
||||
{
|
||||
|
@ -642,7 +641,7 @@ inline void nasal_vm::opr_callh()
|
|||
}
|
||||
inline void nasal_vm::opr_callfv()
|
||||
{
|
||||
size_t args_size=imm[pc];
|
||||
uint32_t args_size=imm[pc];
|
||||
nasal_ref* args=top-args_size+1;
|
||||
if(args[-1].type!=vm_func)
|
||||
die("callfv: must call a function");
|
||||
|
@ -655,13 +654,13 @@ inline void nasal_vm::opr_callfv()
|
|||
// load parameters
|
||||
auto& closure=gc.local.back().vec()->elems;
|
||||
|
||||
size_t para_size=func.keys.size();
|
||||
uint32_t para_size=func.keys.size();
|
||||
// load arguments
|
||||
// if the first default value is not vm_none,then values after it are not nullptr
|
||||
if(args_size<para_size && func.local[args_size+1/*1 is reserved for 'me'*/].type==vm_none)
|
||||
die("callfv: lack argument(s)");
|
||||
// if args_size>para_size,for 0 to args_size will cause corruption
|
||||
size_t min_size=std::min(para_size,args_size);
|
||||
uint32_t min_size=std::min(para_size,args_size);
|
||||
for(uint32_t i=0;i<min_size;++i)
|
||||
closure[i+1]=args[i];
|
||||
// load dynamic argument if args_size>=para_size
|
||||
|
@ -707,7 +706,7 @@ inline void nasal_vm::opr_callfh()
|
|||
}
|
||||
inline void nasal_vm::opr_callb()
|
||||
{
|
||||
(++top)[0]=(*builtin_func[imm[pc]].func)(gc.local.back().vec()->elems,gc);
|
||||
(++top)[0]=(*builtin[imm[pc]].func)(gc.local.back().vec()->elems,gc);
|
||||
if(top[0].type==vm_none)
|
||||
die("native function error.");
|
||||
}
|
||||
|
@ -744,7 +743,7 @@ inline void nasal_vm::opr_slc2()
|
|||
uint8_t type1=val1.type,type2=val2.type;
|
||||
int num1=val1.to_number();
|
||||
int num2=val2.to_number();
|
||||
size_t size=ref.size();
|
||||
int size=ref.size();
|
||||
if(type1==vm_nil && type2==vm_nil)
|
||||
{
|
||||
num1=0;
|
||||
|
@ -799,7 +798,7 @@ inline void nasal_vm::opr_mcallv()
|
|||
mem_addr=ref.get_mem(str);
|
||||
if(!mem_addr)
|
||||
{
|
||||
ref.elems[str]=gc.nil;
|
||||
ref.elems[str]={vm_nil};
|
||||
mem_addr=ref.get_mem(str);
|
||||
}
|
||||
}
|
||||
|
@ -816,7 +815,7 @@ inline void nasal_vm::opr_mcallh()
|
|||
mem_addr=ref.get_mem(str);
|
||||
if(!mem_addr) // create a new key
|
||||
{
|
||||
ref.elems[str]=gc.nil;
|
||||
ref.elems[str]={vm_nil};
|
||||
mem_addr=ref.get_mem(str);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue