This commit is contained in:
Valk Richard Li 2020-10-09 06:41:58 -07:00 committed by GitHub
parent afad8e799e
commit e223eff9b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 124 additions and 9 deletions

View File

@ -59,6 +59,23 @@ var size=func(object)
{
return nasal_call_builtin_size(object);
}
var contains=func(hash,key)
{
return nasal_call_builtin_contains(hash,key);
}
var delete=func(hash,key)
{
nasal_call_builtin_delete(hash,key);
return;
}
var keys=func(hash)
{
return nasal_call_builtin_get_keys(hash);
}
var time=func(begin_time)
{
return nasal_call_builtin_time(begin_time);
}
var io=
{
@ -130,8 +147,3 @@ var math=
return nasal_call_builtin_cpp_atan2(x,y);
},
};
var time=func(begin_time)
{
return nasal_call_builtin_time(begin_time);
}

View File

@ -2,6 +2,7 @@
#define __NASAL_BUILTIN_H__
#define in_builtin_find(value_name_string) (local_scope_addr>=0?nasal_vm.gc_get(local_scope_addr).get_closure().get_value_address(value_name_string):-1)
#define in_builtin_check(value_addr,value_type) (nasal_vm.gc_get(value_addr).get_type()==(value_type))
int nasal_runtime::builtin_print(int local_scope_addr)
{
@ -681,4 +682,62 @@ int nasal_runtime::builtin_time(int local_scope_addr)
nasal_vm.gc_get(ret_addr).set_number((double)time(&begin_time));
return ret_addr;
}
int nasal_runtime::builtin_contains(int local_scope_addr)
{
int hash_addr=in_builtin_find("hash");
int key_addr=in_builtin_find("key");
if(hash_addr<0 || !in_builtin_check(hash_addr,vm_hash))
{
std::cout<<">> [runtime] builtin_contains: cannot find value named \'hash\' or wrong type(must be hash)."<<std::endl;
++error;
return -1;
}
if(key_addr<0 || !in_builtin_check(key_addr,vm_string))
{
std::cout<<">> [runtime] builtin_contains: cannot find value named \'key\' or wrong type(must be string)."<<std::endl;
++error;
return -1;
}
std::string key=nasal_vm.gc_get(key_addr).get_string();
bool contains=nasal_vm.gc_get(hash_addr).get_hash().check_contain(key);
int ret_addr=nasal_vm.gc_alloc();
nasal_vm.gc_get(ret_addr).set_type(vm_number);
nasal_vm.gc_get(ret_addr).set_number((double)contains);
return ret_addr;
}
int nasal_runtime::builtin_delete(int local_scope_addr)
{
int hash_addr=in_builtin_find("hash");
int key_addr=in_builtin_find("key");
if(hash_addr<0 || !in_builtin_check(hash_addr,vm_hash))
{
std::cout<<">> [runtime] builtin_delete: cannot find value named \'hash\' or wrong type(must be hash)."<<std::endl;
++error;
return -1;
}
if(key_addr<0 || !in_builtin_check(key_addr,vm_string))
{
std::cout<<">> [runtime] builtin_delete: cannot find value named \'key\' or wrong type(must be string)."<<std::endl;
++error;
return -1;
}
std::string key=nasal_vm.gc_get(key_addr).get_string();
nasal_vm.gc_get(hash_addr).get_hash().del_elem(key);
int ret_addr=nasal_vm.gc_alloc();
nasal_vm.gc_get(ret_addr).set_type(vm_nil);
return ret_addr;
}
int nasal_runtime::builtin_getkeys(int local_scope_addr)
{
int hash_addr=in_builtin_find("hash");
if(hash_addr<0 || !in_builtin_check(hash_addr,vm_hash))
{
std::cout<<">> [runtime] builtin_delete: cannot find value named \'hash\' or wrong type(must be hash)."<<std::endl;
++error;
return -1;
}
int ret_addr=nasal_vm.gc_get(hash_addr).get_hash().get_keys();
return ret_addr;
}
#endif

View File

@ -40,6 +40,8 @@ public:
int size();
int get_value_address(std::string);
int get_mem_address(std::string);
bool check_contain(std::string);
int get_keys();
};
class nasal_function
@ -248,8 +250,6 @@ void nasal_hash::add_elem(std::string key,int value_address)
nasal_vm.mem_init(memory_address,value_address);
elems[key]=memory_address;
}
else
std::cout<<">> [vm] nasal_hash::add_elem: "<<key<<" already exists."<<std::endl;
return;
}
void nasal_hash::del_elem(std::string key)
@ -259,8 +259,6 @@ void nasal_hash::del_elem(std::string key)
nasal_vm.mem_free(elems[key]);
elems.erase(key);
}
else
std::cout<<">> [vm] nasal_hash::del_elem: "<<key<<" does not exist."<<std::endl;
return;
}
int nasal_hash::size()
@ -317,6 +315,46 @@ int nasal_hash::get_mem_address(std::string key)
}
return ret_mem_addr;
}
bool nasal_hash::check_contain(std::string key)
{
if(elems.find(key)!=elems.end())
return true;
if(elems.find("parents")!=elems.end())
{
bool result=false;
int mem_addr=elems["parents"];
int val_addr=nasal_vm.mem_get(mem_addr);
if(nasal_vm.gc_get(val_addr).get_type()==vm_vector)
{
nasal_vector& vec_ref=nasal_vm.gc_get(val_addr).get_vector();
int size=vec_ref.size();
for(int i=0;i<size;++i)
{
int tmp_val_addr=vec_ref.get_value_address(i);
if(nasal_vm.gc_get(tmp_val_addr).get_type()==vm_hash)
result=nasal_vm.gc_get(tmp_val_addr).get_hash().check_contain(key);
if(result)
break;
}
}
return result;
}
return false;
}
int nasal_hash::get_keys()
{
int ret_addr=nasal_vm.gc_alloc();
nasal_vm.gc_get(ret_addr).set_type(vm_vector);
nasal_vector& ref_vec=nasal_vm.gc_get(ret_addr).get_vector();
for(std::map<std::string,int>::iterator iter=elems.begin();iter!=elems.end();++iter)
{
int str_addr=nasal_vm.gc_alloc();
nasal_vm.gc_get(str_addr).set_type(vm_string);
nasal_vm.gc_get(str_addr).set_string(iter->first);
ref_vec.add_elem(str_addr);
}
return ret_addr;
}
/*functions of nasal_function*/
nasal_function::nasal_function()

View File

@ -96,6 +96,9 @@ private:
int builtin_sqrt(int);
int builtin_atan2(int);
int builtin_time(int);
int builtin_contains(int);
int builtin_delete(int);
int builtin_getkeys(int);
void load_builtin_function();
public:
nasal_runtime();
@ -157,6 +160,9 @@ void nasal_runtime::load_builtin_function()
{"nasal_call_builtin_cpp_math_sqrt", nasal_runtime::builtin_sqrt},
{"nasal_call_builtin_cpp_atan2", nasal_runtime::builtin_atan2},
{"nasal_call_builtin_time", nasal_runtime::builtin_time},
{"nasal_call_builtin_contains", nasal_runtime::builtin_contains},
{"nasal_call_builtin_delete", nasal_runtime::builtin_delete},
{"nasal_call_builtin_get_keys", nasal_runtime::builtin_getkeys},
{"", NULL}
};
for(int i=0;builtin_func_table[i].func_pointer;++i)