This commit is contained in:
Valk Richard Li 2020-09-13 00:27:27 -07:00 committed by GitHub
parent 4b7646223a
commit b674618823
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 145 additions and 14 deletions

View File

@ -1,6 +1,9 @@
#ifndef __NASAL_H__ #ifndef __NASAL_H__
#define __NASAL_H__ #define __NASAL_H__
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>

View File

@ -132,4 +132,70 @@ int nasal_runtime::builtin_setsize(int local_scope_addr)
return ret_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 #endif

View File

@ -129,12 +129,14 @@ class nasal_virtual_machine
} }
}; };
private: private:
bool error_info_output_switch;
nasal_scalar error_returned_value; nasal_scalar error_returned_value;
std::queue<int> garbage_collector_free_space; std::queue<int> garbage_collector_free_space;
std::vector<gc_unit*> garbage_collector_memory; std::vector<gc_unit*> garbage_collector_memory;
std::queue<int> memory_manager_free_space; std::queue<int> memory_manager_free_space;
std::vector<int*> memory_manager_memory; std::vector<int*> memory_manager_memory;
public: public:
nasal_virtual_machine();
~nasal_virtual_machine(); ~nasal_virtual_machine();
void clear(); void clear();
void debug(); 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)) 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 a_num;
double b_num; double b_num;
if(a_ref.type==vm_number) a_num=*(double*)a_ref.scalar_ptr; 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*/ /*functions of nasal_virtual_machine*/
nasal_virtual_machine::nasal_virtual_machine()
{
error_info_output_switch=true;
return;
}
nasal_virtual_machine::~nasal_virtual_machine() nasal_virtual_machine::~nasal_virtual_machine()
{ {
error_info_output_switch=false;
int gc_mem_size=garbage_collector_memory.size(); int gc_mem_size=garbage_collector_memory.size();
int mm_mem_size=memory_manager_memory.size(); int mm_mem_size=memory_manager_memory.size();
for(int i=0;i<gc_mem_size;++i) for(int i=0;i<gc_mem_size;++i)
{
for(int j=0;j<GC_BLK_SIZE;++j) for(int j=0;j<GC_BLK_SIZE;++j)
if(garbage_collector_memory[i][j].ref_cnt) 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(); garbage_collector_memory[i][j].elem.clear();
delete []garbage_collector_memory[i]; delete []garbage_collector_memory[i];
} }
for(int i=0;i<mm_mem_size;++i) for(int i=0;i<mm_mem_size;++i)
delete []memory_manager_memory[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(); garbage_collector_memory.clear();
memory_manager_memory.clear(); memory_manager_memory.clear();
error_info_output_switch=true;
return; return;
} }
void nasal_virtual_machine::debug() void nasal_virtual_machine::debug()
@ -1348,12 +1377,20 @@ void nasal_virtual_machine::debug()
} }
void nasal_virtual_machine::clear() void nasal_virtual_machine::clear()
{ {
error_info_output_switch=false;
int gc_mem_size=garbage_collector_memory.size(); int gc_mem_size=garbage_collector_memory.size();
int mm_mem_size=memory_manager_memory.size(); int mm_mem_size=memory_manager_memory.size();
for(int i=0;i<gc_mem_size;++i) for(int i=0;i<gc_mem_size;++i)
{
for(int j=0;j<GC_BLK_SIZE;++j) for(int j=0;j<GC_BLK_SIZE;++j)
if(garbage_collector_memory[i][j].ref_cnt) 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(); garbage_collector_memory[i][j].elem.clear();
delete []garbage_collector_memory[i]; delete []garbage_collector_memory[i];
} }
@ -1365,6 +1402,7 @@ void nasal_virtual_machine::clear()
memory_manager_free_space.pop(); memory_manager_free_space.pop();
garbage_collector_memory.clear(); garbage_collector_memory.clear();
memory_manager_memory.clear(); memory_manager_memory.clear();
error_info_output_switch=true;
return; return;
} }
int nasal_virtual_machine::gc_alloc() 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; return garbage_collector_memory[blk_num][blk_plc].elem;
else 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; 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) 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; ++garbage_collector_memory[blk_num][blk_plc].ref_cnt;
else 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; return;
} }
void nasal_virtual_machine::del_reference(int value_address) 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; --garbage_collector_memory[blk_num][blk_plc].ref_cnt;
else 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; return;
} }
if(!garbage_collector_memory[blk_num][blk_plc].ref_cnt) 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) 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; return garbage_collector_memory[blk_num][blk_plc].ref_cnt;
else 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; return -1;
} }
int nasal_virtual_machine::mem_alloc() int nasal_virtual_machine::mem_alloc()
@ -1459,7 +1505,8 @@ int nasal_virtual_machine::mem_free(int memory_address)
} }
else 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 0;
} }
return 1; return 1;
@ -1475,7 +1522,8 @@ int nasal_virtual_machine::mem_change(int memory_address,int value_address)
} }
else 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 0;
} }
return 1; 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; memory_manager_memory[memory_address>>8][memory_address&0xff]=value_address;
else 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 0;
} }
return 1; 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)) if(0<=memory_address && memory_address<(memory_manager_memory.size()<<8))
ret=memory_manager_memory[memory_address>>8][memory_address&0xff]; ret=memory_manager_memory[memory_address>>8][memory_address&0xff];
else 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; return ret;
} }
#endif #endif

View File

@ -10,12 +10,15 @@ enum runtime_returned_state
rt_exit_without_error rt_exit_without_error
}; };
#define BUILTIN_FUNC_NUM 3 #define BUILTIN_FUNC_NUM 6
std::string builtin_func_name[BUILTIN_FUNC_NUM]= std::string builtin_func_name[BUILTIN_FUNC_NUM]=
{ {
"nasal_call_builtin_std_cout", "nasal_call_builtin_std_cout",
"nasal_call_builtin_push_back", "nasal_call_builtin_push_back",
"nasal_call_builtin_set_size", "nasal_call_builtin_set_size",
"nasal_call_builtin_system",
"nasal_call_builtin_input",
"nasal_call_builtin_sleep"
}; };
class nasal_runtime class nasal_runtime
@ -77,6 +80,9 @@ private:
int builtin_print(int); int builtin_print(int);
int builtin_append(int); int builtin_append(int);
int builtin_setsize(int); int builtin_setsize(int);
int builtin_system(int);
int builtin_input(int);
int builtin_sleep(int);
public: public:
nasal_runtime(); nasal_runtime();
~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 // return expression will be checked in block_progress
ret_state=block_progress(run_block_node,local_scope_addr,allow_return); 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; break;
condition_value_addr=calculation(condition_node,while_local_scope_addr); condition_value_addr=calculation(condition_node,while_local_scope_addr);
result=check_condition(condition_value_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); nasal_vm.mem_change(mem_addr,value_addr);
} }
ret_state=block_progress(run_block_node,forei_local_scope_addr,allow_return); 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; break;
} }
nasal_vm.del_reference(vector_value_addr); 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) if(ret_state==rt_error)
break; break;
ret_state=block_progress(run_block_node,for_local_scope_addr,allow_return); 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; break;
condition_value_addr=calculation(condition_node,for_local_scope_addr); condition_value_addr=calculation(condition_node,for_local_scope_addr);
result=check_condition(condition_value_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) if(value_type!=vm_function)
{ {
std::cout<<">> [runtime] call_function: incorrect value type,expected a function."<<std::endl; std::cout<<">> [runtime] call_function: incorrect value type,expected a function."<<std::endl;
++error;
return -1; return -1;
} }
nasal_function& reference_of_func=nasal_vm.gc_get(base_value_addr).get_func(); 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 0:ret_value_addr=builtin_print(local_scope_addr);break;
case 1:ret_value_addr=builtin_append(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 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; return ret_value_addr;
} }