This commit is contained in:
Valk Richard Li 2020-07-30 02:49:27 -07:00 committed by GitHub
parent 1c6d8f8998
commit a01e81e9a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 154 additions and 5 deletions

View File

@ -56,6 +56,8 @@ public:
~nasal_scalar(); ~nasal_scalar();
void clear(); void clear();
bool set_type(int); bool set_type(int);
void set_number(double);
void set_string(std::string);
int nasal_scalar_add(int,int); int nasal_scalar_add(int,int);
int nasal_scalar_sub(int,int); int nasal_scalar_sub(int,int);
int nasal_scalar_mult(int,int); int nasal_scalar_mult(int,int);
@ -86,18 +88,22 @@ class nasal_virtual_machine
} }
}; };
private: private:
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();
int gc_alloc(); int gc_alloc(); // garbage collector gives a new space
nasal_scalar& gc_get(int); // get scalar that stored in gc
int add_reference(int); int add_reference(int);
int del_reference(int); int del_reference(int);
int mem_alloc(); int mem_alloc(); // memory gives a new space
int mem_free(int); int mem_free(int); // give space back to memory
int mem_store(int,int); int mem_change(int,int); // change value in memory space
int mem_store(int,int); // init value in memory space
int mem_get(int); // get value in memory space
}; };
/* /*
@ -239,7 +245,7 @@ bool nasal_scalar::set_type(int nasal_scalar_type)
case vm_function: this->scalar_ptr=(void*)(new nasal_function); break; case vm_function: this->scalar_ptr=(void*)(new nasal_function); break;
case vm_closure: this->scalar_ptr=(void*)(new nasal_closure); break; case vm_closure: this->scalar_ptr=(void*)(new nasal_closure); break;
default: default:
std::cout<<">> [scalar] error scalar type: "<<nasal_scalar_type<<std::endl; std::cout<<">> [vm] error scalar type: "<<nasal_scalar_type<<std::endl;
this->type=vm_nil; this->type=vm_nil;
this->scalar_ptr=(void*)NULL; this->scalar_ptr=(void*)NULL;
ret=false; ret=false;
@ -247,6 +253,110 @@ bool nasal_scalar::set_type(int nasal_scalar_type)
} }
return ret; return ret;
} }
void nasal_scalar::set_number(double num)
{
*(double*)(this->scalar_ptr)=num;
return;
}
void nasal_scalar::set_string(std::string str)
{
*(std::string*)(this->scalar_ptr)=str;
return;
}
int nasal_scalar::nasal_scalar_add(int a,int b)
{
int a_scalar_addr=nasal_vm.mem_get(a);
int b_scalar_addr=nasal_vm.mem_get(b);
if(a_scalar_addr<0 || b_scalar_addr<0)
{
std::cout<<">> [vm] scalar_add: memory returned an invalid address"<<std::endl;
return -1;
}
nasal_scalar& a_ref=nasal_vm.gc_get(a);
nasal_scalar& b_ref=nasal_vm.gc_get(b);
if((a_ref.type!=vm_number && a_ref.type!=vm_string)||(b_ref.type!=vm_number && b_ref.type!=vm_string))
{
std::cout<<">> [vm] scalar_add: error value type.only number and string can take part in add."<<std::endl;
return -1;
}
double a_num;
double b_num;
if(a_ref.type==vm_number) a_num=*(double*)a_ref.scalar_ptr;
else
{
if(check_numerable_string(*(std::string*)a_ref.scalar_ptr))
a_num=trans_string_to_number(*(std::string*)a_ref.scalar_ptr);
else
{
std::cout<<">> [vm] scalar_add: "<<*(std::string*)a_ref.scalar_ptr<<" is not a numerable string."<<std::endl;
return -1;
}
}
if(b_ref.type==vm_number) b_num=*(double*)b_ref.scalar_ptr;
else
{
if(check_numerable_string(*(std::string*)b_ref.scalar_ptr))
b_num=trans_string_to_number(*(std::string*)b_ref.scalar_ptr);
else
{
std::cout<<">> [vm] scalar_add: "<<*(std::string*)b_ref.scalar_ptr<<" is not a numerable string."<<std::endl;
return -1;
}
}
double result=a_num+b_num;
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(result);
return new_value_address;
}
int nasal_scalar::nasal_scalar_sub(int a,int b)
{
return -1;
}
int nasal_scalar::nasal_scalar_mult(int a,int b)
{
return -1;
}
int nasal_scalar::nasal_scalar_div(int a,int b)
{
return -1;
}
int nasal_scalar::nasal_scalar_link(int a,int b)
{
return -1;
}
int nasal_scalar::nasal_scalar_unary_sub(int a)
{
return -1;
}
int nasal_scalar::nasal_scalar_unary_not(int a)
{
return -1;
}
int nasal_scalar::nasal_scalar_cmp_equal(int a,int b)
{
return -1;
}
int nasal_scalar::nasal_scalar_cmp_not_equal(int a,int b)
{
return -1;
}
int nasal_scalar::nasal_scalar_cmp_less(int a,int b)
{
return -1;
}
int nasal_scalar::nasal_scalar_cmp_greater(int a,int b)
{
return -1;
}
int nasal_scalar::nasal_scalar_cmp_less_or_equal(int a,int b)
{
return -1;
}
int nasal_scalar::nasal_scalar_cmp_greater_or_equal(int a,int b)
{
return -1;
}
/*functions of nasal_virtual_machine*/ /*functions of nasal_virtual_machine*/
nasal_virtual_machine::~nasal_virtual_machine() nasal_virtual_machine::~nasal_virtual_machine()
@ -277,6 +387,18 @@ int nasal_virtual_machine::gc_alloc()
garbage_collector_free_space.pop(); garbage_collector_free_space.pop();
return ret; return ret;
} }
nasal_scalar& nasal_virtual_machine::gc_get(int memory_address)
{
int blk_num=(memory_address>>8);
int blk_plc=(memory_address&0xff);
if(0<=memory_address && memory_address<(garbage_collector_memory.size()<<8) && !garbage_collector_memory[blk_num][blk_plc].collected)
return garbage_collector_memory[blk_num][blk_plc].elem;
else
{
std::cout<<">> [vm] gc_get:unexpected memory \'"<<memory_address<<"\'."<<std::endl;
return error_returned_value;
}
}
int nasal_virtual_machine::add_reference(int memory_address) int nasal_virtual_machine::add_reference(int memory_address)
{ {
int blk_num=(memory_address>>8); int blk_num=(memory_address>>8);
@ -339,8 +461,25 @@ int nasal_virtual_machine::mem_free(int memory_address)
} }
return 1; return 1;
} }
int nasal_virtual_machine::mem_change(int memory_address,int value_space)
{
// this progress is used to change a memory space's value address
// be careful! this process doesn't check if this mem_space is in use.
if(0<=memory_address && memory_address<(memory_manager_memory.size()<<8))
{
this->del_reference(memory_manager_memory[memory_address>>8][memory_address&0xff]);
memory_manager_memory[memory_address>>8][memory_address&0xff]=value_space;
}
else
{
std::cout<<">> [vm] mem_store:unexpected memory \'"<<memory_address<<"\'."<<std::endl;
return 0;
}
return 1;
}
int nasal_virtual_machine::mem_store(int memory_address,int value_space) int nasal_virtual_machine::mem_store(int memory_address,int value_space)
{ {
// this progress is used to init a memory space
// be careful! this process doesn't check if this mem_space is in use. // be careful! this process doesn't check if this mem_space is in use.
if(0<=memory_address && memory_address<(memory_manager_memory.size()<<8)) if(0<=memory_address && memory_address<(memory_manager_memory.size()<<8))
memory_manager_memory[memory_address>>8][memory_address&0xff]=value_space; memory_manager_memory[memory_address>>8][memory_address&0xff]=value_space;
@ -351,4 +490,14 @@ int nasal_virtual_machine::mem_store(int memory_address,int value_space)
} }
return 1; return 1;
} }
int nasal_virtual_machine::mem_get(int memory_address)
{
int ret=-1;
// be careful! this process doesn't check if this mem_space is in use.
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;
return ret;
}
#endif #endif