update
This commit is contained in:
parent
94f23bb30b
commit
cf0718387b
|
@ -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)
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
#ifndef __NASAL_H__
|
||||
#define __NASAL_H__
|
||||
|
||||
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue