🐛 fix ast print bug & delete some macros

This commit is contained in:
ValKmjolnir 2022-10-30 18:40:03 +08:00
parent 0c216e5f16
commit aaccfbda11
13 changed files with 197 additions and 181 deletions

View File

@ -90,12 +90,11 @@ void execute(const string& file,const std::vector<string>& argv,const u32 cmd)
vm ctx;
// lexer scans file to get tokens
lex.scan(file);
lex.scan(file).chkerr();
// parser gets lexer's token list to compile
parse.compile(lex);
parse.compile(lex).chkerr();
// linker gets parser's ast and load import files to this ast
ld.link(parse,file,cmd&VM_DETAIL);
ld.link(parse,file,cmd&VM_DETAIL).chkerr();
// optimizer does simple optimization on ast
if(cmd&VM_OPT)
optimize(parse.tree());
@ -103,7 +102,7 @@ void execute(const string& file,const std::vector<string>& argv,const u32 cmd)
parse.print();
// code generator gets parser's ast and linker's import file list to generate code
gen.compile(parse,ld);
gen.compile(parse,ld).chkerr();
if(cmd&VM_CODE)
gen.print();

View File

@ -67,20 +67,20 @@ enum ast_node:u32
const char* ast_name[]=
{
"null", "root", "block", "file",
"nil", "num", "str", "id",
"func", "hash", "vec", "pair",
"call", "callh", "callv", "callf",
"subvec", "args", "default", "dynamic",
"and", "or", "=", "+=",
"-=", "*=", "/=" "~=",
"==", "!=", "<", "<=",
">", ">=", "+", "-",
"*", "/", "~", "neg",
"!", "trino", "for", "forindex",
"foreach", "while", "iter", "cond",
"if", "elsif", "else", "multi-id",
"tuple", "def", "multi-assign", "continue",
"null", "root", "block", "file",
"nil", "num", "str", "id",
"func", "hash", "vec", "pair",
"call", "callh", "callv", "callf",
"subvec", "args", "default", "dynamic",
"and", "or", "=", "+=",
"-=", "*=", "/=", "~=",
"==", "!=", "<", "<=",
">", ">=", "+", "-",
"*", "/", "~", "neg",
"!", "trino", "for", "forindex",
"foreach", "while", "iter", "cond",
"if", "elsif", "else", "ltuple",
"tuple", "def", "massign", "continue",
"break", "return"
};

View File

