add io lib & bug fixed

This commit is contained in:
ValKmjolnir 2021-10-27 23:05:25 +08:00
parent 183446d32a
commit fd0d836c03
11 changed files with 219 additions and 136 deletions

13
lib.nas
View File

@ -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=

View File

@ -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)

View File

@ -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';

View File

@ -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

View File

@ -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);
}

View File

@ -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)
{

View File

@ -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

View File

@ -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());

View File

@ -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:
{

View File

@ -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=

View File

@ -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);