update
This commit is contained in:
parent
c184288c96
commit
86fd516915
|
@ -24,5 +24,6 @@
|
||||||
#include "nasal_parse.h"
|
#include "nasal_parse.h"
|
||||||
#include "nasal_gc.h"
|
#include "nasal_gc.h"
|
||||||
#include "nasal_runtime.h"
|
#include "nasal_runtime.h"
|
||||||
|
#include "nasal_builtin.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -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
|
|
@ -47,15 +47,12 @@ class nasal_function
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// this int points to the space in nasal_vm::garbage_collector_memory
|
// this int points to the space in nasal_vm::garbage_collector_memory
|
||||||
bool is_builtin;
|
|
||||||
int closure_addr;
|
int closure_addr;
|
||||||
nasal_ast argument_list;
|
nasal_ast argument_list;
|
||||||
nasal_ast function_expr;
|
nasal_ast function_expr;
|
||||||
public:
|
public:
|
||||||
nasal_function();
|
nasal_function();
|
||||||
~nasal_function();
|
~nasal_function();
|
||||||
void set_builtin_func();
|
|
||||||
bool check_builtin();
|
|
||||||
void set_closure_addr(int);
|
void set_closure_addr(int);
|
||||||
int get_closure_addr();
|
int get_closure_addr();
|
||||||
void set_arguments(nasal_ast&);
|
void set_arguments(nasal_ast&);
|
||||||
|
@ -83,11 +80,6 @@ public:
|
||||||
void deepcopy(nasal_closure&);
|
void deepcopy(nasal_closure&);
|
||||||
};
|
};
|
||||||
|
|
||||||
nasal_vector error_vector;
|
|
||||||
nasal_hash error_hash;
|
|
||||||
nasal_function error_function;
|
|
||||||
nasal_closure error_closure;
|
|
||||||
|
|
||||||
class nasal_scalar
|
class nasal_scalar
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -148,6 +140,7 @@ private:
|
||||||
std::vector<int*> memory_manager_memory;
|
std::vector<int*> memory_manager_memory;
|
||||||
public:
|
public:
|
||||||
~nasal_virtual_machine();
|
~nasal_virtual_machine();
|
||||||
|
void clear();
|
||||||
int gc_alloc(); // garbage collector gives a new space
|
int gc_alloc(); // garbage collector gives a new space
|
||||||
nasal_scalar& gc_get(int); // get scalar that stored in gc
|
nasal_scalar& gc_get(int); // get scalar that stored in gc
|
||||||
int add_reference(int);
|
int add_reference(int);
|
||||||
|
@ -166,6 +159,11 @@ public:
|
||||||
*/
|
*/
|
||||||
nasal_virtual_machine nasal_vm;
|
nasal_virtual_machine nasal_vm;
|
||||||
nasal_scalar nasal_scalar_calculator;
|
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*/
|
/*functions of nasal_vector*/
|
||||||
nasal_vector::nasal_vector()
|
nasal_vector::nasal_vector()
|
||||||
|
@ -337,7 +335,6 @@ void nasal_hash::deepcopy(nasal_hash& tmp)
|
||||||
/*functions of nasal_function*/
|
/*functions of nasal_function*/
|
||||||
nasal_function::nasal_function()
|
nasal_function::nasal_function()
|
||||||
{
|
{
|
||||||
is_builtin=false;
|
|
||||||
closure_addr=-1;
|
closure_addr=-1;
|
||||||
argument_list.clear();
|
argument_list.clear();
|
||||||
function_expr.clear();
|
function_expr.clear();
|
||||||
|
@ -351,17 +348,10 @@ nasal_function::~nasal_function()
|
||||||
function_expr.clear();
|
function_expr.clear();
|
||||||
return;
|
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)
|
void nasal_function::set_closure_addr(int value_address)
|
||||||
{
|
{
|
||||||
|
if(closure_addr>=0)
|
||||||
|
nasal_vm.del_reference(closure_addr);
|
||||||
closure_addr=value_address;
|
closure_addr=value_address;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -423,8 +413,39 @@ void nasal_closure::del_scope()
|
||||||
{
|
{
|
||||||
if(this->elems.empty())
|
if(this->elems.empty())
|
||||||
return;
|
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)
|
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.mem_free(i->second);
|
||||||
|
}
|
||||||
|
nasal_vm.del_reference(closure);
|
||||||
this->elems.pop_back();
|
this->elems.pop_back();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1365,6 +1386,22 @@ nasal_virtual_machine::~nasal_virtual_machine()
|
||||||
memory_manager_memory.clear();
|
memory_manager_memory.clear();
|
||||||
return;
|
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()
|
int nasal_virtual_machine::gc_alloc()
|
||||||
{
|
{
|
||||||
if(garbage_collector_free_space.empty())
|
if(garbage_collector_free_space.empty())
|
||||||
|
|
|
@ -827,10 +827,7 @@ nasal_ast nasal_parse::scalar()
|
||||||
else if(tok_list[ptr].type==tok_string)
|
else if(tok_list[ptr].type==tok_string)
|
||||||
node=string_gen();
|
node=string_gen();
|
||||||
else if(tok_list[ptr].type==tok_identifier)
|
else if(tok_list[ptr].type==tok_identifier)
|
||||||
{
|
node=id_gen();
|
||||||
node.set_type(ast_call);
|
|
||||||
node.add_child(id_gen());
|
|
||||||
}
|
|
||||||
else if(tok_list[ptr].type==tok_func)
|
else if(tok_list[ptr].type==tok_func)
|
||||||
{
|
{
|
||||||
if(ptr+1<tok_list_size && tok_list[ptr+1].type==tok_identifier)
|
if(ptr+1<tok_list_size && tok_list[ptr+1].type==tok_identifier)
|
||||||
|
|
|
@ -10,6 +10,14 @@ enum runtime_returned_state
|
||||||
rt_exit_without_error
|
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
|
class nasal_runtime
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -32,7 +40,7 @@ private:
|
||||||
// generate hash and return gc place of this hash
|
// generate hash and return gc place of this hash
|
||||||
int hash_generation(nasal_ast&,int);
|
int hash_generation(nasal_ast&,int);
|
||||||
// generate function and return gc place of this function
|
// 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'
|
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_vector(nasal_ast&,int,int);
|
||||||
int call_hash(nasal_ast&,int,int);
|
int call_hash(nasal_ast&,int,int);
|
||||||
int call_function(nasal_ast&,int,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)
|
// get scalars' memory place in complex data structure like vector/hash/function/closure(scope)
|
||||||
int call_scalar_mem(nasal_ast&,int);
|
int call_scalar_mem(nasal_ast&,int);
|
||||||
int call_vector_mem(nasal_ast&,int,int);
|
int call_vector_mem(nasal_ast&,int,int);
|
||||||
|
@ -63,6 +72,9 @@ private:
|
||||||
int calculation(nasal_ast&,int);
|
int calculation(nasal_ast&,int);
|
||||||
void definition(nasal_ast&,int);
|
void definition(nasal_ast&,int);
|
||||||
void multi_assignment(nasal_ast&,int);
|
void multi_assignment(nasal_ast&,int);
|
||||||
|
|
||||||
|
// builtin_func defined here
|
||||||
|
int builtin_print(int);
|
||||||
public:
|
public:
|
||||||
nasal_runtime();
|
nasal_runtime();
|
||||||
~nasal_runtime();
|
~nasal_runtime();
|
||||||
|
@ -91,17 +103,21 @@ void nasal_runtime::set_root(nasal_ast& parse_result)
|
||||||
}
|
}
|
||||||
void nasal_runtime::run()
|
void nasal_runtime::run()
|
||||||
{
|
{
|
||||||
int returned_statement;
|
this->error=0;
|
||||||
time_t begin_time,end_time;
|
|
||||||
this->global_scope_address=nasal_vm.gc_alloc();
|
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).set_type(vm_closure);
|
||||||
nasal_vm.gc_get(global_scope_address).get_closure().add_scope();
|
nasal_vm.gc_get(global_scope_address).get_closure().add_scope();
|
||||||
begin_time=std::time(NULL);
|
|
||||||
returned_statement=main_progress();
|
time_t begin_time=std::time(NULL);
|
||||||
end_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.gc_get(global_scope_address).get_closure().del_scope();
|
||||||
nasal_vm.del_reference(global_scope_address);
|
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;
|
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();
|
int new_memory_space=nasal_vm.mem_alloc();
|
||||||
ref_of_this_vector.add_elem(new_memory_space);
|
ref_of_this_vector.add_elem(new_memory_space);
|
||||||
switch(node.get_children()[i].get_type())
|
nasal_vm.mem_init(new_memory_space,calculation(node.get_children()[i],local_scope_addr));
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return new_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();
|
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);
|
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];
|
nasal_ast& ref_of_hash_member_value=node.get_children()[i].get_children()[1];
|
||||||
switch(ref_of_hash_member_value.get_type())
|
nasal_vm.mem_init(new_memory_space,calculation(ref_of_hash_member_value,local_scope_addr));
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return new_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();
|
int new_addr=nasal_vm.gc_alloc();
|
||||||
nasal_vm.gc_get(new_addr).set_type(vm_function);
|
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_arguments(node.get_children()[0]);
|
||||||
ref_of_this_function.set_run_block(node.get_children()[1]);
|
ref_of_this_function.set_run_block(node.get_children()[1]);
|
||||||
if(local_scope_addr>=0)
|
|
||||||
{
|
int new_closure=nasal_vm.gc_alloc();
|
||||||
// codes here make closure
|
nasal_vm.gc_get(new_closure).set_type(vm_closure);
|
||||||
nasal_vm.add_reference(local_scope_addr);
|
ref_of_this_function.set_closure_addr(new_closure);
|
||||||
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);
|
|
||||||
}
|
|
||||||
return new_addr;
|
return new_addr;
|
||||||
}
|
}
|
||||||
int nasal_runtime::main_progress()
|
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_conditional:ret_state=conditional_progress(root.get_children()[i],-1,false);break;
|
||||||
case ast_while:case ast_for:case ast_forindex:case ast_foreach:
|
case ast_while:case ast_for:case ast_forindex:case ast_foreach:
|
||||||
ret_state=loop_progress(root.get_children()[i],-1,false);break;
|
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_call:
|
||||||
case ast_add_equal:case ast_sub_equal:case ast_mult_equal:case ast_div_equal:case ast_link_equal:
|
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_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();
|
nasal_vm.gc_get(local_scope_addr).get_closure().add_scope();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
nasal_vm.add_reference(local_scope_addr);
|
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 expr_number=node.get_children().size();
|
||||||
int process_returned_value_addr=-1;
|
int process_returned_value_addr=-1;
|
||||||
for(int i=0;i<expr_number;++i)
|
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_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:
|
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;
|
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_call:
|
||||||
case ast_add_equal:case ast_sub_equal:case ast_mult_equal:case ast_div_equal:case ast_link_equal:
|
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_unary_sub:case ast_unary_not:
|
||||||
case ast_add:case ast_sub:case ast_mult:case ast_div:case ast_link:
|
case ast_add:case ast_sub:case ast_mult:case ast_div:case ast_link:
|
||||||
case ast_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_break:ret_state=rt_break;break;
|
||||||
case ast_continue:ret_state=rt_continue;break;
|
case ast_continue:ret_state=rt_continue;break;
|
||||||
case ast_return:
|
case ast_return:
|
||||||
ret_state=rt_return;
|
ret_state=rt_return;
|
||||||
if(allow_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
|
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;
|
++error;
|
||||||
}
|
}
|
||||||
break;
|
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)
|
if(error || ret_state==rt_break || ret_state==rt_continue || ret_state==rt_return)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
nasal_vm.gc_get(local_scope_addr).get_closure().del_scope();
|
||||||
nasal_vm.del_reference(local_scope_addr);
|
nasal_vm.del_reference(local_scope_addr);
|
||||||
return ret_state;
|
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_definition:definition(node,local_scope_addr);break;
|
||||||
case ast_multi_assign:multi_assignment(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_call:
|
||||||
case ast_add_equal:case ast_sub_equal:case ast_mult_equal:case ast_div_equal:case ast_link_equal:
|
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_unary_sub:case ast_unary_not:
|
||||||
case ast_add:case ast_sub:case ast_mult:case ast_div:case ast_link:
|
case ast_add:case ast_sub:case ast_mult:case ast_div:case ast_link:
|
||||||
case ast_trinocular:nasal_vm.del_reference(calculation(node,local_scope_addr));break;
|
case ast_trinocular:nasal_vm.del_reference(calculation(node,local_scope_addr));break;
|
||||||
default:
|
default:std::cout<<">> [runtime] before_for_loop: cannot use this expression before for-loop."<<std::endl;++error;break;
|
||||||
std::cout<<">> [runtime] before_for_loop: cannot use this expression before for-loop."<<std::endl;
|
|
||||||
++error;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if(error)
|
if(error)
|
||||||
return rt_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_definition:definition(node,local_scope_addr);break;
|
||||||
case ast_multi_assign:multi_assignment(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_call:
|
||||||
case ast_add_equal:case ast_sub_equal:case ast_mult_equal:case ast_div_equal:case ast_link_equal:
|
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_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();
|
nasal_vm.gc_get(while_local_scope_addr).get_closure().add_scope();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
nasal_vm.add_reference(local_scope_addr);
|
nasal_vm.add_reference(local_scope_addr);
|
||||||
|
nasal_vm.gc_get(while_local_scope_addr).get_closure().add_scope();
|
||||||
|
}
|
||||||
// check condition and begin loop
|
// check condition and begin loop
|
||||||
while(check_condition(calculation(condition_node,while_local_scope_addr)))
|
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)
|
if(ret_state==rt_break || ret_state==rt_error || ret_state==rt_return)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
nasal_vm.gc_get(while_local_scope_addr).get_closure().del_scope();
|
||||||
nasal_vm.del_reference(while_local_scope_addr);
|
nasal_vm.del_reference(while_local_scope_addr);
|
||||||
}
|
}
|
||||||
else if(loop_type==ast_forindex || loop_type==ast_foreach)
|
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();
|
nasal_vm.gc_get(forei_local_scope_addr).get_closure().add_scope();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
nasal_vm.add_reference(local_scope_addr);
|
nasal_vm.add_reference(local_scope_addr);
|
||||||
|
nasal_vm.gc_get(forei_local_scope_addr).get_closure().add_scope();
|
||||||
|
}
|
||||||
// begin loop progress
|
// begin loop progress
|
||||||
int mem_addr=-1;
|
int mem_addr=-1;
|
||||||
if(iter_node.get_type()==ast_new_iter)
|
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)
|
if(ret_state==rt_break || ret_state==rt_return || ret_state==rt_error)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
nasal_vm.gc_get(forei_local_scope_addr).get_closure().del_scope();
|
||||||
nasal_vm.del_reference(forei_local_scope_addr);
|
nasal_vm.del_reference(forei_local_scope_addr);
|
||||||
}
|
}
|
||||||
else if(loop_type==ast_for)
|
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();
|
nasal_vm.gc_get(for_local_scope_addr).get_closure().add_scope();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
nasal_vm.add_reference(local_scope_addr);
|
nasal_vm.add_reference(local_scope_addr);
|
||||||
|
nasal_vm.gc_get(for_local_scope_addr).get_closure().add_scope();
|
||||||
|
}
|
||||||
// for progress
|
// for progress
|
||||||
for(
|
for(
|
||||||
ret_state=before_for_loop(before_loop_node,for_local_scope_addr);
|
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)
|
if(ret_state==rt_error || ret_state==rt_return || ret_state==rt_break)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
nasal_vm.gc_get(for_local_scope_addr).get_closure().del_scope();
|
||||||
nasal_vm.del_reference(for_local_scope_addr);
|
nasal_vm.del_reference(for_local_scope_addr);
|
||||||
}
|
}
|
||||||
if(ret_state==rt_break || ret_state==rt_continue)
|
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());
|
value_address=nasal_vm.gc_get(global_scope_address).get_closure().get_value_address(node.get_children()[0].get_str());
|
||||||
if(value_address<0)
|
if(value_address<0)
|
||||||
{
|
{
|
||||||
// unfinished
|
value_address=call_builtin_function(node.get_children()[0],local_scope_addr);
|
||||||
// builtin-function call will be set here
|
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;
|
std::cout<<">> [runtime] call_nasal_scalar: cannot find value named \'"<<node.get_children()[0].get_str()<<"\'."<<std::endl;
|
||||||
++error;
|
++error;
|
||||||
return -1;
|
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();
|
int run_closure_addr=reference_of_func.get_closure_addr();
|
||||||
nasal_closure& run_closure=nasal_vm.gc_get(run_closure_addr).get_closure();
|
nasal_closure& run_closure=nasal_vm.gc_get(run_closure_addr).get_closure();
|
||||||
run_closure.add_scope();
|
run_closure.add_scope();
|
||||||
nasal_vm.add_reference(last_call_hash_addr);
|
// set hash.me
|
||||||
run_closure.add_new_value("me",last_call_hash_addr);
|
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();
|
nasal_ast& argument_format=reference_of_func.get_arguments();
|
||||||
if(!node.get_children().size())
|
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();
|
run_closure.del_scope();
|
||||||
if(function_returned_address>=0)
|
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;
|
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 nasal_runtime::call_scalar_mem(nasal_ast& node,int local_scope_addr)
|
||||||
{
|
{
|
||||||
int mem_address=-1;
|
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)
|
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());
|
mem_address=nasal_vm.gc_get(local_scope_addr).get_closure().get_mem_address(node.get_children()[0].get_str());
|
||||||
if(mem_address<0)
|
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
|
// after this process, a new address(in nasal_vm.garbage_collector_memory) will be returned
|
||||||
int ret_address=-1;
|
int ret_address=-1;
|
||||||
int calculation_type=node.get_type();
|
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);
|
ret_address=number_generation(node);
|
||||||
else if(calculation_type==ast_string)
|
else if(calculation_type==ast_string)
|
||||||
ret_address=string_generation(node);
|
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)
|
else if(calculation_type==ast_vector)
|
||||||
ret_address=vector_generation(node,local_scope_addr);
|
ret_address=vector_generation(node,local_scope_addr);
|
||||||
else if(calculation_type==ast_hash)
|
else if(calculation_type==ast_hash)
|
||||||
ret_address=hash_generation(node,local_scope_addr);
|
ret_address=hash_generation(node,local_scope_addr);
|
||||||
else if(calculation_type==ast_function)
|
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)
|
else if(calculation_type==ast_call)
|
||||||
ret_address=call_scalar(node,local_scope_addr);
|
ret_address=call_scalar(node,local_scope_addr);
|
||||||
else if(calculation_type==ast_add)
|
else if(calculation_type==ast_add)
|
||||||
|
@ -1371,7 +1452,7 @@ int nasal_runtime::calculation(nasal_ast& node,int local_scope_addr)
|
||||||
}
|
}
|
||||||
else
|
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;
|
++error;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1432,9 +1513,7 @@ void nasal_runtime::definition(nasal_ast& node,int local_scope_addr)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int value_addr=calculation(value_node,local_scope_addr);
|
int value_addr=calculation(value_node,local_scope_addr);
|
||||||
if(value_addr<0)
|
if(value_addr<0 || nasal_vm.gc_get(value_addr).get_type()!=vm_vector)
|
||||||
return;
|
|
||||||
if(nasal_vm.gc_get(value_addr).get_type()!=vm_vector)
|
|
||||||
{
|
{
|
||||||
std::cout<<">> [runtime] definition: must use vector in multi-definition."<<std::endl;
|
std::cout<<">> [runtime] definition: must use vector in multi-definition."<<std::endl;
|
||||||
++error;
|
++error;
|
||||||
|
@ -1455,11 +1534,11 @@ void nasal_runtime::definition(nasal_ast& node,int local_scope_addr)
|
||||||
{
|
{
|
||||||
int new_addr=nasal_vm.gc_alloc();
|
int new_addr=nasal_vm.gc_alloc();
|
||||||
nasal_vm.gc_get(new_addr).deepcopy(nasal_vm.gc_get(tmp_addr));
|
nasal_vm.gc_get(new_addr).deepcopy(nasal_vm.gc_get(tmp_addr));
|
||||||
nasal_vm.del_reference(tmp_addr);
|
|
||||||
tmp_addr=new_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.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;
|
return;
|
||||||
|
@ -1530,11 +1609,11 @@ void nasal_runtime::multi_assignment(nasal_ast& node,int local_scope_addr)
|
||||||
{
|
{
|
||||||
int new_addr=nasal_vm.gc_alloc();
|
int new_addr=nasal_vm.gc_alloc();
|
||||||
nasal_vm.gc_get(new_addr).deepcopy(nasal_vm.gc_get(tmp_addr));
|
nasal_vm.gc_get(new_addr).deepcopy(nasal_vm.gc_get(tmp_addr));
|
||||||
nasal_vm.del_reference(tmp_addr);
|
|
||||||
tmp_addr=new_addr;
|
tmp_addr=new_addr;
|
||||||
}
|
}
|
||||||
nasal_vm.mem_change(mem_table[i],tmp_addr);
|
nasal_vm.mem_change(mem_table[i],tmp_addr);
|
||||||
}
|
}
|
||||||
|
nasal_vm.del_reference(value_addr);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue