From dbc2c365b4a1d8a55a9e8134e8495d6fcddc6960 Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Wed, 8 Mar 2023 23:53:02 +0800 Subject: [PATCH] :sparkles: update error report for parser&codegen --- nasal_ast.h | 42 +++++++++++++++++++++++++++- nasal_codegen.h | 54 +++++++++++++++++++++--------------- nasal_err.h | 27 ++++++++++-------- nasal_parse.h | 74 +++++++++++++++++++++++++++++++++++++++++++------ stl/mat.nas | 6 ++-- 5 files changed, 157 insertions(+), 46 deletions(-) diff --git a/nasal_ast.h b/nasal_ast.h index de11977..8e4e828 100644 --- a/nasal_ast.h +++ b/nasal_ast.h @@ -185,6 +185,8 @@ public: const span& location() const {return loc;} const std::vector& child() const {return nd_child;} std::vector& child() {return nd_child;} + void update_span(); + void update_span(const span&); }; void ast::set_begin(const u32 l,const u32 c) { @@ -198,7 +200,7 @@ void ast::set_end(const u32 l,const u32 c) { } void ast::clear() { - loc={0,0,0,0}; + loc={0,0,0,0,""}; nd_num=0; nd_str.clear(); nd_type=ast_null; @@ -250,3 +252,41 @@ void ast::print(u32 depth,bool last,std::vector& indent) const{ indent.pop_back(); } } + +void ast::update_span() { + if (!nd_child.size()) { + return; + } + for(const auto& i:nd_child) { + if (loc.begin_line>i.loc.begin_line) { + loc.begin_line=i.loc.begin_line; + loc.begin_column=i.loc.begin_column; + } else if (loc.begin_line==i.loc.begin_line && loc.begin_column>i.loc.begin_column) { + loc.begin_column=i.loc.begin_column; + } + if (loc.end_linetloc.begin_line) { + loc.begin_line=tloc.begin_line; + loc.begin_column=tloc.begin_column; + } else if (loc.begin_line==tloc.begin_line && loc.begin_column>tloc.begin_column) { + loc.begin_column=tloc.begin_column; + } + if (loc.end_line1 || tmp[0].type()==ast_subvec)) { - die("bad left-value",tmp.line(),tmp.col(),1); + die("bad left-value with subvec",node.location()); return false; } } else if (node.type()!=ast_id) { - die("bad left-value",node.line(),node.col(),1); + die("bad left-value",node.location()); return false; } return true; } -void codegen::die(const string& info,const u32 line,const u32 col,const u32 len=1) { - err.load(file[fileindex]); - err.err("code",{line,col-len,line,col,file[fileindex]},info); -} - void codegen::regist_num(const f64 num) { if (!num_table.count(num)) { u32 size=num_table.size(); @@ -431,15 +429,15 @@ void codegen::func_gen(const ast& node) { } // check default parameter and dynamic parameter if (checked_default && tmp.type()!=ast_default) { - die("must use default parameters here",tmp.line(),tmp.col(),tmp.str().length()); + die("must use default parameters here",tmp.location()); } if (checked_dynamic && &tmp!=&node[0].child().back()) { - die("dynamic parameter must be the last one",tmp.line(),tmp.col(),tmp.str().length()); + die("dynamic parameter must be the last one",tmp.location()); } // check redefinition string name=tmp.str(); if (argname.count(name)) { - die("redefinition of parameter: "+name,tmp.line(),tmp.col(),name.length()); + die("redefinition of parameter: "+name,tmp.location()); } else { argname[name]=true; } @@ -461,7 +459,7 @@ void codegen::func_gen(const ast& node) { for(auto& tmp:node[0].child()) { const string& str=tmp.str(); if (str=="me") { - die("\"me\" should not be a parameter",tmp.line(),tmp.col(),tmp.str().length()); + die("\"me\" should not be a parameter",tmp.location()); } regist_str(str); switch(tmp.type()) { @@ -488,7 +486,7 @@ void codegen::func_gen(const ast& node) { in_iterloop.pop(); code[lsize].num=local.back().size(); if (local.back().size()>=STACK_DEPTH) { - die("too many local variants: "+std::to_string(local.back().size()),block.line(),0); + die("too many local variants: "+std::to_string(local.back().size()),block.location()); } local.pop_back(); @@ -520,7 +518,7 @@ void codegen::call_id(const ast& node) { if (builtin[i].name==str) { gen(op_callb,i,node.line()); if (local.empty()) { - die("should warp native function in local scope",node.line(),node.col(),node.str().length()); + die("should warp native function in local scope",node.location()); } return; } @@ -538,7 +536,7 @@ void codegen::call_id(const ast& node) { gen(op_callg,index,node.line()); return; } - die("undefined symbol \""+str+"\"",node.line(),node.col(),node.str().length()); + die("undefined symbol \""+str+"\"",node.location()); } void codegen::call_hash(const ast& node) { @@ -622,7 +620,7 @@ void codegen::mcall_id(const ast& node) { const string& str=node.str(); for(u32 i=0;builtin[i].name;++i) { if (builtin[i].name==str) { - die("cannot modify native function",node.line(),node.col(),node.str().length()); + die("cannot modify native function",node.location()); return; } } @@ -639,7 +637,7 @@ void codegen::mcall_id(const ast& node) { gen(op_mcallg,index,node.line()); return; } - die("undefined symbol \""+str+"\"",node.line(),node.col(),node.str().length()); + die("undefined symbol \""+str+"\"",node.location()); } void codegen::mcall_vec(const ast& node) { @@ -665,6 +663,11 @@ void codegen::multi_def(const ast& node) { if (node[1].type()==ast_tuple) { // (var a,b,c)=(c,b,a); auto& vals=node[1].child(); for(usize i=0;inode[1].size()) { - die("too many values in multi-definition",node[1].line(),node[1].col(),1); + die("too many values in multi-definition",node[1].location()); } node[0].type()==ast_id?single_def(node):multi_def(node); } void codegen::multi_assign_gen(const ast& node) { if (node[1].type()==ast_tuple && node[0].size()node[1].size()) { - die("too many values in multi-assignment",node[1].line(),node[1].col(),1); + die("too many values in multi-assignment",node[1].location()); } i32 size=node[0].size(); if (node[1].type()==ast_tuple) { diff --git a/nasal_err.h b/nasal_err.h index 0109ec7..cd33ff4 100644 --- a/nasal_err.h +++ b/nasal_err.h @@ -100,11 +100,11 @@ private: return string(len,' '); } string leftpad(u32 num,usize len) { - string res=std::to_string(num); - while(res.length()