now local values are stored on stack. upvalue is generated when creating a new function in local scope.
may include some bugs inside. but all test files has passed the test so i decide to push it.
This commit is contained in:
parent
980350d70a
commit
e7f503fae1
|
@ -1035,13 +1035,13 @@ If you really want to change source code, check built-in functions in lib.nas an
|
||||||
Definition:
|
Definition:
|
||||||
|
|
||||||
```C++
|
```C++
|
||||||
nasal_ref builtin_print(std::vector<nasal_ref>&,nasal_gc&);
|
nasal_ref builtin_print(nasal_ref*,nasal_gc&);
|
||||||
```
|
```
|
||||||
|
|
||||||
Then complete this function using C++:
|
Then complete this function using C++:
|
||||||
|
|
||||||
```C++
|
```C++
|
||||||
nasal_ref builtin_print(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_print(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
// find value with index begin from 1
|
// find value with index begin from 1
|
||||||
// because local_scope[0] is reserved for value 'me'
|
// because local_scope[0] is reserved for value 'me'
|
||||||
|
@ -1074,7 +1074,7 @@ After that, register the built-in function's name(in nasal) and the function's p
|
||||||
struct func
|
struct func
|
||||||
{
|
{
|
||||||
const char* name;
|
const char* name;
|
||||||
nasal_ref (*func)(std::vector<nasal_ref>&,nasal_gc&);
|
nasal_ref (*func)(nasal_ref*,nasal_gc&);
|
||||||
} builtin_func[]=
|
} builtin_func[]=
|
||||||
{
|
{
|
||||||
{"__builtin_print",builtin_print},
|
{"__builtin_print",builtin_print},
|
||||||
|
@ -1119,7 +1119,7 @@ this is a fatal error.
|
||||||
So use `builtin_alloc` in builtin functions like this:
|
So use `builtin_alloc` in builtin functions like this:
|
||||||
|
|
||||||
```C++
|
```C++
|
||||||
nasal_ref builtin_keys(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_keys(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref hash=local[1];
|
nasal_ref hash=local[1];
|
||||||
if(hash.type!=vm_hash)
|
if(hash.type!=vm_hash)
|
||||||
|
|
2
main.cpp
2
main.cpp
|
@ -48,7 +48,7 @@ void logo()
|
||||||
<<" / \\/ / _` / __|/ _` | | \n"
|
<<" / \\/ / _` / __|/ _` | | \n"
|
||||||
<<" / /\\ / (_| \\__ \\ (_| | | \n"
|
<<" / /\\ / (_| \\__ \\ (_| | | \n"
|
||||||
<<" \\_\\ \\/ \\__,_|___/\\__,_|_|\n"
|
<<" \\_\\ \\/ \\__,_|___/\\__,_|_|\n"
|
||||||
<<"nasal interpreter ver 8.0\n"
|
<<"nasal interpreter ver 9.0\n"
|
||||||
<<"thanks to : https://github.com/andyross/nasal\n"
|
<<"thanks to : https://github.com/andyross/nasal\n"
|
||||||
<<"code repo : https://github.com/ValKmjolnir/Nasal-Interpreter\n"
|
<<"code repo : https://github.com/ValKmjolnir/Nasal-Interpreter\n"
|
||||||
<<"code repo : https://gitee.com/valkmjolnir/Nasal-Interpreter\n"
|
<<"code repo : https://gitee.com/valkmjolnir/Nasal-Interpreter\n"
|
||||||
|
|
161
nasal_builtin.h
161
nasal_builtin.h
|
@ -16,7 +16,7 @@ enum obj_type
|
||||||
};
|
};
|
||||||
// declaration of builtin functions
|
// declaration of builtin functions
|
||||||
// to add new builtin function, declare it here and write the definition below
|
// to add new builtin function, declare it here and write the definition below
|
||||||
#define nas_native(name) nasal_ref name(std::vector<nasal_ref>&,nasal_gc&)
|
#define nas_native(name) nasal_ref name(nasal_ref*,nasal_gc&)
|
||||||
nas_native(builtin_print);
|
nas_native(builtin_print);
|
||||||
nas_native(builtin_append);
|
nas_native(builtin_append);
|
||||||
nas_native(builtin_setsize);
|
nas_native(builtin_setsize);
|
||||||
|
@ -97,7 +97,7 @@ nasal_ref builtin_err(const char* func_name,std::string info)
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
const char* name;
|
const char* name;
|
||||||
nasal_ref (*func)(std::vector<nasal_ref>&,nasal_gc&);
|
nasal_ref (*func)(nasal_ref*,nasal_gc&);
|
||||||
} builtin[]=
|
} builtin[]=
|
||||||
{
|
{
|
||||||
{"__builtin_print", builtin_print },
|
{"__builtin_print", builtin_print },
|
||||||
|
@ -171,7 +171,7 @@ struct
|
||||||
{nullptr, nullptr }
|
{nullptr, nullptr }
|
||||||
};
|
};
|
||||||
|
|
||||||
nasal_ref builtin_print(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_print(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
// get arguments
|
// get arguments
|
||||||
// local[0] is reserved for 'me'
|
// local[0] is reserved for 'me'
|
||||||
|
@ -193,7 +193,7 @@ nasal_ref builtin_print(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
// generate return value
|
// generate return value
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_append(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_append(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref vec=local[1];
|
nasal_ref vec=local[1];
|
||||||
nasal_ref elem=local[2];
|
nasal_ref elem=local[2];
|
||||||
|
@ -204,7 +204,7 @@ nasal_ref builtin_append(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
ref_vec.push_back(i);
|
ref_vec.push_back(i);
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_setsize(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_setsize(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref vec=local[1];
|
nasal_ref vec=local[1];
|
||||||
nasal_ref size=local[2];
|
nasal_ref size=local[2];
|
||||||
|
@ -218,20 +218,20 @@ nasal_ref builtin_setsize(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
vec.vec()->elems.resize(num,nil);
|
vec.vec()->elems.resize(num,nil);
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_system(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_system(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref str=local[1];
|
nasal_ref str=local[1];
|
||||||
if(str.type!=vm_str)
|
if(str.type!=vm_str)
|
||||||
return builtin_err("system","\"str\" must be string");
|
return builtin_err("system","\"str\" must be string");
|
||||||
return {vm_num,(double)system(str.str()->c_str())};
|
return {vm_num,(double)system(str.str()->c_str())};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_input(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_input(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref ret=gc.alloc(vm_str);
|
nasal_ref ret=gc.alloc(vm_str);
|
||||||
std::cin>>*ret.str();
|
std::cin>>*ret.str();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_fin(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_fin(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref val=local[1];
|
nasal_ref val=local[1];
|
||||||
if(val.type!=vm_str)
|
if(val.type!=vm_str)
|
||||||
|
@ -248,7 +248,7 @@ nasal_ref builtin_fin(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
}
|
}
|
||||||
return builtin_err("io.fin","cannot open \""+filename+"\"");
|
return builtin_err("io.fin","cannot open \""+filename+"\"");
|
||||||
}
|
}
|
||||||
nasal_ref builtin_fout(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_fout(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref val=local[1];
|
nasal_ref val=local[1];
|
||||||
nasal_ref str=local[2];
|
nasal_ref str=local[2];
|
||||||
|
@ -262,7 +262,7 @@ nasal_ref builtin_fout(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
fout<<*str.str();
|
fout<<*str.str();
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_split(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_split(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref deli_val=local[1];
|
nasal_ref deli_val=local[1];
|
||||||
nasal_ref str_val=local[2];
|
nasal_ref str_val=local[2];
|
||||||
|
@ -276,9 +276,11 @@ nasal_ref builtin_split(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
size_t source_len=source.length();
|
size_t source_len=source.length();
|
||||||
|
|
||||||
// push it to local scope to avoid being sweeped
|
// push it to local scope to avoid being sweeped
|
||||||
local.push_back(gc.alloc(vm_vec));
|
if(gc.top+1>=gc.stack+STACK_MAX_DEPTH-1)
|
||||||
|
builtin_err("split","expand temporary space error:stackoverflow");
|
||||||
|
(++gc.top)[0]=gc.alloc(vm_vec);
|
||||||
|
|
||||||
std::vector<nasal_ref>& vec=local.back().vec()->elems;
|
std::vector<nasal_ref>& vec=gc.top[0].vec()->elems;
|
||||||
if(!delimeter_len)
|
if(!delimeter_len)
|
||||||
{
|
{
|
||||||
for(int i=0;i<source_len;++i)
|
for(int i=0;i<source_len;++i)
|
||||||
|
@ -286,7 +288,8 @@ nasal_ref builtin_split(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
vec.push_back(gc.alloc(vm_str));
|
vec.push_back(gc.alloc(vm_str));
|
||||||
*vec.back().str()=source[i];
|
*vec.back().str()=source[i];
|
||||||
}
|
}
|
||||||
return local.back();
|
--gc.top;
|
||||||
|
return gc.top[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string tmp="";
|
std::string tmp="";
|
||||||
|
@ -320,9 +323,10 @@ nasal_ref builtin_split(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
*vec.back().str()=tmp;
|
*vec.back().str()=tmp;
|
||||||
tmp="";
|
tmp="";
|
||||||
}
|
}
|
||||||
return local.back();
|
--gc.top;
|
||||||
|
return gc.top[1];
|
||||||
}
|
}
|
||||||
nasal_ref builtin_rand(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_rand(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref val=local[1];
|
nasal_ref val=local[1];
|
||||||
if(val.type!=vm_num && val.type!=vm_nil)
|
if(val.type!=vm_num && val.type!=vm_nil)
|
||||||
|
@ -337,7 +341,7 @@ nasal_ref builtin_rand(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
num=(num+rand())*(1.0/(RAND_MAX+1.0));
|
num=(num+rand())*(1.0/(RAND_MAX+1.0));
|
||||||
return {vm_num,num};
|
return {vm_num,num};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_id(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_id(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref val=local[1];
|
nasal_ref val=local[1];
|
||||||
nasal_ref ret=gc.alloc(vm_str);
|
nasal_ref ret=gc.alloc(vm_str);
|
||||||
|
@ -349,7 +353,7 @@ nasal_ref builtin_id(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
*ret.str()=buf;
|
*ret.str()=buf;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_int(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_int(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref val=local[1];
|
nasal_ref val=local[1];
|
||||||
if(val.type!=vm_num)
|
if(val.type!=vm_num)
|
||||||
|
@ -357,7 +361,7 @@ nasal_ref builtin_int(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
int number=(int)val.num();
|
int number=(int)val.num();
|
||||||
return {vm_num,(double)number};
|
return {vm_num,(double)number};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_num(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_num(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref val=local[1];
|
nasal_ref val=local[1];
|
||||||
if(val.type==vm_num)
|
if(val.type==vm_num)
|
||||||
|
@ -369,7 +373,7 @@ nasal_ref builtin_num(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
return nil;
|
return nil;
|
||||||
return {vm_num,res};
|
return {vm_num,res};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_pop(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_pop(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref val=local[1];
|
nasal_ref val=local[1];
|
||||||
if(val.type!=vm_vec)
|
if(val.type!=vm_vec)
|
||||||
|
@ -382,7 +386,7 @@ nasal_ref builtin_pop(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
}
|
}
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_str(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_str(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref val=local[1];
|
nasal_ref val=local[1];
|
||||||
if(val.type!=vm_num)
|
if(val.type!=vm_num)
|
||||||
|
@ -391,7 +395,7 @@ nasal_ref builtin_str(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
*ret.str()=std::to_string(val.num());
|
*ret.str()=std::to_string(val.num());
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_size(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_size(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref val=local[1];
|
nasal_ref val=local[1];
|
||||||
double num;
|
double num;
|
||||||
|
@ -404,7 +408,7 @@ nasal_ref builtin_size(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
}
|
}
|
||||||
return {vm_num,num};
|
return {vm_num,num};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_xor(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_xor(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref a=local[1];
|
nasal_ref a=local[1];
|
||||||
nasal_ref b=local[2];
|
nasal_ref b=local[2];
|
||||||
|
@ -416,7 +420,7 @@ nasal_ref builtin_xor(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
int number_b=(int)b.num();
|
int number_b=(int)b.num();
|
||||||
return {vm_num,(double)(number_a^number_b)};
|
return {vm_num,(double)(number_a^number_b)};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_and(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_and(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref a=local[1];
|
nasal_ref a=local[1];
|
||||||
nasal_ref b=local[2];
|
nasal_ref b=local[2];
|
||||||
|
@ -428,7 +432,7 @@ nasal_ref builtin_and(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
int number_b=(int)b.num();
|
int number_b=(int)b.num();
|
||||||
return {vm_num,(double)(number_a&number_b)};
|
return {vm_num,(double)(number_a&number_b)};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_or(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_or(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref a=local[1];
|
nasal_ref a=local[1];
|
||||||
nasal_ref b=local[2];
|
nasal_ref b=local[2];
|
||||||
|
@ -440,7 +444,7 @@ nasal_ref builtin_or(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
int number_b=(int)b.num();
|
int number_b=(int)b.num();
|
||||||
return {vm_num,(double)(number_a|number_b)};
|
return {vm_num,(double)(number_a|number_b)};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_nand(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_nand(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref a=local[1];
|
nasal_ref a=local[1];
|
||||||
nasal_ref b=local[2];
|
nasal_ref b=local[2];
|
||||||
|
@ -452,7 +456,7 @@ nasal_ref builtin_nand(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
int number_b=(int)b.num();
|
int number_b=(int)b.num();
|
||||||
return {vm_num,(double)(~(number_a&number_b))};
|
return {vm_num,(double)(~(number_a&number_b))};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_not(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_not(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref a=local[1];
|
nasal_ref a=local[1];
|
||||||
if(a.type!=vm_num)
|
if(a.type!=vm_num)
|
||||||
|
@ -460,56 +464,56 @@ nasal_ref builtin_not(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
int number=(int)a.num();
|
int number=(int)a.num();
|
||||||
return {vm_num,(double)(~number)};
|
return {vm_num,(double)(~number)};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_sin(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_sin(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref val=local[1];
|
nasal_ref val=local[1];
|
||||||
if(val.type!=vm_num)
|
if(val.type!=vm_num)
|
||||||
return builtin_err("sin","\"x\" must be number");
|
return builtin_err("sin","\"x\" must be number");
|
||||||
return {vm_num,sin(val.num())};
|
return {vm_num,sin(val.num())};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_cos(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_cos(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref val=local[1];
|
nasal_ref val=local[1];
|
||||||
if(val.type!=vm_num)
|
if(val.type!=vm_num)
|
||||||
return builtin_err("cos","\"x\" must be number");
|
return builtin_err("cos","\"x\" must be number");
|
||||||
return {vm_num,cos(val.num())};
|
return {vm_num,cos(val.num())};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_tan(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_tan(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref val=local[1];
|
nasal_ref val=local[1];
|
||||||
if(val.type!=vm_num)
|
if(val.type!=vm_num)
|
||||||
return builtin_err("tan","\"x\" must be number");
|
return builtin_err("tan","\"x\" must be number");
|
||||||
return {vm_num,tan(val.num())};
|
return {vm_num,tan(val.num())};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_exp(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_exp(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref val=local[1];
|
nasal_ref val=local[1];
|
||||||
if(val.type!=vm_num)
|
if(val.type!=vm_num)
|
||||||
return builtin_err("exp","\"x\" must be number");
|
return builtin_err("exp","\"x\" must be number");
|
||||||
return {vm_num,exp(val.num())};
|
return {vm_num,exp(val.num())};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_lg(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_lg(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref val=local[1];
|
nasal_ref val=local[1];
|
||||||
if(val.type!=vm_num)
|
if(val.type!=vm_num)
|
||||||
return builtin_err("ln","\"x\" must be number");
|
return builtin_err("ln","\"x\" must be number");
|
||||||
return {vm_num,log(val.num())/log(10.0)};
|
return {vm_num,log(val.num())/log(10.0)};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_ln(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_ln(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref val=local[1];
|
nasal_ref val=local[1];
|
||||||
if(val.type!=vm_num)
|
if(val.type!=vm_num)
|
||||||
return builtin_err("ln","\"x\" must be number");
|
return builtin_err("ln","\"x\" must be number");
|
||||||
return {vm_num,log(val.num())};
|
return {vm_num,log(val.num())};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_sqrt(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_sqrt(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref val=local[1];
|
nasal_ref val=local[1];
|
||||||
if(val.type!=vm_num)
|
if(val.type!=vm_num)
|
||||||
return builtin_err("sqrt","\"x\" must be number");
|
return builtin_err("sqrt","\"x\" must be number");
|
||||||
return {vm_num,sqrt(val.num())};
|
return {vm_num,sqrt(val.num())};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_atan2(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_atan2(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref x=local[1];
|
nasal_ref x=local[1];
|
||||||
nasal_ref y=local[2];
|
nasal_ref y=local[2];
|
||||||
|
@ -519,12 +523,12 @@ nasal_ref builtin_atan2(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
return builtin_err("atan2","\"y\" must be number");
|
return builtin_err("atan2","\"y\" must be number");
|
||||||
return {vm_num,atan2(y.num(),x.num())};
|
return {vm_num,atan2(y.num(),x.num())};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_isnan(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_isnan(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref x=local[1];
|
nasal_ref x=local[1];
|
||||||
return (x.type==vm_num && std::isnan(x.num()))?one:zero;
|
return (x.type==vm_num && std::isnan(x.num()))?one:zero;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_time(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_time(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref val=local[1];
|
nasal_ref val=local[1];
|
||||||
if(val.type!=vm_num)
|
if(val.type!=vm_num)
|
||||||
|
@ -532,7 +536,7 @@ nasal_ref builtin_time(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
time_t begin_time=(time_t)val.num();
|
time_t begin_time=(time_t)val.num();
|
||||||
return {vm_num,(double)time(&begin_time)};
|
return {vm_num,(double)time(&begin_time)};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_contains(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_contains(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref hash=local[1];
|
nasal_ref hash=local[1];
|
||||||
nasal_ref key=local[2];
|
nasal_ref key=local[2];
|
||||||
|
@ -542,7 +546,7 @@ nasal_ref builtin_contains(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
return builtin_err("contains","\"key\" must be string");
|
return builtin_err("contains","\"key\" must be string");
|
||||||
return hash.hash()->elems.count(*key.str())?one:zero;
|
return hash.hash()->elems.count(*key.str())?one:zero;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_delete(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_delete(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref hash=local[1];
|
nasal_ref hash=local[1];
|
||||||
nasal_ref key=local[2];
|
nasal_ref key=local[2];
|
||||||
|
@ -554,23 +558,26 @@ nasal_ref builtin_delete(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
hash.hash()->elems.erase(*key.str());
|
hash.hash()->elems.erase(*key.str());
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_keys(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_keys(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref hash=local[1];
|
nasal_ref hash=local[1];
|
||||||
if(hash.type!=vm_hash)
|
if(hash.type!=vm_hash)
|
||||||
return builtin_err("keys","\"hash\" must be hash");
|
return builtin_err("keys","\"hash\" must be hash");
|
||||||
// push vector into local scope to avoid being sweeped
|
// push vector into local scope to avoid being sweeped
|
||||||
local.push_back(gc.alloc(vm_vec));
|
if(gc.top+1>=gc.stack+STACK_MAX_DEPTH-1)
|
||||||
auto& vec=local.back().vec()->elems;
|
builtin_err("keys","expand temporary space error:stackoverflow");
|
||||||
|
(++gc.top)[0]=gc.alloc(vm_vec);
|
||||||
|
auto& vec=gc.top[0].vec()->elems;
|
||||||
for(auto& iter:hash.hash()->elems)
|
for(auto& iter:hash.hash()->elems)
|
||||||
{
|
{
|
||||||
nasal_ref str=gc.alloc(vm_str);
|
nasal_ref str=gc.alloc(vm_str);
|
||||||
*str.str()=iter.first;
|
*str.str()=iter.first;
|
||||||
vec.push_back(str);
|
vec.push_back(str);
|
||||||
}
|
}
|
||||||
return local.back();
|
--gc.top;
|
||||||
|
return gc.top[1];
|
||||||
}
|
}
|
||||||
nasal_ref builtin_import(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_import(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
// this function is used in preprocessing.
|
// this function is used in preprocessing.
|
||||||
// this function will return nothing when running.
|
// this function will return nothing when running.
|
||||||
|
@ -581,7 +588,7 @@ nasal_ref builtin_import(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
"\n\tmake sure it has correct argument(only one arg allowed)"
|
"\n\tmake sure it has correct argument(only one arg allowed)"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
nasal_ref builtin_die(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_die(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref str=local[1];
|
nasal_ref str=local[1];
|
||||||
if(str.type!=vm_str)
|
if(str.type!=vm_str)
|
||||||
|
@ -589,7 +596,7 @@ nasal_ref builtin_die(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
std::cerr<<"[vm] error: "<<*str.str()<<'\n';
|
std::cerr<<"[vm] error: "<<*str.str()<<'\n';
|
||||||
return nasal_ref(vm_none);
|
return nasal_ref(vm_none);
|
||||||
}
|
}
|
||||||
nasal_ref builtin_type(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_type(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref val=local[1];
|
nasal_ref val=local[1];
|
||||||
nasal_ref ret=gc.alloc(vm_str);
|
nasal_ref ret=gc.alloc(vm_str);
|
||||||
|
@ -606,7 +613,7 @@ nasal_ref builtin_type(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_substr(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_substr(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref str=local[1];
|
nasal_ref str=local[1];
|
||||||
nasal_ref beg=local[2];
|
nasal_ref beg=local[2];
|
||||||
|
@ -627,13 +634,13 @@ nasal_ref builtin_substr(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
*ret.str()=str.str()->substr(begin,length);
|
*ret.str()=str.str()->substr(begin,length);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_streq(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_streq(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref a=local[1];
|
nasal_ref a=local[1];
|
||||||
nasal_ref b=local[2];
|
nasal_ref b=local[2];
|
||||||
return {vm_num,double((a.type!=vm_str || b.type!=vm_str)?0:(*a.str()==*b.str()))};
|
return {vm_num,double((a.type!=vm_str || b.type!=vm_str)?0:(*a.str()==*b.str()))};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_left(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_left(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref str=local[1];
|
nasal_ref str=local[1];
|
||||||
nasal_ref len=local[2];
|
nasal_ref len=local[2];
|
||||||
|
@ -648,7 +655,7 @@ nasal_ref builtin_left(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
*ret.str()=str.str()->substr(0,length);
|
*ret.str()=str.str()->substr(0,length);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_right(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_right(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref str=local[1];
|
nasal_ref str=local[1];
|
||||||
nasal_ref len=local[2];
|
nasal_ref len=local[2];
|
||||||
|
@ -666,7 +673,7 @@ nasal_ref builtin_right(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
*ret.str()=str.str()->substr(srclen-length, srclen);
|
*ret.str()=str.str()->substr(srclen-length, srclen);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_cmp(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_cmp(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref a=local[1];
|
nasal_ref a=local[1];
|
||||||
nasal_ref b=local[2];
|
nasal_ref b=local[2];
|
||||||
|
@ -676,7 +683,7 @@ nasal_ref builtin_cmp(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
return builtin_err("cmp","\"b\" must be string");
|
return builtin_err("cmp","\"b\" must be string");
|
||||||
return {vm_num,(double)strcmp(a.str()->c_str(),b.str()->c_str())};
|
return {vm_num,(double)strcmp(a.str()->c_str(),b.str()->c_str())};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_chr(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_chr(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
const char* extend[]={
|
const char* extend[]={
|
||||||
"€"," ","‚","ƒ","„","…","†","‡",
|
"€"," ","‚","ƒ","„","…","†","‡",
|
||||||
|
@ -709,7 +716,7 @@ nasal_ref builtin_chr(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
*ret.str()=" ";
|
*ret.str()=" ";
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_open(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_open(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref filename=local[1];
|
nasal_ref filename=local[1];
|
||||||
nasal_ref mode=local[2];
|
nasal_ref mode=local[2];
|
||||||
|
@ -725,7 +732,7 @@ nasal_ref builtin_open(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
ret.obj()->ptr=(void*)res;
|
ret.obj()->ptr=(void*)res;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_close(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_close(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref filehandle=local[1];
|
nasal_ref filehandle=local[1];
|
||||||
if(filehandle.type!=vm_obj || filehandle.obj()->type!=obj_file)
|
if(filehandle.type!=vm_obj || filehandle.obj()->type!=obj_file)
|
||||||
|
@ -733,7 +740,7 @@ nasal_ref builtin_close(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
fclose((FILE*)filehandle.obj()->ptr);
|
fclose((FILE*)filehandle.obj()->ptr);
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_read(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_read(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref filehandle=local[1];
|
nasal_ref filehandle=local[1];
|
||||||
nasal_ref buf=local[2];
|
nasal_ref buf=local[2];
|
||||||
|
@ -754,7 +761,7 @@ nasal_ref builtin_read(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
delete []buff;
|
delete []buff;
|
||||||
return {vm_num,res};
|
return {vm_num,res};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_write(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_write(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref filehandle=local[1];
|
nasal_ref filehandle=local[1];
|
||||||
nasal_ref str=local[2];
|
nasal_ref str=local[2];
|
||||||
|
@ -765,7 +772,7 @@ nasal_ref builtin_write(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
double res=(double)fwrite(str.str()->c_str(),1,str.str()->length(),(FILE*)filehandle.obj()->ptr);
|
double res=(double)fwrite(str.str()->c_str(),1,str.str()->length(),(FILE*)filehandle.obj()->ptr);
|
||||||
return {vm_num,res};
|
return {vm_num,res};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_seek(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_seek(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref filehandle=local[1];
|
nasal_ref filehandle=local[1];
|
||||||
nasal_ref position=local[2];
|
nasal_ref position=local[2];
|
||||||
|
@ -779,7 +786,7 @@ nasal_ref builtin_seek(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
double res=fseek((FILE*)filehandle.obj()->ptr,position.num(),whence.num());
|
double res=fseek((FILE*)filehandle.obj()->ptr,position.num(),whence.num());
|
||||||
return {vm_num,res};
|
return {vm_num,res};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_tell(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_tell(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref filehandle=local[1];
|
nasal_ref filehandle=local[1];
|
||||||
if(filehandle.type!=vm_obj || filehandle.obj()->type!=obj_file)
|
if(filehandle.type!=vm_obj || filehandle.obj()->type!=obj_file)
|
||||||
|
@ -787,7 +794,7 @@ nasal_ref builtin_tell(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
double res=ftell((FILE*)filehandle.obj()->ptr);
|
double res=ftell((FILE*)filehandle.obj()->ptr);
|
||||||
return {vm_num,res};
|
return {vm_num,res};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_readln(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_readln(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref filehandle=local[1];
|
nasal_ref filehandle=local[1];
|
||||||
if(filehandle.type!=vm_obj || filehandle.obj()->type!=obj_file)
|
if(filehandle.type!=vm_obj || filehandle.obj()->type!=obj_file)
|
||||||
|
@ -807,7 +814,7 @@ nasal_ref builtin_readln(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
return str;
|
return str;
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_stat(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_stat(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref filename=local[1];
|
nasal_ref filename=local[1];
|
||||||
if(filename.type!=vm_str)
|
if(filename.type!=vm_str)
|
||||||
|
@ -831,7 +838,7 @@ nasal_ref builtin_stat(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
};
|
};
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_eof(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_eof(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref filehandle=local[1];
|
nasal_ref filehandle=local[1];
|
||||||
if(filehandle.type!=vm_obj || filehandle.obj()->type!=obj_file)
|
if(filehandle.type!=vm_obj || filehandle.obj()->type!=obj_file)
|
||||||
|
@ -839,7 +846,7 @@ nasal_ref builtin_eof(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
double res=feof((FILE*)filehandle.obj()->ptr);
|
double res=feof((FILE*)filehandle.obj()->ptr);
|
||||||
return {vm_num,res};
|
return {vm_num,res};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_fld(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_fld(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
// bits.fld(s,0,3);
|
// bits.fld(s,0,3);
|
||||||
// if s stores 10100010(162)
|
// if s stores 10100010(162)
|
||||||
|
@ -862,7 +869,7 @@ nasal_ref builtin_fld(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
res|=1<<(bit+len-i-1);
|
res|=1<<(bit+len-i-1);
|
||||||
return {vm_num,(double)res};
|
return {vm_num,(double)res};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_sfld(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_sfld(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
// bits.sfld(s,0,3);
|
// bits.sfld(s,0,3);
|
||||||
// if s stores 10100010(162)
|
// if s stores 10100010(162)
|
||||||
|
@ -888,7 +895,7 @@ nasal_ref builtin_sfld(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
res|=~((1<<len)-1);
|
res|=~((1<<len)-1);
|
||||||
return {vm_num,(double)((int32_t)res)};
|
return {vm_num,(double)((int32_t)res)};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_setfld(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_setfld(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
// bits.setfld(s,0,8,69);
|
// bits.setfld(s,0,8,69);
|
||||||
// set 01000101(69) to string will get this:
|
// set 01000101(69) to string will get this:
|
||||||
|
@ -917,7 +924,7 @@ nasal_ref builtin_setfld(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
}
|
}
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_buf(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_buf(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref length=local[1];
|
nasal_ref length=local[1];
|
||||||
if(length.type!=vm_num || length.num()<=0)
|
if(length.type!=vm_num || length.num()<=0)
|
||||||
|
@ -927,7 +934,7 @@ nasal_ref builtin_buf(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
s.resize(length.num(),'\0');
|
s.resize(length.num(),'\0');
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_sleep(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_sleep(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref val=local[1];
|
nasal_ref val=local[1];
|
||||||
if(val.type!=vm_num)
|
if(val.type!=vm_num)
|
||||||
|
@ -935,7 +942,7 @@ nasal_ref builtin_sleep(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
usleep((useconds_t)(val.num()*1e6));
|
usleep((useconds_t)(val.num()*1e6));
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_opendir(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_opendir(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref path=local[1];
|
nasal_ref path=local[1];
|
||||||
if(path.type!=vm_str)
|
if(path.type!=vm_str)
|
||||||
|
@ -948,7 +955,7 @@ nasal_ref builtin_opendir(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
ret.obj()->ptr=(void*)p;
|
ret.obj()->ptr=(void*)p;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_readdir(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_readdir(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref handle=local[1];
|
nasal_ref handle=local[1];
|
||||||
if(handle.type!=vm_obj || handle.obj()->type!=obj_dir)
|
if(handle.type!=vm_obj || handle.obj()->type!=obj_dir)
|
||||||
|
@ -960,7 +967,7 @@ nasal_ref builtin_readdir(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
*ret.str()=p->d_name;
|
*ret.str()=p->d_name;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_closedir(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_closedir(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref handle=local[1];
|
nasal_ref handle=local[1];
|
||||||
if(handle.type!=vm_obj || handle.obj()->type!=obj_dir)
|
if(handle.type!=vm_obj || handle.obj()->type!=obj_dir)
|
||||||
|
@ -968,7 +975,7 @@ nasal_ref builtin_closedir(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
closedir((DIR*)handle.obj()->ptr);
|
closedir((DIR*)handle.obj()->ptr);
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_chdir(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_chdir(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref path=local[1];
|
nasal_ref path=local[1];
|
||||||
if(path.type!=vm_str)
|
if(path.type!=vm_str)
|
||||||
|
@ -977,7 +984,7 @@ nasal_ref builtin_chdir(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
return builtin_err("chdir","failed to execute chdir");
|
return builtin_err("chdir","failed to execute chdir");
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_getcwd(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_getcwd(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
getcwd(buf,sizeof(buf));
|
getcwd(buf,sizeof(buf));
|
||||||
|
@ -985,7 +992,7 @@ nasal_ref builtin_getcwd(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
*str.str()=buf;
|
*str.str()=buf;
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_getenv(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_getenv(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref envvar=local[1];
|
nasal_ref envvar=local[1];
|
||||||
if(envvar.type!=vm_str)
|
if(envvar.type!=vm_str)
|
||||||
|
@ -997,7 +1004,7 @@ nasal_ref builtin_getenv(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
*str.str()=res;
|
*str.str()=res;
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_dlopen(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_dlopen(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref dlname=local[1];
|
nasal_ref dlname=local[1];
|
||||||
if(dlname.type!=vm_str)
|
if(dlname.type!=vm_str)
|
||||||
|
@ -1019,7 +1026,7 @@ nasal_ref builtin_dlopen(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
ret.obj()->ptr=ptr;
|
ret.obj()->ptr=ptr;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_dlsym(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_dlsym(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref libptr=local[1];
|
nasal_ref libptr=local[1];
|
||||||
nasal_ref sym=local[2];
|
nasal_ref sym=local[2];
|
||||||
|
@ -1039,7 +1046,7 @@ nasal_ref builtin_dlsym(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
ret.obj()->ptr=func;
|
ret.obj()->ptr=func;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_dlclose(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_dlclose(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref libptr=local[1];
|
nasal_ref libptr=local[1];
|
||||||
if(libptr.type!=vm_obj || libptr.obj()->type!=obj_dylib)
|
if(libptr.type!=vm_obj || libptr.obj()->type!=obj_dylib)
|
||||||
|
@ -1051,7 +1058,7 @@ nasal_ref builtin_dlclose(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
#endif
|
#endif
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_dlcall(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_dlcall(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref funcptr=local[1];
|
nasal_ref funcptr=local[1];
|
||||||
nasal_ref args=local[2];
|
nasal_ref args=local[2];
|
||||||
|
@ -1061,7 +1068,7 @@ nasal_ref builtin_dlcall(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
extern_func func=(extern_func)funcptr.obj()->ptr;
|
extern_func func=(extern_func)funcptr.obj()->ptr;
|
||||||
return func(args.vec()->elems,gc);
|
return func(args.vec()->elems,gc);
|
||||||
}
|
}
|
||||||
nasal_ref builtin_platform(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_platform(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref ret=gc.alloc(vm_str);
|
nasal_ref ret=gc.alloc(vm_str);
|
||||||
#if defined _WIN32 || defined _WIN64
|
#if defined _WIN32 || defined _WIN64
|
||||||
|
@ -1073,7 +1080,7 @@ nasal_ref builtin_platform(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
#endif
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_gc(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_gc(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
gc.mark();
|
gc.mark();
|
||||||
gc.sweep();
|
gc.sweep();
|
||||||
|
|
|
@ -212,7 +212,7 @@ void nasal_dbg::run(
|
||||||
}
|
}
|
||||||
|
|
||||||
// set canary and program counter
|
// set canary and program counter
|
||||||
auto canary=gc.stack+STACK_MAX_DEPTH-1;
|
canary=gc.stack+STACK_MAX_DEPTH-1;
|
||||||
pc=0;
|
pc=0;
|
||||||
// goto the first operand
|
// goto the first operand
|
||||||
goto *code[pc];
|
goto *code[pc];
|
||||||
|
|
|
@ -302,7 +302,7 @@ inline nasal_hash* nasal_ref::hash(){return value.gcobj->ptr.hash;}
|
||||||
inline nasal_func* nasal_ref::func(){return value.gcobj->ptr.func;}
|
inline nasal_func* nasal_ref::func(){return value.gcobj->ptr.func;}
|
||||||
inline nasal_obj* nasal_ref::obj (){return value.gcobj->ptr.obj; }
|
inline nasal_obj* nasal_ref::obj (){return value.gcobj->ptr.obj; }
|
||||||
|
|
||||||
const uint32_t STACK_MAX_DEPTH=4095;
|
const uint32_t STACK_MAX_DEPTH=8191;
|
||||||
const nasal_ref zero={vm_num,(double)0};
|
const nasal_ref zero={vm_num,(double)0};
|
||||||
const nasal_ref one ={vm_num,(double)1};
|
const nasal_ref one ={vm_num,(double)1};
|
||||||
const nasal_ref nil ={vm_nil,nullptr};
|
const nasal_ref nil ={vm_nil,nullptr};
|
||||||
|
@ -313,7 +313,7 @@ struct nasal_gc
|
||||||
std::vector<nasal_ref> strs; // reserved address for const vm_str
|
std::vector<nasal_ref> strs; // reserved address for const vm_str
|
||||||
std::vector<nasal_val*> memory; // gc memory
|
std::vector<nasal_val*> memory; // gc memory
|
||||||
std::queue<nasal_val*> free_list[vm_type_size]; // gc free list
|
std::queue<nasal_val*> free_list[vm_type_size]; // gc free list
|
||||||
std::vector<nasal_ref> local;
|
std::vector<nasal_ref> upvalue;
|
||||||
uint64_t size[vm_type_size];
|
uint64_t size[vm_type_size];
|
||||||
uint64_t count[vm_type_size];
|
uint64_t count[vm_type_size];
|
||||||
void mark();
|
void mark();
|
||||||
|
@ -329,7 +329,7 @@ struct nasal_gc
|
||||||
void nasal_gc::mark()
|
void nasal_gc::mark()
|
||||||
{
|
{
|
||||||
std::queue<nasal_ref> bfs;
|
std::queue<nasal_ref> bfs;
|
||||||
for(auto& i:local)
|
for(auto& i:upvalue)
|
||||||
bfs.push(i);
|
bfs.push(i);
|
||||||
for(nasal_ref* i=stack;i<=top;++i)
|
for(nasal_ref* i=stack;i<=top;++i)
|
||||||
bfs.push(*i);
|
bfs.push(*i);
|
||||||
|
@ -405,10 +405,10 @@ void nasal_gc::clear()
|
||||||
for(auto i:memory)
|
for(auto i:memory)
|
||||||
delete i;
|
delete i;
|
||||||
memory.clear();
|
memory.clear();
|
||||||
|
upvalue.clear();
|
||||||
for(uint8_t i=0;i<vm_type_size;++i)
|
for(uint8_t i=0;i<vm_type_size;++i)
|
||||||
while(!free_list[i].empty())
|
while(!free_list[i].empty())
|
||||||
free_list[i].pop();
|
free_list[i].pop();
|
||||||
local.clear();
|
|
||||||
for(auto& i:strs)
|
for(auto& i:strs)
|
||||||
delete i.value.gcobj;
|
delete i.value.gcobj;
|
||||||
strs.clear();
|
strs.clear();
|
||||||
|
|
112
nasal_vm.h
112
nasal_vm.h
|
@ -9,7 +9,7 @@ protected:
|
||||||
const double* num_table;// const numbers, ref from nasal_codegen
|
const double* num_table;// const numbers, ref from nasal_codegen
|
||||||
const std::string* str_table;// const symbols, ref from nasal_codegen
|
const std::string* str_table;// const symbols, ref from nasal_codegen
|
||||||
std::stack<nasal_func*> fstk; // stack to store function, used to get upvalues
|
std::stack<nasal_func*> fstk; // stack to store function, used to get upvalues
|
||||||
std::stack<uint32_t> local_stk;
|
std::stack<nasal_ref*> lstk; // stack to store local scopes' begin address
|
||||||
std::vector<uint32_t> imm; // immediate number
|
std::vector<uint32_t> imm; // immediate number
|
||||||
nasal_ref* mem_addr; // used for mem_call
|
nasal_ref* mem_addr; // used for mem_call
|
||||||
/* garbage collector */
|
/* garbage collector */
|
||||||
|
@ -234,17 +234,16 @@ void nasal_vm::global_state()
|
||||||
}
|
}
|
||||||
void nasal_vm::local_state()
|
void nasal_vm::local_state()
|
||||||
{
|
{
|
||||||
if(gc.local.empty() || !gc.local.back().vec()->elems.size())
|
if(lstk.empty() || !fstk.top()->lsize)
|
||||||
{
|
{
|
||||||
printf("no local value exists\n");
|
printf("no local value exists\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
printf("local:\n");
|
printf("local:\n");
|
||||||
auto& vec=gc.local.back().vec()->elems;
|
for(uint32_t i=0;i<fstk.top()->lsize;++i)
|
||||||
for(uint32_t i=0;i<vec.size();++i)
|
|
||||||
{
|
{
|
||||||
printf("[0x%.8x]",i);
|
printf("[0x%.8x]",i);
|
||||||
valinfo(vec[i]);
|
valinfo(lstk.top()[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void nasal_vm::upval_state()
|
void nasal_vm::upval_state()
|
||||||
|
@ -335,7 +334,8 @@ inline void nasal_vm::opr_loadg()
|
||||||
}
|
}
|
||||||
inline void nasal_vm::opr_loadl()
|
inline void nasal_vm::opr_loadl()
|
||||||
{
|
{
|
||||||
gc.local.back().vec()->elems[imm[pc]]=(gc.top--)[0];
|
lstk.top()[imm[pc]]=(gc.top--)[0];
|
||||||
|
//gc.local.back().vec()->elems[imm[pc]]=(gc.top--)[0];
|
||||||
}
|
}
|
||||||
inline void nasal_vm::opr_loadu()
|
inline void nasal_vm::opr_loadu()
|
||||||
{
|
{
|
||||||
|
@ -374,10 +374,17 @@ inline void nasal_vm::opr_newf()
|
||||||
nasal_func* func=gc.top[0].func();
|
nasal_func* func=gc.top[0].func();
|
||||||
func->entry=imm[pc];
|
func->entry=imm[pc];
|
||||||
func->psize=1;
|
func->psize=1;
|
||||||
if(!gc.local.empty())
|
|
||||||
|
/* this means you create a new function in local scope */
|
||||||
|
if(!lstk.empty())
|
||||||
{
|
{
|
||||||
func->upvalue=fstk.top()->upvalue;
|
func->upvalue=fstk.top()->upvalue;
|
||||||
func->upvalue.push_back(gc.local.back());
|
nasal_ref upval=(gc.upvalue.back().type==vm_nil)?gc.alloc(vm_vec):gc.upvalue.back();
|
||||||
|
func->upvalue.push_back(upval);
|
||||||
|
gc.upvalue.back()=upval;
|
||||||
|
auto& vec=upval.vec()->elems;
|
||||||
|
for(uint32_t i=0;i<fstk.top()->lsize;++i)
|
||||||
|
vec.push_back(lstk.top()[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inline void nasal_vm::opr_happ()
|
inline void nasal_vm::opr_happ()
|
||||||
|
@ -586,7 +593,7 @@ inline void nasal_vm::opr_callg()
|
||||||
}
|
}
|
||||||
inline void nasal_vm::opr_calll()
|
inline void nasal_vm::opr_calll()
|
||||||
{
|
{
|
||||||
(++gc.top)[0]=gc.local.back().vec()->elems[imm[pc]];
|
(++gc.top)[0]=lstk.top()[imm[pc]];
|
||||||
}
|
}
|
||||||
inline void nasal_vm::opr_upval()
|
inline void nasal_vm::opr_upval()
|
||||||
{
|
{
|
||||||
|
@ -651,58 +658,60 @@ inline void nasal_vm::opr_callh()
|
||||||
inline void nasal_vm::opr_callfv()
|
inline void nasal_vm::opr_callfv()
|
||||||
{
|
{
|
||||||
uint32_t argc=imm[pc]; // arguments counter
|
uint32_t argc=imm[pc]; // arguments counter
|
||||||
nasal_ref* args=gc.top-argc+1;// arguments begin place
|
nasal_ref* args=gc.top-argc+1;// arguments begin address
|
||||||
if(args[-1].type!=vm_func)
|
if(args[-1].type!=vm_func)
|
||||||
die("callfv: must call a function");
|
die("callfv: must call a function");
|
||||||
|
|
||||||
nasal_func* func=args[-1].func();
|
nasal_func* func=args[-1].func();
|
||||||
if(gc.top+func->lsize>=canary)
|
if(gc.top-argc+func->lsize+1>=canary) // gc.top-argc+lsize(local) +1(pc)
|
||||||
die("stackoverflow");
|
die("stack overflow");
|
||||||
fstk.push(func);// push called function into stack to provide upvalue
|
fstk.push(func); // push called function into stack to provide upvalue
|
||||||
|
lstk.push(gc.top-argc+1); // store begin of local scope
|
||||||
gc.local.push_back(gc.alloc(vm_vec)); // get new vector as local scope
|
|
||||||
gc.local.back().vec()->elems=func->local;// copy data from func.local to local scope
|
|
||||||
auto& local=gc.local.back().vec()->elems;
|
|
||||||
|
|
||||||
uint32_t psize=func->psize-1;// parameter size is func->psize-1, 1 is reserved for "me"
|
uint32_t psize=func->psize-1; // parameter size is func->psize-1, 1 is reserved for "me"
|
||||||
// load arguments
|
|
||||||
// if the first default value is not vm_none,then values after it are not nullptr
|
|
||||||
// args_size+1 is because the first space is reserved for 'me'
|
|
||||||
if(argc<psize && func->local[argc+1].type==vm_none)
|
if(argc<psize && func->local[argc+1].type==vm_none)
|
||||||
die("callfv: lack argument(s)");
|
die("callfv: lack argument(s)");
|
||||||
// if args_size>para_size,for 0 to args_size will cause corruption
|
|
||||||
uint32_t min_size=std::min(psize,argc);
|
nasal_ref* local=args;
|
||||||
for(uint32_t i=0;i<min_size;++i)
|
nasal_ref dynamic=nil;
|
||||||
local[i+1]=args[i];
|
gc.top=local+func->lsize;
|
||||||
// load dynamic argument if args_size>=para_size
|
if(func->dynpara>=0)// load dynamic arguments
|
||||||
if(func->dynpara>=0)
|
|
||||||
{
|
{
|
||||||
nasal_ref vec=gc.alloc(vm_vec);
|
dynamic=gc.alloc(vm_vec);
|
||||||
for(uint32_t i=psize;i<argc;++i)
|
for(uint32_t i=psize;i<argc;++i)
|
||||||
vec.vec()->elems.push_back(args[i]);
|
dynamic.vec()->elems.push_back(args[i]);
|
||||||
local[min_size+1]=vec;
|
|
||||||
}
|
}
|
||||||
|
uint32_t min_size=std::min(psize,argc);
|
||||||
gc.top-=argc; // pop arguments
|
for(uint32_t i=min_size;i>=1;--i)// load arguments
|
||||||
(++gc.top)[0]={vm_ret,pc};
|
local[i]=local[i-1];
|
||||||
|
local[0]=func->local[0];// load "me"
|
||||||
|
for(uint32_t i=min_size+1;i<func->lsize;++i)// load local scope & default arguments
|
||||||
|
local[i]=func->local[i];
|
||||||
|
if(func->dynpara>=0)
|
||||||
|
local[psize+1]=dynamic;
|
||||||
|
|
||||||
|
gc.top[0]={vm_ret,pc};
|
||||||
pc=func->entry-1;
|
pc=func->entry-1;
|
||||||
|
gc.upvalue.push_back(nil);
|
||||||
}
|
}
|
||||||
inline void nasal_vm::opr_callfh()
|
inline void nasal_vm::opr_callfh()
|
||||||
{
|
{
|
||||||
auto& hash=gc.top[0].hash()->elems;
|
auto& hash=gc.top[0].hash()->elems;
|
||||||
if(gc.top[-1].type!=vm_func)
|
if(gc.top[-1].type!=vm_func)
|
||||||
die("callfh: must call a function");
|
die("callfh: must call a function");
|
||||||
// push function and new local scope
|
|
||||||
nasal_func* func=gc.top[-1].func();
|
nasal_func* func=gc.top[-1].func();
|
||||||
if(gc.top+func->lsize>=canary)
|
if(gc.top+func->lsize>=canary) // gc.top -1(hash) +lsize(local) +1(pc)
|
||||||
die("stackoverflow");
|
die("stack overflow");
|
||||||
if(func->dynpara>=0)
|
if(func->dynpara>=0)
|
||||||
die("callfh: special call cannot use dynamic argument");
|
die("callfh: special call cannot use dynamic argument");
|
||||||
fstk.push(func);
|
fstk.push(func); // push called function into stack to provide upvalue
|
||||||
|
lstk.push(gc.top); // store begin of local scope
|
||||||
|
|
||||||
gc.local.push_back(gc.alloc(vm_vec));
|
nasal_ref* local=gc.top;
|
||||||
gc.local.back().vec()->elems=func->local;
|
gc.top+=func->lsize;
|
||||||
auto& local=gc.local.back().vec()->elems;
|
for(uint32_t i=0;i<func->lsize;++i)
|
||||||
|
local[i]=func->local[i];
|
||||||
|
|
||||||
for(auto& i:func->keys)
|
for(auto& i:func->keys)
|
||||||
{
|
{
|
||||||
|
@ -714,10 +723,11 @@ inline void nasal_vm::opr_callfh()
|
||||||
|
|
||||||
gc.top[0]={vm_ret,(uint32_t)pc}; // rewrite top with vm_ret
|
gc.top[0]={vm_ret,(uint32_t)pc}; // rewrite top with vm_ret
|
||||||
pc=func->entry-1;
|
pc=func->entry-1;
|
||||||
|
gc.upvalue.push_back(nil);
|
||||||
}
|
}
|
||||||
inline void nasal_vm::opr_callb()
|
inline void nasal_vm::opr_callb()
|
||||||
{
|
{
|
||||||
(++gc.top)[0]=(*builtin[imm[pc]].func)(gc.local.back().vec()->elems,gc);
|
(++gc.top)[0]=(*builtin[imm[pc]].func)(lstk.top(),gc);
|
||||||
if(gc.top[0].type==vm_none)
|
if(gc.top[0].type==vm_none)
|
||||||
die("native function error.");
|
die("native function error.");
|
||||||
}
|
}
|
||||||
|
@ -782,7 +792,7 @@ inline void nasal_vm::opr_mcallg()
|
||||||
}
|
}
|
||||||
inline void nasal_vm::opr_mcalll()
|
inline void nasal_vm::opr_mcalll()
|
||||||
{
|
{
|
||||||
mem_addr=&(gc.local.back().vec()->elems[imm[pc]]);
|
mem_addr=lstk.top()+imm[pc];
|
||||||
(++gc.top)[0]=mem_addr[0];
|
(++gc.top)[0]=mem_addr[0];
|
||||||
}
|
}
|
||||||
inline void nasal_vm::opr_mupval()
|
inline void nasal_vm::opr_mupval()
|
||||||
|
@ -836,15 +846,21 @@ inline void nasal_vm::opr_ret()
|
||||||
// +-----------------+
|
// +-----------------+
|
||||||
// | return address | <- gc.top[-1]
|
// | return address | <- gc.top[-1]
|
||||||
// +-----------------+
|
// +-----------------+
|
||||||
// | called function | <- gc.top[-2] funct is set on stack because gc may mark it
|
// | local scope |
|
||||||
|
// +-----------------+ <- local pointer stored in lstk
|
||||||
|
// | called function | <- funct is set on stack because gc may mark it
|
||||||
// +-----------------+
|
// +-----------------+
|
||||||
|
nasal_ref ret=gc.top[0];
|
||||||
pc=gc.top[-1].ret();
|
pc=gc.top[-1].ret();
|
||||||
gc.top[-2].func()->local[0]={vm_nil,nullptr}; // get func and set 'me' to nil
|
|
||||||
gc.top[-2]=gc.top[0]; // rewrite func with returned value
|
gc.top=lstk.top()-1;
|
||||||
gc.top-=2;
|
lstk.pop();
|
||||||
|
|
||||||
|
gc.top[0].func()->local[0]={vm_nil,nullptr}; // get func and set 'me' to nil
|
||||||
|
gc.top[0]=ret; // rewrite func with returned value
|
||||||
|
|
||||||
fstk.pop();
|
fstk.pop();
|
||||||
gc.local.pop_back();
|
gc.upvalue.pop_back();
|
||||||
}
|
}
|
||||||
void nasal_vm::run(
|
void nasal_vm::run(
|
||||||
const nasal_codegen& gen,
|
const nasal_codegen& gen,
|
||||||
|
@ -968,7 +984,7 @@ upval: exec_operand(opr_upval ,op_upval ); // +1
|
||||||
callv: exec_opnodie(opr_callv ,op_callv ); // -0
|
callv: exec_opnodie(opr_callv ,op_callv ); // -0
|
||||||
callvi: exec_opnodie(opr_callvi ,op_callvi ); // -0
|
callvi: exec_opnodie(opr_callvi ,op_callvi ); // -0
|
||||||
callh: exec_opnodie(opr_callh ,op_callh ); // -0
|
callh: exec_opnodie(opr_callh ,op_callh ); // -0
|
||||||
callfv: exec_operand(opr_callfv ,op_callfv ); // +1-imm[pc] call this will push >=0 arguments
|
callfv: exec_opnodie(opr_callfv ,op_callfv ); // check in the function
|
||||||
callfh: exec_opnodie(opr_callfh ,op_callfh ); // -0 call this will push one hash
|
callfh: exec_opnodie(opr_callfh ,op_callfh ); // -0 call this will push one hash
|
||||||
callb: exec_opnodie(opr_callb ,op_callb ); // -0
|
callb: exec_opnodie(opr_callb ,op_callb ); // -0
|
||||||
slcbegin:exec_operand(opr_slcbegin,op_slcbegin); // +1
|
slcbegin:exec_operand(opr_slcbegin,op_slcbegin); // +1
|
||||||
|
|
20
test/bf.nas
20
test/bf.nas
|
@ -152,6 +152,15 @@ var (ptr,pc)=(0,0);
|
||||||
var (code,inum,stack)=([],[],[]);
|
var (code,inum,stack)=([],[],[]);
|
||||||
var (add,mov,jt,jf,in,out)=(0,1,2,3,4,5);
|
var (add,mov,jt,jf,in,out)=(0,1,2,3,4,5);
|
||||||
|
|
||||||
|
var funcs=[
|
||||||
|
func{paper[ptr]+=inum[pc];},
|
||||||
|
func{ptr+=inum[pc];},
|
||||||
|
func{if(paper[ptr])pc=inum[pc];},
|
||||||
|
func{if(!paper[ptr])pc=inum[pc];},
|
||||||
|
func{paper[ptr]=input()[0];},
|
||||||
|
func{print(chr(paper[ptr]));}
|
||||||
|
];
|
||||||
|
|
||||||
var bf=func(program){
|
var bf=func(program){
|
||||||
setsize(paper,131072);
|
setsize(paper,131072);
|
||||||
var len=size(program);
|
var len=size(program);
|
||||||
|
@ -212,15 +221,8 @@ var bf=func(program){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
len=size(code);
|
len=size(code);
|
||||||
for(pc=0;pc<len;pc+=1){
|
for(pc=0;pc<len;pc+=1)
|
||||||
var c=code[pc];
|
funcs[code[pc]]();
|
||||||
if(c==add) paper[ptr]+=inum[pc];
|
|
||||||
elsif(c==mov)ptr+=inum[pc];
|
|
||||||
elsif(c==jt){if(paper[ptr])pc=inum[pc];}
|
|
||||||
elsif(c==jf){if(!paper[ptr])pc=inum[pc];}
|
|
||||||
elsif(c==in) paper[ptr]=input()[0];
|
|
||||||
else print(chr(paper[ptr]));
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue