From aaccfbda115cea0c8501a710df735867f930f733 Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Sun, 30 Oct 2022 18:40:03 +0800 Subject: [PATCH] :bug: fix ast print bug & delete some macros --- main.cpp | 9 ++- nasal_ast.h | 28 ++++----- nasal_builtin.h | 62 ++++++++++--------- nasal_codegen.h | 6 +- nasal_err.h | 41 +++++++------ nasal_gc.h | 12 ++-- nasal_import.h | 6 +- nasal_lexer.h | 150 ++++++++++++++++++++++----------------------- nasal_parse.h | 29 +++++---- nasal_vm.h | 22 +++---- test/bfs.nas | 2 +- test/coroutine.nas | 9 +-- test/life.nas | 2 +- 13 files changed, 197 insertions(+), 181 deletions(-) diff --git a/main.cpp b/main.cpp index 5393bde..bd9e6f7 100644 --- a/main.cpp +++ b/main.cpp @@ -90,12 +90,11 @@ void execute(const string& file,const std::vector& 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& 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(); diff --git a/nasal_ast.h b/nasal_ast.h index 1a5f784..391274d 100644 --- a/nasal_ast.h +++ b/nasal_ast.h @@ -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" }; diff --git a/nasal_builtin.h b/nasal_builtin.h index 4aa723f..57ac3ae 100644 --- a/nasal_builtin.h +++ b/nasal_builtin.h @@ -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<"); - fout<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); } diff --git a/nasal_codegen.h b/nasal_codegen.h index 16dc75c..6662274 100644 --- a/nasal_codegen.h +++ b/nasal_codegen.h @@ -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& strs() const {return str_res;} const std::vector& 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) diff --git a/nasal_err.h b/nasal_err.h index 09fab2f..1f5b2a1 100644 --- a/nasal_err.h +++ b/nasal_err.h @@ -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< "< "< "< "<& 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; } diff --git a/nasal_lexer.h b/nasal_lexer.h index 431a189..bbce5cd 100644 --- a/nasal_lexer.h +++ b/nasal_lexer.h @@ -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 toks; std::unordered_map 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& 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<"); + 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=""; - err.chkerr(); -} - -void lexer::print() -{ - for(auto& tok:toks) - std::cout<<"("<"); - ++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 diff --git a/nasal_vm.h b/nasal_vm.h index dfd0549..77e4139 100644 --- a/nasal_vm.h +++ b/nasal_vm.h @@ -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"<, limit "<=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) diff --git a/test/bfs.nas b/test/bfs.nas index f0dc14f..97fb818 100644 --- a/test/bfs.nas +++ b/test/bfs.nas @@ -19,7 +19,7 @@ var prt=func(){ } s~='+--------------------+\n'; print(s); - unix.sleep(1/144); + unix.sleep(1/200); } var bfs=func(begin,end){ diff --git a/test/coroutine.nas b/test/coroutine.nas index dc06aa8..ff938f0 100644 --- a/test/coroutine.nas +++ b/test/coroutine.nas @@ -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(){ diff --git a/test/life.nas b/test/life.nas index cb2e1e9..e18df02 100644 --- a/test/life.nas +++ b/test/life.nas @@ -25,7 +25,7 @@ var prt=func() s~='\n'; } print(s); - unix.sleep(1/144); + unix.sleep(1/160); } func(){