@ -98,10 +98,10 @@ var builtin_fin(var* local,gc& ngc)
var val=local[1];
if(val.type!=vm_str)
return nas_err("io::fin","\"filename\" must be string");
std::ifstream fin(val.str(),std::ios::binary);
std::ifstream in(val.str(),std::ios::binary);
std::stringstream rd;
if(!fin.fail())
rd<<fin.rdbuf();
if(!in.fail())
rd<<in.rdbuf();
return ngc.newstr(rd.str());
}
var builtin_fout(var* local,gc& ngc)
@ -110,10 +110,10 @@ var builtin_fout(var* local,gc& ngc)
var str=local[2];
if(val.type!=vm_str)
return nas_err("io::fout","\"filename\" must be string");
std::ofstream fout(val.str());
if(fout.fail())
std::ofstream out(val.str());
if(out.fail())
return nas_err("io::fout","cannot open <"+val.str()+">");
fout<<str;
out<<str;
return nil;
}
var builtin_split(var* local,gc& ngc)
@ -330,17 +330,15 @@ var builtin_time(var* local,gc& ngc)
{
var val=local[1];
if(val.type!=vm_num)
return nas_err("time","\"begin_time\" must be number");
time_t begin_time=(time_t)val.num();
return {vm_num,(f64)time(&begin_time)};
return nas_err("time","\"begin\" must be number");
time_t begin=(time_t)val.num();
return {vm_num,(f64)time(&begin)};
}
var builtin_contains(var* local,gc& ngc)
{
var hash=local[1];
var key=local[2];
if(hash.type!=vm_hash)
return nas_err("contains","\"hash\" must be hash");
if(key.type!=vm_str)
if(hash.type!=vm_hash || key.type!=vm_str)
return zero;
return hash.hash().elems.count(key.str())?one:zero;
}
@ -734,7 +732,7 @@ var builtin_pipe(var* local,gc& ngc)
res.vec().elems.push_back({vm_num,(f64)fd[1]});
return res;
#endif
return nas_err("pipe","not supported for windows");
return nas_err("pipe","not supported");
}
var builtin_fork(var* local,gc& ngc)
{
@ -744,7 +742,7 @@ var builtin_fork(var* local,gc& ngc)
return nas_err("fork","failed to fork a process");
return {vm_num,(f64)res};
#endif
return nas_err("fork","not supported for windows");
return nas_err("fork","not supported");
}
var builtin_waitpid(var* local,gc& ngc)
{
@ -760,7 +758,7 @@ var builtin_waitpid(var* local,gc& ngc)
vec.vec().elems.push_back({vm_num,(f64)status});
return vec;
#endif
return nas_err("waitpid","not supported for windows");
return nas_err("waitpid","not supported");
}
void obj_dir_dtor(void* ptr)
{
@ -1032,18 +1030,18 @@ var builtin_md5(var* local,gc& ngc)
var builtin_cocreate(var* local,gc& ngc)
{
// +-----------------+
// | old pc | <- top[0]
// +-----------------+
// | old localr | <- top[-1]
// +-----------------+
// | old upvalr | <- top[-2]
// +-----------------+
// | local scope |
// | ... |
// +-----------------+ <- local pointer stored in localr
// | old funcr | <- old function stored in funcr
// +-----------------+
// +-------------+
// | old pc | <- top[0]
// +-------------+
// | old localr | <- top[-1]
// +-------------+
// | old upvalr | <- top[-2]
// +-------------+
// | local scope |
// | ... |
// +-------------+ <- local pointer stored in localr
// | old funcr | <- old function stored in funcr
// +-------------+
var func=local[1];
if(func.type!=vm_func)
return nas_err("coroutine::create","must use a function to create coroutine");
@ -1124,7 +1122,15 @@ var builtin_logtime(var* local,gc& ngc)
time_t t=time(nullptr);
tm* tm_t=localtime(&t);
char s[128];
sprintf(s,"%d-%.2d-%.2d %.2d:%.2d:%.2d",tm_t->tm_year+1900,tm_t->tm_mon+1,tm_t->tm_mday,tm_t->tm_hour,tm_t->tm_min,tm_t->tm_sec);
sprintf(
s,"%d-%.2d-%.2d %.2d:%.2d:%.2d",
tm_t->tm_year+1900,
tm_t->tm_mon+1,
tm_t->tm_mday,
tm_t->tm_hour,
tm_t->tm_min,
tm_t->tm_sec
);
return ngc.newstr(s);
}

View File

@ -264,7 +264,7 @@ private:
void singleop(const u32);
public:
codegen(error& e):fileindex(0),err(e),file(nullptr){}
void compile(const parse&,const linker&);
const error& compile(const parse&,const linker&);
void print();
const std::vector<string>& strs() const {return str_res;}
const std::vector<f64>& nums() const {return num_res;}
@ -1235,7 +1235,7 @@ void codegen::ret_gen(const ast& node)
gen(op_ret,0,node.line());
}
void codegen::compile(const parse& parse,const linker& import)
const error& codegen::compile(const parse& parse,const linker& import)
{
fileindex=0;
file=import.filelist().data();
@ -1248,7 +1248,7 @@ void codegen::compile(const parse& parse,const linker& import)
die("too many global variants: "+std::to_string(global.size()),0,0);
if(code.size()>0xffffffff)
die("too large generated bytecode file: "+std::to_string(code.size()),0,0);
err.chkerr();
return err;
}
void codegen::singleop(const u32 index)

View File

