This commit is contained in:
Valk Richard Li 2020-09-09 02:51:31 -07:00 committed by GitHub
parent c184288c96
commit 86fd516915
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 233 additions and 82 deletions

View File

@ -24,5 +24,6 @@
#include "nasal_parse.h"
#include "nasal_gc.h"
#include "nasal_runtime.h"
#include "nasal_builtin.h"
#endif

View File

@ -0,0 +1,37 @@
#ifndef __NASAL_BUILTIN_H__
#define __NASAL_BUILTIN_H__
int nasal_runtime::builtin_print(int local_scope_addr)
{
int vector_value_addr=-1;
if(local_scope_addr>=0)
vector_value_addr=nasal_vm.gc_get(local_scope_addr).get_closure().get_value_address("dyn");
if(vector_value_addr<0 || nasal_vm.gc_get(vector_value_addr).get_type()!=vm_vector)
{
std::cout<<">> [runtime] builtin_print: cannot find values or wrong value type."<<std::endl;
++error;
return -1;
}
nasal_vector& ref_vec=nasal_vm.gc_get(vector_value_addr).get_vector();
int size=ref_vec.size();
for(int i=0;i<size;++i)
{
nasal_scalar& tmp=nasal_vm.gc_get(ref_vec.get_value_address(i));
switch(tmp.get_type())
{
case vm_nil:std::cout<<"nil";break;
case vm_number:std::cout<<tmp.get_number();break;
case vm_string:std::cout<<tmp.get_string();break;
case vm_vector:std::cout<<"[...]";break;
case vm_hash:std::cout<<"{...}";break;
case vm_function:std::cout<<"func(...){...}";break;
case vm_closure:std::cout<<"closure{{...}}";break;
}
std::cout<<(i==size-1? '\n':',');
}
int ret_addr=nasal_vm.gc_alloc();
nasal_vm.gc_get(ret_addr).set_type(vm_nil);
return ret_addr;
}
#endif

View File

@ -47,15 +47,12 @@ class nasal_function
{
private:
// this int points to the space in nasal_vm::garbage_collector_memory
bool is_builtin;
int closure_addr;
nasal_ast argument_list;
nasal_ast function_expr;
public:
nasal_function();
~nasal_function();
void set_builtin_func();
bool check_builtin();
void set_closure_addr(int);
int get_closure_addr();
void set_arguments(nasal_ast&);
@ -83,11 +80,6 @@ public:
void deepcopy(nasal_closure&);
};
nasal_vector error_vector;
nasal_hash error_hash;
nasal_function error_function;
nasal_closure error_closure;
class nasal_scalar
{
private:
@ -148,6 +140,7 @@ private:
std::vector<int*> memory_manager_memory;
public:
~nasal_virtual_machine();
void clear();
int gc_alloc(); // garbage collector gives a new space
nasal_scalar& gc_get(int); // get scalar that stored in gc
int add_reference(int);
@ -166,6 +159,11 @@ public:
*/
nasal_virtual_machine nasal_vm;
nasal_scalar nasal_scalar_calculator;
// error values set here,if defined before nasal_vm,SIGSEGV will occur.
nasal_vector error_vector;
nasal_hash error_hash;
nasal_function error_function;
nasal_closure error_closure;
/*functions of nasal_vector*/
nasal_vector::nasal_vector()
@ -337,7 +335,6 @@ void nasal_hash::deepcopy(nasal_hash& tmp)
/*functions of nasal_function*/
nasal_function::nasal_function()
{
is_builtin=false;
closure_addr=-1;
argument_list.clear();
function_expr.clear();
@ -351,17 +348,10 @@ nasal_function::~nasal_function()
function_expr.clear();
return;
}
void nasal_function::set_builtin_func()
{
is_builtin=true;
return;
}
bool nasal_function::check_builtin()
{
return is_builtin;
}
void nasal_function::set_closure_addr(int value_address)
{
if(closure_addr>=0)
nasal_vm.del_reference(closure_addr);
closure_addr=value_address;
return;
}
@ -423,8 +413,39 @@ void nasal_closure::del_scope()
{
if(this->elems.empty())
return;
// make closure here
// functions in different scope but the same closure will get different copies of closures
// functions in the same scope will get the same copy of closure,when running these functions,one closure will be changed,make sure you are using it correctly!
// please notice this,otherwise your programme may not work correctly
int closure=nasal_vm.gc_alloc();
nasal_vm.gc_get(closure).set_type(vm_closure);
nasal_closure& new_closure=nasal_vm.gc_get(closure).get_closure();
new_closure.deepcopy(*this);
std::vector<std::string> func_name;
for(std::map<std::string,int>::iterator i=new_closure.elems.back().begin();i!=new_closure.elems.back().end();++i)
{
int value_addr=nasal_vm.mem_get(i->second);
if(nasal_vm.gc_get(value_addr).get_type()==vm_function)
{
func_name.push_back(i->first);
nasal_vm.mem_free(i->second); // mem_free will delete the reference of mem_get(i->second)
}
}
for(int i=0;i<func_name.size();++i)
new_closure.elems.back().erase(func_name[i]);
for(std::map<std::string,int>::iterator i=this->elems.back().begin();i!=this->elems.back().end();++i)
{
int value_addr=nasal_vm.mem_get(i->second);
if(nasal_vm.gc_get(value_addr).get_type()==vm_function)
{
nasal_vm.gc_get(value_addr).get_func().set_closure_addr(closure);
nasal_vm.add_reference(closure);
}
nasal_vm.mem_free(i->second);
}
nasal_vm.del_reference(closure);
this->elems.pop_back();
return;
}
@ -1365,6 +1386,22 @@ nasal_virtual_machine::~nasal_virtual_machine()
memory_manager_memory.clear();
return;
}
void nasal_virtual_machine::clear()
{
int gc_mem_size=garbage_collector_memory.size();
int mm_mem_size=memory_manager_memory.size();
for(int i=0;i<gc_mem_size;++i)
delete []garbage_collector_memory[i];
for(int i=0;i<mm_mem_size;++i)
delete []memory_manager_memory[i];
while(!garbage_collector_free_space.empty())
garbage_collector_free_space.pop();
while(!memory_manager_free_space.empty())
memory_manager_free_space.pop();
garbage_collector_memory.clear();
memory_manager_memory.clear();
return;
}
int nasal_virtual_machine::gc_alloc()
{
if(garbage_collector_free_space.empty())

View File

@ -827,10 +827,7 @@ nasal_ast nasal_parse::scalar()
else if(tok_list[ptr].type==tok_string)
node=string_gen();
else if(tok_list[ptr].type==tok_identifier)
{
node.set_type(ast_call);
node.add_child(id_gen());
}
node=id_gen();
else if(tok_list[ptr].type==tok_func)
{
if(ptr+1<tok_list_size && tok_list[ptr+1].type==tok_identifier)

View File

@ -10,6 +10,14 @@ enum runtime_returned_state
rt_exit_without_error
};
#define BUILTIN_FUNC_NUM 3
std::string builtin_func_name[BUILTIN_FUNC_NUM]=
{
"nasal_call_builtin_std_cout",
"nasal_call_builtin_push_back",
"nasal_call_builtin_set_size",
};
class nasal_runtime
{
private:
@ -32,7 +40,7 @@ private:
// generate hash and return gc place of this hash
int hash_generation(nasal_ast&,int);
// generate function and return gc place of this function
int function_generation(nasal_ast&,int);
int function_generation(nasal_ast&);
/*
functions after this note may have parameter named 'local_scope_addr'
@ -55,6 +63,7 @@ private:
int call_vector(nasal_ast&,int,int);
int call_hash(nasal_ast&,int,int);
int call_function(nasal_ast&,int,int,int);
int call_builtin_function(nasal_ast&,int);
// get scalars' memory place in complex data structure like vector/hash/function/closure(scope)
int call_scalar_mem(nasal_ast&,int);
int call_vector_mem(nasal_ast&,int,int);
@ -63,6 +72,9 @@ private:
int calculation(nasal_ast&,int);
void definition(nasal_ast&,int);
void multi_assignment(nasal_ast&,int);
// builtin_func defined here
int builtin_print(int);
public:
nasal_runtime();
~nasal_runtime();
@ -91,17 +103,21 @@ void nasal_runtime::set_root(nasal_ast& parse_result)
}
void nasal_runtime::run()
{
int returned_statement;
time_t begin_time,end_time;
this->error=0;
this->global_scope_address=nasal_vm.gc_alloc();
nasal_vm.gc_get(global_scope_address).set_type(vm_closure);
nasal_vm.gc_get(global_scope_address).get_closure().add_scope();
begin_time=std::time(NULL);
returned_statement=main_progress();
end_time=std::time(NULL);
time_t begin_time=std::time(NULL);
int returned_statement=main_progress();
time_t end_time=std::time(NULL);
nasal_vm.gc_get(global_scope_address).get_closure().del_scope();
nasal_vm.del_reference(global_scope_address);
std::cout<<">> [runtime] process exited after "<<end_time-begin_time<<"s with returned value "<<returned_statement<<'.'<<std::endl;
nasal_vm.clear();
std::cout<<">> [runtime] process exited after "<<end_time-begin_time<<"s "<<(returned_statement==rt_exit_without_error?"without errors.":"with errors.")<<std::endl;
return;
}
@ -131,14 +147,7 @@ int nasal_runtime::vector_generation(nasal_ast& node,int local_scope_addr)
{
int new_memory_space=nasal_vm.mem_alloc();
ref_of_this_vector.add_elem(new_memory_space);
switch(node.get_children()[i].get_type())
{
case ast_number: nasal_vm.mem_init(new_memory_space,number_generation(node.get_children()[i]));break;
case ast_string: nasal_vm.mem_init(new_memory_space,string_generation(node.get_children()[i]));break;
case ast_vector: nasal_vm.mem_init(new_memory_space,vector_generation(node.get_children()[i],local_scope_addr));break;
case ast_hash: nasal_vm.mem_init(new_memory_space,hash_generation(node.get_children()[i],local_scope_addr));break;
case ast_function: nasal_vm.mem_init(new_memory_space,function_generation(node.get_children()[i],local_scope_addr));break;
}
nasal_vm.mem_init(new_memory_space,calculation(node.get_children()[i],local_scope_addr));
}
return new_addr;
}
@ -155,18 +164,11 @@ int nasal_runtime::hash_generation(nasal_ast& node,int local_scope_addr)
std::string hash_member_name=node.get_children()[i].get_children()[0].get_str();
ref_of_this_hash.add_elem(hash_member_name,new_memory_space);
nasal_ast& ref_of_hash_member_value=node.get_children()[i].get_children()[1];
switch(ref_of_hash_member_value.get_type())
{
case ast_number: nasal_vm.mem_init(new_memory_space,number_generation(ref_of_hash_member_value));break;
case ast_string: nasal_vm.mem_init(new_memory_space,string_generation(ref_of_hash_member_value));break;
case ast_vector: nasal_vm.mem_init(new_memory_space,vector_generation(ref_of_hash_member_value,local_scope_addr));break;
case ast_hash: nasal_vm.mem_init(new_memory_space,hash_generation(ref_of_hash_member_value,local_scope_addr));break;
case ast_function: nasal_vm.mem_init(new_memory_space,function_generation(ref_of_hash_member_value,local_scope_addr));break;
}
nasal_vm.mem_init(new_memory_space,calculation(ref_of_hash_member_value,local_scope_addr));
}
return new_addr;
}
int nasal_runtime::function_generation(nasal_ast& node,int local_scope_addr)
int nasal_runtime::function_generation(nasal_ast& node)
{
int new_addr=nasal_vm.gc_alloc();
nasal_vm.gc_get(new_addr).set_type(vm_function);
@ -174,18 +176,10 @@ int nasal_runtime::function_generation(nasal_ast& node,int local_scope_addr)
ref_of_this_function.set_arguments(node.get_children()[0]);
ref_of_this_function.set_run_block(node.get_children()[1]);
if(local_scope_addr>=0)
{
// codes here make closure
nasal_vm.add_reference(local_scope_addr);
ref_of_this_function.set_closure_addr(local_scope_addr);
}
else
{
int new_closure_addr=nasal_vm.gc_alloc();
nasal_vm.gc_get(new_closure_addr).set_type(vm_closure);
ref_of_this_function.set_closure_addr(new_closure_addr);
}
int new_closure=nasal_vm.gc_alloc();
nasal_vm.gc_get(new_closure).set_type(vm_closure);
ref_of_this_function.set_closure_addr(new_closure);
return new_addr;
}
int nasal_runtime::main_progress()
@ -203,7 +197,8 @@ int nasal_runtime::main_progress()
case ast_conditional:ret_state=conditional_progress(root.get_children()[i],-1,false);break;
case ast_while:case ast_for:case ast_forindex:case ast_foreach:
ret_state=loop_progress(root.get_children()[i],-1,false);break;
case ast_number:case ast_string:break;
case ast_number:case ast_string:case ast_function:break;
case ast_vector:case ast_hash:
case ast_call:
case ast_add_equal:case ast_sub_equal:case ast_mult_equal:case ast_div_equal:case ast_link_equal:
case ast_unary_sub:case ast_unary_not:
@ -239,7 +234,10 @@ int nasal_runtime::block_progress(nasal_ast& node,int local_scope_addr,bool allo
nasal_vm.gc_get(local_scope_addr).get_closure().add_scope();
}
else
{
nasal_vm.add_reference(local_scope_addr);
nasal_vm.gc_get(local_scope_addr).get_closure().add_scope();
}
int expr_number=node.get_children().size();
int process_returned_value_addr=-1;
for(int i=0;i<expr_number;++i)
@ -252,21 +250,22 @@ int nasal_runtime::block_progress(nasal_ast& node,int local_scope_addr,bool allo
case ast_conditional:ret_state=conditional_progress(node.get_children()[i],local_scope_addr,allow_return);break;
case ast_while:case ast_for:case ast_forindex:case ast_foreach:
ret_state=loop_progress(node.get_children()[i],local_scope_addr,allow_return);break;
case ast_number:case ast_string:break;
case ast_number:case ast_string:case ast_function:break;
case ast_vector:case ast_hash:
case ast_call:
case ast_add_equal:case ast_sub_equal:case ast_mult_equal:case ast_div_equal:case ast_link_equal:
case ast_unary_sub:case ast_unary_not:
case ast_add:case ast_sub:case ast_mult:case ast_div:case ast_link:
case ast_trinocular:nasal_vm.del_reference(calculation(root.get_children()[i],local_scope_addr));break;
case ast_trinocular:nasal_vm.del_reference(calculation(node.get_children()[i],local_scope_addr));break;
case ast_break:ret_state=rt_break;break;
case ast_continue:ret_state=rt_continue;break;
case ast_return:
ret_state=rt_return;
if(allow_return)
function_returned_address=calculation(root.get_children()[i].get_children()[0],local_scope_addr);
function_returned_address=calculation(node.get_children()[i].get_children()[0],local_scope_addr);
else
{
std::cout<<">> [runtime] return expression is not allowed here."<<std::endl;
std::cout<<">> [runtime] block_progress: return expression is not allowed here."<<std::endl;
++error;
}
break;
@ -279,6 +278,7 @@ int nasal_runtime::block_progress(nasal_ast& node,int local_scope_addr,bool allo
if(error || ret_state==rt_break || ret_state==rt_continue || ret_state==rt_return)
break;
}
nasal_vm.gc_get(local_scope_addr).get_closure().del_scope();
nasal_vm.del_reference(local_scope_addr);
return ret_state;
}
@ -289,16 +289,14 @@ int nasal_runtime::before_for_loop(nasal_ast& node,int local_scope_addr)
{
case ast_definition:definition(node,local_scope_addr);break;
case ast_multi_assign:multi_assignment(node,local_scope_addr);break;
case ast_number:case ast_string:break;
case ast_number:case ast_string:case ast_function:break;
case ast_vector:case ast_hash:
case ast_call:
case ast_add_equal:case ast_sub_equal:case ast_mult_equal:case ast_div_equal:case ast_link_equal:
case ast_unary_sub:case ast_unary_not:
case ast_add:case ast_sub:case ast_mult:case ast_div:case ast_link:
case ast_trinocular:nasal_vm.del_reference(calculation(node,local_scope_addr));break;
default:
std::cout<<">> [runtime] before_for_loop: cannot use this expression before for-loop."<<std::endl;
++error;
break;
default:std::cout<<">> [runtime] before_for_loop: cannot use this expression before for-loop."<<std::endl;++error;break;
}
if(error)
return rt_error;
@ -311,7 +309,8 @@ int nasal_runtime::after_each_for_loop(nasal_ast& node,int local_scope_addr)
{
case ast_definition:definition(node,local_scope_addr);break;
case ast_multi_assign:multi_assignment(node,local_scope_addr);break;
case ast_number:case ast_string:break;
case ast_number:case ast_string:case ast_function:break;
case ast_vector:case ast_hash:
case ast_call:
case ast_add_equal:case ast_sub_equal:case ast_mult_equal:case ast_div_equal:case ast_link_equal:
case ast_unary_sub:case ast_unary_not:
@ -340,7 +339,10 @@ int nasal_runtime::loop_progress(nasal_ast& node,int local_scope_addr,bool allow
nasal_vm.gc_get(while_local_scope_addr).get_closure().add_scope();
}
else
{
nasal_vm.add_reference(local_scope_addr);
nasal_vm.gc_get(while_local_scope_addr).get_closure().add_scope();
}
// check condition and begin loop
while(check_condition(calculation(condition_node,while_local_scope_addr)))
{
@ -349,6 +351,7 @@ int nasal_runtime::loop_progress(nasal_ast& node,int local_scope_addr,bool allow
if(ret_state==rt_break || ret_state==rt_error || ret_state==rt_return)
break;
}
nasal_vm.gc_get(while_local_scope_addr).get_closure().del_scope();
nasal_vm.del_reference(while_local_scope_addr);
}
else if(loop_type==ast_forindex || loop_type==ast_foreach)
@ -373,7 +376,10 @@ int nasal_runtime::loop_progress(nasal_ast& node,int local_scope_addr,bool allow
nasal_vm.gc_get(forei_local_scope_addr).get_closure().add_scope();
}
else
{
nasal_vm.add_reference(local_scope_addr);
nasal_vm.gc_get(forei_local_scope_addr).get_closure().add_scope();
}
// begin loop progress
int mem_addr=-1;
if(iter_node.get_type()==ast_new_iter)
@ -414,6 +420,7 @@ int nasal_runtime::loop_progress(nasal_ast& node,int local_scope_addr,bool allow
if(ret_state==rt_break || ret_state==rt_return || ret_state==rt_error)
break;
}
nasal_vm.gc_get(forei_local_scope_addr).get_closure().del_scope();
nasal_vm.del_reference(forei_local_scope_addr);
}
else if(loop_type==ast_for)
@ -432,7 +439,10 @@ int nasal_runtime::loop_progress(nasal_ast& node,int local_scope_addr,bool allow
nasal_vm.gc_get(for_local_scope_addr).get_closure().add_scope();
}
else
{
nasal_vm.add_reference(local_scope_addr);
nasal_vm.gc_get(for_local_scope_addr).get_closure().add_scope();
}
// for progress
for(
ret_state=before_for_loop(before_loop_node,for_local_scope_addr);
@ -446,6 +456,7 @@ int nasal_runtime::loop_progress(nasal_ast& node,int local_scope_addr,bool allow
if(ret_state==rt_error || ret_state==rt_return || ret_state==rt_break)
break;
}
nasal_vm.gc_get(for_local_scope_addr).get_closure().del_scope();
nasal_vm.del_reference(for_local_scope_addr);
}
if(ret_state==rt_break || ret_state==rt_continue)
@ -518,8 +529,12 @@ int nasal_runtime::call_scalar(nasal_ast& node,int local_scope_addr)
value_address=nasal_vm.gc_get(global_scope_address).get_closure().get_value_address(node.get_children()[0].get_str());
if(value_address<0)
{
// unfinished
// builtin-function call will be set here
value_address=call_builtin_function(node.get_children()[0],local_scope_addr);
if(value_address>=0)
return value_address;
}
if(value_address<0)
{
std::cout<<">> [runtime] call_nasal_scalar: cannot find value named \'"<<node.get_children()[0].get_str()<<"\'."<<std::endl;
++error;
return -1;
@ -831,8 +846,12 @@ int nasal_runtime::call_function(nasal_ast& node,int base_value_addr,int last_ca
int run_closure_addr=reference_of_func.get_closure_addr();
nasal_closure& run_closure=nasal_vm.gc_get(run_closure_addr).get_closure();
run_closure.add_scope();
nasal_vm.add_reference(last_call_hash_addr);
run_closure.add_new_value("me",last_call_hash_addr);
// set hash.me
if(last_call_hash_addr>=0)
{
nasal_vm.add_reference(last_call_hash_addr);
run_closure.add_new_value("me",last_call_hash_addr);
}
nasal_ast& argument_format=reference_of_func.get_arguments();
if(!node.get_children().size())
{
@ -1002,7 +1021,15 @@ int nasal_runtime::call_function(nasal_ast& node,int base_value_addr,int last_ca
}
}
}
block_progress(reference_of_func.get_run_block(),run_closure_addr,true);
int ret_state=block_progress(reference_of_func.get_run_block(),run_closure_addr,true);
if(ret_state==rt_break || ret_state==rt_continue)
{
std::cout<<">> [runtime] call_function: break and continue are not allowed to be used here."<<std::endl;
++error;
return -1;
}
else if(ret_state==rt_error)
return -1;
run_closure.del_scope();
if(function_returned_address>=0)
@ -1017,9 +1044,44 @@ int nasal_runtime::call_function(nasal_ast& node,int base_value_addr,int last_ca
}
return ret_value_addr;
}
int nasal_runtime::call_builtin_function(nasal_ast& node,int local_scope_addr)
{
int ret_value_addr=-1;
int builtin_num=-1;
std::string builtin_name=node.get_str();
for(int i=0;i<BUILTIN_FUNC_NUM;++i)
if(builtin_name==builtin_func_name[i])
{
builtin_num=i;
break;
}
if(builtin_num<0)
return -1;
switch(builtin_num)
{
case 0:ret_value_addr=builtin_print(local_scope_addr);break;
case 1:break;
case 2:break;
}
return ret_value_addr;
}
int nasal_runtime::call_scalar_mem(nasal_ast& node,int local_scope_addr)
{
int mem_address=-1;
if(node.get_type()==ast_identifier)
{
if(local_scope_addr>=0)
mem_address=nasal_vm.gc_get(local_scope_addr).get_closure().get_mem_address(node.get_str());
if(mem_address<0)
mem_address=nasal_vm.gc_get(global_scope_address).get_closure().get_mem_address(node.get_str());
if(mem_address<0)
{
std::cout<<">> [runtime] call_scalar_mem: cannot find value named \'"<<node.get_str()<<"\'."<<std::endl;
++error;
return -1;
}
return mem_address;
}
if(local_scope_addr>=0)
mem_address=nasal_vm.gc_get(local_scope_addr).get_closure().get_mem_address(node.get_children()[0].get_str());
if(mem_address<0)
@ -1134,16 +1196,35 @@ int nasal_runtime::calculation(nasal_ast& node,int local_scope_addr)
// after this process, a new address(in nasal_vm.garbage_collector_memory) will be returned
int ret_address=-1;
int calculation_type=node.get_type();
if(calculation_type==ast_number)
if(calculation_type==ast_nil)
{
ret_address=nasal_vm.gc_alloc();
nasal_vm.gc_get(ret_address).set_type(vm_nil);
}
else if(calculation_type==ast_number)
ret_address=number_generation(node);
else if(calculation_type==ast_string)
ret_address=string_generation(node);
else if(calculation_type==ast_identifier)
{
if(local_scope_addr>=0)
ret_address=nasal_vm.gc_get(local_scope_addr).get_closure().get_value_address(node.get_str());
if(ret_address<0)
ret_address=nasal_vm.gc_get(global_scope_address).get_closure().get_value_address(node.get_str());
if(ret_address<0)
{
std::cout<<">> [runtime] calculation: cannot find value named \'"<<node.get_str()<<"\'."<<std::endl;
++error;
return -1;
}
nasal_vm.add_reference(ret_address);
}
else if(calculation_type==ast_vector)
ret_address=vector_generation(node,local_scope_addr);
else if(calculation_type==ast_hash)
ret_address=hash_generation(node,local_scope_addr);
else if(calculation_type==ast_function)
ret_address=function_generation(node,local_scope_addr);
ret_address=function_generation(node);
else if(calculation_type==ast_call)
ret_address=call_scalar(node,local_scope_addr);
else if(calculation_type==ast_add)
@ -1371,7 +1452,7 @@ int nasal_runtime::calculation(nasal_ast& node,int local_scope_addr)
}
else
{
std::cout<<">> [runtime] calculation: this expression cannot be calculated."<<std::endl;
std::cout<<">> [runtime] calculation: this expression cannot be calculated.expression type:"<<ast_str(node.get_type())<<"."<<std::endl;
++error;
return -1;
}
@ -1432,9 +1513,7 @@ void nasal_runtime::definition(nasal_ast& node,int local_scope_addr)
else
{
int value_addr=calculation(value_node,local_scope_addr);
if(value_addr<0)
return;
if(nasal_vm.gc_get(value_addr).get_type()!=vm_vector)
if(value_addr<0 || nasal_vm.gc_get(value_addr).get_type()!=vm_vector)
{
std::cout<<">> [runtime] definition: must use vector in multi-definition."<<std::endl;
++error;
@ -1455,11 +1534,11 @@ void nasal_runtime::definition(nasal_ast& node,int local_scope_addr)
{
int new_addr=nasal_vm.gc_alloc();
nasal_vm.gc_get(new_addr).deepcopy(nasal_vm.gc_get(tmp_addr));
nasal_vm.del_reference(tmp_addr);
tmp_addr=new_addr;
}
nasal_vm.gc_get(local_scope_addr<0?global_scope_address:local_scope_addr).get_closure().add_new_value(identifier_table[i],tmp_addr);
}
nasal_vm.del_reference(value_addr);
}
}
return;
@ -1530,11 +1609,11 @@ void nasal_runtime::multi_assignment(nasal_ast& node,int local_scope_addr)
{
int new_addr=nasal_vm.gc_alloc();
nasal_vm.gc_get(new_addr).deepcopy(nasal_vm.gc_get(tmp_addr));
nasal_vm.del_reference(tmp_addr);
tmp_addr=new_addr;
}
nasal_vm.mem_change(mem_table[i],tmp_addr);
}
nasal_vm.del_reference(value_addr);
}
return;
}