This commit is contained in:
Valk Richard Li 2020-09-15 03:45:48 -07:00 committed by GitHub
parent 94f23bb30b
commit cf0718387b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 253 additions and 33 deletions

View File

@ -27,6 +27,32 @@ var sleep=func(duration)
nasal_call_builtin_sleep(duration);
return;
}
var split=func(delimeter,string)
{
return nasal_call_builtin_split(delimeter,string);
}
var rand=func(seed=nil)
{
return nasal_call_builtin_rand(seed);
}
var id=func(thing)
{
return nasal_call_builtin_get_id(thing);
}
var int=func(value)
{
return nasal_call_builtin_trans_int(value);
}
var num=func(value)
{
return nasal_call_builtin_trans_num(value);
}
var pop=func(vector)
{
return nasal_call_builtin_pop_back(vector);
}
var io=
{
fin:func(filename)

View File

@ -1,8 +1,7 @@
#ifndef __NASAL_H__
#define __NASAL_H__
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>

View File

@ -119,7 +119,11 @@ int nasal_runtime::builtin_setsize(int local_scope_addr)
int vec_size=ref_vector.size();
if(number<vec_size)
for(int i=number;i<vec_size;++i)
ref_vector.del_elem(number);
{
int addr=ref_vector.del_elem();
if(addr>=0)
nasal_vm.del_reference(addr);
}
else if(number>vec_size)
for(int i=vec_size;i<number;++i)
{
@ -192,7 +196,7 @@ int nasal_runtime::builtin_sleep(int local_scope_addr)
}
else
sleep_time=(unsigned long)nasal_vm.gc_get(value_addr).get_number();
_sleep(sleep_time);
sleep(sleep_time); // sleep in unistd.h will make this progress sleep sleep_time seconds.
int ret_addr=nasal_vm.gc_alloc();
nasal_vm.gc_get(ret_addr).set_type(vm_nil);
return ret_addr;
@ -258,4 +262,171 @@ int nasal_runtime::builtin_foutput(int local_scope_addr)
return ret_addr;
}
int nasal_runtime::builtin_split(int local_scope_addr)
{
int delimeter_value_addr=-1;
if(local_scope_addr>=0)
delimeter_value_addr=nasal_vm.gc_get(local_scope_addr).get_closure().get_value_address("delimeter");
if(delimeter_value_addr<0 || nasal_vm.gc_get(delimeter_value_addr).get_type()!=vm_string)
{
std::cout<<">> [runtime] builtin_split: cannot find values or wrong value type(must be string)."<<std::endl;
++error;
return -1;
}
int string_value_addr=-1;
if(local_scope_addr>=0)
string_value_addr=nasal_vm.gc_get(local_scope_addr).get_closure().get_value_address("string");
if(string_value_addr<0 || nasal_vm.gc_get(string_value_addr).get_type()!=vm_string)
{
std::cout<<">> [runtime] builtin_split: cannot find values or wrong value type(must be string)."<<std::endl;
++error;
return -1;
}
std::string delimeter=nasal_vm.gc_get(delimeter_value_addr).get_string();
std::string source=nasal_vm.gc_get(string_value_addr).get_string();
int delimeter_len=delimeter.length();
if(delimeter_len<1)
{
std::cout<<">> [runtime] builtin_split: delimeter's length must be greater than 0."<<std::endl;
++error;
return -1;
}
int source_len=source.length();
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();
std::string tmp="";
for(int i=0;i<source_len;++i)
{
bool check_delimeter=false;
if(source[i]==delimeter[0])
for(int j=0;j<delimeter_len;++j)
{
if(i+j>=source_len || source[i+j]!=delimeter[j])
break;
if(j==delimeter_len-1)
check_delimeter=true;
}
if(check_delimeter)
{
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(tmp);
ref_vec.add_elem(str_addr);
tmp="";
i+=delimeter_len-1;
}
else
tmp+=source[i];
}
if(tmp.length())
{
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(tmp);
ref_vec.add_elem(str_addr);
tmp="";
}
return ret_addr;
}
int nasal_runtime::builtin_rand(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("seed");
if(value_addr<0 || (nasal_vm.gc_get(value_addr).get_type()!=vm_number && nasal_vm.gc_get(value_addr).get_type()!=vm_nil))
{
std::cout<<">> [runtime] builtin_rand: cannot find values or wrong value type(must be nil or number)."<<std::endl;
++error;
return -1;
}
if(nasal_vm.gc_get(value_addr).get_type()==vm_number)
{
unsigned int number=(unsigned int)nasal_vm.gc_get(value_addr).get_number();
srand(number);
int ret_addr=nasal_vm.gc_alloc();
nasal_vm.gc_get(ret_addr).set_type(vm_nil);
return ret_addr;
}
double num=0;
for(int i=0;i<5;++i)
num=(num+rand())*(1.0/(RAND_MAX+1.0));
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(num);
return ret_addr;
}
int nasal_runtime::builtin_id(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("id");
if(value_addr<0)
{
std::cout<<">> [runtime] builtin_id: cannot find this value."<<std::endl;
++error;
return -1;
}
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)value_addr);
return ret_addr;
}
int nasal_runtime::builtin_int(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("value");
if(value_addr<0 || nasal_vm.gc_get(value_addr).get_type()!=vm_number)
{
std::cout<<">> [runtime] builtin_int: cannot find this value or wrong value type(must be number)."<<std::endl;
++error;
return -1;
}
int number=(int)nasal_vm.gc_get(value_addr).get_number();
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)number);
return ret_addr;
}
int nasal_runtime::builtin_num(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("value");
if(value_addr<0 || nasal_vm.gc_get(value_addr).get_type()!=vm_string)
{
std::cout<<">> [runtime] builtin_num: cannot find this value or wrong value type(must be string)."<<std::endl;
++error;
return -1;
}
std::string str=nasal_vm.gc_get(value_addr).get_string();
if(!check_numerable_string(str))
{
std::cout<<">> [runtime] builtin_num: this is not a numerable string."<<std::endl;
++error;
return -1;
}
double number=trans_string_to_number(str);
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(number);
return ret_addr;
}
int nasal_runtime::builtin_pop(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("vector");
if(value_addr<0 || nasal_vm.gc_get(value_addr).get_type()!=vm_vector)
{
std::cout<<">> [runtime] builtin_pop: cannot find this value or wrong value type(must be vector)."<<std::endl;
++error;
return -1;
}
int ret_addr=nasal_vm.gc_get(value_addr).get_vector().del_elem();
return -1;
}
#endif

View File

@ -21,7 +21,7 @@ public:
nasal_vector();
~nasal_vector();
void add_elem(int);
int del_elem(int);
int del_elem();
int size();
int get_value_address(int);
int get_mem_address(int);
@ -186,14 +186,14 @@ void nasal_vector::add_elem(int value_address)
elems.push_back(memory_address);
return;
}
int nasal_vector::del_elem(int index)
int nasal_vector::del_elem()
{
if(index>=elems.size())
// pop back
if(!elems.size())
return -1;
int ret=elems[index];
nasal_vm.mem_free(ret);
for(int i=index;i<elems.size()-1;++i)
elems[i]=elems[i+1];
int ret=nasal_vm.mem_get(elems.back());
nasal_vm.add_reference(ret);
nasal_vm.mem_free(elems.back());
elems.pop_back();
return ret;
}

View File

@ -10,7 +10,7 @@ enum runtime_returned_state
rt_exit_without_error
};
#define BUILTIN_FUNC_NUM 8
#define BUILTIN_FUNC_NUM 14
std::string builtin_func_name[BUILTIN_FUNC_NUM]=
{
"nasal_call_builtin_std_cout",
@ -20,7 +20,13 @@ std::string builtin_func_name[BUILTIN_FUNC_NUM]=
"nasal_call_builtin_input",
"nasal_call_builtin_sleep",
"nasal_call_builtin_finput",
"nasal_call_builtin_foutput"
"nasal_call_builtin_foutput",
"nasal_call_builtin_split",
"nasal_call_builtin_rand",
"nasal_call_builtin_get_id",
"nasal_call_builtin_trans_int",
"nasal_call_builtin_trans_num",
"nasal_call_builtin_pop_back"
};
class nasal_runtime
@ -87,6 +93,12 @@ private:
int builtin_sleep(int);
int builtin_finput(int);
int builtin_foutput(int);
int builtin_split(int);
int builtin_rand(int);
int builtin_id(int);
int builtin_int(int);
int builtin_num(int);
int builtin_pop(int);
public:
nasal_runtime();
~nasal_runtime();
@ -558,24 +570,30 @@ int nasal_runtime::conditional_progress(nasal_ast& node,int local_scope_addr,boo
int nasal_runtime::call_scalar(nasal_ast& node,int local_scope_addr)
{
int value_address=-1;
std::string val_name=node.get_children()[0].get_str();
if(local_scope_addr>=0)
value_address=nasal_vm.gc_get(local_scope_addr).get_closure().get_value_address(val_name);
if(value_address<0)
value_address=nasal_vm.gc_get(global_scope_address).get_closure().get_value_address(val_name);
if(value_address<0)
std::string val_name="";
if(node.get_children()[0].get_type()==ast_identifier)
{
value_address=call_builtin_function(node.get_children()[0],local_scope_addr);
if(value_address>=0)
return value_address;
val_name=node.get_children()[0].get_str();
if(local_scope_addr>=0)
value_address=nasal_vm.gc_get(local_scope_addr).get_closure().get_value_address(val_name);
if(value_address<0)
value_address=nasal_vm.gc_get(global_scope_address).get_closure().get_value_address(val_name);
if(value_address<0)
{
value_address=call_builtin_function(node.get_children()[0],local_scope_addr);
if(value_address>=0)
return value_address;
}
if(value_address<0)
{
std::cout<<">> [runtime] call_nasal_scalar: cannot find value named \'"<<val_name<<"\'."<<std::endl;
++error;
return -1;
}
nasal_vm.add_reference(value_address);
}
if(value_address<0)
{
std::cout<<">> [runtime] call_nasal_scalar: cannot find value named \'"<<val_name<<"\'."<<std::endl;
++error;
return -1;
}
nasal_vm.add_reference(value_address);
else
value_address=calculation(node.get_children()[0],local_scope_addr);
int call_expr_size=node.get_children().size();
int last_call_hash_addr=-1;
for(int i=1;i<call_expr_size;++i)
@ -1059,17 +1077,17 @@ int nasal_runtime::call_function(nasal_ast& node,std::string func_name,int base_
int nasal_runtime::call_builtin_function(nasal_ast& node,int local_scope_addr)
{
int ret_value_addr=-1;
int builtin_num=-1;
int builtin_func_num=-1;
std::string builtin_name=node.get_str();
for(int i=0;i<BUILTIN_FUNC_NUM;++i)
if(builtin_name==builtin_func_name[i])
{
builtin_num=i;
builtin_func_num=i;
break;
}
if(builtin_num<0)
if(builtin_func_num<0)
return -1;
switch(builtin_num)
switch(builtin_func_num)
{
case 0:ret_value_addr=builtin_print(local_scope_addr);break;
case 1:ret_value_addr=builtin_append(local_scope_addr);break;
@ -1079,6 +1097,12 @@ int nasal_runtime::call_builtin_function(nasal_ast& node,int local_scope_addr)
case 5:ret_value_addr=builtin_sleep(local_scope_addr);break;
case 6:ret_value_addr=builtin_finput(local_scope_addr);break;
case 7:ret_value_addr=builtin_foutput(local_scope_addr);break;
case 8:ret_value_addr=builtin_split(local_scope_addr);break;
case 9:ret_value_addr=builtin_rand(local_scope_addr);break;
case 10:ret_value_addr=builtin_id(local_scope_addr);break;
case 11:ret_value_addr=builtin_int(local_scope_addr);break;
case 12:ret_value_addr=builtin_num(local_scope_addr);break;
case 13:ret_value_addr=builtin_pop(local_scope_addr);break;
}
return ret_value_addr;
}