@ -71,7 +71,7 @@ std::ostream& reset(std::ostream& s)
return s;
}
class fstreamline
class flstream
{
protected:
string file;
@ -100,7 +100,7 @@ public:
usize size(){return res.size();}
};
class error:public fstreamline
class error:public flstream
{
private:
u32 cnt;
@ -115,26 +115,29 @@ public:
void err(const string& stage,const string& info)
{
++cnt;
std::cerr<<red<<stage<<": "
<<white<<info<<reset<<"\n\n";
std::cerr
<<red<<stage<<": "
<<white<<info<<reset<<"\n\n";
}
void err(const string& stage,u32 line,u32 col,const string& info)
{
++cnt;
const string& code=res[line-1];
const string iden=identation(std::to_string(line).length());
std::cerr<<red<<stage<<": "
<<white<<info<<reset<<"\n"
<<cyan<<" --> "<<reset
<<orange<<file<<":"<<line<<":"<<col<<"\n";
std::cerr
<<red<<stage<<": "
<<white<<info<<reset<<"\n"
<<cyan<<" --> "<<reset
<<orange<<file<<":"<<line<<":"<<col<<"\n";
if(!line)
{
std::cerr<<"\n";
return;
}
std::cerr<<cyan<<iden<<" | "<<reset<<"\n"
<<cyan<<line<<" | "<<reset<<code<<"\n"
<<cyan<<iden<<" | "<<reset;
std::cerr
<<cyan<<iden<<" | "<<reset<<"\n"
<<cyan<<line<<" | "<<reset<<code<<"\n"
<<cyan<<iden<<" | "<<reset;
for(i32 i=0;i<(i32)col-1;++i)
std::cerr<<char(" \t"[code[i]=='\t']);
std::cerr<<red<<"^ "<<info<<reset<<"\n\n";
@ -143,18 +146,20 @@ public:
{
++cnt;
const string iden=identation(std::to_string(line).length());
std::cerr<<red<<stage<<": "
<<white<<info<<reset<<"\n"
<<cyan<<" --> "<<reset
<<orange<<file<<":"<<line<<"\n";
std::cerr
<<red<<stage<<": "
<<white<<info<<reset<<"\n"
<<cyan<<" --> "<<reset
<<orange<<file<<":"<<line<<"\n";
if(!line)
{
std::cerr<<"\n";
return;
}
std::cerr<<cyan<<iden<<" | "<<reset<<"\n"
<<cyan<<line<<" | "<<reset<<res[line-1]<<"\n"
<<cyan<<iden<<" | "<<reset<<"\n\n";
std::cerr
<<cyan<<iden<<" | "<<reset<<"\n"
<<cyan<<line<<" | "<<reset<<res[line-1]<<"\n"
<<cyan<<iden<<" | "<<reset<<"\n\n";
}
void chkerr() const {if(cnt)std::exit(1);}
};

View File

@ -108,9 +108,9 @@ struct nas_vec
nas_vec():printed(false){}
friend std::ostream& operator<<(std::ostream&,nas_vec&);
usize size(){return elems.size();}
var get_val(const i32);
var* get_mem(const i32);
usize size(){return elems.size();}
var get_val(const i32);
var* get_mem(const i32);
};
struct nas_hash
@ -120,9 +120,9 @@ struct nas_hash
nas_hash():printed(false){}
friend std::ostream& operator<<(std::ostream&,nas_hash&);
usize size(){return elems.size();}
var get_val(const string&);
var* get_mem(const string&);
usize size(){return elems.size();}
var get_val(const string&);
var* get_mem(const string&);
};
struct nas_func

View File

@ -30,7 +30,7 @@ private:
ast load(ast&,u16);
public:
linker(error&);
void link(parse&,const string&,bool);
const error& link(parse&,const string&,bool);
const std::vector<string>& filelist() const {return files;}
};
@ -213,7 +213,7 @@ ast linker::load(ast& root,u16 fileindex)
return tree;
}
void linker::link(parse& parse,const string& self,bool spath=false)
const error& linker::link(parse& parse,const string& self,bool spath=false)
{
show_path=spath;
// initializing
@ -221,5 +221,5 @@ void linker::link(parse& parse,const string& self,bool spath=false)
// scan root and import files,then generate a new ast and return to import_ast
// the main file's index is 0
parse.tree()=load(parse.tree(),0);
err.chkerr();
return err;
}

View File

