📝 change name of used types
This commit is contained in:
parent
e9fc70bba8
commit
46516485b5
|
@ -196,7 +196,7 @@ __`vm_nil`__ is a null type. It means nothing.
|
||||||
var spc=nil;
|
var spc=nil;
|
||||||
```
|
```
|
||||||
|
|
||||||
__`vm_num`__ has 3 formats: `dec`, `hex` and `oct`. Using IEEE754 double to store.
|
__`vm_num`__ has 3 formats: `dec`, `hex` and `oct`. Using IEEE754 `double` to store.
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
# this language use '#' to write notes
|
# this language use '#' to write notes
|
||||||
|
|
|
@ -180,7 +180,7 @@ __`vm_nil`__ 是空类型。类似于null。
|
||||||
var spc=nil;
|
var spc=nil;
|
||||||
```
|
```
|
||||||
|
|
||||||
__`vm_num`__ 有三种形式:十进制,十六进制以及八进制。并且该类型使用IEEE754标准的浮点数double格式来存储。
|
__`vm_num`__ 有三种形式:十进制,十六进制以及八进制。并且该类型使用IEEE754标准的浮点数`double`格式来存储。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
# this language use '#' to write notes
|
# this language use '#' to write notes
|
||||||
|
|
24
main.cpp
24
main.cpp
|
@ -1,14 +1,14 @@
|
||||||
#include "nasal.h"
|
#include "nasal.h"
|
||||||
|
|
||||||
const uint32_t VM_LEXINFO =0x01;
|
const u32 VM_LEXINFO =0x01;
|
||||||
const uint32_t VM_ASTINFO =0x02;
|
const u32 VM_ASTINFO =0x02;
|
||||||
const uint32_t VM_CODEINFO =0x04;
|
const u32 VM_CODEINFO =0x04;
|
||||||
const uint32_t VM_EXECTIME =0x08;
|
const u32 VM_EXECTIME =0x08;
|
||||||
const uint32_t VM_OPCALLNUM=0x10;
|
const u32 VM_OPCALLNUM=0x10;
|
||||||
const uint32_t VM_EXEC =0x20;
|
const u32 VM_EXEC =0x20;
|
||||||
const uint32_t VM_DBGINFO =0x40;
|
const u32 VM_DBGINFO =0x40;
|
||||||
const uint32_t VM_DEBUG =0x80;
|
const u32 VM_DEBUG =0x80;
|
||||||
const uint32_t VM_OPTIMIZE =0x100;
|
const u32 VM_OPTIMIZE =0x100;
|
||||||
|
|
||||||
void help()
|
void help()
|
||||||
{
|
{
|
||||||
|
@ -70,7 +70,7 @@ void err()
|
||||||
std::exit(1);
|
std::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void execute(const std::string& file,const std::vector<std::string>& argv,const uint32_t cmd)
|
void execute(const std::string& file,const std::vector<std::string>& argv,const u32 cmd)
|
||||||
{
|
{
|
||||||
// front end use the same error module
|
// front end use the same error module
|
||||||
nasal_err nerr;
|
nasal_err nerr;
|
||||||
|
@ -138,7 +138,7 @@ int main(int argc,const char* argv[])
|
||||||
err();
|
err();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
std::unordered_map<std::string,uint32_t> cmdlst={
|
std::unordered_map<std::string,u32> cmdlst={
|
||||||
{"--lex",VM_LEXINFO},{"-l",VM_LEXINFO},
|
{"--lex",VM_LEXINFO},{"-l",VM_LEXINFO},
|
||||||
{"--ast",VM_ASTINFO},{"-a",VM_ASTINFO},
|
{"--ast",VM_ASTINFO},{"-a",VM_ASTINFO},
|
||||||
{"--code",VM_CODEINFO},{"-c",VM_CODEINFO},
|
{"--code",VM_CODEINFO},{"-c",VM_CODEINFO},
|
||||||
|
@ -149,7 +149,7 @@ int main(int argc,const char* argv[])
|
||||||
{"--optimize",VM_OPTIMIZE},{"-op",VM_OPTIMIZE},
|
{"--optimize",VM_OPTIMIZE},{"-op",VM_OPTIMIZE},
|
||||||
{"--debug",VM_DEBUG},{"-dbg",VM_DEBUG}
|
{"--debug",VM_DEBUG},{"-dbg",VM_DEBUG}
|
||||||
};
|
};
|
||||||
uint32_t cmd=0;
|
u32 cmd=0;
|
||||||
std::string filename;
|
std::string filename;
|
||||||
std::vector<std::string> vm_argv;
|
std::vector<std::string> vm_argv;
|
||||||
for(int i=1;i<argc;++i)
|
for(int i=1;i<argc;++i)
|
||||||
|
|
32
nasal.h
32
nasal.h
|
@ -40,11 +40,21 @@
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const uint32_t STACK_DEPTH=2048;
|
using i32=std::int32_t;
|
||||||
|
using i64=std::int64_t;
|
||||||
|
using u8 =std::uint8_t;
|
||||||
|
using u16=std::uint16_t;
|
||||||
|
using u32=std::uint32_t;
|
||||||
|
using u64=std::uint64_t;
|
||||||
|
using usize=std::size_t;
|
||||||
|
using f64=double;
|
||||||
|
|
||||||
inline double hex_to_double(const char* str)
|
|
||||||
|
const u32 STACK_DEPTH=2048;
|
||||||
|
|
||||||
|
inline f64 hex_to_double(const char* str)
|
||||||
{
|
{
|
||||||
double ret=0;
|
f64 ret=0;
|
||||||
for(;*str;++str)
|
for(;*str;++str)
|
||||||
{
|
{
|
||||||
ret*=16;
|
ret*=16;
|
||||||
|
@ -59,9 +69,9 @@ inline double hex_to_double(const char* str)
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
inline double oct_to_double(const char* str)
|
inline f64 oct_to_double(const char* str)
|
||||||
{
|
{
|
||||||
double ret=0;
|
f64 ret=0;
|
||||||
for(;*str;++str)
|
for(;*str;++str)
|
||||||
{
|
{
|
||||||
ret*=8;
|
ret*=8;
|
||||||
|
@ -72,9 +82,9 @@ inline double oct_to_double(const char* str)
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
inline double dec_to_double(const char* str)
|
inline f64 dec_to_double(const char* str)
|
||||||
{
|
{
|
||||||
double ret=0,negative=1,num_pow=0;
|
f64 ret=0,negative=1,num_pow=0;
|
||||||
while('0'<=*str && *str<='9')
|
while('0'<=*str && *str<='9')
|
||||||
ret=ret*10+(*str++-'0');
|
ret=ret*10+(*str++-'0');
|
||||||
if(!*str) return ret;
|
if(!*str) return ret;
|
||||||
|
@ -105,10 +115,10 @@ inline double dec_to_double(const char* str)
|
||||||
}
|
}
|
||||||
return ret*std::pow(10,negative*num_pow);
|
return ret*std::pow(10,negative*num_pow);
|
||||||
}
|
}
|
||||||
double str2num(const char* str)
|
f64 str2num(const char* str)
|
||||||
{
|
{
|
||||||
bool negative=false;
|
bool negative=false;
|
||||||
double res=0;
|
f64 res=0;
|
||||||
if(*str=='-' || *str=='+')
|
if(*str=='-' || *str=='+')
|
||||||
negative=(*str++=='-');
|
negative=(*str++=='-');
|
||||||
if(!*str)
|
if(!*str)
|
||||||
|
@ -125,7 +135,7 @@ double str2num(const char* str)
|
||||||
int utf8_hdchk(const char head)
|
int utf8_hdchk(const char head)
|
||||||
{
|
{
|
||||||
// RFC-2279 but now we use RFC-3629 so nbytes is less than 4
|
// RFC-2279 but now we use RFC-3629 so nbytes is less than 4
|
||||||
const uint8_t c=(uint8_t)head;
|
const u8 c=(u8)head;
|
||||||
if((c>>5)==0x06) // 110x xxxx (10xx xxxx)^1
|
if((c>>5)==0x06) // 110x xxxx (10xx xxxx)^1
|
||||||
return 1;
|
return 1;
|
||||||
if((c>>4)==0x0e) // 1110 xxxx (10xx xxxx)^2
|
if((c>>4)==0x0e) // 1110 xxxx (10xx xxxx)^2
|
||||||
|
@ -140,7 +150,7 @@ std::string chrhex(const char c)
|
||||||
return {"0123456789abcdef"[(c&0xf0)>>4],"0123456789abcdef"[c&0x0f]};
|
return {"0123456789abcdef"[(c&0xf0)>>4],"0123456789abcdef"[c&0x0f]};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string rawstr(const std::string& str,const size_t maxlen=0)
|
std::string rawstr(const std::string& str,const usize maxlen=0)
|
||||||
{
|
{
|
||||||
std::string ret("");
|
std::string ret("");
|
||||||
for(auto i:str)
|
for(auto i:str)
|
||||||
|
|
24
nasal_ast.h
24
nasal_ast.h
|
@ -129,13 +129,13 @@ const char* ast_name[]=
|
||||||
class nasal_ast
|
class nasal_ast
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
uint32_t _line;
|
u32 _line;
|
||||||
uint32_t _type;
|
u32 _type;
|
||||||
double _num;
|
f64 _num;
|
||||||
std::string _str;
|
std::string _str;
|
||||||
std::vector<nasal_ast> _child;
|
std::vector<nasal_ast> _child;
|
||||||
public:
|
public:
|
||||||
nasal_ast(const uint32_t l=0,const uint32_t t=ast_null):_line(l),_type(t),_num(0){}
|
nasal_ast(const u32 l=0,const u32 t=ast_null):_line(l),_type(t),_num(0){}
|
||||||
nasal_ast(const nasal_ast&);
|
nasal_ast(const nasal_ast&);
|
||||||
nasal_ast(nasal_ast&&);
|
nasal_ast(nasal_ast&&);
|
||||||
void print(int,bool);
|
void print(int,bool);
|
||||||
|
@ -145,18 +145,18 @@ public:
|
||||||
nasal_ast& operator=(nasal_ast&&);
|
nasal_ast& operator=(nasal_ast&&);
|
||||||
nasal_ast& operator[](const int index){return _child[index];}
|
nasal_ast& operator[](const int index){return _child[index];}
|
||||||
const nasal_ast& operator[](const int index) const {return _child[index];}
|
const nasal_ast& operator[](const int index) const {return _child[index];}
|
||||||
size_t size() const {return _child.size();}
|
usize size() const {return _child.size();}
|
||||||
|
|
||||||
void add(nasal_ast&& ast){_child.push_back(std::move(ast));}
|
void add(nasal_ast&& ast){_child.push_back(std::move(ast));}
|
||||||
void add(const nasal_ast& ast){_child.push_back(ast);}
|
void add(const nasal_ast& ast){_child.push_back(ast);}
|
||||||
void set_line(const uint32_t l){_line=l;}
|
void set_line(const u32 l){_line=l;}
|
||||||
void set_type(const uint32_t t){_type=t;}
|
void set_type(const u32 t){_type=t;}
|
||||||
void set_str(const std::string& s){_str=s;}
|
void set_str(const std::string& s){_str=s;}
|
||||||
void set_num(const double n){_num=n;}
|
void set_num(const f64 n){_num=n;}
|
||||||
|
|
||||||
inline uint32_t line() const {return _line;}
|
inline u32 line() const {return _line;}
|
||||||
inline uint32_t type() const {return _type;}
|
inline u32 type() const {return _type;}
|
||||||
inline double num() const {return _num;}
|
inline f64 num() const {return _num;}
|
||||||
inline const std::string& str() const {return _str;}
|
inline const std::string& str() const {return _str;}
|
||||||
inline const std::vector<nasal_ast>& child() const {return _child;}
|
inline const std::vector<nasal_ast>& child() const {return _child;}
|
||||||
inline std::vector<nasal_ast>& child(){return _child;}
|
inline std::vector<nasal_ast>& child(){return _child;}
|
||||||
|
@ -232,7 +232,7 @@ void nasal_ast::print(int depth,bool last=false)
|
||||||
#else
|
#else
|
||||||
intentation.back()="│ ";
|
intentation.back()="│ ";
|
||||||
#endif
|
#endif
|
||||||
for(uint32_t i=0;i<_child.size();++i)
|
for(u32 i=0;i<_child.size();++i)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
intentation.push_back(i==_child.size()-1?"`-":"|-");
|
intentation.push_back(i==_child.size()-1?"`-":"|-");
|
||||||
|
|
186
nasal_builtin.h
186
nasal_builtin.h
|
@ -262,7 +262,7 @@ nasal_ref builtin_setsize(nasal_ref* local,nasal_gc& gc)
|
||||||
return builtin_err("setsize","\"vector\" must be vector");
|
return builtin_err("setsize","\"vector\" must be vector");
|
||||||
if(size.type!=vm_num)
|
if(size.type!=vm_num)
|
||||||
return builtin_err("setsize","\"size\" is not a number");
|
return builtin_err("setsize","\"size\" is not a number");
|
||||||
int64_t num=(int64_t)size.num();
|
i64 num=(i64)size.num();
|
||||||
if(num<0)
|
if(num<0)
|
||||||
return builtin_err("setsize","\"size\" must be greater than -1");
|
return builtin_err("setsize","\"size\" must be greater than -1");
|
||||||
vec.vec().elems.resize(num,nil);
|
vec.vec().elems.resize(num,nil);
|
||||||
|
@ -273,7 +273,7 @@ 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,(f64)system(str.str().c_str())};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_input(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_input(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
|
@ -331,8 +331,8 @@ nasal_ref builtin_split(nasal_ref* local,nasal_gc& gc)
|
||||||
gc.temp=nil;
|
gc.temp=nil;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
size_t last=0;
|
usize last=0;
|
||||||
size_t pos=s.find(deli,last);
|
usize pos=s.find(deli,last);
|
||||||
while(pos!=std::string::npos)
|
while(pos!=std::string::npos)
|
||||||
{
|
{
|
||||||
if(pos>last)
|
if(pos>last)
|
||||||
|
@ -355,7 +355,7 @@ nasal_ref builtin_rand(nasal_ref* local,nasal_gc& gc)
|
||||||
srand((unsigned int)val.num());
|
srand((unsigned int)val.num());
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
double num=0;
|
f64 num=0;
|
||||||
for(int i=0;i<5;++i)
|
for(int i=0;i<5;++i)
|
||||||
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};
|
||||||
|
@ -365,7 +365,7 @@ nasal_ref builtin_id(nasal_ref* local,nasal_gc& gc)
|
||||||
nasal_ref val=local[1];
|
nasal_ref val=local[1];
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
if(val.type>vm_num)
|
if(val.type>vm_num)
|
||||||
ss<<"0x"<<std::hex<<(uint64_t)val.val.gcobj<<std::dec;
|
ss<<"0x"<<std::hex<<(u64)val.val.gcobj<<std::dec;
|
||||||
else
|
else
|
||||||
ss<<"0";
|
ss<<"0";
|
||||||
return gc.newstr(ss.str());
|
return gc.newstr(ss.str());
|
||||||
|
@ -376,7 +376,7 @@ nasal_ref builtin_int(nasal_ref* local,nasal_gc& gc)
|
||||||
if(val.type!=vm_num)
|
if(val.type!=vm_num)
|
||||||
return nil;
|
return nil;
|
||||||
int number=(int)val.num();
|
int number=(int)val.num();
|
||||||
return {vm_num,(double)number};
|
return {vm_num,(f64)number};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_floor(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_floor(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
|
@ -390,7 +390,7 @@ nasal_ref builtin_num(nasal_ref* local,nasal_gc& gc)
|
||||||
return val;
|
return val;
|
||||||
if(val.type!=vm_str)
|
if(val.type!=vm_str)
|
||||||
return nil;
|
return nil;
|
||||||
double res=val.tonum();
|
f64 res=val.tonum();
|
||||||
if(std::isnan(res))
|
if(std::isnan(res))
|
||||||
return nil;
|
return nil;
|
||||||
return {vm_num,res};
|
return {vm_num,res};
|
||||||
|
@ -422,7 +422,7 @@ nasal_ref builtin_str(nasal_ref* local,nasal_gc& gc)
|
||||||
nasal_ref builtin_size(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=0;
|
f64 num=0;
|
||||||
switch(val.type)
|
switch(val.type)
|
||||||
{
|
{
|
||||||
case vm_num: num=val.num(); break;
|
case vm_num: num=val.num(); break;
|
||||||
|
@ -436,59 +436,59 @@ nasal_ref builtin_i32xor(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
int a=(int)local[1].num();
|
int a=(int)local[1].num();
|
||||||
int b=(int)local[2].num();
|
int b=(int)local[2].num();
|
||||||
return {vm_num,(double)(a^b)};
|
return {vm_num,(f64)(a^b)};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_i32and(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_i32and(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
int a=(int)local[1].num();
|
int a=(int)local[1].num();
|
||||||
int b=(int)local[2].num();
|
int b=(int)local[2].num();
|
||||||
return {vm_num,(double)(a&b)};
|
return {vm_num,(f64)(a&b)};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_i32or(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_i32or(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
int a=(int)local[1].num();
|
int a=(int)local[1].num();
|
||||||
int b=(int)local[2].num();
|
int b=(int)local[2].num();
|
||||||
return {vm_num,(double)(a|b)};
|
return {vm_num,(f64)(a|b)};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_i32nand(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_i32nand(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
int a=(int)local[1].num();
|
int a=(int)local[1].num();
|
||||||
int b=(int)local[2].num();
|
int b=(int)local[2].num();
|
||||||
return {vm_num,(double)(~(a&b))};
|
return {vm_num,(f64)(~(a&b))};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_i32not(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_i32not(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
int n=(int)local[1].num();
|
int n=(int)local[1].num();
|
||||||
return {vm_num,(double)(~n)};
|
return {vm_num,(f64)(~n)};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_u32xor(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_u32xor(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
uint32_t a=(uint32_t)local[1].num();
|
u32 a=(u32)local[1].num();
|
||||||
uint32_t b=(uint32_t)local[2].num();
|
u32 b=(u32)local[2].num();
|
||||||
return {vm_num,(double)(a^b)};
|
return {vm_num,(f64)(a^b)};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_u32and(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_u32and(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
uint32_t a=(uint32_t)local[1].num();
|
u32 a=(u32)local[1].num();
|
||||||
uint32_t b=(uint32_t)local[2].num();
|
u32 b=(u32)local[2].num();
|
||||||
return {vm_num,(double)(a&b)};
|
return {vm_num,(f64)(a&b)};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_u32or(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_u32or(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
uint32_t a=(uint32_t)local[1].num();
|
u32 a=(u32)local[1].num();
|
||||||
uint32_t b=(uint32_t)local[2].num();
|
u32 b=(u32)local[2].num();
|
||||||
return {vm_num,(double)(a|b)};
|
return {vm_num,(f64)(a|b)};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_u32nand(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_u32nand(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
uint32_t a=(uint32_t)local[1].num();
|
u32 a=(u32)local[1].num();
|
||||||
uint32_t b=(uint32_t)local[2].num();
|
u32 b=(u32)local[2].num();
|
||||||
return {vm_num,(double)(~(a&b))};
|
return {vm_num,(f64)(~(a&b))};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_u32not(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_u32not(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
uint32_t n=(uint32_t)local[1].num();
|
u32 n=(u32)local[1].num();
|
||||||
return {vm_num,(double)(~n)};
|
return {vm_num,(f64)(~n)};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_pow(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_pow(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
|
@ -568,7 +568,7 @@ nasal_ref builtin_time(nasal_ref* local,nasal_gc& gc)
|
||||||
if(val.type!=vm_num)
|
if(val.type!=vm_num)
|
||||||
return builtin_err("time","\"begin_time\" must be number");
|
return builtin_err("time","\"begin_time\" must be number");
|
||||||
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,(f64)time(&begin_time)};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_contains(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_contains(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
|
@ -621,10 +621,10 @@ nasal_ref builtin_find(nasal_ref* local,nasal_gc& gc)
|
||||||
return builtin_err("find","\"needle\" must be string");
|
return builtin_err("find","\"needle\" must be string");
|
||||||
if(haystack.type!=vm_str)
|
if(haystack.type!=vm_str)
|
||||||
return builtin_err("find","\"haystack\" must be string");
|
return builtin_err("find","\"haystack\" must be string");
|
||||||
size_t pos=haystack.str().find(needle.str());
|
usize pos=haystack.str().find(needle.str());
|
||||||
if(pos==std::string::npos)
|
if(pos==std::string::npos)
|
||||||
return {vm_num,(double)-1};
|
return {vm_num,(f64)-1};
|
||||||
return {vm_num,(double)pos};
|
return {vm_num,(f64)pos};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_type(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_type(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
|
@ -657,8 +657,8 @@ nasal_ref builtin_substr(nasal_ref* local,nasal_gc& gc)
|
||||||
return builtin_err("substr","\"begin\" should be greater than or equal to zero");
|
return builtin_err("substr","\"begin\" should be greater than or equal to zero");
|
||||||
if(len.num()<0)
|
if(len.num()<0)
|
||||||
return builtin_err("substr","\"length\" should be greater than or equal to zero");
|
return builtin_err("substr","\"length\" should be greater than or equal to zero");
|
||||||
size_t begin=(size_t)beg.num();
|
usize begin=(usize)beg.num();
|
||||||
size_t length=(size_t)len.num();
|
usize length=(usize)len.num();
|
||||||
if(begin>=str.str().length() || begin+length>str.str().length())
|
if(begin>=str.str().length() || begin+length>str.str().length())
|
||||||
return builtin_err("susbtr","index out of range");
|
return builtin_err("susbtr","index out of range");
|
||||||
return gc.newstr(str.str().substr(begin,length));
|
return gc.newstr(str.str().substr(begin,length));
|
||||||
|
@ -667,7 +667,7 @@ 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,f64((a.type!=vm_str || b.type!=vm_str)?0:(a.str()==b.str()))};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_left(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_left(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
|
@ -706,7 +706,7 @@ nasal_ref builtin_cmp(nasal_ref* local,nasal_gc& gc)
|
||||||
return builtin_err("cmp","\"a\" must be string");
|
return builtin_err("cmp","\"a\" must be string");
|
||||||
if(b.type!=vm_str)
|
if(b.type!=vm_str)
|
||||||
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,(f64)strcmp(a.str().c_str(),b.str().c_str())};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_chr(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_chr(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
|
@ -792,10 +792,10 @@ nasal_ref builtin_read(nasal_ref* local,nasal_gc& gc)
|
||||||
return builtin_err("read","\"len\" must be number");
|
return builtin_err("read","\"len\" must be number");
|
||||||
if(len.num()<=0 || len.num()>=(1<<30))
|
if(len.num()<=0 || len.num()>=(1<<30))
|
||||||
return builtin_err("read","\"len\" less than 1 or too large");
|
return builtin_err("read","\"len\" less than 1 or too large");
|
||||||
char* buff=new char[(size_t)len.num()+1];
|
char* buff=new char[(usize)len.num()+1];
|
||||||
if(!buff)
|
if(!buff)
|
||||||
return builtin_err("read","memory allocation error");
|
return builtin_err("read","memory allocation error");
|
||||||
double res=fread(buff,1,len.num(),(FILE*)fd.obj().ptr);
|
f64 res=fread(buff,1,len.num(),(FILE*)fd.obj().ptr);
|
||||||
buf.str()=buff;
|
buf.str()=buff;
|
||||||
delete []buff;
|
delete []buff;
|
||||||
return {vm_num,res};
|
return {vm_num,res};
|
||||||
|
@ -808,7 +808,7 @@ nasal_ref builtin_write(nasal_ref* local,nasal_gc& gc)
|
||||||
return builtin_err("write","not a valid filehandle");
|
return builtin_err("write","not a valid filehandle");
|
||||||
if(str.type!=vm_str)
|
if(str.type!=vm_str)
|
||||||
return builtin_err("write","\"str\" must be string");
|
return builtin_err("write","\"str\" must be string");
|
||||||
double res=(double)fwrite(str.str().c_str(),1,str.str().length(),(FILE*)fd.obj().ptr);
|
f64 res=(f64)fwrite(str.str().c_str(),1,str.str().length(),(FILE*)fd.obj().ptr);
|
||||||
return {vm_num,res};
|
return {vm_num,res};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_seek(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_seek(nasal_ref* local,nasal_gc& gc)
|
||||||
|
@ -822,7 +822,7 @@ nasal_ref builtin_seek(nasal_ref* local,nasal_gc& gc)
|
||||||
return builtin_err("seek","\"pos\" must be number");
|
return builtin_err("seek","\"pos\" must be number");
|
||||||
if(whence.type!=vm_num || whence.num()<0 || whence.num()>2)
|
if(whence.type!=vm_num || whence.num()<0 || whence.num()>2)
|
||||||
return builtin_err("seek","\"whence\" must be number between 0 and 2");
|
return builtin_err("seek","\"whence\" must be number between 0 and 2");
|
||||||
double res=fseek((FILE*)fd.obj().ptr,pos.num(),whence.num());
|
f64 res=fseek((FILE*)fd.obj().ptr,pos.num(),whence.num());
|
||||||
return {vm_num,res};
|
return {vm_num,res};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_tell(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_tell(nasal_ref* local,nasal_gc& gc)
|
||||||
|
@ -830,7 +830,7 @@ nasal_ref builtin_tell(nasal_ref* local,nasal_gc& gc)
|
||||||
nasal_ref fd=local[1];
|
nasal_ref fd=local[1];
|
||||||
if(!fd.objchk(nasal_obj::file))
|
if(!fd.objchk(nasal_obj::file))
|
||||||
return builtin_err("tell","not a valid filehandle");
|
return builtin_err("tell","not a valid filehandle");
|
||||||
double res=ftell((FILE*)fd.obj().ptr);
|
f64 res=ftell((FILE*)fd.obj().ptr);
|
||||||
return {vm_num,res};
|
return {vm_num,res};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_readln(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_readln(nasal_ref* local,nasal_gc& gc)
|
||||||
|
@ -863,17 +863,17 @@ nasal_ref builtin_stat(nasal_ref* local,nasal_gc& gc)
|
||||||
return builtin_err("stat","failed to open file <"+name.str()+">");
|
return builtin_err("stat","failed to open file <"+name.str()+">");
|
||||||
nasal_ref ret=gc.alloc(vm_vec);
|
nasal_ref ret=gc.alloc(vm_vec);
|
||||||
ret.vec().elems={
|
ret.vec().elems={
|
||||||
{vm_num,(double)buf.st_dev},
|
{vm_num,(f64)buf.st_dev},
|
||||||
{vm_num,(double)buf.st_ino},
|
{vm_num,(f64)buf.st_ino},
|
||||||
{vm_num,(double)buf.st_mode},
|
{vm_num,(f64)buf.st_mode},
|
||||||
{vm_num,(double)buf.st_nlink},
|
{vm_num,(f64)buf.st_nlink},
|
||||||
{vm_num,(double)buf.st_uid},
|
{vm_num,(f64)buf.st_uid},
|
||||||
{vm_num,(double)buf.st_gid},
|
{vm_num,(f64)buf.st_gid},
|
||||||
{vm_num,(double)buf.st_rdev},
|
{vm_num,(f64)buf.st_rdev},
|
||||||
{vm_num,(double)buf.st_size},
|
{vm_num,(f64)buf.st_size},
|
||||||
{vm_num,(double)buf.st_atime},
|
{vm_num,(f64)buf.st_atime},
|
||||||
{vm_num,(double)buf.st_mtime},
|
{vm_num,(f64)buf.st_mtime},
|
||||||
{vm_num,(double)buf.st_ctime}
|
{vm_num,(f64)buf.st_ctime}
|
||||||
};
|
};
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -882,7 +882,7 @@ nasal_ref builtin_eof(nasal_ref* local,nasal_gc& gc)
|
||||||
nasal_ref fd=local[1];
|
nasal_ref fd=local[1];
|
||||||
if(!fd.objchk(nasal_obj::file))
|
if(!fd.objchk(nasal_obj::file))
|
||||||
return builtin_err("readln","not a valid filehandle");
|
return builtin_err("readln","not a valid filehandle");
|
||||||
return {vm_num,(double)feof((FILE*)fd.obj().ptr)};
|
return {vm_num,(f64)feof((FILE*)fd.obj().ptr)};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_fld(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_fld(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
|
@ -896,16 +896,16 @@ nasal_ref builtin_fld(nasal_ref* local,nasal_gc& gc)
|
||||||
return builtin_err("fld","\"str\" must be mutable string");
|
return builtin_err("fld","\"str\" must be mutable string");
|
||||||
if(startbit.type!=vm_num || length.type!=vm_num)
|
if(startbit.type!=vm_num || length.type!=vm_num)
|
||||||
return builtin_err("fld","\"startbit\",\"len\" must be number");
|
return builtin_err("fld","\"startbit\",\"len\" must be number");
|
||||||
uint32_t bit=(uint32_t)startbit.num();
|
u32 bit=(u32)startbit.num();
|
||||||
uint32_t len=(uint32_t)length.num();
|
u32 len=(u32)length.num();
|
||||||
if(bit+len>8*str.str().length())
|
if(bit+len>8*str.str().length())
|
||||||
return builtin_err("fld","bitfield out of bounds");
|
return builtin_err("fld","bitfield out of bounds");
|
||||||
uint32_t res=0;
|
u32 res=0;
|
||||||
auto& s=str.str();
|
auto& s=str.str();
|
||||||
for(uint32_t i=bit;i<bit+len;++i)
|
for(u32 i=bit;i<bit+len;++i)
|
||||||
if(s[i>>3]&(1<<(7-(i&7))))
|
if(s[i>>3]&(1<<(7-(i&7))))
|
||||||
res|=1<<(bit+len-i-1);
|
res|=1<<(bit+len-i-1);
|
||||||
return {vm_num,(double)res};
|
return {vm_num,(f64)res};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_sfld(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_sfld(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
|
@ -920,18 +920,18 @@ nasal_ref builtin_sfld(nasal_ref* local,nasal_gc& gc)
|
||||||
return builtin_err("sfld","\"str\" must be mutable string");
|
return builtin_err("sfld","\"str\" must be mutable string");
|
||||||
if(startbit.type!=vm_num || length.type!=vm_num)
|
if(startbit.type!=vm_num || length.type!=vm_num)
|
||||||
return builtin_err("sfld","\"startbit\",\"len\" must be number");
|
return builtin_err("sfld","\"startbit\",\"len\" must be number");
|
||||||
uint32_t bit=(uint32_t)startbit.num();
|
u32 bit=(u32)startbit.num();
|
||||||
uint32_t len=(uint32_t)length.num();
|
u32 len=(u32)length.num();
|
||||||
if(bit+len>8*str.str().length())
|
if(bit+len>8*str.str().length())
|
||||||
return builtin_err("sfld","bitfield out of bounds");
|
return builtin_err("sfld","bitfield out of bounds");
|
||||||
uint32_t res=0;
|
u32 res=0;
|
||||||
auto& s=str.str();
|
auto& s=str.str();
|
||||||
for(uint32_t i=bit;i<bit+len;++i)
|
for(u32 i=bit;i<bit+len;++i)
|
||||||
if(s[i>>3]&(1<<(7-(i&7))))
|
if(s[i>>3]&(1<<(7-(i&7))))
|
||||||
res|=1<<(bit+len-i-1);
|
res|=1<<(bit+len-i-1);
|
||||||
if(res&(1<<(len-1)))
|
if(res&(1<<(len-1)))
|
||||||
res|=~((1<<len)-1);
|
res|=~((1<<len)-1);
|
||||||
return {vm_num,(double)((int32_t)res)};
|
return {vm_num,(f64)((i32)res)};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_setfld(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_setfld(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
|
@ -947,13 +947,13 @@ nasal_ref builtin_setfld(nasal_ref* local,nasal_gc& gc)
|
||||||
return builtin_err("setfld","\"str\" must be mutable string");
|
return builtin_err("setfld","\"str\" must be mutable string");
|
||||||
if(startbit.type!=vm_num || length.type!=vm_num || value.type!=vm_num)
|
if(startbit.type!=vm_num || length.type!=vm_num || value.type!=vm_num)
|
||||||
return builtin_err("setfld","\"startbit\",\"len\",\"val\" must be number");
|
return builtin_err("setfld","\"startbit\",\"len\",\"val\" must be number");
|
||||||
uint32_t bit=(uint32_t)startbit.num();
|
u32 bit=(u32)startbit.num();
|
||||||
uint32_t len=(uint32_t)length.num();
|
u32 len=(u32)length.num();
|
||||||
uint64_t val=(uint64_t)value.num();
|
u64 val=(u64)value.num();
|
||||||
if(bit+len>8*str.str().length())
|
if(bit+len>8*str.str().length())
|
||||||
return builtin_err("setfld","bitfield out of bounds");
|
return builtin_err("setfld","bitfield out of bounds");
|
||||||
auto& s=str.str();
|
auto& s=str.str();
|
||||||
for(uint32_t i=bit;i<bit+len;++i)
|
for(u32 i=bit;i<bit+len;++i)
|
||||||
{
|
{
|
||||||
if(val&(1<<(i-bit)))
|
if(val&(1<<(i-bit)))
|
||||||
s[i>>3]|=(1<<(7-(i&7)));
|
s[i>>3]|=(1<<(7-(i&7)));
|
||||||
|
@ -977,7 +977,7 @@ 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)
|
||||||
return builtin_err("sleep","\"duration\" must be number");
|
return builtin_err("sleep","\"duration\" must be number");
|
||||||
std::this_thread::sleep_for(std::chrono::microseconds(int64_t(val.num()*1e6)));
|
std::this_thread::sleep_for(std::chrono::microseconds(i64(val.num()*1e6)));
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_pipe(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_pipe(nasal_ref* local,nasal_gc& gc)
|
||||||
|
@ -987,8 +987,8 @@ nasal_ref builtin_pipe(nasal_ref* local,nasal_gc& gc)
|
||||||
nasal_ref res=gc.alloc(vm_vec);
|
nasal_ref res=gc.alloc(vm_vec);
|
||||||
if(pipe(fd)==-1)
|
if(pipe(fd)==-1)
|
||||||
return builtin_err("pipe","failed to create pipe");
|
return builtin_err("pipe","failed to create pipe");
|
||||||
res.vec().elems.push_back({vm_num,(double)fd[0]});
|
res.vec().elems.push_back({vm_num,(f64)fd[0]});
|
||||||
res.vec().elems.push_back({vm_num,(double)fd[1]});
|
res.vec().elems.push_back({vm_num,(f64)fd[1]});
|
||||||
return res;
|
return res;
|
||||||
#endif
|
#endif
|
||||||
return builtin_err("pipe","not supported for windows");
|
return builtin_err("pipe","not supported for windows");
|
||||||
|
@ -996,10 +996,10 @@ nasal_ref builtin_pipe(nasal_ref* local,nasal_gc& gc)
|
||||||
nasal_ref builtin_fork(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_fork(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
double res=fork();
|
f64 res=fork();
|
||||||
if(res<0)
|
if(res<0)
|
||||||
return builtin_err("fork","failed to fork a process");
|
return builtin_err("fork","failed to fork a process");
|
||||||
return {vm_num,(double)res};
|
return {vm_num,(f64)res};
|
||||||
#endif
|
#endif
|
||||||
return builtin_err("fork","not supported for windows");
|
return builtin_err("fork","not supported for windows");
|
||||||
}
|
}
|
||||||
|
@ -1014,8 +1014,8 @@ nasal_ref builtin_waitpid(nasal_ref* local,nasal_gc& gc)
|
||||||
int status;
|
int status;
|
||||||
ret_pid=waitpid(pid.num(),&status,nohang.num()==0?0:WNOHANG);
|
ret_pid=waitpid(pid.num(),&status,nohang.num()==0?0:WNOHANG);
|
||||||
nasal_ref vec=gc.alloc(vm_vec);
|
nasal_ref vec=gc.alloc(vm_vec);
|
||||||
vec.vec().elems.push_back({vm_num,(double)ret_pid});
|
vec.vec().elems.push_back({vm_num,(f64)ret_pid});
|
||||||
vec.vec().elems.push_back({vm_num,(double)status});
|
vec.vec().elems.push_back({vm_num,(f64)status});
|
||||||
return vec;
|
return vec;
|
||||||
#endif
|
#endif
|
||||||
return builtin_err("waitpid","not supported for windows");
|
return builtin_err("waitpid","not supported for windows");
|
||||||
|
@ -1206,14 +1206,14 @@ nasal_ref builtin_gc(nasal_ref* local,nasal_gc& gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// md5 related functions
|
// md5 related functions
|
||||||
std::string tohex(uint32_t num)
|
std::string tohex(u32 num)
|
||||||
{
|
{
|
||||||
const char str16[]="0123456789abcdef";
|
const char str16[]="0123456789abcdef";
|
||||||
std::string str="";
|
std::string str="";
|
||||||
for(uint32_t i=0;i<4;i++,num>>=8)
|
for(u32 i=0;i<4;i++,num>>=8)
|
||||||
{
|
{
|
||||||
std::string tmp="";
|
std::string tmp="";
|
||||||
for(uint32_t j=0,b=num&0xff;j<2;j++,b>>=4)
|
for(u32 j=0,b=num&0xff;j<2;j++,b>>=4)
|
||||||
tmp.insert(0,1,str16[b&0xf]);
|
tmp.insert(0,1,str16[b&0xf]);
|
||||||
str+=tmp;
|
str+=tmp;
|
||||||
}
|
}
|
||||||
|
@ -1221,18 +1221,18 @@ std::string tohex(uint32_t num)
|
||||||
}
|
}
|
||||||
std::string md5(const std::string& source)
|
std::string md5(const std::string& source)
|
||||||
{
|
{
|
||||||
std::vector<uint32_t> buff;
|
std::vector<u32> buff;
|
||||||
uint32_t num=((source.length()+8)>>6)+1;
|
u32 num=((source.length()+8)>>6)+1;
|
||||||
uint32_t buffsize=num<<4;
|
u32 buffsize=num<<4;
|
||||||
buff.resize(buffsize,0);
|
buff.resize(buffsize,0);
|
||||||
for(uint32_t i=0;i<source.length();i++)
|
for(u32 i=0;i<source.length();i++)
|
||||||
buff[i>>2]|=((unsigned char)source[i])<<((i&0x3)<<3);
|
buff[i>>2]|=((unsigned char)source[i])<<((i&0x3)<<3);
|
||||||
buff[source.length()>>2]|=0x80<<(((source.length()%4))<<3);
|
buff[source.length()>>2]|=0x80<<(((source.length()%4))<<3);
|
||||||
buff[buffsize-2]=(source.length()<<3)&0xffffffff;
|
buff[buffsize-2]=(source.length()<<3)&0xffffffff;
|
||||||
buff[buffsize-1]=((source.length()<<3)>>32)&0xffffffff;
|
buff[buffsize-1]=((source.length()<<3)>>32)&0xffffffff;
|
||||||
|
|
||||||
// uint32_t(abs(sin(i+1))*(2pow32))
|
// u32(abs(sin(i+1))*(2pow32))
|
||||||
const uint32_t k[]={
|
const u32 k[]={
|
||||||
0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,
|
0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,
|
||||||
0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be,0x6b901122,0xfd987193,0xa679438e,0x49b40821,
|
0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be,0x6b901122,0xfd987193,0xa679438e,0x49b40821,
|
||||||
0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa,0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,
|
0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa,0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,
|
||||||
|
@ -1244,7 +1244,7 @@ std::string md5(const std::string& source)
|
||||||
};
|
};
|
||||||
|
|
||||||
// left shift bits
|
// left shift bits
|
||||||
const uint32_t s[]={
|
const u32 s[]={
|
||||||
7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
|
7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
|
||||||
5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
|
5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
|
||||||
4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,
|
4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,
|
||||||
|
@ -1252,7 +1252,7 @@ std::string md5(const std::string& source)
|
||||||
};
|
};
|
||||||
|
|
||||||
// index
|
// index
|
||||||
const uint32_t idx[]={
|
const u32 idx[]={
|
||||||
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, // g=i
|
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, // g=i
|
||||||
1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12, // g=(5*i+1)%16;
|
1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12, // g=(5*i+1)%16;
|
||||||
5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2, // g=(3*i+5)%16;
|
5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2, // g=(3*i+5)%16;
|
||||||
|
@ -1265,18 +1265,18 @@ std::string md5(const std::string& source)
|
||||||
#define md5h(x,y,z) ((x)^(y)^(z))
|
#define md5h(x,y,z) ((x)^(y)^(z))
|
||||||
#define md5i(x,y,z) ((y)^((x)|(~z)))
|
#define md5i(x,y,z) ((y)^((x)|(~z)))
|
||||||
|
|
||||||
uint32_t atmp=0x67452301,btmp=0xefcdab89;
|
u32 atmp=0x67452301,btmp=0xefcdab89;
|
||||||
uint32_t ctmp=0x98badcfe,dtmp=0x10325476;
|
u32 ctmp=0x98badcfe,dtmp=0x10325476;
|
||||||
for(uint32_t i=0;i<buffsize;i+=16)
|
for(u32 i=0;i<buffsize;i+=16)
|
||||||
{
|
{
|
||||||
uint32_t f,a=atmp,b=btmp,c=ctmp,d=dtmp;
|
u32 f,a=atmp,b=btmp,c=ctmp,d=dtmp;
|
||||||
for(uint32_t j=0;j<64;j++)
|
for(u32 j=0;j<64;j++)
|
||||||
{
|
{
|
||||||
if(j<16) f=md5f(b,c,d);
|
if(j<16) f=md5f(b,c,d);
|
||||||
else if(j<32) f=md5g(b,c,d);
|
else if(j<32) f=md5g(b,c,d);
|
||||||
else if(j<48) f=md5h(b,c,d);
|
else if(j<48) f=md5h(b,c,d);
|
||||||
else f=md5i(b,c,d);
|
else f=md5i(b,c,d);
|
||||||
uint32_t tmp=d;
|
u32 tmp=d;
|
||||||
d=c;
|
d=c;
|
||||||
c=b;
|
c=b;
|
||||||
b=b+shift((a+f+k[j]+buff[i+idx[j]]),s[j]);
|
b=b+shift((a+f+k[j]+buff[i+idx[j]]),s[j]);
|
||||||
|
@ -1328,7 +1328,7 @@ nasal_ref builtin_cocreate(nasal_ref* local,nasal_gc& gc)
|
||||||
coroutine.top++;
|
coroutine.top++;
|
||||||
coroutine.top[0]={vm_addr,(nasal_ref*)nullptr}; // old localr
|
coroutine.top[0]={vm_addr,(nasal_ref*)nullptr}; // old localr
|
||||||
coroutine.top++;
|
coroutine.top++;
|
||||||
coroutine.top[0]={vm_ret,(uint32_t)0}; // old pc, set to zero to make op_ret recognizing this as coroutine function
|
coroutine.top[0]={vm_ret,(u32)0}; // old pc, set to zero to make op_ret recognizing this as coroutine function
|
||||||
|
|
||||||
coroutine.funcr=func; // make sure the coroutine function can use correct upvalues
|
coroutine.funcr=func; // make sure the coroutine function can use correct upvalues
|
||||||
coroutine.status=nasal_co::suspended;
|
coroutine.status=nasal_co::suspended;
|
||||||
|
@ -1377,7 +1377,7 @@ nasal_ref builtin_corun(nasal_ref* local,nasal_gc& gc)
|
||||||
}
|
}
|
||||||
nasal_ref builtin_millisec(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_millisec(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
double res=std::chrono::duration_cast<std::chrono::milliseconds>
|
f64 res=std::chrono::duration_cast<std::chrono::milliseconds>
|
||||||
(std::chrono::high_resolution_clock::now().time_since_epoch())
|
(std::chrono::high_resolution_clock::now().time_since_epoch())
|
||||||
.count();
|
.count();
|
||||||
return {vm_num,res};
|
return {vm_num,res};
|
||||||
|
|
|
@ -166,11 +166,11 @@ struct
|
||||||
|
|
||||||
struct opcode
|
struct opcode
|
||||||
{
|
{
|
||||||
uint8_t op; // opcode
|
u8 op; // opcode
|
||||||
uint16_t fidx;// source code file index
|
u16 fidx;// source code file index
|
||||||
uint32_t num; // imm num
|
u32 num; // imm num
|
||||||
uint32_t line;// line of source code
|
u32 line;// line of source code
|
||||||
opcode(uint8_t o=op_exit,uint16_t f=0,uint32_t n=0,uint32_t l=0):
|
opcode(u8 o=op_exit,u16 f=0,u32 n=0,u32 l=0):
|
||||||
op(o),fidx(f),num(n),line(l){}
|
op(o),fidx(f),num(n),line(l){}
|
||||||
opcode& operator=(const opcode& tmp)
|
opcode& operator=(const opcode& tmp)
|
||||||
{
|
{
|
||||||
|
@ -181,20 +181,20 @@ struct opcode
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
void print(const char*,
|
void print(const char*,
|
||||||
const double*,
|
const f64*,
|
||||||
const std::string*,
|
const std::string*,
|
||||||
const uint32_t,bool) const;
|
const u32,bool) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
void opcode::print(const char* header,
|
void opcode::print(const char* header,
|
||||||
const double* constnum,
|
const f64* constnum,
|
||||||
const std::string* conststr,
|
const std::string* conststr,
|
||||||
const uint32_t index,
|
const u32 index,
|
||||||
bool deftnum=false) const
|
bool deftnum=false) const
|
||||||
{
|
{
|
||||||
std::cout<<header<<std::hex<<"0x"
|
std::cout<<header<<std::hex<<"0x"
|
||||||
<<std::setw(8)<<std::setfill('0')<<index<<": "
|
<<std::setw(8)<<std::setfill('0')<<index<<": "
|
||||||
<<std::setw(2)<<std::setfill('0')<<(uint32_t)op<<" "
|
<<std::setw(2)<<std::setfill('0')<<(u32)op<<" "
|
||||||
<<std::setw(2)<<std::setfill('0')<<((num>>24)&0xff)<<" "
|
<<std::setw(2)<<std::setfill('0')<<((num>>24)&0xff)<<" "
|
||||||
<<std::setw(2)<<std::setfill('0')<<((num>>16)&0xff)<<" "
|
<<std::setw(2)<<std::setfill('0')<<((num>>16)&0xff)<<" "
|
||||||
<<std::setw(2)<<std::setfill('0')<<((num>>8)&0xff)<<" "
|
<<std::setw(2)<<std::setfill('0')<<((num>>8)&0xff)<<" "
|
||||||
|
@ -244,13 +244,13 @@ void opcode::print(const char* header,
|
||||||
class nasal_codegen
|
class nasal_codegen
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
uint16_t fileindex;
|
u16 fileindex;
|
||||||
nasal_err& nerr;
|
nasal_err& nerr;
|
||||||
const std::string* file;
|
const std::string* file;
|
||||||
std::stack<uint32_t> in_iterloop;
|
std::stack<u32> in_iterloop;
|
||||||
std::unordered_map<double,uint32_t> num_table;
|
std::unordered_map<f64,u32> num_table;
|
||||||
std::unordered_map<std::string,uint32_t> str_table;
|
std::unordered_map<std::string,u32> str_table;
|
||||||
std::vector<double> num_res;
|
std::vector<f64> num_res;
|
||||||
std::vector<std::string> str_res;
|
std::vector<std::string> str_res;
|
||||||
std::vector<opcode> code;
|
std::vector<opcode> code;
|
||||||
std::list<std::vector<int>> continue_ptr;
|
std::list<std::vector<int>> continue_ptr;
|
||||||
|
@ -261,18 +261,18 @@ private:
|
||||||
std::list<std::unordered_map<std::string,int>> local;
|
std::list<std::unordered_map<std::string,int>> local;
|
||||||
|
|
||||||
// func end stack, reserved for code print
|
// func end stack, reserved for code print
|
||||||
std::stack<uint32_t> fbstk;
|
std::stack<u32> fbstk;
|
||||||
std::stack<uint32_t> festk;
|
std::stack<u32> festk;
|
||||||
|
|
||||||
void die(const std::string&,const uint32_t);
|
void die(const std::string&,const u32);
|
||||||
void regist_num(const double);
|
void regist_num(const f64);
|
||||||
void regist_str(const std::string&);
|
void regist_str(const std::string&);
|
||||||
void find_symbol(const nasal_ast&);
|
void find_symbol(const nasal_ast&);
|
||||||
void add_sym(const std::string&);
|
void add_sym(const std::string&);
|
||||||
int local_find(const std::string&);
|
int local_find(const std::string&);
|
||||||
int global_find(const std::string&);
|
int global_find(const std::string&);
|
||||||
int upvalue_find(const std::string&);
|
int upvalue_find(const std::string&);
|
||||||
void gen(uint8_t,uint32_t,uint32_t);
|
void gen(u8,u32,u32);
|
||||||
void num_gen(const nasal_ast&);
|
void num_gen(const nasal_ast&);
|
||||||
void str_gen(const nasal_ast&);
|
void str_gen(const nasal_ast&);
|
||||||
void vec_gen(const nasal_ast&);
|
void vec_gen(const nasal_ast&);
|
||||||
|
@ -305,27 +305,27 @@ private:
|
||||||
void block_gen(const nasal_ast&);
|
void block_gen(const nasal_ast&);
|
||||||
void ret_gen(const nasal_ast&);
|
void ret_gen(const nasal_ast&);
|
||||||
|
|
||||||
void singleop(const uint32_t);
|
void singleop(const u32);
|
||||||
public:
|
public:
|
||||||
nasal_codegen(nasal_err& e):fileindex(0),nerr(e),file(nullptr){}
|
nasal_codegen(nasal_err& e):fileindex(0),nerr(e),file(nullptr){}
|
||||||
void compile(const nasal_parse&,const nasal_import&);
|
void compile(const nasal_parse&,const nasal_import&);
|
||||||
void print();
|
void print();
|
||||||
const std::vector<std::string>& strs() const {return str_res;}
|
const std::vector<std::string>& strs() const {return str_res;}
|
||||||
const std::vector<double>& nums() const {return num_res;}
|
const std::vector<f64>& nums() const {return num_res;}
|
||||||
const std::vector<opcode>& codes() const {return code;}
|
const std::vector<opcode>& codes() const {return code;}
|
||||||
};
|
};
|
||||||
|
|
||||||
void nasal_codegen::die(const std::string& info,const uint32_t line)
|
void nasal_codegen::die(const std::string& info,const u32 line)
|
||||||
{
|
{
|
||||||
nerr.load(file[fileindex]);
|
nerr.load(file[fileindex]);
|
||||||
nerr.err("code",line,info);
|
nerr.err("code",line,info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nasal_codegen::regist_num(const double num)
|
void nasal_codegen::regist_num(const f64 num)
|
||||||
{
|
{
|
||||||
if(!num_table.count(num))
|
if(!num_table.count(num))
|
||||||
{
|
{
|
||||||
uint32_t size=num_table.size();
|
u32 size=num_table.size();
|
||||||
num_table[num]=size;
|
num_table[num]=size;
|
||||||
num_res.push_back(num);
|
num_res.push_back(num);
|
||||||
}
|
}
|
||||||
|
@ -335,7 +335,7 @@ void nasal_codegen::regist_str(const std::string& str)
|
||||||
{
|
{
|
||||||
if(!str_table.count(str))
|
if(!str_table.count(str))
|
||||||
{
|
{
|
||||||
uint32_t size=str_table.size();
|
u32 size=str_table.size();
|
||||||
str_table[str]=size;
|
str_table[str]=size;
|
||||||
str_res.push_back(str);
|
str_res.push_back(str);
|
||||||
}
|
}
|
||||||
|
@ -398,24 +398,24 @@ int nasal_codegen::upvalue_find(const std::string& name)
|
||||||
{
|
{
|
||||||
// 32768 level 65536 upvalues
|
// 32768 level 65536 upvalues
|
||||||
int index=-1;
|
int index=-1;
|
||||||
size_t size=local.size();
|
usize size=local.size();
|
||||||
if(size<=1)
|
if(size<=1)
|
||||||
return -1;
|
return -1;
|
||||||
auto iter=local.begin();
|
auto iter=local.begin();
|
||||||
for(uint32_t i=0;i<size-1;++i,++iter)
|
for(u32 i=0;i<size-1;++i,++iter)
|
||||||
if(iter->count(name))
|
if(iter->count(name))
|
||||||
index=((i<<16)|(*iter)[name]);
|
index=((i<<16)|(*iter)[name]);
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nasal_codegen::gen(uint8_t op,uint32_t num,uint32_t line)
|
void nasal_codegen::gen(u8 op,u32 num,u32 line)
|
||||||
{
|
{
|
||||||
code.push_back({op,fileindex,num,line});
|
code.push_back({op,fileindex,num,line});
|
||||||
}
|
}
|
||||||
|
|
||||||
void nasal_codegen::num_gen(const nasal_ast& ast)
|
void nasal_codegen::num_gen(const nasal_ast& ast)
|
||||||
{
|
{
|
||||||
double num=ast.num();
|
f64 num=ast.num();
|
||||||
regist_num(num);
|
regist_num(num);
|
||||||
gen(op_pnum,num_table[num],ast.line());
|
gen(op_pnum,num_table[num],ast.line());
|
||||||
}
|
}
|
||||||
|
@ -523,7 +523,7 @@ void nasal_codegen::call_gen(const nasal_ast& ast)
|
||||||
void nasal_codegen::call_id(const nasal_ast& ast)
|
void nasal_codegen::call_id(const nasal_ast& ast)
|
||||||
{
|
{
|
||||||
const std::string& str=ast.str();
|
const std::string& str=ast.str();
|
||||||
for(uint32_t i=0;builtin[i].name;++i)
|
for(u32 i=0;builtin[i].name;++i)
|
||||||
if(builtin[i].name==str)
|
if(builtin[i].name==str)
|
||||||
{
|
{
|
||||||
gen(op_callb,i,ast.line());
|
gen(op_callb,i,ast.line());
|
||||||
|
@ -621,7 +621,7 @@ void nasal_codegen::mcall(const nasal_ast& ast)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
calc_gen(ast[0]);
|
calc_gen(ast[0]);
|
||||||
for(size_t i=1;i<ast.size()-1;++i)
|
for(usize i=1;i<ast.size()-1;++i)
|
||||||
{
|
{
|
||||||
const nasal_ast& tmp=ast[i];
|
const nasal_ast& tmp=ast[i];
|
||||||
switch(tmp.type())
|
switch(tmp.type())
|
||||||
|
@ -641,7 +641,7 @@ void nasal_codegen::mcall(const nasal_ast& ast)
|
||||||
void nasal_codegen::mcall_id(const nasal_ast& ast)
|
void nasal_codegen::mcall_id(const nasal_ast& ast)
|
||||||
{
|
{
|
||||||
const std::string& str=ast.str();
|
const std::string& str=ast.str();
|
||||||
for(uint32_t i=0;builtin[i].name;++i)
|
for(u32 i=0;builtin[i].name;++i)
|
||||||
if(builtin[i].name==str)
|
if(builtin[i].name==str)
|
||||||
{
|
{
|
||||||
die("cannot change builtin function.",ast.line());
|
die("cannot change builtin function.",ast.line());
|
||||||
|
@ -1267,7 +1267,7 @@ void nasal_codegen::block_gen(const nasal_ast& ast)
|
||||||
|
|
||||||
void nasal_codegen::ret_gen(const nasal_ast& ast)
|
void nasal_codegen::ret_gen(const nasal_ast& ast)
|
||||||
{
|
{
|
||||||
for(uint32_t i=0;i<in_iterloop.top();++i)
|
for(u32 i=0;i<in_iterloop.top();++i)
|
||||||
{
|
{
|
||||||
gen(op_pop,0,ast.line());
|
gen(op_pop,0,ast.line());
|
||||||
gen(op_pop,0,ast.line());
|
gen(op_pop,0,ast.line());
|
||||||
|
@ -1297,7 +1297,7 @@ void nasal_codegen::compile(const nasal_parse& parse,const nasal_import& import)
|
||||||
nerr.chkerr();
|
nerr.chkerr();
|
||||||
}
|
}
|
||||||
|
|
||||||
void nasal_codegen::singleop(const uint32_t index)
|
void nasal_codegen::singleop(const u32 index)
|
||||||
{
|
{
|
||||||
// print opcode index,opcode name,opcode immediate number
|
// print opcode index,opcode name,opcode immediate number
|
||||||
const opcode& c=code[index];
|
const opcode& c=code[index];
|
||||||
|
@ -1312,7 +1312,7 @@ void nasal_codegen::singleop(const uint32_t index)
|
||||||
if(c.op==op_newf)
|
if(c.op==op_newf)
|
||||||
{
|
{
|
||||||
std::cout<<std::hex<<"\nfunc <0x"<<index<<std::dec<<">:\n";
|
std::cout<<std::hex<<"\nfunc <0x"<<index<<std::dec<<">:\n";
|
||||||
for(uint32_t i=index;i<code.size();++i)
|
for(u32 i=index;i<code.size();++i)
|
||||||
if(code[i].op==op_jmp)
|
if(code[i].op==op_jmp)
|
||||||
{
|
{
|
||||||
fbstk.push(index);
|
fbstk.push(index);
|
||||||
|
@ -1331,7 +1331,7 @@ void nasal_codegen::print()
|
||||||
for(auto& str:str_res)
|
for(auto& str:str_res)
|
||||||
std::cout<<" .symbol \""<<rawstr(str)<<"\"\n";
|
std::cout<<" .symbol \""<<rawstr(str)<<"\"\n";
|
||||||
std::cout<<"\n";
|
std::cout<<"\n";
|
||||||
for(uint32_t i=0;i<code.size();++i)
|
for(u32 i=0;i<code.size();++i)
|
||||||
singleop(i);
|
singleop(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
24
nasal_dbg.h
24
nasal_dbg.h
|
@ -7,13 +7,13 @@ class nasal_dbg:public nasal_vm
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
bool next_step;
|
bool next_step;
|
||||||
size_t fsize;
|
usize fsize;
|
||||||
uint16_t bk_fidx;
|
u16 bk_fidx;
|
||||||
uint32_t bk_line;
|
u32 bk_line;
|
||||||
fstreamline src;
|
fstreamline src;
|
||||||
|
|
||||||
std::vector<std::string> parse(const std::string&);
|
std::vector<std::string> parse(const std::string&);
|
||||||
uint16_t fileindex(const std::string&);
|
u16 fileindex(const std::string&);
|
||||||
void err();
|
void err();
|
||||||
void help();
|
void help();
|
||||||
void stepinfo();
|
void stepinfo();
|
||||||
|
@ -32,7 +32,7 @@ public:
|
||||||
std::vector<std::string> nasal_dbg::parse(const std::string& cmd)
|
std::vector<std::string> nasal_dbg::parse(const std::string& cmd)
|
||||||
{
|
{
|
||||||
std::vector<std::string> res;
|
std::vector<std::string> res;
|
||||||
size_t last=0,pos=cmd.find(" ",0);
|
usize last=0,pos=cmd.find(" ",0);
|
||||||
while(pos!=std::string::npos)
|
while(pos!=std::string::npos)
|
||||||
{
|
{
|
||||||
if(pos>last)
|
if(pos>last)
|
||||||
|
@ -45,9 +45,9 @@ std::vector<std::string> nasal_dbg::parse(const std::string& cmd)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t nasal_dbg::fileindex(const std::string& filename)
|
u16 nasal_dbg::fileindex(const std::string& filename)
|
||||||
{
|
{
|
||||||
for(uint16_t i=0;i<fsize;++i)
|
for(u16 i=0;i<fsize;++i)
|
||||||
if(filename==files[i])
|
if(filename==files[i])
|
||||||
return i;
|
return i;
|
||||||
return 65535;
|
return 65535;
|
||||||
|
@ -81,18 +81,18 @@ void nasal_dbg::help()
|
||||||
|
|
||||||
void nasal_dbg::stepinfo()
|
void nasal_dbg::stepinfo()
|
||||||
{
|
{
|
||||||
uint32_t begin,end;
|
u32 begin,end;
|
||||||
uint32_t line=bytecode[pc].line==0?0:bytecode[pc].line-1;
|
u32 line=bytecode[pc].line==0?0:bytecode[pc].line-1;
|
||||||
src.load(files[bytecode[pc].fidx]);
|
src.load(files[bytecode[pc].fidx]);
|
||||||
std::cout<<"\nsource code:\n";
|
std::cout<<"\nsource code:\n";
|
||||||
begin=(line>>3)==0?0:((line>>3)<<3);
|
begin=(line>>3)==0?0:((line>>3)<<3);
|
||||||
end=(1+(line>>3))<<3;
|
end=(1+(line>>3))<<3;
|
||||||
for(uint32_t i=begin;i<end && i<src.size();++i)
|
for(u32 i=begin;i<end && i<src.size();++i)
|
||||||
std::cout<<(i==line?"--> ":" ")<<src[i]<<"\n";
|
std::cout<<(i==line?"--> ":" ")<<src[i]<<"\n";
|
||||||
std::cout<<"next bytecode:\n";
|
std::cout<<"next bytecode:\n";
|
||||||
begin=(pc>>3)==0?0:((pc>>3)<<3);
|
begin=(pc>>3)==0?0:((pc>>3)<<3);
|
||||||
end=(1+(pc>>3))<<3;
|
end=(1+(pc>>3))<<3;
|
||||||
for(uint32_t i=begin;i<end && bytecode[i].op!=op_exit;++i)
|
for(u32 i=begin;i<end && bytecode[i].op!=op_exit;++i)
|
||||||
bytecodeinfo(i==pc?"--> ":" ",i);
|
bytecodeinfo(i==pc?"--> ":" ",i);
|
||||||
stackinfo(10);
|
stackinfo(10);
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,7 @@ void nasal_dbg::interact()
|
||||||
else if(res[0]=="c" || res[0]=="continue")
|
else if(res[0]=="c" || res[0]=="continue")
|
||||||
return;
|
return;
|
||||||
else if(res[0]=="f" || res[0]=="file")
|
else if(res[0]=="f" || res[0]=="file")
|
||||||
for(size_t i=0;i<fsize;++i)
|
for(usize i=0;i<fsize;++i)
|
||||||
std::cout<<"["<<i<<"] "<<files[i]<<"\n";
|
std::cout<<"["<<i<<"] "<<files[i]<<"\n";
|
||||||
else if(res[0]=="g" || res[0]=="global")
|
else if(res[0]=="g" || res[0]=="global")
|
||||||
global_state();
|
global_state();
|
||||||
|
|
10
nasal_err.h
10
nasal_err.h
|
@ -35,15 +35,15 @@ public:
|
||||||
std::vector<std::string> tmp;
|
std::vector<std::string> tmp;
|
||||||
res.swap(tmp);
|
res.swap(tmp);
|
||||||
}
|
}
|
||||||
const std::string& operator[](const uint32_t line){return res[line];}
|
const std::string& operator[](const u32 line){return res[line];}
|
||||||
const std::string& name(){return file;}
|
const std::string& name(){return file;}
|
||||||
size_t size(){return res.size();}
|
usize size(){return res.size();}
|
||||||
};
|
};
|
||||||
|
|
||||||
class nasal_err:public fstreamline
|
class nasal_err:public fstreamline
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
uint32_t error;
|
u32 error;
|
||||||
public:
|
public:
|
||||||
nasal_err():error(0){}
|
nasal_err():error(0){}
|
||||||
void err(const char* stage,const std::string& info)
|
void err(const char* stage,const std::string& info)
|
||||||
|
@ -51,7 +51,7 @@ public:
|
||||||
++error;
|
++error;
|
||||||
std::cerr<<"["<<stage<<"] "<<info<<"\n";
|
std::cerr<<"["<<stage<<"] "<<info<<"\n";
|
||||||
}
|
}
|
||||||
void err(const char* stage,uint32_t line,uint32_t column,const std::string& info)
|
void err(const char* stage,u32 line,u32 column,const std::string& info)
|
||||||
{
|
{
|
||||||
++error;
|
++error;
|
||||||
const std::string& code=res[line-1];
|
const std::string& code=res[line-1];
|
||||||
|
@ -60,7 +60,7 @@ public:
|
||||||
std::cerr<<char(" \t"[code[i]=='\t']);
|
std::cerr<<char(" \t"[code[i]=='\t']);
|
||||||
std::cerr<<"^\n";
|
std::cerr<<"^\n";
|
||||||
}
|
}
|
||||||
void err(const char* stage,uint32_t line,const std::string& info)
|
void err(const char* stage,u32 line,const std::string& info)
|
||||||
{
|
{
|
||||||
++error;
|
++error;
|
||||||
std::cerr<<"["<<stage<<"] "<<file<<":"<<line<<" "<<info<<"\n"<<res[line-1]<<'\n';
|
std::cerr<<"["<<stage<<"] "<<file<<":"<<line<<" "<<info<<"\n"<<res[line-1]<<'\n';
|
||||||
|
|
154
nasal_gc.h
154
nasal_gc.h
|
@ -1,7 +1,7 @@
|
||||||
#ifndef __NASAL_GC_H__
|
#ifndef __NASAL_GC_H__
|
||||||
#define __NASAL_GC_H__
|
#define __NASAL_GC_H__
|
||||||
|
|
||||||
enum vm_type:std::uint8_t{
|
enum vm_type:u8{
|
||||||
/* none-gc object */
|
/* none-gc object */
|
||||||
vm_none=0,
|
vm_none=0,
|
||||||
vm_cnt,
|
vm_cnt,
|
||||||
|
@ -19,10 +19,10 @@ enum vm_type:std::uint8_t{
|
||||||
vm_co,
|
vm_co,
|
||||||
vm_tsize
|
vm_tsize
|
||||||
};
|
};
|
||||||
const uint32_t gc_tsize=vm_tsize-vm_str;
|
const u32 gc_tsize=vm_tsize-vm_str;
|
||||||
// change parameters here to make your own efficient gc
|
// change parameters here to make your own efficient gc
|
||||||
// better set bigger number on vm_vec
|
// better set bigger number on vm_vec
|
||||||
const uint32_t ini[gc_tsize]=
|
const u32 ini[gc_tsize]=
|
||||||
{
|
{
|
||||||
128, // vm_str
|
128, // vm_str
|
||||||
128, // vm_vec
|
128, // vm_vec
|
||||||
|
@ -32,7 +32,7 @@ const uint32_t ini[gc_tsize]=
|
||||||
0, // vm_obj
|
0, // vm_obj
|
||||||
0 // vm_co
|
0 // vm_co
|
||||||
};
|
};
|
||||||
const uint32_t incr[gc_tsize]=
|
const u32 incr[gc_tsize]=
|
||||||
{
|
{
|
||||||
256, // vm_str
|
256, // vm_str
|
||||||
512, // vm_vec
|
512, // vm_vec
|
||||||
|
@ -53,40 +53,40 @@ struct nasal_val; // nasal_val includes gc-managed types
|
||||||
|
|
||||||
struct nasal_ref
|
struct nasal_ref
|
||||||
{
|
{
|
||||||
uint8_t type;
|
u8 type;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
uint32_t ret;
|
u32 ret;
|
||||||
int64_t cnt;
|
i64 cnt;
|
||||||
double num;
|
f64 num;
|
||||||
nasal_ref* addr;
|
nasal_ref* addr;
|
||||||
nasal_val* gcobj;
|
nasal_val* gcobj;
|
||||||
} val;
|
} val;
|
||||||
|
|
||||||
// vm_none/vm_nil
|
// vm_none/vm_nil
|
||||||
nasal_ref(const uint8_t t=vm_none):type(t){}
|
nasal_ref(const u8 t=vm_none):type(t){}
|
||||||
// vm_ret
|
// vm_ret
|
||||||
nasal_ref(const uint8_t t,const uint32_t n):type(t){val.ret=n;}
|
nasal_ref(const u8 t,const u32 n):type(t){val.ret=n;}
|
||||||
// vm_cnt
|
// vm_cnt
|
||||||
nasal_ref(const uint8_t t,const int64_t n):type(t){val.cnt=n;}
|
nasal_ref(const u8 t,const i64 n):type(t){val.cnt=n;}
|
||||||
// vm_num
|
// vm_num
|
||||||
nasal_ref(const uint8_t t,const double n):type(t){val.num=n;}
|
nasal_ref(const u8 t,const f64 n):type(t){val.num=n;}
|
||||||
// vm_str/vm_func/vm_vec/vm_hash/vm_upval/vm_obj
|
// vm_str/vm_func/vm_vec/vm_hash/vm_upval/vm_obj
|
||||||
nasal_ref(const uint8_t t,nasal_val* n):type(t){val.gcobj=n;}
|
nasal_ref(const u8 t,nasal_val* n):type(t){val.gcobj=n;}
|
||||||
// vm_addr
|
// vm_addr
|
||||||
nasal_ref(const uint8_t t,nasal_ref* n):type(t){val.addr=n;}
|
nasal_ref(const u8 t,nasal_ref* n):type(t){val.addr=n;}
|
||||||
nasal_ref(const nasal_ref& nr):type(nr.type),val(nr.val){}
|
nasal_ref(const nasal_ref& nr):type(nr.type),val(nr.val){}
|
||||||
bool operator==(const nasal_ref& nr){return type==nr.type && val.gcobj==nr.val.gcobj;}
|
bool operator==(const nasal_ref& nr){return type==nr.type && val.gcobj==nr.val.gcobj;}
|
||||||
bool operator!=(const nasal_ref& nr){return type!=nr.type || val.gcobj!=nr.val.gcobj;}
|
bool operator!=(const nasal_ref& nr){return type!=nr.type || val.gcobj!=nr.val.gcobj;}
|
||||||
// number and string can be translated to each other
|
// number and string can be translated to each other
|
||||||
double tonum();
|
f64 tonum();
|
||||||
std::string tostr();
|
std::string tostr();
|
||||||
void print();
|
void print();
|
||||||
bool objchk(uint32_t);
|
bool objchk(u32);
|
||||||
inline nasal_ref* addr();
|
inline nasal_ref* addr();
|
||||||
inline uint32_t ret ();
|
inline u32 ret ();
|
||||||
inline int64_t& cnt ();
|
inline i64& cnt ();
|
||||||
inline double num ();
|
inline f64 num ();
|
||||||
inline std::string& str ();
|
inline std::string& str ();
|
||||||
inline nasal_vec& vec ();
|
inline nasal_vec& vec ();
|
||||||
inline nasal_hash& hash();
|
inline nasal_hash& hash();
|
||||||
|
@ -103,7 +103,7 @@ struct nasal_vec
|
||||||
|
|
||||||
nasal_vec():printed(false){}
|
nasal_vec():printed(false){}
|
||||||
void print();
|
void print();
|
||||||
size_t size(){return elems.size();}
|
usize size(){return elems.size();}
|
||||||
nasal_ref get_val(const int);
|
nasal_ref get_val(const int);
|
||||||
nasal_ref* get_mem(const int);
|
nasal_ref* get_mem(const int);
|
||||||
};
|
};
|
||||||
|
@ -115,20 +115,20 @@ struct nasal_hash
|
||||||
|
|
||||||
nasal_hash():printed(false){}
|
nasal_hash():printed(false){}
|
||||||
void print();
|
void print();
|
||||||
size_t size(){return elems.size();}
|
usize size(){return elems.size();}
|
||||||
nasal_ref get_val(const std::string&);
|
nasal_ref get_val(const std::string&);
|
||||||
nasal_ref* get_mem(const std::string&);
|
nasal_ref* get_mem(const std::string&);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nasal_func
|
struct nasal_func
|
||||||
{
|
{
|
||||||
int32_t dynpara; // dynamic parameter name index in hash.
|
i32 dynpara; // dynamic parameter name index in hash.
|
||||||
uint32_t entry; // pc will set to entry-1 to call this function
|
u32 entry; // pc will set to entry-1 to call this function
|
||||||
uint32_t psize; // used to load default parameters to a new function
|
u32 psize; // used to load default parameters to a new function
|
||||||
uint32_t lsize; // used to expand memory space for local values on stack
|
u32 lsize; // used to expand memory space for local values on stack
|
||||||
std::vector<nasal_ref> local; // local scope with default value(nasal_ref)
|
std::vector<nasal_ref> local; // local scope with default value(nasal_ref)
|
||||||
std::vector<nasal_ref> upvalue; // closure
|
std::vector<nasal_ref> upvalue; // closure
|
||||||
std::unordered_map<uint32_t,uint32_t> keys; // parameter name table, size_t begins from 1
|
std::unordered_map<u32,u32> keys; // parameter name table, u32 begins from 1
|
||||||
|
|
||||||
nasal_func():dynpara(-1),entry(0),psize(0),lsize(0){}
|
nasal_func():dynpara(-1),entry(0),psize(0),lsize(0){}
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -137,7 +137,7 @@ struct nasal_func
|
||||||
struct nasal_upval
|
struct nasal_upval
|
||||||
{
|
{
|
||||||
bool onstk;
|
bool onstk;
|
||||||
uint32_t size;
|
u32 size;
|
||||||
nasal_ref* stk;
|
nasal_ref* stk;
|
||||||
std::vector<nasal_ref> elems;
|
std::vector<nasal_ref> elems;
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ struct nasal_upval
|
||||||
|
|
||||||
struct nasal_obj
|
struct nasal_obj
|
||||||
{
|
{
|
||||||
enum obj_t:std::uint32_t
|
enum obj_t:u32
|
||||||
{
|
{
|
||||||
null,
|
null,
|
||||||
file,
|
file,
|
||||||
|
@ -158,7 +158,7 @@ struct nasal_obj
|
||||||
};
|
};
|
||||||
/* RAII constructor */
|
/* RAII constructor */
|
||||||
/* new object is initialized when creating */
|
/* new object is initialized when creating */
|
||||||
uint32_t type;
|
u32 type;
|
||||||
void* ptr;
|
void* ptr;
|
||||||
/* RAII destroyer */
|
/* RAII destroyer */
|
||||||
/* default destroyer does nothing */
|
/* default destroyer does nothing */
|
||||||
|
@ -167,7 +167,7 @@ struct nasal_obj
|
||||||
|
|
||||||
nasal_obj():type(obj_t::null),ptr(nullptr),dtor(nullptr){}
|
nasal_obj():type(obj_t::null),ptr(nullptr),dtor(nullptr){}
|
||||||
~nasal_obj(){clear();}
|
~nasal_obj(){clear();}
|
||||||
void set(uint32_t t=obj_t::null,void* p=nullptr,dest d=nullptr)
|
void set(u32 t=obj_t::null,void* p=nullptr,dest d=nullptr)
|
||||||
{
|
{
|
||||||
type=t;
|
type=t;
|
||||||
ptr=p;
|
ptr=p;
|
||||||
|
@ -192,7 +192,7 @@ struct nasal_co
|
||||||
};
|
};
|
||||||
nasal_ref stack[STACK_DEPTH];
|
nasal_ref stack[STACK_DEPTH];
|
||||||
|
|
||||||
uint32_t pc;
|
u32 pc;
|
||||||
nasal_ref* top;
|
nasal_ref* top;
|
||||||
nasal_ref* canary;
|
nasal_ref* canary;
|
||||||
nasal_ref* localr;
|
nasal_ref* localr;
|
||||||
|
@ -200,41 +200,41 @@ struct nasal_co
|
||||||
nasal_ref funcr;
|
nasal_ref funcr;
|
||||||
nasal_ref upvalr;
|
nasal_ref upvalr;
|
||||||
|
|
||||||
uint32_t status;
|
u32 status;
|
||||||
nasal_co():
|
nasal_co():
|
||||||
pc(0),
|
pc(0),
|
||||||
top(stack),
|
top(stack),
|
||||||
canary(stack+STACK_DEPTH-1),
|
canary(stack+STACK_DEPTH-1),
|
||||||
localr(nullptr),
|
localr(nullptr),
|
||||||
memr(nullptr),
|
memr(nullptr),
|
||||||
funcr({vm_nil,(double)0}),
|
funcr({vm_nil,(f64)0}),
|
||||||
upvalr({vm_nil,(double)0}),
|
upvalr({vm_nil,(f64)0}),
|
||||||
status(nasal_co::suspended)
|
status(nasal_co::suspended)
|
||||||
{
|
{
|
||||||
for(uint32_t i=0;i<STACK_DEPTH;++i)
|
for(u32 i=0;i<STACK_DEPTH;++i)
|
||||||
stack[i]={vm_nil,(double)0};
|
stack[i]={vm_nil,(f64)0};
|
||||||
}
|
}
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
for(uint32_t i=0;i<STACK_DEPTH;++i)
|
for(u32 i=0;i<STACK_DEPTH;++i)
|
||||||
stack[i]={vm_nil,(double)0};
|
stack[i]={vm_nil,(f64)0};
|
||||||
pc=0;
|
pc=0;
|
||||||
localr=nullptr;
|
localr=nullptr;
|
||||||
memr=nullptr;
|
memr=nullptr;
|
||||||
top=stack;
|
top=stack;
|
||||||
status=nasal_co::suspended;
|
status=nasal_co::suspended;
|
||||||
funcr={vm_nil,(double)0};
|
funcr={vm_nil,(f64)0};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t GC_UNCOLLECTED=0;
|
const u8 GC_UNCOLLECTED=0;
|
||||||
const uint8_t GC_COLLECTED =1;
|
const u8 GC_COLLECTED =1;
|
||||||
const uint8_t GC_FOUND =2;
|
const u8 GC_FOUND =2;
|
||||||
struct nasal_val
|
struct nasal_val
|
||||||
{
|
{
|
||||||
uint8_t mark;
|
u8 mark;
|
||||||
uint8_t type;
|
u8 type;
|
||||||
uint8_t unmut; // used to mark if a string is unmutable
|
u8 unmut; // used to mark if a string is unmutable
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
std::string* str;
|
std::string* str;
|
||||||
|
@ -246,7 +246,7 @@ struct nasal_val
|
||||||
nasal_co* co;
|
nasal_co* co;
|
||||||
}ptr;
|
}ptr;
|
||||||
|
|
||||||
nasal_val(uint8_t);
|
nasal_val(u8);
|
||||||
~nasal_val();
|
~nasal_val();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -272,8 +272,8 @@ void nasal_vec::print()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
printed=true;
|
printed=true;
|
||||||
size_t iter=0;
|
usize iter=0;
|
||||||
size_t size=elems.size();
|
usize size=elems.size();
|
||||||
std::cout<<'[';
|
std::cout<<'[';
|
||||||
for(auto& i:elems)
|
for(auto& i:elems)
|
||||||
{
|
{
|
||||||
|
@ -329,8 +329,8 @@ void nasal_hash::print()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
printed=true;
|
printed=true;
|
||||||
size_t iter=0;
|
usize iter=0;
|
||||||
size_t size=elems.size();
|
usize size=elems.size();
|
||||||
std::cout<<'{';
|
std::cout<<'{';
|
||||||
for(auto& i:elems)
|
for(auto& i:elems)
|
||||||
{
|
{
|
||||||
|
@ -349,7 +349,7 @@ void nasal_func::clear()
|
||||||
keys.clear();
|
keys.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
nasal_val::nasal_val(uint8_t val_type)
|
nasal_val::nasal_val(u8 val_type)
|
||||||
{
|
{
|
||||||
mark=GC_COLLECTED;
|
mark=GC_COLLECTED;
|
||||||
type=val_type;
|
type=val_type;
|
||||||
|
@ -379,7 +379,7 @@ nasal_val::~nasal_val()
|
||||||
}
|
}
|
||||||
type=vm_nil;
|
type=vm_nil;
|
||||||
}
|
}
|
||||||
double nasal_ref::tonum()
|
f64 nasal_ref::tonum()
|
||||||
{
|
{
|
||||||
return type!=vm_str?val.num:str2num(str().c_str());
|
return type!=vm_str?val.num:str2num(str().c_str());
|
||||||
}
|
}
|
||||||
|
@ -411,14 +411,14 @@ void nasal_ref::print()
|
||||||
case vm_co: std::cout<<"<coroutine>"; break;
|
case vm_co: std::cout<<"<coroutine>"; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool nasal_ref::objchk(uint32_t objtype)
|
bool nasal_ref::objchk(u32 objtype)
|
||||||
{
|
{
|
||||||
return type==vm_obj && obj().type==objtype && obj().ptr;
|
return type==vm_obj && obj().type==objtype && obj().ptr;
|
||||||
}
|
}
|
||||||
inline nasal_ref* nasal_ref::addr (){return val.addr; }
|
inline nasal_ref* nasal_ref::addr (){return val.addr; }
|
||||||
inline uint32_t nasal_ref::ret (){return val.ret; }
|
inline u32 nasal_ref::ret (){return val.ret; }
|
||||||
inline int64_t& nasal_ref::cnt (){return val.cnt; }
|
inline i64& nasal_ref::cnt (){return val.cnt; }
|
||||||
inline double nasal_ref::num (){return val.num; }
|
inline f64 nasal_ref::num (){return val.num; }
|
||||||
inline std::string& nasal_ref::str (){return *val.gcobj->ptr.str; }
|
inline std::string& nasal_ref::str (){return *val.gcobj->ptr.str; }
|
||||||
inline nasal_vec& nasal_ref::vec (){return *val.gcobj->ptr.vec; }
|
inline nasal_vec& nasal_ref::vec (){return *val.gcobj->ptr.vec; }
|
||||||
inline nasal_hash& nasal_ref::hash (){return *val.gcobj->ptr.hash; }
|
inline nasal_hash& nasal_ref::hash (){return *val.gcobj->ptr.hash; }
|
||||||
|
@ -427,15 +427,15 @@ inline nasal_upval& nasal_ref::upval(){return *val.gcobj->ptr.upval;}
|
||||||
inline nasal_obj& nasal_ref::obj (){return *val.gcobj->ptr.obj; }
|
inline nasal_obj& nasal_ref::obj (){return *val.gcobj->ptr.obj; }
|
||||||
inline nasal_co& nasal_ref::co (){return *val.gcobj->ptr.co; }
|
inline nasal_co& nasal_ref::co (){return *val.gcobj->ptr.co; }
|
||||||
|
|
||||||
const nasal_ref zero={vm_num,(double)0};
|
const nasal_ref zero={vm_num,(f64)0};
|
||||||
const nasal_ref one ={vm_num,(double)1};
|
const nasal_ref one ={vm_num,(f64)1};
|
||||||
const nasal_ref nil ={vm_nil,(double)0};
|
const nasal_ref nil ={vm_nil,(f64)0};
|
||||||
|
|
||||||
struct nasal_gc
|
struct nasal_gc
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint32_t pc;
|
u32 pc;
|
||||||
nasal_ref* top;
|
nasal_ref* top;
|
||||||
nasal_ref* localr;
|
nasal_ref* localr;
|
||||||
nasal_ref* memr;
|
nasal_ref* memr;
|
||||||
|
@ -446,7 +446,7 @@ struct nasal_gc
|
||||||
} main_ctx;
|
} main_ctx;
|
||||||
|
|
||||||
/* runtime context */
|
/* runtime context */
|
||||||
uint32_t& pc; // program counter
|
u32& pc; // program counter
|
||||||
nasal_ref*& localr; // local scope register
|
nasal_ref*& localr; // local scope register
|
||||||
nasal_ref*& memr; // used for mem_call
|
nasal_ref*& memr; // used for mem_call
|
||||||
nasal_ref& funcr; // function register
|
nasal_ref& funcr; // function register
|
||||||
|
@ -464,11 +464,11 @@ struct nasal_gc
|
||||||
std::queue<nasal_val*> unused[gc_tsize]; // gc free list
|
std::queue<nasal_val*> unused[gc_tsize]; // gc free list
|
||||||
|
|
||||||
/* values for analysis */
|
/* values for analysis */
|
||||||
uint64_t size[gc_tsize];
|
u64 size[gc_tsize];
|
||||||
uint64_t count[gc_tsize];
|
u64 count[gc_tsize];
|
||||||
uint64_t allocc[gc_tsize];
|
u64 allocc[gc_tsize];
|
||||||
nasal_gc(
|
nasal_gc(
|
||||||
uint32_t& _pc,
|
u32& _pc,
|
||||||
nasal_ref*& _localr,
|
nasal_ref*& _localr,
|
||||||
nasal_ref*& _memr,
|
nasal_ref*& _memr,
|
||||||
nasal_ref& _funcr,
|
nasal_ref& _funcr,
|
||||||
|
@ -483,7 +483,7 @@ struct nasal_gc
|
||||||
void init(const std::vector<std::string>&,const std::vector<std::string>&);
|
void init(const std::vector<std::string>&,const std::vector<std::string>&);
|
||||||
void clear();
|
void clear();
|
||||||
void info();
|
void info();
|
||||||
nasal_ref alloc(const uint8_t);
|
nasal_ref alloc(const u8);
|
||||||
nasal_ref newstr(char);
|
nasal_ref newstr(char);
|
||||||
nasal_ref newstr(const char*);
|
nasal_ref newstr(const char*);
|
||||||
nasal_ref newstr(const std::string&);
|
nasal_ref newstr(const std::string&);
|
||||||
|
@ -575,10 +575,10 @@ void nasal_gc::init(const std::vector<std::string>& s,const std::vector<std::str
|
||||||
// initiaize function register
|
// initiaize function register
|
||||||
funcr=nil;
|
funcr=nil;
|
||||||
|
|
||||||
for(uint8_t i=0;i<gc_tsize;++i)
|
for(u8 i=0;i<gc_tsize;++i)
|
||||||
size[i]=count[i]=allocc[i]=0;
|
size[i]=count[i]=allocc[i]=0;
|
||||||
for(uint8_t i=0;i<gc_tsize;++i)
|
for(u8 i=0;i<gc_tsize;++i)
|
||||||
for(uint32_t j=0;j<ini[i];++j)
|
for(u32 j=0;j<ini[i];++j)
|
||||||
{
|
{
|
||||||
nasal_val* tmp=new nasal_val(i+vm_str);
|
nasal_val* tmp=new nasal_val(i+vm_str);
|
||||||
memory.push_back(tmp);
|
memory.push_back(tmp);
|
||||||
|
@ -587,7 +587,7 @@ void nasal_gc::init(const std::vector<std::string>& s,const std::vector<std::str
|
||||||
coroutine=nullptr;
|
coroutine=nullptr;
|
||||||
// init constant strings
|
// init constant strings
|
||||||
strs.resize(s.size());
|
strs.resize(s.size());
|
||||||
for(uint32_t i=0;i<strs.size();++i)
|
for(u32 i=0;i<strs.size();++i)
|
||||||
{
|
{
|
||||||
strs[i]={vm_str,new nasal_val(vm_str)};
|
strs[i]={vm_str,new nasal_val(vm_str)};
|
||||||
strs[i].val.gcobj->unmut=1;
|
strs[i].val.gcobj->unmut=1;
|
||||||
|
@ -595,7 +595,7 @@ void nasal_gc::init(const std::vector<std::string>& s,const std::vector<std::str
|
||||||
}
|
}
|
||||||
// record arguments
|
// record arguments
|
||||||
env_argv.resize(argv.size());
|
env_argv.resize(argv.size());
|
||||||
for(size_t i=0;i<argv.size();++i)
|
for(usize i=0;i<argv.size();++i)
|
||||||
{
|
{
|
||||||
env_argv[i]={vm_str,new nasal_val(vm_str)};
|
env_argv[i]={vm_str,new nasal_val(vm_str)};
|
||||||
env_argv[i].val.gcobj->unmut=1;
|
env_argv[i].val.gcobj->unmut=1;
|
||||||
|
@ -607,7 +607,7 @@ void nasal_gc::clear()
|
||||||
for(auto i:memory)
|
for(auto i:memory)
|
||||||
delete i;
|
delete i;
|
||||||
memory.clear();
|
memory.clear();
|
||||||
for(uint8_t i=0;i<gc_tsize;++i)
|
for(u8 i=0;i<gc_tsize;++i)
|
||||||
while(!unused[i].empty())
|
while(!unused[i].empty())
|
||||||
unused[i].pop();
|
unused[i].pop();
|
||||||
for(auto& i:strs)
|
for(auto& i:strs)
|
||||||
|
@ -619,16 +619,16 @@ void nasal_gc::info()
|
||||||
{
|
{
|
||||||
const char* name[]={"str ","vec ","hash ","func ","upval","obj ","co "};
|
const char* name[]={"str ","vec ","hash ","func ","upval","obj ","co "};
|
||||||
std::cout<<"\ngarbage collector info(gc/alloc)\n";
|
std::cout<<"\ngarbage collector info(gc/alloc)\n";
|
||||||
for(uint8_t i=0;i<gc_tsize;++i)
|
for(u8 i=0;i<gc_tsize;++i)
|
||||||
if(count[i] || allocc[i])
|
if(count[i] || allocc[i])
|
||||||
std::cout<<" "<<name[i]<<" | "<<count[i]<<","<<allocc[i]<<"\n";
|
std::cout<<" "<<name[i]<<" | "<<count[i]<<","<<allocc[i]<<"\n";
|
||||||
std::cout<<"\nmemory allocator info(max size)\n";
|
std::cout<<"\nmemory allocator info(max size)\n";
|
||||||
for(uint8_t i=0;i<gc_tsize;++i)
|
for(u8 i=0;i<gc_tsize;++i)
|
||||||
std::cout<<" "<<name[i]<<" | "<<ini[i]+size[i]*incr[i]<<" (+"<<size[i]<<")\n";
|
std::cout<<" "<<name[i]<<" | "<<ini[i]+size[i]*incr[i]<<" (+"<<size[i]<<")\n";
|
||||||
}
|
}
|
||||||
nasal_ref nasal_gc::alloc(uint8_t type)
|
nasal_ref nasal_gc::alloc(u8 type)
|
||||||
{
|
{
|
||||||
const uint8_t index=type-vm_str;
|
const u8 index=type-vm_str;
|
||||||
++allocc[index];
|
++allocc[index];
|
||||||
if(unused[index].empty())
|
if(unused[index].empty())
|
||||||
{
|
{
|
||||||
|
@ -639,7 +639,7 @@ nasal_ref nasal_gc::alloc(uint8_t type)
|
||||||
if(unused[index].empty())
|
if(unused[index].empty())
|
||||||
{
|
{
|
||||||
++size[index];
|
++size[index];
|
||||||
for(uint32_t i=0;i<incr[index];++i)
|
for(u32 i=0;i<incr[index];++i)
|
||||||
{
|
{
|
||||||
nasal_val* tmp=new nasal_val(type);
|
nasal_val* tmp=new nasal_val(type);
|
||||||
memory.push_back(tmp);
|
memory.push_back(tmp);
|
||||||
|
|
|
@ -18,7 +18,7 @@ private:
|
||||||
std::string path(const nasal_ast&);
|
std::string path(const nasal_ast&);
|
||||||
nasal_ast fimpt(nasal_ast&);
|
nasal_ast fimpt(nasal_ast&);
|
||||||
nasal_ast libimpt();
|
nasal_ast libimpt();
|
||||||
nasal_ast load(nasal_ast&,uint16_t);
|
nasal_ast load(nasal_ast&,u16);
|
||||||
public:
|
public:
|
||||||
nasal_import(nasal_err&);
|
nasal_import(nasal_err&);
|
||||||
void link(nasal_parse&,const std::string&);
|
void link(nasal_parse&,const std::string&);
|
||||||
|
@ -32,8 +32,8 @@ nasal_import::nasal_import(nasal_err& e):lib_loaded(false),nerr(e){
|
||||||
char sep=':';
|
char sep=':';
|
||||||
#endif
|
#endif
|
||||||
std::string PATH=getenv("PATH");
|
std::string PATH=getenv("PATH");
|
||||||
size_t last=0;
|
usize last=0;
|
||||||
size_t pos=PATH.find(sep,last);
|
usize pos=PATH.find(sep,last);
|
||||||
while(pos!=std::string::npos)
|
while(pos!=std::string::npos)
|
||||||
{
|
{
|
||||||
std::string dirpath=PATH.substr(last,pos-last);
|
std::string dirpath=PATH.substr(last,pos-last);
|
||||||
|
@ -51,7 +51,7 @@ std::string nasal_import::path(const nasal_ast& node)
|
||||||
if(node[1].type()==ast_callf)
|
if(node[1].type()==ast_callf)
|
||||||
return node[1][0].str();
|
return node[1][0].str();
|
||||||
std::string fpath=".";
|
std::string fpath=".";
|
||||||
for(size_t i=1;i<node.size();++i)
|
for(usize i=1;i<node.size();++i)
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
fpath+="/"+node[i].str();
|
fpath+="/"+node[i].str();
|
||||||
#else
|
#else
|
||||||
|
@ -71,7 +71,7 @@ bool nasal_import::imptchk(const nasal_ast& node)
|
||||||
*/
|
*/
|
||||||
if(node.type()==ast_call && node[0].str()=="import" && node.size()>=2 && node[1].type()==ast_callh)
|
if(node.type()==ast_call && node[0].str()=="import" && node.size()>=2 && node[1].type()==ast_callh)
|
||||||
{
|
{
|
||||||
for(size_t i=1;i<node.size();++i)
|
for(usize i=1;i<node.size();++i)
|
||||||
if(node[i].type()!=ast_callh)
|
if(node[i].type()!=ast_callh)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
|
@ -185,7 +185,7 @@ nasal_ast nasal_import::libimpt()
|
||||||
return load(tmp,files.size()-1);
|
return load(tmp,files.size()-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
nasal_ast nasal_import::load(nasal_ast& root,uint16_t fileindex)
|
nasal_ast nasal_import::load(nasal_ast& root,u16 fileindex)
|
||||||
{
|
{
|
||||||
nasal_ast new_root(0,ast_root);
|
nasal_ast new_root(0,ast_root);
|
||||||
if(!lib_loaded)
|
if(!lib_loaded)
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#define CALC_OPERATOR(c) (c=='='||c=='+'||c=='-'||c=='*'||c=='!'||c=='/'||c=='<'||c=='>'||c=='~')
|
#define CALC_OPERATOR(c) (c=='='||c=='+'||c=='-'||c=='*'||c=='!'||c=='/'||c=='<'||c=='>'||c=='~')
|
||||||
#define NOTE(c) (c=='#')
|
#define NOTE(c) (c=='#')
|
||||||
|
|
||||||
enum tok:std::uint32_t{
|
enum tok:u32{
|
||||||
tok_null=0, // null token (default token type)
|
tok_null=0, // null token (default token type)
|
||||||
tok_num, // number basic token type
|
tok_num, // number basic token type
|
||||||
tok_str, // string basic token type
|
tok_str, // string basic token type
|
||||||
|
@ -41,7 +41,7 @@ enum tok:std::uint32_t{
|
||||||
|
|
||||||
struct{
|
struct{
|
||||||
const char* str;
|
const char* str;
|
||||||
const uint32_t type;
|
const u32 type;
|
||||||
}tok_table[]={
|
}tok_table[]={
|
||||||
{"for" ,tok_for },
|
{"for" ,tok_for },
|
||||||
{"forindex",tok_forindex },
|
{"forindex",tok_forindex },
|
||||||
|
@ -93,11 +93,11 @@ struct{
|
||||||
|
|
||||||
struct token
|
struct token
|
||||||
{
|
{
|
||||||
uint32_t line;
|
u32 line;
|
||||||
uint32_t col;
|
u32 col;
|
||||||
uint32_t type;
|
u32 type;
|
||||||
std::string str;
|
std::string str;
|
||||||
token(uint32_t l=0,uint32_t c=0,uint32_t t=tok_null,const std::string& s=""):str(s)
|
token(u32 l=0,u32 c=0,u32 t=tok_null,const std::string& s=""):str(s)
|
||||||
{
|
{
|
||||||
line=l;
|
line=l;
|
||||||
col=c;
|
col=c;
|
||||||
|
@ -108,14 +108,14 @@ struct token
|
||||||
class nasal_lexer
|
class nasal_lexer
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
uint32_t line;
|
u32 line;
|
||||||
uint32_t column;
|
u32 column;
|
||||||
size_t ptr;
|
usize ptr;
|
||||||
nasal_err& nerr;
|
nasal_err& nerr;
|
||||||
std::string res;
|
std::string res;
|
||||||
std::vector<token> tokens;
|
std::vector<token> tokens;
|
||||||
|
|
||||||
uint32_t get_type(const std::string&);
|
u32 get_type(const std::string&);
|
||||||
void die(const std::string& info){nerr.err("lexer",line,column,info);}
|
void die(const std::string& info){nerr.err("lexer",line,column,info);}
|
||||||
void open(const std::string&);
|
void open(const std::string&);
|
||||||
std::string utf8_gen();
|
std::string utf8_gen();
|
||||||
|
@ -152,9 +152,9 @@ void nasal_lexer::open(const std::string& file)
|
||||||
res=ss.str();
|
res=ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t nasal_lexer::get_type(const std::string& str)
|
u32 nasal_lexer::get_type(const std::string& str)
|
||||||
{
|
{
|
||||||
for(uint32_t i=0;tok_table[i].str;++i)
|
for(u32 i=0;tok_table[i].str;++i)
|
||||||
if(str==tok_table[i].str)
|
if(str==tok_table[i].str)
|
||||||
return tok_table[i].type;
|
return tok_table[i].type;
|
||||||
return tok_null;
|
return tok_null;
|
||||||
|
@ -166,18 +166,18 @@ std::string nasal_lexer::utf8_gen()
|
||||||
while(ptr<res.size() && res[ptr]<0)
|
while(ptr<res.size() && res[ptr]<0)
|
||||||
{
|
{
|
||||||
std::string tmp="";
|
std::string tmp="";
|
||||||
uint32_t nbytes=utf8_hdchk(res[ptr]);
|
u32 nbytes=utf8_hdchk(res[ptr]);
|
||||||
if(nbytes)
|
if(nbytes)
|
||||||
{
|
{
|
||||||
tmp+=res[ptr++];
|
tmp+=res[ptr++];
|
||||||
for(uint32_t i=0;i<nbytes;++i,++ptr)
|
for(u32 i=0;i<nbytes;++i,++ptr)
|
||||||
if(ptr<res.size() && (res[ptr]&0xc0)==0x80)
|
if(ptr<res.size() && (res[ptr]&0xc0)==0x80)
|
||||||
tmp+=res[ptr];
|
tmp+=res[ptr];
|
||||||
if(tmp.length()!=1+nbytes)
|
if(tmp.length()!=1+nbytes)
|
||||||
{
|
{
|
||||||
++column;
|
++column;
|
||||||
std::string utf_info="0x"+chrhex(tmp[0]);
|
std::string utf_info="0x"+chrhex(tmp[0]);
|
||||||
for(uint32_t i=1;i<tmp.size();++i)
|
for(u32 i=1;i<tmp.size();++i)
|
||||||
utf_info+=" 0x"+chrhex(tmp[i]);
|
utf_info+=" 0x"+chrhex(tmp[i]);
|
||||||
die("invalid utf-8 character `"+utf_info+"`, make sure it is utf8-text file.");
|
die("invalid utf-8 character `"+utf_info+"`, make sure it is utf8-text file.");
|
||||||
std::exit(1);
|
std::exit(1);
|
||||||
|
@ -351,7 +351,7 @@ void nasal_lexer::scan(const std::string& file)
|
||||||
if(ID(res[ptr]))
|
if(ID(res[ptr]))
|
||||||
{
|
{
|
||||||
str=id_gen();
|
str=id_gen();
|
||||||
uint32_t type=get_type(str);
|
u32 type=get_type(str);
|
||||||
tokens.push_back({line,column,type?type:tok_id,str});
|
tokens.push_back({line,column,type?type:tok_id,str});
|
||||||
}
|
}
|
||||||
else if(DIGIT(res[ptr]))
|
else if(DIGIT(res[ptr]))
|
||||||
|
@ -368,7 +368,7 @@ void nasal_lexer::scan(const std::string& file)
|
||||||
{
|
{
|
||||||
str=res[ptr];
|
str=res[ptr];
|
||||||
++column;
|
++column;
|
||||||
uint32_t type=get_type(str);
|
u32 type=get_type(str);
|
||||||
if(!type)
|
if(!type)
|
||||||
die("invalid operator `"+str+"`.");
|
die("invalid operator `"+str+"`.");
|
||||||
tokens.push_back({line,column,type,str});
|
tokens.push_back({line,column,type,str});
|
||||||
|
|
|
@ -12,7 +12,7 @@ void const_str(nasal_ast& root)
|
||||||
void const_num(nasal_ast& root)
|
void const_num(nasal_ast& root)
|
||||||
{
|
{
|
||||||
auto& vec=root.child();
|
auto& vec=root.child();
|
||||||
double res;
|
f64 res;
|
||||||
switch(root.type())
|
switch(root.type())
|
||||||
{
|
{
|
||||||
case ast_add: res=vec[0].num()+vec[1].num(); break;
|
case ast_add: res=vec[0].num()+vec[1].num(); break;
|
||||||
|
@ -39,7 +39,7 @@ void calc_const(nasal_ast& root)
|
||||||
calc_const(i);
|
calc_const(i);
|
||||||
if(vec.size()==1 && root.type()==ast_neg && vec[0].type()==ast_num)
|
if(vec.size()==1 && root.type()==ast_neg && vec[0].type()==ast_num)
|
||||||
{
|
{
|
||||||
double res=-vec[0].num();
|
f64 res=-vec[0].num();
|
||||||
root.set_num(res);
|
root.set_num(res);
|
||||||
root.child().clear();
|
root.child().clear();
|
||||||
root.set_type(ast_num);
|
root.set_type(ast_num);
|
||||||
|
|
|
@ -41,16 +41,16 @@ class nasal_parse
|
||||||
#define error_line (tokens[ptr].line)
|
#define error_line (tokens[ptr].line)
|
||||||
#define is_call(type) ((type)==tok_lcurve || (type)==tok_lbracket || (type)==tok_dot)
|
#define is_call(type) ((type)==tok_lcurve || (type)==tok_lbracket || (type)==tok_dot)
|
||||||
private:
|
private:
|
||||||
uint32_t ptr;
|
u32 ptr;
|
||||||
uint32_t in_func; // count function block
|
u32 in_func; // count function block
|
||||||
uint32_t in_loop; // count loop block
|
u32 in_loop; // count loop block
|
||||||
const token* tokens;// ref from nasal_lexer
|
const token* tokens;// ref from nasal_lexer
|
||||||
nasal_ast root;
|
nasal_ast root;
|
||||||
nasal_err& nerr;
|
nasal_err& nerr;
|
||||||
|
|
||||||
void die(uint32_t,std::string,bool);
|
void die(u32,std::string,bool);
|
||||||
void match(uint32_t type,const char* info=nullptr);
|
void match(u32 type,const char* info=nullptr);
|
||||||
bool check_comma(const uint32_t*);
|
bool check_comma(const u32*);
|
||||||
bool check_multi_scalar();
|
bool check_multi_scalar();
|
||||||
bool check_func_end(const nasal_ast&);
|
bool check_func_end(const nasal_ast&);
|
||||||
bool check_special_call();
|
bool check_special_call();
|
||||||
|
@ -121,7 +121,7 @@ void nasal_parse::compile(const nasal_lexer& lexer)
|
||||||
}
|
}
|
||||||
nerr.chkerr();
|
nerr.chkerr();
|
||||||
}
|
}
|
||||||
void nasal_parse::die(uint32_t line,std::string info,bool report_prev=false)
|
void nasal_parse::die(u32 line,std::string info,bool report_prev=false)
|
||||||
{
|
{
|
||||||
int col=(int)tokens[ptr].col-(int)tokens[ptr].str.length();
|
int col=(int)tokens[ptr].col-(int)tokens[ptr].str.length();
|
||||||
if(tokens[ptr].type==tok_str)
|
if(tokens[ptr].type==tok_str)
|
||||||
|
@ -133,7 +133,7 @@ void nasal_parse::die(uint32_t line,std::string info,bool report_prev=false)
|
||||||
}
|
}
|
||||||
nerr.err("parse",line,col<0?0:col,info);
|
nerr.err("parse",line,col<0?0:col,info);
|
||||||
}
|
}
|
||||||
void nasal_parse::match(uint32_t type,const char* info)
|
void nasal_parse::match(u32 type,const char* info)
|
||||||
{
|
{
|
||||||
if(tokens[ptr].type!=type)
|
if(tokens[ptr].type!=type)
|
||||||
{
|
{
|
||||||
|
@ -155,9 +155,9 @@ void nasal_parse::match(uint32_t type,const char* info)
|
||||||
return;
|
return;
|
||||||
++ptr;
|
++ptr;
|
||||||
}
|
}
|
||||||
bool nasal_parse::check_comma(const uint32_t* panic_set)
|
bool nasal_parse::check_comma(const u32* panic_set)
|
||||||
{
|
{
|
||||||
for(uint32_t i=0;panic_set[i];++i)
|
for(u32 i=0;panic_set[i];++i)
|
||||||
if(tokens[ptr].type==panic_set[i])
|
if(tokens[ptr].type==panic_set[i])
|
||||||
{
|
{
|
||||||
die(error_line,"expected \',\' between scalars",true);
|
die(error_line,"expected \',\' between scalars",true);
|
||||||
|
@ -167,7 +167,7 @@ bool nasal_parse::check_comma(const uint32_t* panic_set)
|
||||||
}
|
}
|
||||||
bool nasal_parse::check_multi_scalar()
|
bool nasal_parse::check_multi_scalar()
|
||||||
{
|
{
|
||||||
uint32_t check_ptr=ptr,curve=1,bracket=0,brace=0;
|
u32 check_ptr=ptr,curve=1,bracket=0,brace=0;
|
||||||
while(tokens[++check_ptr].type!=tok_eof && curve)
|
while(tokens[++check_ptr].type!=tok_eof && curve)
|
||||||
{
|
{
|
||||||
switch(tokens[check_ptr].type)
|
switch(tokens[check_ptr].type)
|
||||||
|
@ -186,7 +186,7 @@ bool nasal_parse::check_multi_scalar()
|
||||||
}
|
}
|
||||||
bool nasal_parse::check_func_end(const nasal_ast& node)
|
bool nasal_parse::check_func_end(const nasal_ast& node)
|
||||||
{
|
{
|
||||||
uint32_t type=node.type();
|
u32 type=node.type();
|
||||||
if(type==ast_func)
|
if(type==ast_func)
|
||||||
return true;
|
return true;
|
||||||
else if(type==ast_num || type==ast_id || type==ast_str || type==ast_nil || type==ast_vec || type==ast_hash)
|
else if(type==ast_num || type==ast_id || type==ast_str || type==ast_nil || type==ast_vec || type==ast_hash)
|
||||||
|
@ -211,7 +211,7 @@ bool nasal_parse::check_func_end(const nasal_ast& node)
|
||||||
bool nasal_parse::check_special_call()
|
bool nasal_parse::check_special_call()
|
||||||
{
|
{
|
||||||
// special call means like this: function_name(a:1,b:2,c:3);
|
// special call means like this: function_name(a:1,b:2,c:3);
|
||||||
uint32_t check_ptr=ptr,curve=1,bracket=0,brace=0;
|
u32 check_ptr=ptr,curve=1,bracket=0,brace=0;
|
||||||
while(tokens[++check_ptr].type!=tok_eof && curve)
|
while(tokens[++check_ptr].type!=tok_eof && curve)
|
||||||
{
|
{
|
||||||
switch(tokens[check_ptr].type)
|
switch(tokens[check_ptr].type)
|
||||||
|
@ -233,7 +233,7 @@ bool nasal_parse::check_special_call()
|
||||||
}
|
}
|
||||||
bool nasal_parse::need_semi_check(const nasal_ast& node)
|
bool nasal_parse::need_semi_check(const nasal_ast& node)
|
||||||
{
|
{
|
||||||
uint32_t type=node.type();
|
u32 type=node.type();
|
||||||
if(type==ast_for || type==ast_foreach || type==ast_forindex || type==ast_while || type==ast_conditional)
|
if(type==ast_for || type==ast_foreach || type==ast_forindex || type==ast_while || type==ast_conditional)
|
||||||
return false;
|
return false;
|
||||||
return !check_func_end(node);
|
return !check_func_end(node);
|
||||||
|
@ -282,7 +282,7 @@ nasal_ast nasal_parse::vec()
|
||||||
// panic set for this token is not ','
|
// panic set for this token is not ','
|
||||||
// this is the FIRST set of calculation
|
// this is the FIRST set of calculation
|
||||||
// array end with tok_null=0
|
// array end with tok_null=0
|
||||||
const uint32_t panic_set[]={
|
const u32 panic_set[]={
|
||||||
tok_id,tok_str,tok_num,
|
tok_id,tok_str,tok_num,
|
||||||
tok_not,tok_sub,tok_nil,
|
tok_not,tok_sub,tok_nil,
|
||||||
tok_func,tok_var,tok_lcurve,
|
tok_func,tok_var,tok_lcurve,
|
||||||
|
@ -436,7 +436,7 @@ nasal_ast nasal_parse::lcurve_expr()
|
||||||
}
|
}
|
||||||
nasal_ast nasal_parse::expr()
|
nasal_ast nasal_parse::expr()
|
||||||
{
|
{
|
||||||
uint32_t type=tokens[ptr].type;
|
u32 type=tokens[ptr].type;
|
||||||
if((type==tok_break || type==tok_continue) && !in_loop)
|
if((type==tok_break || type==tok_continue) && !in_loop)
|
||||||
die(error_line,"should use break/continue in loops");
|
die(error_line,"should use break/continue in loops");
|
||||||
if(type==tok_ret && !in_func)
|
if(type==tok_ret && !in_func)
|
||||||
|
@ -681,7 +681,7 @@ nasal_ast nasal_parse::callv()
|
||||||
// panic set for this token is not ','
|
// panic set for this token is not ','
|
||||||
// this is the FIRST set of subvec
|
// this is the FIRST set of subvec
|
||||||
// array end with tok_null=0
|
// array end with tok_null=0
|
||||||
const uint32_t panic_set[]={
|
const u32 panic_set[]={
|
||||||
tok_id,tok_str,tok_num,
|
tok_id,tok_str,tok_num,
|
||||||
tok_not,tok_sub,tok_nil,
|
tok_not,tok_sub,tok_nil,
|
||||||
tok_func,tok_var,tok_lcurve,
|
tok_func,tok_var,tok_lcurve,
|
||||||
|
@ -708,7 +708,7 @@ nasal_ast nasal_parse::callf()
|
||||||
// panic set for this token is not ','
|
// panic set for this token is not ','
|
||||||
// this is the FIRST set of calculation/hashmember
|
// this is the FIRST set of calculation/hashmember
|
||||||
// array end with tok_null=0
|
// array end with tok_null=0
|
||||||
const uint32_t panic_set[]={
|
const u32 panic_set[]={
|
||||||
tok_id,tok_str,tok_num,
|
tok_id,tok_str,tok_num,
|
||||||
tok_not,tok_sub,tok_nil,
|
tok_not,tok_sub,tok_nil,
|
||||||
tok_func,tok_var,tok_lcurve,
|
tok_func,tok_var,tok_lcurve,
|
||||||
|
@ -809,7 +809,7 @@ nasal_ast nasal_parse::multi_id()
|
||||||
nasal_ast nasal_parse::multi_scalar(bool check_call_memory)
|
nasal_ast nasal_parse::multi_scalar(bool check_call_memory)
|
||||||
{
|
{
|
||||||
// if check_call_memory is true,we will check if value called here can reach a memory space
|
// if check_call_memory is true,we will check if value called here can reach a memory space
|
||||||
const uint32_t panic_set[]={
|
const u32 panic_set[]={
|
||||||
tok_id,tok_str,tok_num,
|
tok_id,tok_str,tok_num,
|
||||||
tok_not,tok_sub,tok_nil,
|
tok_not,tok_sub,tok_nil,
|
||||||
tok_func,tok_var,tok_lcurve,
|
tok_func,tok_var,tok_lcurve,
|
||||||
|
@ -999,7 +999,7 @@ nasal_ast nasal_parse::ret_expr()
|
||||||
{
|
{
|
||||||
nasal_ast node(tokens[ptr].line,ast_ret);
|
nasal_ast node(tokens[ptr].line,ast_ret);
|
||||||
match(tok_ret);
|
match(tok_ret);
|
||||||
uint32_t type=tokens[ptr].type;
|
u32 type=tokens[ptr].type;
|
||||||
if(
|
if(
|
||||||
type==tok_nil ||
|
type==tok_nil ||
|
||||||
type==tok_num ||
|
type==tok_num ||
|
||||||
|
|
138
nasal_vm.h
138
nasal_vm.h
|
@ -5,16 +5,16 @@ class nasal_vm
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
/* registers and constants of nasal_vm */
|
/* registers and constants of nasal_vm */
|
||||||
uint32_t pc; // program counter
|
u32 pc; // program counter
|
||||||
nasal_ref* localr; // local scope register
|
nasal_ref* localr; // local scope register
|
||||||
nasal_ref* memr; // used for mem_call
|
nasal_ref* memr; // used for mem_call
|
||||||
nasal_ref funcr; // function register
|
nasal_ref funcr; // function register
|
||||||
nasal_ref upvalr; // upvalue register
|
nasal_ref upvalr; // upvalue register
|
||||||
nasal_ref* canary; // avoid stackoverflow
|
nasal_ref* canary; // avoid stackoverflow
|
||||||
nasal_ref* top; // stack top
|
nasal_ref* top; // stack top
|
||||||
const double* num_table;// const numbers, ref from nasal_codegen
|
const f64* 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::vector<uint32_t> imm; // immediate number
|
std::vector<u32> imm; // immediate number
|
||||||
|
|
||||||
/* garbage collector */
|
/* garbage collector */
|
||||||
nasal_gc gc;
|
nasal_gc gc;
|
||||||
|
@ -27,22 +27,22 @@ protected:
|
||||||
|
|
||||||
void init(
|
void init(
|
||||||
const std::vector<std::string>&,
|
const std::vector<std::string>&,
|
||||||
const std::vector<double>&,
|
const std::vector<f64>&,
|
||||||
const std::vector<opcode>&,
|
const std::vector<opcode>&,
|
||||||
const std::vector<std::string>&,
|
const std::vector<std::string>&,
|
||||||
const std::vector<std::string>&);
|
const std::vector<std::string>&);
|
||||||
/* debug functions */
|
/* debug functions */
|
||||||
bool detail_info;
|
bool detail_info;
|
||||||
void valinfo(nasal_ref&);
|
void valinfo(nasal_ref&);
|
||||||
void bytecodeinfo(const char*,const uint32_t);
|
void bytecodeinfo(const char*,const u32);
|
||||||
void traceback();
|
void traceback();
|
||||||
void stackinfo(const uint32_t);
|
void stackinfo(const u32);
|
||||||
void register_info();
|
void register_info();
|
||||||
void global_state();
|
void global_state();
|
||||||
void local_state();
|
void local_state();
|
||||||
void upval_state();
|
void upval_state();
|
||||||
void detail();
|
void detail();
|
||||||
void opcallsort(const uint64_t*);
|
void opcallsort(const u64*);
|
||||||
void die(const std::string&);
|
void die(const std::string&);
|
||||||
/* vm calculation functions*/
|
/* vm calculation functions*/
|
||||||
bool condition(nasal_ref);
|
bool condition(nasal_ref);
|
||||||
|
@ -137,7 +137,7 @@ public:
|
||||||
|
|
||||||
void nasal_vm::init(
|
void nasal_vm::init(
|
||||||
const std::vector<std::string>& strs,
|
const std::vector<std::string>& strs,
|
||||||
const std::vector<double>& nums,
|
const std::vector<f64>& nums,
|
||||||
const std::vector<opcode>& code,
|
const std::vector<opcode>& code,
|
||||||
const std::vector<std::string>& filenames,
|
const std::vector<std::string>& filenames,
|
||||||
const std::vector<std::string>& argv)
|
const std::vector<std::string>& argv)
|
||||||
|
@ -156,7 +156,7 @@ void nasal_vm::init(
|
||||||
top=stack;
|
top=stack;
|
||||||
|
|
||||||
/* clear main stack */
|
/* clear main stack */
|
||||||
for(uint32_t i=0;i<STACK_DEPTH;++i)
|
for(u32 i=0;i<STACK_DEPTH;++i)
|
||||||
stack[i]=nil;
|
stack[i]=nil;
|
||||||
}
|
}
|
||||||
void nasal_vm::valinfo(nasal_ref& val)
|
void nasal_vm::valinfo(nasal_ref& val)
|
||||||
|
@ -169,35 +169,35 @@ void nasal_vm::valinfo(nasal_ref& val)
|
||||||
case vm_ret: std::cout<<"| pc | 0x"<<std::hex
|
case vm_ret: std::cout<<"| pc | 0x"<<std::hex
|
||||||
<<val.ret()<<std::dec;break;
|
<<val.ret()<<std::dec;break;
|
||||||
case vm_addr: std::cout<<"| addr | 0x"<<std::hex
|
case vm_addr: std::cout<<"| addr | 0x"<<std::hex
|
||||||
<<(uint64_t)val.addr()<<std::dec;break;
|
<<(u64)val.addr()<<std::dec;break;
|
||||||
case vm_cnt: std::cout<<"| cnt | "<<val.cnt();break;
|
case vm_cnt: std::cout<<"| cnt | "<<val.cnt();break;
|
||||||
case vm_nil: std::cout<<"| nil |";break;
|
case vm_nil: std::cout<<"| nil |";break;
|
||||||
case vm_num: std::cout<<"| num | "<<val.num();break;
|
case vm_num: std::cout<<"| num | "<<val.num();break;
|
||||||
case vm_str: std::cout<<"| str | <0x"<<std::hex<<(uint64_t)p
|
case vm_str: std::cout<<"| str | <0x"<<std::hex<<(u64)p
|
||||||
<<"> "<<rawstr(val.str(),16)<<std::dec;break;
|
<<"> "<<rawstr(val.str(),16)<<std::dec;break;
|
||||||
case vm_func: std::cout<<"| func | <0x"<<std::hex<<(uint64_t)p
|
case vm_func: std::cout<<"| func | <0x"<<std::hex<<(u64)p
|
||||||
<<"> entry:0x"<<val.func().entry
|
<<"> entry:0x"<<val.func().entry
|
||||||
<<std::dec;break;
|
<<std::dec;break;
|
||||||
case vm_upval:std::cout<<"| upval| <0x"<<std::hex<<(uint64_t)p
|
case vm_upval:std::cout<<"| upval| <0x"<<std::hex<<(u64)p
|
||||||
<<std::dec<<"> ["<<val.upval().size
|
<<std::dec<<"> ["<<val.upval().size
|
||||||
<<" val]";break;
|
<<" val]";break;
|
||||||
case vm_vec: std::cout<<"| vec | <0x"<<std::hex<<(uint64_t)p
|
case vm_vec: std::cout<<"| vec | <0x"<<std::hex<<(u64)p
|
||||||
<<std::dec<<"> ["<<val.vec().size()
|
<<std::dec<<"> ["<<val.vec().size()
|
||||||
<<" val]";break;
|
<<" val]";break;
|
||||||
case vm_hash: std::cout<<"| hash | <0x"<<std::hex<<(uint64_t)p
|
case vm_hash: std::cout<<"| hash | <0x"<<std::hex<<(u64)p
|
||||||
<<std::dec<<"> {"<<val.hash().size()
|
<<std::dec<<"> {"<<val.hash().size()
|
||||||
<<" val}";break;
|
<<" val}";break;
|
||||||
case vm_obj: std::cout<<"| obj | <0x"<<std::hex<<(uint64_t)p
|
case vm_obj: std::cout<<"| obj | <0x"<<std::hex<<(u64)p
|
||||||
<<"> obj:0x"<<(uint64_t)val.obj().ptr
|
<<"> obj:0x"<<(u64)val.obj().ptr
|
||||||
<<std::dec;break;
|
<<std::dec;break;
|
||||||
case vm_co: std::cout<<"| co | <0x"<<std::hex<<(uint64_t)p
|
case vm_co: std::cout<<"| co | <0x"<<std::hex<<(u64)p
|
||||||
<<std::dec<<"> coroutine";break;
|
<<std::dec<<"> coroutine";break;
|
||||||
default: std::cout<<"| err | <0x"<<std::hex<<(uint64_t)p
|
default: std::cout<<"| err | <0x"<<std::hex<<(u64)p
|
||||||
<<std::dec<<"> unknown object";break;
|
<<std::dec<<"> unknown object";break;
|
||||||
}
|
}
|
||||||
std::cout<<"\n";
|
std::cout<<"\n";
|
||||||
}
|
}
|
||||||
void nasal_vm::bytecodeinfo(const char* header,const uint32_t p)
|
void nasal_vm::bytecodeinfo(const char* header,const u32 p)
|
||||||
{
|
{
|
||||||
const opcode& c=bytecode[p];
|
const opcode& c=bytecode[p];
|
||||||
c.print(header,num_table,str_table,p,true);
|
c.print(header,num_table,str_table,p,true);
|
||||||
|
@ -205,18 +205,18 @@ void nasal_vm::bytecodeinfo(const char* header,const uint32_t p)
|
||||||
}
|
}
|
||||||
void nasal_vm::traceback()
|
void nasal_vm::traceback()
|
||||||
{
|
{
|
||||||
const uint32_t global_size=bytecode[0].num; // bytecode[0] is op_intg
|
const u32 global_size=bytecode[0].num; // bytecode[0] is op_intg
|
||||||
nasal_ref* t=top;
|
nasal_ref* t=top;
|
||||||
nasal_ref* bottom=stack+global_size;
|
nasal_ref* bottom=stack+global_size;
|
||||||
std::stack<uint32_t> ret;
|
std::stack<u32> ret;
|
||||||
for(nasal_ref* i=bottom;i<=t;++i)
|
for(nasal_ref* i=bottom;i<=t;++i)
|
||||||
if(i->type==vm_ret)
|
if(i->type==vm_ret)
|
||||||
ret.push(i->ret());
|
ret.push(i->ret());
|
||||||
// push pc to ret stack to store the position program crashed
|
// push pc to ret stack to store the position program crashed
|
||||||
ret.push(pc);
|
ret.push(pc);
|
||||||
std::cout<<"trace back:\n";
|
std::cout<<"trace back:\n";
|
||||||
uint32_t same=0,last=0xffffffff;
|
u32 same=0,last=0xffffffff;
|
||||||
for(uint32_t point=0;!ret.empty();last=point,ret.pop())
|
for(u32 point=0;!ret.empty();last=point,ret.pop())
|
||||||
{
|
{
|
||||||
if((point=ret.top())==last)
|
if((point=ret.top())==last)
|
||||||
{
|
{
|
||||||
|
@ -233,20 +233,20 @@ void nasal_vm::traceback()
|
||||||
std::cout<<" 0x"<<std::hex<<std::setw(8)<<std::setfill('0')
|
std::cout<<" 0x"<<std::hex<<std::setw(8)<<std::setfill('0')
|
||||||
<<last<<std::dec<<": "<<same<<" same call(s)\n";
|
<<last<<std::dec<<": "<<same<<" same call(s)\n";
|
||||||
}
|
}
|
||||||
void nasal_vm::stackinfo(const uint32_t limit=10)
|
void nasal_vm::stackinfo(const u32 limit=10)
|
||||||
{
|
{
|
||||||
/* bytecode[0] is op_intg, the .num is the global size */
|
/* bytecode[0] is op_intg, the .num is the global size */
|
||||||
uint32_t gsize=gc.stack==stack?bytecode[0].num:0;
|
u32 gsize=gc.stack==stack?bytecode[0].num:0;
|
||||||
nasal_ref* t=top;
|
nasal_ref* t=top;
|
||||||
nasal_ref* bottom=gc.stack+gsize;
|
nasal_ref* bottom=gc.stack+gsize;
|
||||||
std::cout<<"vm stack(0x"<<std::hex<<(uint64_t)bottom<<std::dec
|
std::cout<<"vm stack(0x"<<std::hex<<(u64)bottom<<std::dec
|
||||||
<<"<sp+"<<gsize<<">, limit "<<limit<<", total "
|
<<"<sp+"<<gsize<<">, limit "<<limit<<", total "
|
||||||
<<(t<bottom? 0:(int64_t)(t-bottom+1))<<")\n";
|
<<(t<bottom? 0:(i64)(t-bottom+1))<<")\n";
|
||||||
for(uint32_t i=0;i<limit && t>=bottom;++i,--t)
|
for(u32 i=0;i<limit && t>=bottom;++i,--t)
|
||||||
{
|
{
|
||||||
std::cout<<" 0x"<<std::hex
|
std::cout<<" 0x"<<std::hex
|
||||||
<<std::setw(8)<<std::setfill('0')
|
<<std::setw(8)<<std::setfill('0')
|
||||||
<<(uint64_t)(t-gc.stack)<<std::dec;
|
<<(u64)(t-gc.stack)<<std::dec;
|
||||||
valinfo(t[0]);
|
valinfo(t[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -254,11 +254,11 @@ void nasal_vm::register_info()
|
||||||
{
|
{
|
||||||
std::cout<<"registers("<<(gc.coroutine?"coroutine":"main")<<")\n"<<std::hex
|
std::cout<<"registers("<<(gc.coroutine?"coroutine":"main")<<")\n"<<std::hex
|
||||||
<<" [ pc ] | pc | 0x"<<pc<<"\n"
|
<<" [ pc ] | pc | 0x"<<pc<<"\n"
|
||||||
<<" [ global ] | addr | 0x"<<(uint64_t)stack<<"\n"
|
<<" [ global ] | addr | 0x"<<(u64)stack<<"\n"
|
||||||
<<" [ localr ] | addr | 0x"<<(uint64_t)localr<<"\n"
|
<<" [ localr ] | addr | 0x"<<(u64)localr<<"\n"
|
||||||
<<" [ memr ] | addr | 0x"<<(uint64_t)memr<<"\n"
|
<<" [ memr ] | addr | 0x"<<(u64)memr<<"\n"
|
||||||
<<" [ canary ] | addr | 0x"<<(uint64_t)canary<<"\n"
|
<<" [ canary ] | addr | 0x"<<(u64)canary<<"\n"
|
||||||
<<" [ top ] | addr | 0x"<<(uint64_t)top<<"\n"
|
<<" [ top ] | addr | 0x"<<(u64)top<<"\n"
|
||||||
<<std::dec;
|
<<std::dec;
|
||||||
std::cout<<" [ funcr ]";valinfo(funcr);
|
std::cout<<" [ funcr ]";valinfo(funcr);
|
||||||
std::cout<<" [ upvalr ]";valinfo(upvalr);
|
std::cout<<" [ upvalr ]";valinfo(upvalr);
|
||||||
|
@ -267,8 +267,8 @@ void nasal_vm::global_state()
|
||||||
{
|
{
|
||||||
if(!bytecode[0].num || stack[0].type==vm_none) // bytecode[0].op is op_intg
|
if(!bytecode[0].num || stack[0].type==vm_none) // bytecode[0].op is op_intg
|
||||||
return;
|
return;
|
||||||
std::cout<<"global(0x"<<std::hex<<(uint64_t)stack<<"<sp+0>)\n"<<std::dec;
|
std::cout<<"global(0x"<<std::hex<<(u64)stack<<"<sp+0>)\n"<<std::dec;
|
||||||
for(uint32_t i=0;i<bytecode[0].num;++i)
|
for(u32 i=0;i<bytecode[0].num;++i)
|
||||||
{
|
{
|
||||||
std::cout<<" 0x"<<std::hex<<std::setw(8)
|
std::cout<<" 0x"<<std::hex<<std::setw(8)
|
||||||
<<std::setfill('0')<<i<<std::dec;
|
<<std::setfill('0')<<i<<std::dec;
|
||||||
|
@ -279,10 +279,10 @@ void nasal_vm::local_state()
|
||||||
{
|
{
|
||||||
if(!localr || !funcr.func().lsize)
|
if(!localr || !funcr.func().lsize)
|
||||||
return;
|
return;
|
||||||
const uint32_t lsize=funcr.func().lsize;
|
const u32 lsize=funcr.func().lsize;
|
||||||
std::cout<<"local(0x"<<std::hex<<(uint64_t)localr
|
std::cout<<"local(0x"<<std::hex<<(u64)localr
|
||||||
<<"<sp+"<<(uint64_t)(localr-gc.stack)<<">)\n"<<std::dec;
|
<<"<sp+"<<(u64)(localr-gc.stack)<<">)\n"<<std::dec;
|
||||||
for(uint32_t i=0;i<lsize;++i)
|
for(u32 i=0;i<lsize;++i)
|
||||||
{
|
{
|
||||||
std::cout<<" 0x"<<std::hex<<std::setw(8)
|
std::cout<<" 0x"<<std::hex<<std::setw(8)
|
||||||
<<std::setfill('0')<<i<<std::dec;
|
<<std::setfill('0')<<i<<std::dec;
|
||||||
|
@ -295,11 +295,11 @@ void nasal_vm::upval_state()
|
||||||
return;
|
return;
|
||||||
std::cout<<"upvalue\n";
|
std::cout<<"upvalue\n";
|
||||||
auto& upval=funcr.func().upvalue;
|
auto& upval=funcr.func().upvalue;
|
||||||
for(uint32_t i=0;i<upval.size();++i)
|
for(u32 i=0;i<upval.size();++i)
|
||||||
{
|
{
|
||||||
std::cout<<" -> upval["<<i<<"]:\n";
|
std::cout<<" -> upval["<<i<<"]:\n";
|
||||||
auto& uv=upval[i].upval();
|
auto& uv=upval[i].upval();
|
||||||
for(uint32_t j=0;j<uv.size;++j)
|
for(u32 j=0;j<uv.size;++j)
|
||||||
{
|
{
|
||||||
std::cout<<" 0x"<<std::hex<<std::setw(8)
|
std::cout<<" 0x"<<std::hex<<std::setw(8)
|
||||||
<<std::setfill('0')<<j<<std::dec;
|
<<std::setfill('0')<<j<<std::dec;
|
||||||
|
@ -314,12 +314,12 @@ void nasal_vm::detail()
|
||||||
local_state();
|
local_state();
|
||||||
upval_state();
|
upval_state();
|
||||||
}
|
}
|
||||||
void nasal_vm::opcallsort(const uint64_t* arr)
|
void nasal_vm::opcallsort(const u64* arr)
|
||||||
{
|
{
|
||||||
typedef std::pair<uint32_t,uint64_t> op;
|
typedef std::pair<u32,u64> op;
|
||||||
std::vector<op> opcall;
|
std::vector<op> opcall;
|
||||||
uint64_t total=0;
|
u64 total=0;
|
||||||
for(uint32_t i=0;i<op_ret+1;++i)
|
for(u32 i=0;i<op_ret+1;++i)
|
||||||
{
|
{
|
||||||
total+=arr[i];
|
total+=arr[i];
|
||||||
opcall.push_back({i,arr[i]});
|
opcall.push_back({i,arr[i]});
|
||||||
|
@ -330,7 +330,7 @@ void nasal_vm::opcallsort(const uint64_t* arr)
|
||||||
std::clog<<"\noperands call info";
|
std::clog<<"\noperands call info";
|
||||||
for(auto& i:opcall)
|
for(auto& i:opcall)
|
||||||
{
|
{
|
||||||
uint64_t rate=i.second*100/total;
|
u64 rate=i.second*100/total;
|
||||||
if(rate)
|
if(rate)
|
||||||
std::clog<<"\n "<<code_table[i.first].name
|
std::clog<<"\n "<<code_table[i.first].name
|
||||||
<<" : "<<i.second<<" ("<<rate<<"%)";
|
<<" : "<<i.second<<" ("<<rate<<"%)";
|
||||||
|
@ -357,7 +357,7 @@ inline bool nasal_vm::condition(nasal_ref val)
|
||||||
return val.num();
|
return val.num();
|
||||||
else if(val.type==vm_str)
|
else if(val.type==vm_str)
|
||||||
{
|
{
|
||||||
const double num=str2num(val.str().c_str());
|
const f64 num=str2num(val.str().c_str());
|
||||||
return std::isnan(num)?!val.str().empty():num;
|
return std::isnan(num)?!val.str().empty():num;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -405,7 +405,7 @@ inline void nasal_vm::opr_newv()
|
||||||
vec.resize(imm[pc]);
|
vec.resize(imm[pc]);
|
||||||
// use top-=imm[pc]-1 here will cause error if imm[pc] is 0
|
// use top-=imm[pc]-1 here will cause error if imm[pc] is 0
|
||||||
top=top-imm[pc]+1;
|
top=top-imm[pc]+1;
|
||||||
for(uint32_t i=0;i<imm[pc];++i)
|
for(u32 i=0;i<imm[pc];++i)
|
||||||
vec[i]=top[i];
|
vec[i]=top[i];
|
||||||
top[0]=newv;
|
top[0]=newv;
|
||||||
}
|
}
|
||||||
|
@ -464,9 +464,9 @@ inline void nasal_vm::opr_unot()
|
||||||
case vm_num:top[0]=val.num()?zero:one;break;
|
case vm_num:top[0]=val.num()?zero:one;break;
|
||||||
case vm_str:
|
case vm_str:
|
||||||
{
|
{
|
||||||
const double num=str2num(val.str().c_str());
|
const f64 num=str2num(val.str().c_str());
|
||||||
if(std::isnan(num))
|
if(std::isnan(num))
|
||||||
top[0]={vm_num,(double)val.str().empty()};
|
top[0]={vm_num,(f64)val.str().empty()};
|
||||||
else
|
else
|
||||||
top[0]=num?zero:one;
|
top[0]=num?zero:one;
|
||||||
}break;
|
}break;
|
||||||
|
@ -616,22 +616,22 @@ inline void nasal_vm::opr_cnt()
|
||||||
{
|
{
|
||||||
if(top[0].type!=vm_vec)
|
if(top[0].type!=vm_vec)
|
||||||
die("cnt: must use vector in forindex/foreach");
|
die("cnt: must use vector in forindex/foreach");
|
||||||
(++top)[0]={vm_cnt,(int64_t)-1};
|
(++top)[0]={vm_cnt,(i64)-1};
|
||||||
}
|
}
|
||||||
inline void nasal_vm::opr_findex()
|
inline void nasal_vm::opr_findex()
|
||||||
{
|
{
|
||||||
if((size_t)(++top[0].cnt())>=top[-1].vec().size())
|
if((usize)(++top[0].cnt())>=top[-1].vec().size())
|
||||||
{
|
{
|
||||||
pc=imm[pc]-1;
|
pc=imm[pc]-1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
top[1]={vm_num,(double)top[0].cnt()};
|
top[1]={vm_num,(f64)top[0].cnt()};
|
||||||
++top;
|
++top;
|
||||||
}
|
}
|
||||||
inline void nasal_vm::opr_feach()
|
inline void nasal_vm::opr_feach()
|
||||||
{
|
{
|
||||||
std::vector<nasal_ref>& ref=top[-1].vec().elems;
|
std::vector<nasal_ref>& ref=top[-1].vec().elems;
|
||||||
if((size_t)(++top[0].cnt())>=ref.size())
|
if((usize)(++top[0].cnt())>=ref.size())
|
||||||
{
|
{
|
||||||
pc=imm[pc]-1;
|
pc=imm[pc]-1;
|
||||||
return;
|
return;
|
||||||
|
@ -679,7 +679,7 @@ inline void nasal_vm::opr_callv()
|
||||||
int len=str.length();
|
int len=str.length();
|
||||||
if(num<-len || num>=len)
|
if(num<-len || num>=len)
|
||||||
die("callv: index out of range:"+std::to_string(val.tonum()));
|
die("callv: index out of range:"+std::to_string(val.tonum()));
|
||||||
top[0]={vm_num,double((uint8_t)str[num>=0? num:num+len])};
|
top[0]={vm_num,f64((u8)str[num>=0? num:num+len])};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
die("callv: must call a vector/hash/string");
|
die("callv: must call a vector/hash/string");
|
||||||
|
@ -710,7 +710,7 @@ 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
|
u32 argc=imm[pc]; // arguments counter
|
||||||
nasal_ref* local=top-argc+1; // arguments begin address
|
nasal_ref* local=top-argc+1; // arguments begin address
|
||||||
if(local[-1].type!=vm_func)
|
if(local[-1].type!=vm_func)
|
||||||
die("callfv: must call a function");
|
die("callfv: must call a function");
|
||||||
|
@ -723,7 +723,7 @@ inline void nasal_vm::opr_callfv()
|
||||||
if(top-argc+func.lsize+3>=canary)
|
if(top-argc+func.lsize+3>=canary)
|
||||||
die("stack overflow");
|
die("stack overflow");
|
||||||
// parameter size is func->psize-1, 1 is reserved for "me"
|
// parameter size is func->psize-1, 1 is reserved for "me"
|
||||||
uint32_t psize=func.psize-1;
|
u32 psize=func.psize-1;
|
||||||
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)");
|
||||||
|
|
||||||
|
@ -732,19 +732,19 @@ inline void nasal_vm::opr_callfv()
|
||||||
if(func.dynpara>=0)// load dynamic arguments
|
if(func.dynpara>=0)// load dynamic arguments
|
||||||
{
|
{
|
||||||
dynamic=gc.alloc(vm_vec);
|
dynamic=gc.alloc(vm_vec);
|
||||||
for(uint32_t i=psize;i<argc;++i)
|
for(u32 i=psize;i<argc;++i)
|
||||||
dynamic.vec().elems.push_back(local[i]);
|
dynamic.vec().elems.push_back(local[i]);
|
||||||
}
|
}
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
uint32_t min_size=(std::min)(psize,argc);
|
u32 min_size=(std::min)(psize,argc);
|
||||||
#else
|
#else
|
||||||
uint32_t min_size=std::min(psize,argc);
|
u32 min_size=std::min(psize,argc);
|
||||||
#endif
|
#endif
|
||||||
for(uint32_t i=min_size;i>=1;--i)// load arguments
|
for(u32 i=min_size;i>=1;--i)// load arguments
|
||||||
local[i]=local[i-1];
|
local[i]=local[i-1];
|
||||||
local[0]=func.local[0];// load "me"
|
local[0]=func.local[0];// load "me"
|
||||||
// load local scope & default arguments
|
// load local scope & default arguments
|
||||||
for(uint32_t i=min_size+1;i<func.lsize;++i)
|
for(u32 i=min_size+1;i<func.lsize;++i)
|
||||||
local[i]=func.local[i];
|
local[i]=func.local[i];
|
||||||
if(func.dynpara>=0)
|
if(func.dynpara>=0)
|
||||||
local[psize+1]=dynamic;
|
local[psize+1]=dynamic;
|
||||||
|
@ -774,7 +774,7 @@ inline void nasal_vm::opr_callfh()
|
||||||
|
|
||||||
nasal_ref* local=top;
|
nasal_ref* local=top;
|
||||||
top+=func.lsize;
|
top+=func.lsize;
|
||||||
for(uint32_t i=0;i<func.lsize;++i)
|
for(u32 i=0;i<func.lsize;++i)
|
||||||
local[i]=func.local[i];
|
local[i]=func.local[i];
|
||||||
|
|
||||||
for(auto& i:func.keys)
|
for(auto& i:func.keys)
|
||||||
|
@ -836,7 +836,7 @@ inline void nasal_vm::opr_slc2()
|
||||||
std::vector<nasal_ref>& ref=top[-1].vec().elems;
|
std::vector<nasal_ref>& ref=top[-1].vec().elems;
|
||||||
std::vector<nasal_ref>& aim=top[0].vec().elems;
|
std::vector<nasal_ref>& aim=top[0].vec().elems;
|
||||||
|
|
||||||
uint8_t type1=val1.type,type2=val2.type;
|
u8 type1=val1.type,type2=val2.type;
|
||||||
int num1=val1.tonum();
|
int num1=val1.tonum();
|
||||||
int num2=val2.tonum();
|
int num2=val2.tonum();
|
||||||
int size=ref.size();
|
int size=ref.size();
|
||||||
|
@ -957,7 +957,7 @@ inline void nasal_vm::opr_ret()
|
||||||
auto& upval=up.upval();
|
auto& upval=up.upval();
|
||||||
auto size=func.func().lsize;
|
auto size=func.func().lsize;
|
||||||
upval.onstk=false;
|
upval.onstk=false;
|
||||||
for(uint32_t i=0;i<size;++i)
|
for(u32 i=0;i<size;++i)
|
||||||
upval.elems.push_back(local[i]);
|
upval.elems.push_back(local[i]);
|
||||||
}
|
}
|
||||||
// cannot use gc.coroutine to judge,
|
// cannot use gc.coroutine to judge,
|
||||||
|
@ -974,7 +974,7 @@ void nasal_vm::run(
|
||||||
{
|
{
|
||||||
detail_info=detail;
|
detail_info=detail;
|
||||||
init(gen.strs(),gen.nums(),gen.codes(),linker.filelist(),argv);
|
init(gen.strs(),gen.nums(),gen.codes(),linker.filelist(),argv);
|
||||||
uint64_t count[op_ret+1]={0};
|
u64 count[op_ret+1]={0};
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
const void* oprs[]=
|
const void* oprs[]=
|
||||||
{
|
{
|
||||||
|
@ -1049,7 +1049,7 @@ void nasal_vm::run(
|
||||||
&nasal_vm::opr_mcallv, &nasal_vm::opr_mcallh,
|
&nasal_vm::opr_mcallv, &nasal_vm::opr_mcallh,
|
||||||
&nasal_vm::opr_ret
|
&nasal_vm::opr_ret
|
||||||
};
|
};
|
||||||
std::vector<uint32_t> code;
|
std::vector<u32> code;
|
||||||
for(auto& i:gen.codes())
|
for(auto& i:gen.codes())
|
||||||
{
|
{
|
||||||
code.push_back(i.op);
|
code.push_back(i.op);
|
||||||
|
|
Loading…
Reference in New Issue