update
This commit is contained in:
parent
4b7646223a
commit
b674618823
|
@ -1,6 +1,9 @@
|
|||
#ifndef __NASAL_H__
|
||||
#define __NASAL_H__
|
||||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
|
|
@ -132,4 +132,70 @@ int nasal_runtime::builtin_setsize(int local_scope_addr)
|
|||
return ret_addr;
|
||||
}
|
||||
|
||||
int nasal_runtime::builtin_system(int local_scope_addr)
|
||||
{
|
||||
int str_value_addr=-1;
|
||||
if(local_scope_addr>=0)
|
||||
str_value_addr=nasal_vm.gc_get(local_scope_addr).get_closure().get_value_address("str");
|
||||
if(str_value_addr<0 || nasal_vm.gc_get(str_value_addr).get_type()!=vm_string)
|
||||
{
|
||||
std::cout<<">> [runtime] builtin_system: cannot find values or wrong value type(must be string)."<<std::endl;
|
||||
++error;
|
||||
return -1;
|
||||
}
|
||||
std::string str=nasal_vm.gc_get(str_value_addr).get_string();
|
||||
int size=str.length();
|
||||
char* command=new char[size+1];
|
||||
for(int i=0;i<size;++i)
|
||||
command[i]=str[i];
|
||||
command[size]='\0';
|
||||
system(command);
|
||||
delete []command;
|
||||
int ret_addr=nasal_vm.gc_alloc();
|
||||
nasal_vm.gc_get(ret_addr).set_type(vm_nil);
|
||||
return ret_addr;
|
||||
}
|
||||
|
||||
int nasal_runtime::builtin_input(int local_scope_addr)
|
||||
{
|
||||
int ret_addr=nasal_vm.gc_alloc();
|
||||
nasal_vm.gc_get(ret_addr).set_type(vm_string);
|
||||
std::string str;
|
||||
std::cin>>str;
|
||||
nasal_vm.gc_get(ret_addr).set_string(str);
|
||||
return ret_addr;
|
||||
}
|
||||
|
||||
int nasal_runtime::builtin_sleep(int local_scope_addr)
|
||||
{
|
||||
int value_addr=-1;
|
||||
if(local_scope_addr>=0)
|
||||
value_addr=nasal_vm.gc_get(local_scope_addr).get_closure().get_value_address("duration");
|
||||
if(value_addr<0 || (nasal_vm.gc_get(value_addr).get_type()!=vm_string && nasal_vm.gc_get(value_addr).get_type()!=vm_number))
|
||||
{
|
||||
std::cout<<">> [runtime] builtin_sleep: cannot find values or wrong value type(must be string or numebr)."<<std::endl;
|
||||
++error;
|
||||
return -1;
|
||||
}
|
||||
unsigned long sleep_time=0;
|
||||
if(nasal_vm.gc_get(value_addr).get_type()==vm_string)
|
||||
{
|
||||
std::string str=nasal_vm.gc_get(value_addr).get_string();
|
||||
if(check_numerable_string(str))
|
||||
sleep_time=(unsigned long)trans_string_to_number(str);
|
||||
else
|
||||
{
|
||||
std::cout<<">> [runtime] builtin_sleep: this is not a numerable string."<<std::endl;
|
||||
++error;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
sleep_time=(unsigned long)nasal_vm.gc_get(value_addr).get_number();
|
||||
_sleep(sleep_time);
|
||||
int ret_addr=nasal_vm.gc_alloc();
|
||||
nasal_vm.gc_get(ret_addr).set_type(vm_nil);
|
||||
return ret_addr;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -129,12 +129,14 @@ class nasal_virtual_machine
|
|||
}
|
||||
};
|
||||
private:
|
||||
bool error_info_output_switch;
|
||||
nasal_scalar error_returned_value;
|
||||
std::queue<int> garbage_collector_free_space;
|
||||
std::vector<gc_unit*> garbage_collector_memory;
|
||||
std::queue<int> memory_manager_free_space;
|
||||
std::vector<int*> memory_manager_memory;
|
||||
public:
|
||||
nasal_virtual_machine();
|
||||
~nasal_virtual_machine();
|
||||
void clear();
|
||||
void debug();
|
||||
|
@ -1090,6 +1092,15 @@ int nasal_scalar::nasal_scalar_cmp_not_equal(int a_scalar_addr,int b_scalar_addr
|
|||
}
|
||||
else if((a_ref.type==vm_number || a_ref.type==vm_string) && (b_ref.type==vm_number || b_ref.type==vm_string))
|
||||
{
|
||||
if(a_ref.type==vm_string && b_ref.type==vm_string)
|
||||
{
|
||||
std::string astr=*(std::string*)a_ref.scalar_ptr;
|
||||
std::string bstr=*(std::string*)b_ref.scalar_ptr;
|
||||
int new_value_address=nasal_vm.gc_alloc();
|
||||
nasal_vm.gc_get(new_value_address).set_type(vm_number);
|
||||
nasal_vm.gc_get(new_value_address).set_number((double)(astr!=bstr));
|
||||
return new_value_address;
|
||||
}
|
||||
double a_num;
|
||||
double b_num;
|
||||
if(a_ref.type==vm_number) a_num=*(double*)a_ref.scalar_ptr;
|
||||
|
@ -1306,21 +1317,39 @@ int nasal_scalar::nasal_scalar_cmp_greater_or_equal(int a_scalar_addr,int b_scal
|
|||
}
|
||||
|
||||
/*functions of nasal_virtual_machine*/
|
||||
nasal_virtual_machine::nasal_virtual_machine()
|
||||
{
|
||||
error_info_output_switch=true;
|
||||
return;
|
||||
}
|
||||
nasal_virtual_machine::~nasal_virtual_machine()
|
||||
{
|
||||
error_info_output_switch=false;
|
||||
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)
|
||||
{
|
||||
for(int j=0;j<GC_BLK_SIZE;++j)
|
||||
if(garbage_collector_memory[i][j].ref_cnt)
|
||||
{
|
||||
garbage_collector_memory[i][j].ref_cnt=0;
|
||||
garbage_collector_memory[i][j].collected=true;
|
||||
}
|
||||
for(int i=0;i<gc_mem_size;++i)
|
||||
{
|
||||
for(int j=0;j<GC_BLK_SIZE;++j)
|
||||
if(garbage_collector_memory[i][j].elem.get_type()!=vm_nil)
|
||||
garbage_collector_memory[i][j].elem.clear();
|
||||
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();
|
||||
error_info_output_switch=true;
|
||||
return;
|
||||
}
|
||||
void nasal_virtual_machine::debug()
|
||||
|
@ -1348,12 +1377,20 @@ void nasal_virtual_machine::debug()
|
|||
}
|
||||
void nasal_virtual_machine::clear()
|
||||
{
|
||||
error_info_output_switch=false;
|
||||
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)
|
||||
{
|
||||
for(int j=0;j<GC_BLK_SIZE;++j)
|
||||
if(garbage_collector_memory[i][j].ref_cnt)
|
||||
{
|
||||
garbage_collector_memory[i][j].ref_cnt=0;
|
||||
garbage_collector_memory[i][j].collected=true;
|
||||
}
|
||||
for(int i=0;i<gc_mem_size;++i)
|
||||
{
|
||||
for(int j=0;j<GC_BLK_SIZE;++j)
|
||||
if(garbage_collector_memory[i][j].elem.get_type()!=vm_nil)
|
||||
garbage_collector_memory[i][j].elem.clear();
|
||||
delete []garbage_collector_memory[i];
|
||||
}
|
||||
|
@ -1365,6 +1402,7 @@ void nasal_virtual_machine::clear()
|
|||
memory_manager_free_space.pop();
|
||||
garbage_collector_memory.clear();
|
||||
memory_manager_memory.clear();
|
||||
error_info_output_switch=true;
|
||||
return;
|
||||
}
|
||||
int nasal_virtual_machine::gc_alloc()
|
||||
|
@ -1391,7 +1429,8 @@ nasal_scalar& nasal_virtual_machine::gc_get(int value_address)
|
|||
return garbage_collector_memory[blk_num][blk_plc].elem;
|
||||
else
|
||||
{
|
||||
std::cout<<">> [vm] gc_get:unexpected memory \'"<<value_address<<"\'."<<std::endl;
|
||||
if(error_info_output_switch)
|
||||
std::cout<<">> [vm] gc_get:unexpected memory \'"<<value_address<<"\'."<<std::endl;
|
||||
return error_returned_value;
|
||||
}
|
||||
}
|
||||
|
@ -1402,7 +1441,10 @@ void nasal_virtual_machine::add_reference(int value_address)
|
|||
if(0<=value_address && value_address<(garbage_collector_memory.size()<<8) && !garbage_collector_memory[blk_num][blk_plc].collected)
|
||||
++garbage_collector_memory[blk_num][blk_plc].ref_cnt;
|
||||
else
|
||||
std::cout<<">> [vm] gc_add_ref:unexpected memory \'"<<value_address<<"\'."<<std::endl;
|
||||
{
|
||||
if(error_info_output_switch)
|
||||
std::cout<<">> [vm] gc_add_ref:unexpected memory \'"<<value_address<<"\'."<<std::endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
void nasal_virtual_machine::del_reference(int value_address)
|
||||
|
@ -1413,7 +1455,8 @@ void nasal_virtual_machine::del_reference(int value_address)
|
|||
--garbage_collector_memory[blk_num][blk_plc].ref_cnt;
|
||||
else
|
||||
{
|
||||
std::cout<<">> [vm] gc_del_ref:unexpected memory \'"<<value_address<<"\'."<<std::endl;
|
||||
if(error_info_output_switch)
|
||||
std::cout<<">> [vm] gc_del_ref:unexpected memory \'"<<value_address<<"\'."<<std::endl;
|
||||
return;
|
||||
}
|
||||
if(!garbage_collector_memory[blk_num][blk_plc].ref_cnt)
|
||||
|
@ -1431,7 +1474,10 @@ int nasal_virtual_machine::get_refcnt(int value_address)
|
|||
if(0<=value_address && value_address<(garbage_collector_memory.size()<<8) && !garbage_collector_memory[blk_num][blk_plc].collected)
|
||||
return garbage_collector_memory[blk_num][blk_plc].ref_cnt;
|
||||
else
|
||||
std::cout<<">> [vm] get_refcnt:unexpected memory \'"<<value_address<<"\'."<<std::endl;
|
||||
{
|
||||
if(error_info_output_switch)
|
||||
std::cout<<">> [vm] get_refcnt:unexpected memory \'"<<value_address<<"\'."<<std::endl;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
int nasal_virtual_machine::mem_alloc()
|
||||
|
@ -1459,7 +1505,8 @@ int nasal_virtual_machine::mem_free(int memory_address)
|
|||
}
|
||||
else
|
||||
{
|
||||
std::cout<<">> [vm] mem_free:unexpected memory \'"<<memory_address<<"\'."<<std::endl;
|
||||
if(error_info_output_switch)
|
||||
std::cout<<">> [vm] mem_free:unexpected memory \'"<<memory_address<<"\'."<<std::endl;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
@ -1475,7 +1522,8 @@ int nasal_virtual_machine::mem_change(int memory_address,int value_address)
|
|||
}
|
||||
else
|
||||
{
|
||||
std::cout<<">> [vm] mem_store:unexpected memory \'"<<memory_address<<"\'."<<std::endl;
|
||||
if(error_info_output_switch)
|
||||
std::cout<<">> [vm] mem_store:unexpected memory \'"<<memory_address<<"\'."<<std::endl;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
@ -1488,7 +1536,8 @@ int nasal_virtual_machine::mem_init(int memory_address,int value_address)
|
|||
memory_manager_memory[memory_address>>8][memory_address&0xff]=value_address;
|
||||
else
|
||||
{
|
||||
std::cout<<">> [vm] mem_store:unexpected memory \'"<<memory_address<<"\'."<<std::endl;
|
||||
if(error_info_output_switch)
|
||||
std::cout<<">> [vm] mem_store:unexpected memory \'"<<memory_address<<"\'."<<std::endl;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
@ -1500,7 +1549,10 @@ int nasal_virtual_machine::mem_get(int memory_address)
|
|||
if(0<=memory_address && memory_address<(memory_manager_memory.size()<<8))
|
||||
ret=memory_manager_memory[memory_address>>8][memory_address&0xff];
|
||||
else
|
||||
std::cout<<">> [vm] mem_get:unexpected memory \'"<<memory_address<<"\'."<<std::endl;
|
||||
{
|
||||
if(error_info_output_switch)
|
||||
std::cout<<">> [vm] mem_get:unexpected memory \'"<<memory_address<<"\'."<<std::endl;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
|
@ -10,12 +10,15 @@ enum runtime_returned_state
|
|||
rt_exit_without_error
|
||||
};
|
||||
|
||||
#define BUILTIN_FUNC_NUM 3
|
||||
#define BUILTIN_FUNC_NUM 6
|
||||
std::string builtin_func_name[BUILTIN_FUNC_NUM]=
|
||||
{
|
||||
"nasal_call_builtin_std_cout",
|
||||
"nasal_call_builtin_push_back",
|
||||
"nasal_call_builtin_set_size",
|
||||
"nasal_call_builtin_system",
|
||||
"nasal_call_builtin_input",
|
||||
"nasal_call_builtin_sleep"
|
||||
};
|
||||
|
||||
class nasal_runtime
|
||||
|
@ -77,6 +80,9 @@ private:
|
|||
int builtin_print(int);
|
||||
int builtin_append(int);
|
||||
int builtin_setsize(int);
|
||||
int builtin_system(int);
|
||||
int builtin_input(int);
|
||||
int builtin_sleep(int);
|
||||
public:
|
||||
nasal_runtime();
|
||||
~nasal_runtime();
|
||||
|
@ -364,7 +370,7 @@ int nasal_runtime::loop_progress(nasal_ast& node,int local_scope_addr,bool allow
|
|||
{
|
||||
// return expression will be checked in block_progress
|
||||
ret_state=block_progress(run_block_node,local_scope_addr,allow_return);
|
||||
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 || error)
|
||||
break;
|
||||
condition_value_addr=calculation(condition_node,while_local_scope_addr);
|
||||
result=check_condition(condition_value_addr);
|
||||
|
@ -436,7 +442,7 @@ int nasal_runtime::loop_progress(nasal_ast& node,int local_scope_addr,bool allow
|
|||
nasal_vm.mem_change(mem_addr,value_addr);
|
||||
}
|
||||
ret_state=block_progress(run_block_node,forei_local_scope_addr,allow_return);
|
||||
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 || error)
|
||||
break;
|
||||
}
|
||||
nasal_vm.del_reference(vector_value_addr);
|
||||
|
@ -473,7 +479,7 @@ int nasal_runtime::loop_progress(nasal_ast& node,int local_scope_addr,bool allow
|
|||
if(ret_state==rt_error)
|
||||
break;
|
||||
ret_state=block_progress(run_block_node,for_local_scope_addr,allow_return);
|
||||
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 || error)
|
||||
break;
|
||||
condition_value_addr=calculation(condition_node,for_local_scope_addr);
|
||||
result=check_condition(condition_value_addr);
|
||||
|
@ -838,6 +844,7 @@ int nasal_runtime::call_function(nasal_ast& node,std::string func_name,int base_
|
|||
if(value_type!=vm_function)
|
||||
{
|
||||
std::cout<<">> [runtime] call_function: incorrect value type,expected a function."<<std::endl;
|
||||
++error;
|
||||
return -1;
|
||||
}
|
||||
nasal_function& reference_of_func=nasal_vm.gc_get(base_value_addr).get_func();
|
||||
|
@ -1063,6 +1070,9 @@ int nasal_runtime::call_builtin_function(nasal_ast& node,int local_scope_addr)
|
|||
case 0:ret_value_addr=builtin_print(local_scope_addr);break;
|
||||
case 1:ret_value_addr=builtin_append(local_scope_addr);break;
|
||||
case 2:ret_value_addr=builtin_setsize(local_scope_addr);break;
|
||||
case 3:ret_value_addr=builtin_system(local_scope_addr);break;
|
||||
case 4:ret_value_addr=builtin_input(local_scope_addr);break;
|
||||
case 5:ret_value_addr=builtin_sleep(local_scope_addr);break;
|
||||
}
|
||||
return ret_value_addr;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue