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__
#define __NASAL_H__
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <fstream>

View File

@ -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

View File

@ -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

View File

@ -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;
}