@ -67,12 +67,8 @@ struct token
u32 col;
u32 type;
string str;
token(u32 l=0,u32 c=0,u32 t=tok_null,const string& s=""):str(s)
{
line=l;
col=c;
type=t;
}
token(u32 l=0,u32 c=0,u32 t=tok_null,const string& s="")
:line(l),col(c),type(t),str(s){}
};
class lexer
@ -85,54 +81,55 @@ private:
error& err;
std::vector<token> toks;
std::unordered_map<string,u32> typetbl {
{"for" ,tok_for },
{"forindex",tok_forindex },
{"foreach" ,tok_foreach },
{"while" ,tok_while },
{"var" ,tok_var },
{"func" ,tok_func },
{"break" ,tok_break },
{"continue",tok_continue },
{"return" ,tok_ret },
{"if" ,tok_if },
{"elsif" ,tok_elsif },
{"else" ,tok_else },
{"nil" ,tok_nil },
{"(" ,tok_lcurve },
{")" ,tok_rcurve },
{"[" ,tok_lbracket },
{"]" ,tok_rbracket },
{"{" ,tok_lbrace },
{"}" ,tok_rbrace },
{";" ,tok_semi },
{"and" ,tok_and },
{"or" ,tok_or },
{"," ,tok_comma },
{"." ,tok_dot },
{"..." ,tok_ellipsis },
{"?" ,tok_quesmark },
{":" ,tok_colon },
{"+" ,tok_add },
{"-" ,tok_sub },
{"*" ,tok_mult },
{"/" ,tok_div },
{"~" ,tok_link },
{"!" ,tok_not },
{"=" ,tok_eq },
{"+=" ,tok_addeq },
{"-=" ,tok_subeq },
{"*=" ,tok_multeq },
{"/=" ,tok_diveq },
{"~=" ,tok_lnkeq },
{"==" ,tok_cmpeq },
{"!=" ,tok_neq },
{"<" ,tok_less },
{"<=" ,tok_leq },
{">" ,tok_grt },
{">=" ,tok_geq }
{"for" ,tok_for },
{"forindex",tok_forindex},
{"foreach" ,tok_foreach },
{"while" ,tok_while },
{"var" ,tok_var },
{"func" ,tok_func },
{"break" ,tok_break },
{"continue",tok_continue},
{"return" ,tok_ret },
{"if" ,tok_if },
{"elsif" ,tok_elsif },
{"else" ,tok_else },
{"nil" ,tok_nil },
{"(" ,tok_lcurve },
{")" ,tok_rcurve },
{"[" ,tok_lbracket},
{"]" ,tok_rbracket},
{"{" ,tok_lbrace },
{"}" ,tok_rbrace },
{";" ,tok_semi },
{"and" ,tok_and },
{"or" ,tok_or },
{"," ,tok_comma },
{"." ,tok_dot },
{"..." ,tok_ellipsis},
{"?" ,tok_quesmark},
{":" ,tok_colon },
{"+" ,tok_add },
{"-" ,tok_sub },
{"*" ,tok_mult },
{"/" ,tok_div },
{"~" ,tok_link },
{"!" ,tok_not },
{"=" ,tok_eq },
{"+=" ,tok_addeq },
{"-=" ,tok_subeq },
{"*=" ,tok_multeq },
{"/=" ,tok_diveq },
{"~=" ,tok_lnkeq },
{"==" ,tok_cmpeq },
{"!=" ,tok_neq },
{"<" ,tok_less },
{"<=" ,tok_leq },
{">" ,tok_grt },
{">=" ,tok_geq }
};
u32 get_type(const string&);
bool skip(char);
bool is_id(char);
bool is_hex(char);
bool is_oct(char);
@ -140,22 +137,23 @@ private:
bool is_str(char);
bool is_single_opr(char);
bool is_calc_opr(char);
void die(const string& info){err.err("lexer",line,column,info);}
void die(const string&);
void open(const string&);
string utf8_gen();
string id_gen();
string num_gen();
string str_gen();
public:
lexer(error& e):
line(1),column(0),
ptr(0),res(""),
err(e){}
void scan(const string&);
void print();
lexer(error& e):line(1),column(0),ptr(0),res(""),err(e){}
const error& scan(const string&);
const std::vector<token>& result() const {return toks;}
};
bool lexer::skip(char c)
{
return c==' '||c=='\n'||c=='\t'||c=='\r'||c==0;
}
bool lexer::is_id(char c)
{
return (c=='_')||('a'<=c && c<='z')||('A'<=c&&c<='Z')||(c<0);
@ -194,7 +192,16 @@ bool lexer::is_single_opr(char c)
bool lexer::is_calc_opr(char c)
{
return c=='='||c=='+'||c=='-'||c=='*'||c=='!'||c=='/'||c=='<'||c=='>'||c=='~';
return (
c=='='||c=='+'||c=='-'||c=='*'||
c=='!'||c=='/'||c=='<'||c=='>'||
c=='~'
);
}
void lexer::die(const string& info)
{
err.err("lexer",line,column,info);
}
void lexer::open(const string& file)
@ -205,21 +212,19 @@ void lexer::open(const string& file)
err.err("lexer","<"+file+"> is not a regular file");
err.chkerr();
}
std::ifstream fin(file,std::ios::binary);
if(fin.fail())
std::ifstream in(file,std::ios::binary);
if(in.fail())
err.err("lexer","failed to open <"+file+">");
else
err.load(file);
std::stringstream ss;
ss<<fin.rdbuf();
ss<<in.rdbuf();
res=ss.str();
}
u32 lexer::get_type(const string& str)
{
if(typetbl.count(str))
return typetbl.at(str);
return tok_null;
return typetbl.count(str)?typetbl.at(str):tok_null;
}
string lexer::utf8_gen()
@ -241,7 +246,8 @@ string lexer::utf8_gen()
string utf_info="0x"+chrhex(tmp[0]);
for(u32 i=1;i<tmp.size();++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 <"+utf_info+">");
err.err("lexer","fatal error occurred, stop");
std::exit(1);
}
str+=tmp;
@ -385,7 +391,7 @@ string lexer::str_gen()
return str;
}
void lexer::scan(const string& file)
const error& lexer::scan(const string& file)
{
line=1;
column=0;
@ -395,7 +401,7 @@ void lexer::scan(const string& file)
string str;
while(ptr<res.size())
{
while(ptr<res.size() && (res[ptr]==' ' || res[ptr]=='\n' || res[ptr]=='\t' || res[ptr]=='\r' || res[ptr]==0))
while(ptr<res.size() && skip(res[ptr]))
{
// these characters will be ignored, and '\n' will cause ++line
++column;
@ -461,11 +467,5 @@ void lexer::scan(const string& file)
}
toks.push_back({line,column,tok_eof,"<eof>"});
res="";
err.chkerr();
}
void lexer::print()
{
for(auto& tok:toks)
std::cout<<"("<<tok.line<<" | "<<rawstr(tok.str,32)<<")\n";
return err;
}

View File

@ -40,7 +40,6 @@
class parse
{
#define err_line (toks[ptr].line)
#define is_call(type) ((type)==tok_lcurve || (type)==tok_lbracket || (type)==tok_dot)
private:
u32 ptr;
u32 in_func; // count function block
@ -97,10 +96,12 @@ private:
};
void die(u32,string,bool);
void next() {++ptr;};
void match(u32 type,const char* info=nullptr);
bool lookahead(u32 type);
bool lookahead(u32);
bool is_call(u32);
bool check_comma(const u32*);
bool check_multi_scalar();
bool check_tuple();
bool check_func_end(const ast&);
bool check_special_call();
bool need_semi_check(const ast&);
@ -152,11 +153,11 @@ public:
toks(nullptr),root(0,0,ast_root),
err(e){}
void print(){root.print_tree();}
void compile(const lexer&);
const error& compile(const lexer&);
ast& tree(){return root;}
const ast& tree() const {return root;}
};
void parse::compile(const lexer& lexer)
const error& parse::compile(const lexer& lexer)
{
toks=lexer.result().data();
ptr=in_func=in_loop=0;
@ -171,7 +172,7 @@ void parse::compile(const lexer& lexer)
else if(need_semi_check(root.child().back()) && !lookahead(tok_eof))
die(err_line,"expected \";\"",true);
}
err.chkerr();
return err;
}
void parse::die(u32 line,string info,bool report_prev=false)
{
@ -205,12 +206,16 @@ void parse::match(u32 type,const char* info)
}
if(lookahead(tok_eof))
return;
++ptr;
next();
}
bool parse::lookahead(u32 type)
{
return toks[ptr].type==type;
}
bool parse::is_call(u32 type)
{
return type==tok_lcurve || type==tok_lbracket || type==tok_dot;
}
bool parse::check_comma(const u32* panic_set)
{
for(u32 i=0;panic_set[i];++i)
@ -221,7 +226,7 @@ bool parse::check_comma(const u32* panic_set)
}
return false;
}
bool parse::check_multi_scalar()
bool parse::check_tuple()
{
u32 check_ptr=ptr,curve=1,bracket=0,brace=0;
while(toks[++check_ptr].type!=tok_eof && curve)
@ -486,7 +491,7 @@ ast parse::lcurve_expr()
{
if(toks[ptr+1].type==tok_var)
return definition();
return check_multi_scalar()?multi_assgin():calc();
return check_tuple()?multi_assgin():calc();
}
ast parse::expr()
{
@ -519,7 +524,7 @@ ast parse::expr()
case tok_semi: break;
default:
die(err_line,"incorrect token <"+toks[ptr].str+">");
++ptr;
next();
break;
}
return {toks[ptr].line,toks[ptr].col,ast_null};
@ -808,7 +813,7 @@ ast parse::definition()
node.add(incurve_def());
match(tok_eq);
if(lookahead(tok_lcurve))
node.add(check_multi_scalar()?multi_scalar(false):calc());
node.add(check_tuple()?multi_scalar(false):calc());
else
node.add(calc());
if(node[0].type()==ast_id && node[1].type()==ast_tuple)
@ -889,7 +894,7 @@ ast parse::multi_assgin()
return node;
}
if(lookahead(tok_lcurve))
node.add(check_multi_scalar()?multi_scalar(false):calc());
node.add(check_tuple()?multi_scalar(false):calc());
else
node.add(calc());
if(node[1].type()==ast_tuple

View File

@ -49,7 +49,7 @@ protected:
void die(const string&);
#define vm_error(info) {die(info);return;}
/* vm calculation functions*/
bool condition(var);
bool cond(var&);
/* vm operands */
void o_intg();
void o_intl();
@ -232,8 +232,8 @@ void vm::stackinfo(const u32 limit=10)
{
/* bytecode[0].num is the global size */
const u32 gsize=ngc.stack==stack?bytecode[0].num:0;
var* t=top;
var* bottom=ngc.stack+gsize;
var* t=top;
var* bottom=ngc.stack+gsize;
std::cout<<"vm stack (0x"<<std::hex<<(u64)bottom<<std::dec
<<" <sp+"<<gsize<<">, limit "<<limit<<", total "
<<(t<bottom? 0:(i64)(t-bottom+1))<<")\n";
@ -324,7 +324,7 @@ void vm::die(const string& str)
top[0]=nil;
}
}
inline bool vm::condition(var val)
inline bool vm::cond(var& val)
{
if(val.type==vm_num)
return val.num();
@ -578,12 +578,12 @@ inline void vm::o_jmp()
}
inline void vm::o_jt()
{
if(condition(top[0]))
if(cond(top[0]))
pc=imm[pc]-1;
}
inline void vm::o_jf()
{
if(!condition(top[0]))
if(!cond(top[0]))
pc=imm[pc]-1;
--top;
}
@ -635,7 +635,7 @@ inline void vm::o_callv()
{
top[0]=vec.vec().get_val(val.tonum());
if(top[0].type==vm_none)
vm_error("index out of range:"+std::to_string(val.tonum()));
vm_error("out of range:"+std::to_string(val.tonum()));
}
else if(vec.type==vm_hash)
{
@ -653,7 +653,7 @@ inline void vm::o_callv()
i32 num=val.tonum();
i32 len=str.length();
if(num<-len || num>=len)
vm_error("index out of range:"+std::to_string(val.tonum()));
vm_error("out of range:"+std::to_string(val.tonum()));
top[0]={vm_num,f64((u8)str[num>=0? num:num+len])};
}
else
@ -667,7 +667,7 @@ inline void vm::o_callvi()
// cannot use operator[],because this may cause overflow
(++top)[0]=val.vec().get_val(imm[pc]);
if(top[0].type==vm_none)
vm_error("index out of range:"+std::to_string(imm[pc]));
vm_error("out of range:"+std::to_string(imm[pc]));
}
inline void vm::o_callh()
{
@ -796,7 +796,7 @@ inline void vm::o_slc()
var val=(top--)[0];
var res=top[-1].vec().get_val(val.tonum());
if(res.type==vm_none)
vm_error("index out of range:"+std::to_string(val.tonum()));
vm_error("out of range:"+std::to_string(val.tonum()));
top[0].vec().elems.push_back(res);
}
inline void vm::o_slc2()
@ -856,7 +856,7 @@ inline void vm::o_mcallv()
{
memr=vec.vec().get_mem(val.tonum());
if(!memr)
vm_error("index out of range:"+std::to_string(val.tonum()));
vm_error("out of range:"+std::to_string(val.tonum()));
}else if(vec.type==vm_hash) // do mcallh but use the mcallv way
{
if(val.type!=vm_str)

View File

@ -19,7 +19,7 @@ var prt=func(){
}
s~='+--------------------+\n';
print(s);
unix.sleep(1/144);
unix.sleep(1/200);
}
var bfs=func(begin,end){

View File

@ -2,6 +2,11 @@
# 2022/5/19
import.stl.process_bar;
if(os.platform()=="windows"){
system("chcp 65001");
system("color");
}
var fib=func(){
var (a,b)=(1,1);
coroutine.yield(a);
@ -76,10 +81,6 @@ var total=1000; # ms
var co=coroutine.create(productor);
var tm=maketimestamp();
if(os.platform()=="windows"){
system("chcp 65001");
system("color");
}
var counter=0;
var bar=process_bar.high_resolution_bar(40);
var consumer=func(){

View File

@ -25,7 +25,7 @@ var prt=func()
s~='\n';
}
print(s);
unix.sleep(1/144);
unix.sleep(1/160);
}
func(){