add io lib & bug fixed
This commit is contained in:
parent
183446d32a
commit
fd0d836c03
13
lib.nas
13
lib.nas
|
@ -116,7 +116,18 @@ var chr=func(code)
|
|||
var io=
|
||||
{
|
||||
fin: func(filename){return __builtin_fin(filename);},
|
||||
fout:func(filename,str){return __builtin_fout(filename,str);}
|
||||
fout:func(filename,str){return __builtin_fout(filename,str);},
|
||||
SEEK_SET:0,
|
||||
SEEK_CUR:1,
|
||||
SEEK_END:2,
|
||||
open:func(filename,mode="r"){return __builtin_open(filename,mode);},
|
||||
close:func(filehandle){return __builtin_close(filehandle);},
|
||||
read:func(filehandle,buf,len){return __builtin_read(filehandle,buf,len);},
|
||||
write:func(filehandle,str){return __builtin_write(filehandle,str);},
|
||||
seek:func(filehandle,pos,whence){return __builtin_seek(filehandle,pos,whence);},
|
||||
tell:func(filehandle){return __builtin_tell(filehandle);},
|
||||
readln:func(filehandle){return __builtin_readln(filehandle);},
|
||||
stat:func(filename){return __builtin_stat(filename);}
|
||||
};
|
||||
|
||||
var bits=
|
||||
|
|
4
nasal.h
4
nasal.h
|
@ -19,6 +19,8 @@
|
|||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
inline double hex_to_double(const char* str)
|
||||
{
|
||||
double ret=0;
|
||||
|
@ -99,7 +101,7 @@ double str2num(const char* str)
|
|||
return is_negative?-ret_num:ret_num;
|
||||
}
|
||||
|
||||
std::string raw_string(const std::string& str)
|
||||
std::string rawstr(const std::string& str)
|
||||
{
|
||||
std::string ret("");
|
||||
for(auto i:str)
|
||||
|
|
|
@ -157,7 +157,7 @@ void nasal_ast::print(const int depth)
|
|||
_type==ast_default ||
|
||||
_type==ast_dynamic ||
|
||||
_type==ast_callh)
|
||||
std::cout<<":"<<raw_string(_str);
|
||||
std::cout<<":"<<rawstr(_str);
|
||||
else if(_type==ast_num || _type==ast_file)
|
||||
std::cout<<":"<<_num;
|
||||
std::cout<<'\n';
|
||||
|
|
225
nasal_builtin.h
225
nasal_builtin.h
|
@ -1,59 +1,69 @@
|
|||
#ifndef __NASAL_BUILTIN_H__
|
||||
#define __NASAL_BUILTIN_H__
|
||||
/*
|
||||
builtin functions must be called inside a outer function like this:
|
||||
var print=func(elems...)
|
||||
{
|
||||
builtin functions must be called inside a function like this:
|
||||
var print=func(elems...){
|
||||
return __builtin_print(elems);
|
||||
}
|
||||
builtin function __builtin_print is wrapped up by print
|
||||
*/
|
||||
|
||||
enum obj_type
|
||||
{
|
||||
obj_file,
|
||||
};
|
||||
// declaration of builtin functions
|
||||
// to add new builtin function,declare it here and write the definition below
|
||||
|
||||
nasal_ref builtin_print(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_append(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_setsize(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_system(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_input(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_sleep(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_fin(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_fout(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_split(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_rand(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_id(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_int(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_num(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_pop(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_str(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_size(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_xor(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_and(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_or(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_nand(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_not(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_sin(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_cos(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_tan(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_exp(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_ln(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_sqrt(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_atan2(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_isnan(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_time(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_contains(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_delete(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_keys(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_import(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_die(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_type(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_substr(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_streq(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_left(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_right(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_cmp(std::vector<nasal_ref>&,nasal_gc&);
|
||||
nasal_ref builtin_chr(std::vector<nasal_ref>&,nasal_gc&);
|
||||
// to add new builtin function, declare it here and write the definition below
|
||||
#define nas_native(name) nasal_ref name(std::vector<nasal_ref>&,nasal_gc&)
|
||||
nas_native(builtin_print);
|
||||
nas_native(builtin_append);
|
||||
nas_native(builtin_setsize);
|
||||
nas_native(builtin_system);
|
||||
nas_native(builtin_input);
|
||||
nas_native(builtin_sleep);
|
||||
nas_native(builtin_fin);
|
||||
nas_native(builtin_fout);
|
||||
nas_native(builtin_split);
|
||||
nas_native(builtin_rand);
|
||||
nas_native(builtin_id);
|
||||
nas_native(builtin_int);
|
||||
nas_native(builtin_num);
|
||||
nas_native(builtin_pop);
|
||||
nas_native(builtin_str);
|
||||
nas_native(builtin_size);
|
||||
nas_native(builtin_xor);
|
||||
nas_native(builtin_and);
|
||||
nas_native(builtin_or);
|
||||
nas_native(builtin_nand);
|
||||
nas_native(builtin_not);
|
||||
nas_native(builtin_sin);
|
||||
nas_native(builtin_cos);
|
||||
nas_native(builtin_tan);
|
||||
nas_native(builtin_exp);
|
||||
nas_native(builtin_ln);
|
||||
nas_native(builtin_sqrt);
|
||||
nas_native(builtin_atan2);
|
||||
nas_native(builtin_isnan);
|
||||
nas_native(builtin_time);
|
||||
nas_native(builtin_contains);
|
||||
nas_native(builtin_delete);
|
||||
nas_native(builtin_keys);
|
||||
nas_native(builtin_import);
|
||||
nas_native(builtin_die);
|
||||
nas_native(builtin_type);
|
||||
nas_native(builtin_substr);
|
||||
nas_native(builtin_streq);
|
||||
nas_native(builtin_left);
|
||||
nas_native(builtin_right);
|
||||
nas_native(builtin_cmp);
|
||||
nas_native(builtin_chr);
|
||||
nas_native(builtin_open);
|
||||
nas_native(builtin_close);
|
||||
nas_native(builtin_read);
|
||||
nas_native(builtin_write);
|
||||
nas_native(builtin_seek);
|
||||
nas_native(builtin_tell);
|
||||
nas_native(builtin_readln);
|
||||
nas_native(builtin_stat);
|
||||
|
||||
nasal_ref builtin_err(const char* func_name,std::string info)
|
||||
{
|
||||
|
@ -111,6 +121,14 @@ struct
|
|||
{"__builtin_right", builtin_right },
|
||||
{"__builtin_cmp", builtin_cmp },
|
||||
{"__builtin_chr", builtin_chr },
|
||||
{"__builtin_open", builtin_open },
|
||||
{"__builtin_close", builtin_close },
|
||||
{"__builtin_read", builtin_read },
|
||||
{"__builtin_write", builtin_write },
|
||||
{"__builtin_seek", builtin_seek },
|
||||
{"__builtin_tell", builtin_tell },
|
||||
{"__builtin_readln", builtin_readln },
|
||||
{"__builtin_stat", builtin_stat },
|
||||
{nullptr, nullptr }
|
||||
};
|
||||
|
||||
|
@ -644,5 +662,114 @@ nasal_ref builtin_chr(std::vector<nasal_ref>& local,nasal_gc& gc)
|
|||
*ret.str()=" ";
|
||||
return ret;
|
||||
}
|
||||
|
||||
nasal_ref builtin_open(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||
{
|
||||
nasal_ref filename=local[1];
|
||||
nasal_ref mode=local[2];
|
||||
if(filename.type!=vm_str)
|
||||
return builtin_err("open","\"filename\" must be string");
|
||||
if(mode.type!=vm_str)
|
||||
return builtin_err("open","\"mode\" must be string");
|
||||
FILE* res=fopen(filename.str()->c_str(),mode.str()->c_str());
|
||||
if(!res)
|
||||
return builtin_err("open","failed to open file <"+*filename.str()+"> errno "+std::to_string(errno));
|
||||
nasal_ref ret=gc.alloc(vm_obj);
|
||||
ret.obj()->type=obj_file;
|
||||
ret.obj()->ptr=(void*)res;
|
||||
return ret;
|
||||
}
|
||||
nasal_ref builtin_close(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||
{
|
||||
nasal_ref filehandle=local[1];
|
||||
if(filehandle.type!=vm_obj || filehandle.obj()->type!=obj_file)
|
||||
return builtin_err("close","not a correct filehandle");
|
||||
fclose((FILE*)filehandle.obj()->ptr);
|
||||
return gc.nil;
|
||||
}
|
||||
nasal_ref builtin_read(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||
{
|
||||
nasal_ref filehandle=local[1];
|
||||
nasal_ref buf=local[2];
|
||||
nasal_ref len=local[3];
|
||||
if(filehandle.type!=vm_obj || filehandle.obj()->type!=obj_file)
|
||||
return builtin_err("read","not a correct filehandle");
|
||||
if(buf.type!=vm_str)
|
||||
return builtin_err("read","\"buf\" must be string");
|
||||
if(len.type!=vm_num)
|
||||
return builtin_err("read","\"len\" must be number");
|
||||
if(len.num()<=0 || len.num()>=(1<<30))
|
||||
return builtin_err("read","\"len\" less than 1 or too large");
|
||||
char* buff=new char[(size_t)len.num()+1];
|
||||
if(!buff)
|
||||
return builtin_err("read","memory allocation error");
|
||||
double res=fread(buff,1,len.num(),(FILE*)filehandle.obj()->ptr);
|
||||
*buf.str()=buff;
|
||||
delete []buff;
|
||||
return {vm_num,res};
|
||||
}
|
||||
nasal_ref builtin_write(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||
{
|
||||
nasal_ref filehandle=local[1];
|
||||
nasal_ref str=local[2];
|
||||
if(filehandle.type!=vm_obj || filehandle.obj()->type!=obj_file)
|
||||
return builtin_err("write","not a correct filehandle");
|
||||
if(str.type!=vm_str)
|
||||
return builtin_err("write","\"str\" must be string");
|
||||
double res=(double)fwrite(str.str()->c_str(),1,str.str()->length(),(FILE*)filehandle.obj()->ptr);
|
||||
return {vm_num,res};
|
||||
}
|
||||
nasal_ref builtin_seek(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||
{
|
||||
nasal_ref filehandle=local[1];
|
||||
nasal_ref position=local[2];
|
||||
nasal_ref whence=local[3];
|
||||
if(filehandle.type!=vm_obj || filehandle.obj()->type!=obj_file)
|
||||
return builtin_err("seek","not a correct filehandle");
|
||||
if(position.type!=vm_num)
|
||||
return builtin_err("seek","\"pos\" must be number");
|
||||
if(whence.type!=vm_num || whence.num()<0 || whence.num()>2)
|
||||
return builtin_err("seek","\"whence\" must be number between 0 and 2");
|
||||
double res=fseek((FILE*)filehandle.obj()->ptr,position.num(),whence.num());
|
||||
return {vm_num,res};
|
||||
}
|
||||
nasal_ref builtin_tell(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||
{
|
||||
nasal_ref filehandle=local[1];
|
||||
if(filehandle.type!=vm_obj || filehandle.obj()->type!=obj_file)
|
||||
return builtin_err("tell","not a correct filehandle");
|
||||
double res=ftell((FILE*)filehandle.obj()->ptr);
|
||||
return {vm_num,res};
|
||||
}
|
||||
nasal_ref builtin_readln(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||
{
|
||||
nasal_ref filehandle=local[1];
|
||||
if(filehandle.type!=vm_obj || filehandle.obj()->type!=obj_file)
|
||||
return builtin_err("readln","not a correct filehandle");
|
||||
/* unfinished */
|
||||
return gc.nil;
|
||||
}
|
||||
nasal_ref builtin_stat(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||
{
|
||||
nasal_ref filename=local[1];
|
||||
if(filename!=vm_str)
|
||||
return builtin_err("stat","\"filename\" must be string");
|
||||
struct stat buf;
|
||||
if(stat(filename.str()->c_str(),&buf)<0)
|
||||
return builtin_err("stat","failed to open file <"+*filename.str()+">");
|
||||
nasal_ref ret=gc.alloc(vm_vec);
|
||||
ret.vec()->elems={
|
||||
{vm_num,(double)buf.st_dev},
|
||||
{vm_num,(double)buf.st_ino},
|
||||
{vm_num,(double)buf.st_mode},
|
||||
{vm_num,(double)buf.st_nlink},
|
||||
{vm_num,(double)buf.st_uid},
|
||||
{vm_num,(double)buf.st_gid},
|
||||
{vm_num,(double)buf.st_rdev},
|
||||
{vm_num,(double)buf.st_size},
|
||||
{vm_num,(double)buf.st_atime},
|
||||
{vm_num,(double)buf.st_mtime},
|
||||
{vm_num,(double)buf.st_ctime}
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
#endif
|
|
@ -272,7 +272,6 @@ void nasal_codegen::regist_number(const double num)
|
|||
num_table[num]=size;
|
||||
num_res.push_back(num);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::regist_string(const std::string& str)
|
||||
|
@ -283,7 +282,6 @@ void nasal_codegen::regist_string(const std::string& str)
|
|||
str_table[str]=size;
|
||||
str_res.push_back(str);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::find_symbol(const nasal_ast& node)
|
||||
|
@ -309,7 +307,6 @@ void nasal_codegen::find_symbol(const nasal_ast& node)
|
|||
else
|
||||
for(auto& i:node.child())
|
||||
find_symbol(i);
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::add_sym(const std::string& name)
|
||||
|
@ -320,15 +317,12 @@ void nasal_codegen::add_sym(const std::string& name)
|
|||
if(sym==name)
|
||||
return;
|
||||
global.push_back(name);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(auto& sym:local.back())
|
||||
if(sym==name)
|
||||
return;
|
||||
local.back().push_back(name);
|
||||
}
|
||||
return;
|
||||
for(auto& sym:local.back())
|
||||
if(sym==name)
|
||||
return;
|
||||
local.back().push_back(name);
|
||||
}
|
||||
|
||||
int nasal_codegen::local_find(const std::string& name)
|
||||
|
@ -357,20 +351,16 @@ int nasal_codegen::upvalue_find(const std::string& name)
|
|||
if(size<=1)
|
||||
return -1;
|
||||
auto iter=local.begin();
|
||||
for(uint32_t i=0;i<size-1;++i)
|
||||
{
|
||||
for(uint32_t i=0;i<size-1;++i,++iter)
|
||||
for(uint32_t j=0;j<iter->size();++j)
|
||||
if((*iter)[j]==name)
|
||||
index=((i<<16)|j);
|
||||
++iter;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
void nasal_codegen::gen(uint8_t op,uint32_t num,uint32_t line)
|
||||
{
|
||||
code.push_back({op,fileindex,num,line});
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::num_gen(const nasal_ast& ast)
|
||||
|
@ -383,14 +373,12 @@ void nasal_codegen::num_gen(const nasal_ast& ast)
|
|||
regist_number(num);
|
||||
gen(op_pnum,num_table[num],ast.line());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::str_gen(const nasal_ast& ast)
|
||||
{
|
||||
regist_string(ast.str());
|
||||
gen(op_pstr,str_table[ast.str()],ast.line());
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::vec_gen(const nasal_ast& ast)
|
||||
|
@ -398,7 +386,6 @@ void nasal_codegen::vec_gen(const nasal_ast& ast)
|
|||
for(auto& node:ast.child())
|
||||
calc_gen(node);
|
||||
gen(op_newv,ast.size(),ast.line());
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::hash_gen(const nasal_ast& ast)
|
||||
|
@ -411,7 +398,6 @@ void nasal_codegen::hash_gen(const nasal_ast& ast)
|
|||
regist_string(str);
|
||||
gen(op_happ,str_table[str],node.line());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::func_gen(const nasal_ast& ast)
|
||||
|
@ -465,7 +451,6 @@ void nasal_codegen::func_gen(const nasal_ast& ast)
|
|||
gen(op_ret,0,block.line());
|
||||
}
|
||||
code[jmp_ptr].num=code.size();
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::call_gen(const nasal_ast& ast)
|
||||
|
@ -486,7 +471,6 @@ void nasal_codegen::call_gen(const nasal_ast& ast)
|
|||
case ast_callf:call_func(tmp);break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::call_id(const nasal_ast& ast)
|
||||
|
@ -517,14 +501,12 @@ void nasal_codegen::call_id(const nasal_ast& ast)
|
|||
return;
|
||||
}
|
||||
die("undefined symbol \""+str+"\".",ast.line());
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::call_hash(const nasal_ast& ast)
|
||||
{
|
||||
regist_string(ast.str());
|
||||
gen(op_callh,str_table[ast.str()],ast.line());
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::call_vec(const nasal_ast& ast)
|
||||
|
@ -552,7 +534,6 @@ void nasal_codegen::call_vec(const nasal_ast& ast)
|
|||
}
|
||||
}
|
||||
gen(op_slcend,0,ast.line());
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::call_func(const nasal_ast& ast)
|
||||
|
@ -570,7 +551,6 @@ void nasal_codegen::call_func(const nasal_ast& ast)
|
|||
calc_gen(node);
|
||||
gen(op_callfv,ast.size(),ast.line());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::mcall(const nasal_ast& ast)
|
||||
|
@ -596,7 +576,6 @@ void nasal_codegen::mcall(const nasal_ast& ast)
|
|||
mcall_hash(tmp);
|
||||
else if(tmp.type()==ast_callv)
|
||||
mcall_vec(tmp);
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::mcall_id(const nasal_ast& ast)
|
||||
|
@ -625,21 +604,18 @@ void nasal_codegen::mcall_id(const nasal_ast& ast)
|
|||
return;
|
||||
}
|
||||
die("undefined symbol \""+str+"\".",ast.line());
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::mcall_vec(const nasal_ast& ast)
|
||||
{
|
||||
calc_gen(ast[0]);
|
||||
gen(op_mcallv,0,ast.line());
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::mcall_hash(const nasal_ast& ast)
|
||||
{
|
||||
regist_string(ast.str());
|
||||
gen(op_mcallh,str_table[ast.str()],ast.line());
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::single_def(const nasal_ast& ast)
|
||||
|
@ -649,7 +625,6 @@ void nasal_codegen::single_def(const nasal_ast& ast)
|
|||
local.empty()?
|
||||
gen(op_loadg,global_find(str),ast.line()):
|
||||
gen(op_loadl,local_find(str),ast.line());
|
||||
return;
|
||||
}
|
||||
void nasal_codegen::multi_def(const nasal_ast& ast)
|
||||
{
|
||||
|
@ -680,7 +655,6 @@ void nasal_codegen::multi_def(const nasal_ast& ast)
|
|||
}
|
||||
gen(op_pop,0,ast.line());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::def_gen(const nasal_ast& ast)
|
||||
|
@ -688,7 +662,6 @@ void nasal_codegen::def_gen(const nasal_ast& ast)
|
|||
ast[0].type()==ast_id?
|
||||
single_def(ast):
|
||||
multi_def(ast);
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::multi_assign_gen(const nasal_ast& ast)
|
||||
|
@ -739,7 +712,6 @@ void nasal_codegen::multi_assign_gen(const nasal_ast& ast)
|
|||
}
|
||||
gen(op_pop,0,ast.line());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::conditional_gen(const nasal_ast& ast)
|
||||
|
@ -769,7 +741,6 @@ void nasal_codegen::conditional_gen(const nasal_ast& ast)
|
|||
}
|
||||
for(auto i:jmp_label)
|
||||
code[i].num=code.size();
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::loop_gen(const nasal_ast& ast)
|
||||
|
@ -783,7 +754,6 @@ void nasal_codegen::loop_gen(const nasal_ast& ast)
|
|||
case ast_forindex: ++in_forindex;forindex_gen(ast);--in_forindex; break;
|
||||
case ast_foreach: ++in_foreach; foreach_gen(ast); --in_foreach; break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::load_continue_break(int continue_place,int break_place)
|
||||
|
@ -794,7 +764,6 @@ void nasal_codegen::load_continue_break(int continue_place,int break_place)
|
|||
code[i].num=break_place;
|
||||
continue_ptr.pop_front();
|
||||
break_ptr.pop_front();
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::while_gen(const nasal_ast& ast)
|
||||
|
@ -808,7 +777,6 @@ void nasal_codegen::while_gen(const nasal_ast& ast)
|
|||
gen(op_jmp,loop_ptr,0);
|
||||
code[condition_ptr].num=code.size();
|
||||
load_continue_break(code.size()-1,code.size());
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::for_gen(const nasal_ast& ast)
|
||||
|
@ -884,7 +852,6 @@ void nasal_codegen::for_gen(const nasal_ast& ast)
|
|||
code[label_exit].num=code.size();
|
||||
|
||||
load_continue_break(continue_place,code.size());
|
||||
return;
|
||||
}
|
||||
void nasal_codegen::forindex_gen(const nasal_ast& ast)
|
||||
{
|
||||
|
@ -912,7 +879,6 @@ void nasal_codegen::forindex_gen(const nasal_ast& ast)
|
|||
load_continue_break(code.size()-1,code.size());
|
||||
gen(op_pop,0,0);// pop vector
|
||||
gen(op_cntpop,0,0);
|
||||
return;
|
||||
}
|
||||
void nasal_codegen::foreach_gen(const nasal_ast& ast)
|
||||
{
|
||||
|
@ -940,7 +906,6 @@ void nasal_codegen::foreach_gen(const nasal_ast& ast)
|
|||
load_continue_break(code.size()-1,code.size());
|
||||
gen(op_pop,0,0);// pop vector
|
||||
gen(op_cntpop,0,0);
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::or_gen(const nasal_ast& ast)
|
||||
|
@ -958,7 +923,6 @@ void nasal_codegen::or_gen(const nasal_ast& ast)
|
|||
gen(op_pnil,0,0);
|
||||
|
||||
code[l1].num=code[l2].num=code.size();
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::and_gen(const nasal_ast& ast)
|
||||
|
@ -977,7 +941,6 @@ void nasal_codegen::and_gen(const nasal_ast& ast)
|
|||
gen(op_pop,0,0);
|
||||
gen(op_pnil,0,0);
|
||||
//jt jumps here
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::trino_gen(const nasal_ast& ast)
|
||||
|
@ -991,7 +954,6 @@ void nasal_codegen::trino_gen(const nasal_ast& ast)
|
|||
code[lfalse].num=code.size();
|
||||
calc_gen(ast[2]);
|
||||
code[lexit].num=code.size();
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::calc_gen(const nasal_ast& ast)
|
||||
|
@ -1097,7 +1059,6 @@ void nasal_codegen::calc_gen(const nasal_ast& ast)
|
|||
call_id(ast[0]);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::block_gen(const nasal_ast& ast)
|
||||
|
@ -1167,17 +1128,11 @@ void nasal_codegen::block_gen(const nasal_ast& ast)
|
|||
case ast_trino:calc_gen(tmp);gen(op_pop,0,0);break;
|
||||
case ast_ret:ret_gen(tmp);break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::ret_gen(const nasal_ast& ast)
|
||||
{
|
||||
for(uint32_t i=0;i<in_foreach;++i)
|
||||
{
|
||||
gen(op_pop,0,0);
|
||||
gen(op_cntpop,0,0);
|
||||
}
|
||||
for(uint32_t i=0;i<in_forindex;++i)
|
||||
for(uint32_t i=0;i<in_foreach+in_forindex;++i)
|
||||
{
|
||||
gen(op_pop,0,0);
|
||||
gen(op_cntpop,0,0);
|
||||
|
@ -1187,7 +1142,6 @@ void nasal_codegen::ret_gen(const nasal_ast& ast)
|
|||
else
|
||||
gen(op_pnil,0,ast.line());
|
||||
gen(op_ret,0,ast.line());
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::compile(const nasal_parse& parse,const nasal_import& import)
|
||||
|
@ -1272,7 +1226,6 @@ void nasal_codegen::compile(const nasal_parse& parse,const nasal_import& import)
|
|||
gen(op_exit,0,0);
|
||||
if(global.size()>=STACK_MAX_DEPTH)
|
||||
die("too many global variants: "+std::to_string(global.size())+".",0);
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::print_op(uint32_t index)
|
||||
|
@ -1303,11 +1256,9 @@ void nasal_codegen::print_op(uint32_t index)
|
|||
case op_lnkc: case op_lnkeqc:
|
||||
case op_callh: case op_mcallh:
|
||||
case op_para: case op_defpara:case op_dynpara:
|
||||
printf("0x%x (\"%s\")\n",c.num,raw_string(str_res[c.num]).c_str());
|
||||
break;
|
||||
printf("0x%x (\"%s\")\n",c.num,rawstr(str_res[c.num]).c_str());break;
|
||||
default:printf("\n");break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::print()
|
||||
|
@ -1315,7 +1266,7 @@ void nasal_codegen::print()
|
|||
for(auto num:num_res)
|
||||
std::cout<<".number "<<num<<'\n';
|
||||
for(auto& str:str_res)
|
||||
std::cout<<".symbol \""<<raw_string(str)<<"\"\n";
|
||||
std::cout<<".symbol \""<<rawstr(str)<<"\"\n";
|
||||
for(uint32_t i=0;i<code.size();++i)
|
||||
print_op(i);
|
||||
}
|
||||
|
|
17
nasal_gc.h
17
nasal_gc.h
|
@ -29,7 +29,7 @@ const uint32_t increment[vm_type_size]=
|
|||
1024, // vm_func
|
||||
8192, // vm_vec
|
||||
512, // vm_hash
|
||||
128 // vm_obj
|
||||
64 // vm_obj
|
||||
};
|
||||
|
||||
struct nasal_vec;
|
||||
|
@ -105,7 +105,7 @@ struct nasal_obj
|
|||
uint32_t type;
|
||||
void* ptr;
|
||||
nasal_obj():ptr(nullptr){}
|
||||
void clear();
|
||||
void clear(){ptr=nullptr;}
|
||||
};
|
||||
|
||||
constexpr uint8_t GC_UNCOLLECTED=0;
|
||||
|
@ -258,18 +258,11 @@ void nasal_func::clear()
|
|||
keys.clear();
|
||||
}
|
||||
|
||||
void nasal_obj::clear()
|
||||
{
|
||||
if(ptr)
|
||||
free(ptr);
|
||||
ptr=nullptr;
|
||||
}
|
||||
|
||||
nasal_val::nasal_val(uint8_t val_type)
|
||||
{
|
||||
mark=GC_COLLECTED;
|
||||
type=val_type;
|
||||
switch(type)
|
||||
switch(val_type)
|
||||
{
|
||||
case vm_str: ptr.str=new std::string; break;
|
||||
case vm_vec: ptr.vec=new nasal_vec; break;
|
||||
|
@ -364,7 +357,6 @@ void nasal_gc::mark()
|
|||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
void nasal_gc::sweep()
|
||||
{
|
||||
|
@ -386,7 +378,6 @@ void nasal_gc::sweep()
|
|||
else if(i->mark==GC_FOUND)
|
||||
i->mark=GC_UNCOLLECTED;
|
||||
}
|
||||
return;
|
||||
}
|
||||
void nasal_gc::init(const std::vector<std::string>& s)
|
||||
{
|
||||
|
@ -411,7 +402,6 @@ void nasal_gc::init(const std::vector<std::string>& s)
|
|||
strs[i]={vm_str,new nasal_val(vm_str)};
|
||||
*strs[i].str()=s[i];
|
||||
}
|
||||
return;
|
||||
}
|
||||
void nasal_gc::clear()
|
||||
{
|
||||
|
@ -425,7 +415,6 @@ void nasal_gc::clear()
|
|||
for(auto& i:strs)
|
||||
delete i.value.gcobj;
|
||||
strs.clear();
|
||||
return;
|
||||
}
|
||||
nasal_ref nasal_gc::alloc(uint8_t type)
|
||||
{
|
||||
|
|
|
@ -345,7 +345,7 @@ void nasal_lexer::scan(const std::string& file)
|
|||
void nasal_lexer::print()
|
||||
{
|
||||
for(auto& tok:tokens)
|
||||
std::cout<<"("<<tok.line<<" | "<<raw_string(tok.str)<<")\n";
|
||||
std::cout<<"("<<tok.line<<" | "<<rawstr(tok.str)<<")\n";
|
||||
}
|
||||
|
||||
#endif
|
|
@ -166,7 +166,6 @@ void nasal_parse::match(uint32_t type,const char* info)
|
|||
if(tokens[ptr].type==tok_eof)
|
||||
return;
|
||||
++ptr;
|
||||
return;
|
||||
}
|
||||
bool nasal_parse::check_comma(const uint32_t* panic_set)
|
||||
{
|
||||
|
@ -264,7 +263,6 @@ void nasal_parse::check_memory_reachable(const nasal_ast& node)
|
|||
}
|
||||
else if(node.type()!=ast_id)
|
||||
die(node.line(),"bad left-value");
|
||||
return;
|
||||
}
|
||||
nasal_ast nasal_parse::null()
|
||||
{
|
||||
|
@ -907,7 +905,6 @@ nasal_ast nasal_parse::for_loop()
|
|||
node.add(lcurve_expr());
|
||||
else
|
||||
node.add(calc());
|
||||
// check first semi
|
||||
match(tok_semi,"expected \';\' in for(;;)");
|
||||
// conditional expression
|
||||
if(tokens[ptr].type==tok_eof)
|
||||
|
@ -916,7 +913,6 @@ nasal_ast nasal_parse::for_loop()
|
|||
node.add(null());
|
||||
else
|
||||
node.add(calc());
|
||||
// check second semi
|
||||
match(tok_semi,"expected \';\' in for(;;)");
|
||||
//after loop expression
|
||||
if(tokens[ptr].type==tok_eof)
|
||||
|
@ -943,9 +939,7 @@ nasal_ast nasal_parse::forei_loop()
|
|||
if(tokens[ptr].type!=tok_var && tokens[ptr].type!=tok_id)
|
||||
die(error_line,"expected iterator");
|
||||
node.add(iter_gen());
|
||||
// check semi
|
||||
match(tok_semi,"expected \';\' in foreach/forindex(iter;vector)");
|
||||
// check vector
|
||||
if(tokens[ptr].type==tok_eof)
|
||||
die(error_line,"expected vector");
|
||||
node.add(calc());
|
||||
|
|
|
@ -151,7 +151,7 @@ void nasal_vm::valinfo(nasal_ref& val)
|
|||
case vm_none: printf("\tnull |\n");break;
|
||||
case vm_nil: printf("\tnil |\n");break;
|
||||
case vm_num: printf("\tnum | %lf\n",val.num());break;
|
||||
case vm_str: printf("\tstr | <%p> %s\n",p,raw_string(*val.str()).c_str());break;
|
||||
case vm_str: printf("\tstr | <%p> %s\n",p,rawstr(*val.str()).c_str());break;
|
||||
case vm_func: printf("\tfunc | <%p> func{entry=0x%x}\n",p,val.func()->entry);break;
|
||||
case vm_vec: printf("\tvec | <%p> [%lu val]\n",p,val.vec()->elems.size());break;
|
||||
case vm_hash: printf("\thash | <%p> {%lu member}\n",p,val.hash()->elems.size());break;
|
||||
|
@ -389,7 +389,7 @@ inline void nasal_vm::opr_unot()
|
|||
nasal_ref val=gc.top[0];
|
||||
switch(val.type)
|
||||
{
|
||||
case vm_nil:gc.top[0]=gc.zero;break;
|
||||
case vm_nil:gc.top[0]=gc.one;break;
|
||||
case vm_num:gc.top[0]=val.num()?gc.zero:gc.one;break;
|
||||
case vm_str:
|
||||
{
|
||||
|
|
13
stl/lib.nas
13
stl/lib.nas
|
@ -116,7 +116,18 @@ var chr=func(code)
|
|||
var io=
|
||||
{
|
||||
fin: func(filename){return __builtin_fin(filename);},
|
||||
fout:func(filename,str){return __builtin_fout(filename,str);}
|
||||
fout:func(filename,str){return __builtin_fout(filename,str);},
|
||||
SEEK_SET:0,
|
||||
SEEK_CUR:1,
|
||||
SEEK_END:2,
|
||||
open:func(filename,mode="r"){return __builtin_open(filename,mode);},
|
||||
close:func(filehandle){return __builtin_close(filehandle);},
|
||||
read:func(filehandle,buf,len){return __builtin_read(filehandle,buf,len);},
|
||||
write:func(filehandle,str){return __builtin_write(filehandle,str);},
|
||||
seek:func(filehandle,pos,whence){return __builtin_seek(filehandle,pos,whence);},
|
||||
tell:func(filehandle){return __builtin_tell(filehandle);},
|
||||
readln:func(filehandle){return __builtin_readln(filehandle);},
|
||||
stat:func(filename){return __builtin_stat(filename);}
|
||||
};
|
||||
|
||||
var bits=
|
||||
|
|
|
@ -163,8 +163,6 @@ var func_table=[
|
|||
var bf=func(program)
|
||||
{
|
||||
setsize(paper,131072);
|
||||
for(var i=0;i<131072;i+=1)
|
||||
paper[i]=0;
|
||||
(ptr,code,inum,stack)=(0,[],[],[]);
|
||||
var len=size(program);
|
||||
|
||||
|
|
Loading…
Reference in New Issue