update error report for parser&codegen

This commit is contained in:
ValKmjolnir 2023-03-08 23:53:02 +08:00
parent 1678567c5d
commit dbc2c365b4
5 changed files with 157 additions and 46 deletions

View File

@ -185,6 +185,8 @@ public:
const span& location() const {return loc;} const span& location() const {return loc;}
const std::vector<ast>& child() const {return nd_child;} const std::vector<ast>& child() const {return nd_child;}
std::vector<ast>& child() {return nd_child;} std::vector<ast>& child() {return nd_child;}
void update_span();
void update_span(const span&);
}; };
void ast::set_begin(const u32 l,const u32 c) { 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() { void ast::clear() {
loc={0,0,0,0}; loc={0,0,0,0,""};
nd_num=0; nd_num=0;
nd_str.clear(); nd_str.clear();
nd_type=ast_null; nd_type=ast_null;
@ -250,3 +252,41 @@ void ast::print(u32 depth,bool last,std::vector<string>& indent) const{
indent.pop_back(); 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_line<i.loc.end_line) {
loc.end_line=i.loc.end_line;
loc.end_column=i.loc.end_column;
} else if (loc.end_line==i.loc.end_line && loc.end_column<i.loc.end_column) {
loc.end_column=i.loc.end_column;
}
loc.file=i.loc.file;
}
}
void ast::update_span(const span& tloc) {
update_span();
if (loc.begin_line>tloc.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_line<tloc.end_line) {
loc.end_line=tloc.end_line;
loc.end_column=tloc.end_column;
} else if (loc.end_line==tloc.end_line && loc.end_column<tloc.end_column) {
loc.end_column=tloc.end_column;
}
loc.file=tloc.file;
}

View File

@ -223,7 +223,10 @@ private:
bool check_memory_reachable(const ast&); bool check_memory_reachable(const ast&);
void die(const string&,const u32,const u32,const u32); void die(const string& info,const span& loc) {
err.err("code",loc,info);
}
void regist_num(const f64); void regist_num(const f64);
void regist_str(const string&); void regist_str(const string&);
void find_symbol(const ast&); void find_symbol(const ast&);
@ -279,25 +282,20 @@ bool codegen::check_memory_reachable(const ast& node) {
if (node.type()==ast_call) { if (node.type()==ast_call) {
const ast& tmp=node.child().back(); const ast& tmp=node.child().back();
if (tmp.type()==ast_callf) { if (tmp.type()==ast_callf) {
die("bad left-value",tmp.line(),tmp.col(),1); die("bad left-value with function call",node.location());
return false; return false;
} }
if (tmp.type()==ast_callv && (tmp.size()==0 || tmp.size()>1 || tmp[0].type()==ast_subvec)) { if (tmp.type()==ast_callv && (tmp.size()==0 || tmp.size()>1 || tmp[0].type()==ast_subvec)) {
die("bad left-value",tmp.line(),tmp.col(),1); die("bad left-value with subvec",node.location());
return false; return false;
} }
} else if (node.type()!=ast_id) { } else if (node.type()!=ast_id) {
die("bad left-value",node.line(),node.col(),1); die("bad left-value",node.location());
return false; return false;
} }
return true; 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) { void codegen::regist_num(const f64 num) {
if (!num_table.count(num)) { if (!num_table.count(num)) {
u32 size=num_table.size(); u32 size=num_table.size();
@ -431,15 +429,15 @@ void codegen::func_gen(const ast& node) {
} }
// check default parameter and dynamic parameter // check default parameter and dynamic parameter
if (checked_default && tmp.type()!=ast_default) { 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()) { 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 // check redefinition
string name=tmp.str(); string name=tmp.str();
if (argname.count(name)) { if (argname.count(name)) {
die("redefinition of parameter: "+name,tmp.line(),tmp.col(),name.length()); die("redefinition of parameter: "+name,tmp.location());
} else { } else {
argname[name]=true; argname[name]=true;
} }
@ -461,7 +459,7 @@ void codegen::func_gen(const ast& node) {
for(auto& tmp:node[0].child()) { for(auto& tmp:node[0].child()) {
const string& str=tmp.str(); const string& str=tmp.str();
if (str=="me") { 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); regist_str(str);
switch(tmp.type()) { switch(tmp.type()) {
@ -488,7 +486,7 @@ void codegen::func_gen(const ast& node) {
in_iterloop.pop(); in_iterloop.pop();
code[lsize].num=local.back().size(); code[lsize].num=local.back().size();
if (local.back().size()>=STACK_DEPTH) { 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(); local.pop_back();
@ -520,7 +518,7 @@ void codegen::call_id(const ast& node) {
if (builtin[i].name==str) { if (builtin[i].name==str) {
gen(op_callb,i,node.line()); gen(op_callb,i,node.line());
if (local.empty()) { 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; return;
} }
@ -538,7 +536,7 @@ void codegen::call_id(const ast& node) {
gen(op_callg,index,node.line()); gen(op_callg,index,node.line());
return; 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) { void codegen::call_hash(const ast& node) {
@ -622,7 +620,7 @@ void codegen::mcall_id(const ast& node) {
const string& str=node.str(); const string& str=node.str();
for(u32 i=0;builtin[i].name;++i) { for(u32 i=0;builtin[i].name;++i) {
if (builtin[i].name==str) { 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; return;
} }
} }
@ -639,7 +637,7 @@ void codegen::mcall_id(const ast& node) {
gen(op_mcallg,index,node.line()); gen(op_mcallg,index,node.line());
return; 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) { 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); if (node[1].type()==ast_tuple) { // (var a,b,c)=(c,b,a);
auto& vals=node[1].child(); auto& vals=node[1].child();
for(usize i=0;i<size;++i) { for(usize i=0;i<size;++i) {
// check node type, only identifier is allowed
if (ids[i].type()!=ast_id) {
die("cannot call identifier in multi-definition",ids[i].location());
continue;
}
calc_gen(vals[i]); calc_gen(vals[i]);
const string& str=ids[i].str(); const string& str=ids[i].str();
local.empty()? local.empty()?
@ -674,6 +677,11 @@ void codegen::multi_def(const ast& node) {
} else { // (var a,b,c)=[0,1,2]; } else { // (var a,b,c)=[0,1,2];
calc_gen(node[1]); calc_gen(node[1]);
for(usize i=0;i<size;++i) { for(usize i=0;i<size;++i) {
// check node type, only identifier is allowed
if (ids[i].type()!=ast_id) {
die("cannot call identifier in multi-definition",ids[i].location());
continue;
}
gen(op_callvi,i,node[1].line()); gen(op_callvi,i,node[1].line());
const string& str=ids[i].str(); const string& str=ids[i].str();
local.empty()? local.empty()?
@ -686,20 +694,20 @@ void codegen::multi_def(const ast& node) {
void codegen::def_gen(const ast& node) { void codegen::def_gen(const ast& node) {
if (node[0].type()==ast_id && node[1].type()==ast_tuple) { if (node[0].type()==ast_id && node[1].type()==ast_tuple) {
die("cannot accept too many values",node[1].line(),node[1].col(),1); die("cannot accept too many values",node[1].location());
} else if (node[0].type()==ast_multi_id && node[1].type()==ast_tuple && node[0].size()<node[1].size()) { } else if (node[0].type()==ast_multi_id && node[1].type()==ast_tuple && node[0].size()<node[1].size()) {
die("lack values in multi-definition",node[1].line(),node[1].col(),1); die("lack values in multi-definition",node[1].location());
} else if (node[0].type()==ast_multi_id && node[1].type()==ast_tuple && node[0].size()>node[1].size()) { } else if (node[0].type()==ast_multi_id && node[1].type()==ast_tuple && node[0].size()>node[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); node[0].type()==ast_id?single_def(node):multi_def(node);
} }
void codegen::multi_assign_gen(const ast& node) { void codegen::multi_assign_gen(const ast& node) {
if (node[1].type()==ast_tuple && node[0].size()<node[1].size()) { if (node[1].type()==ast_tuple && node[0].size()<node[1].size()) {
die("lack values in multi-assignment",node[1].line(),node[1].col(),1); die("lack values in multi-assignment",node[1].location());
} else if (node[1].type()==ast_tuple && node[0].size()>node[1].size()) { } else 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(); i32 size=node[0].size();
if (node[1].type()==ast_tuple) { if (node[1].type()==ast_tuple) {

View File

@ -100,11 +100,11 @@ private:
return string(len,' '); return string(len,' ');
} }
string leftpad(u32 num,usize len) { string leftpad(u32 num,usize len) {
string res=std::to_string(num); string tmp=std::to_string(num);
while(res.length()<len) { while(tmp.length()<len) {
res=" "+res; tmp=" "+tmp;
} }
return res; return tmp;
} }
public: public:
error():cnt(0) {} error():cnt(0) {}
@ -175,7 +175,7 @@ void error::err(const string& stage,const span& loc,const string& info) {
const string iden=identation(maxlen); const string iden=identation(maxlen);
for(u32 line=loc.begin_line;line<=loc.end_line;++line) { for(u32 line=loc.begin_line;line<=loc.end_line;++line) {
if (!line || !res[line-1].length()) { if (!line) {
continue; continue;
} }
@ -186,30 +186,35 @@ void error::err(const string& stage,const span& loc,const string& info) {
continue; continue;
} }
// if this line has nothing, skip
if (!res[line-1].length() && line!=loc.end_line) {
continue;
}
const string& code=res[line-1]; const string& code=res[line-1];
std::cerr<<cyan<<leftpad(line,maxlen)<<" | "<<reset<<code<<"\n"; std::cerr<<cyan<<leftpad(line,maxlen)<<" | "<<reset<<code<<"\n";
// output underline // output underline
std::cerr<<cyan<<iden<<" | "<<reset; std::cerr<<cyan<<iden<<" | "<<reset;
if (loc.begin_line==loc.end_line) { if (loc.begin_line==loc.end_line) {
for(i32 i=0;i<loc.begin_column;++i) { for(u32 i=0;i<loc.begin_column;++i) {
std::cerr<<char(" \t"[code[i]=='\t']); std::cerr<<char(" \t"[code[i]=='\t']);
} }
for(i32 i=loc.begin_column;i<loc.end_column;++i) { for(u32 i=loc.begin_column;i<loc.end_column;++i) {
std::cerr<<red<<(code[i]=='\t'?"^^^^":"^")<<reset; std::cerr<<red<<(code[i]=='\t'?"^^^^":"^")<<reset;
} }
} else if (line==loc.begin_line) { } else if (line==loc.begin_line) {
for(i32 i=0;i<loc.begin_column;++i) { for(u32 i=0;i<loc.begin_column;++i) {
std::cerr<<char(" \t"[code[i]=='\t']); std::cerr<<char(" \t"[code[i]=='\t']);
} }
for(i32 i=loc.begin_column;i<code.size();++i) { for(u32 i=loc.begin_column;i<code.size();++i) {
std::cerr<<red<<(code[i]=='\t'?"^^^^":"^")<<reset; std::cerr<<red<<(code[i]=='\t'?"^^^^":"^")<<reset;
} }
} else if (loc.begin_line<line && line<loc.end_line) { } else if (loc.begin_line<line && line<loc.end_line) {
for(i32 i=0;i<code.size();++i) { for(u32 i=0;i<code.size();++i) {
std::cerr<<red<<(code[i]=='\t'?"^^^^":"^"); std::cerr<<red<<(code[i]=='\t'?"^^^^":"^");
} }
} else { } else {
for(i32 i=0;i<loc.end_column;++i) { for(u32 i=0;i<loc.end_column;++i) {
std::cerr<<red<<(code[i]=='\t'?"^^^^":"^"); std::cerr<<red<<(code[i]=='\t'?"^^^^":"^");
} }
} }

View File

@ -176,7 +176,7 @@ const error& parse::compile(const lexer& lexer) {
toks=lexer.result().data(); toks=lexer.result().data();
ptr=in_func=in_loop=0; ptr=in_func=in_loop=0;
root={{0,0,0,0,toks[0].loc.file},ast_root}; root={toks[0].loc,ast_root};
while(!lookahead(tok::eof)) { while(!lookahead(tok::eof)) {
root.add(expr()); root.add(expr());
if (lookahead(tok::semi)) { if (lookahead(tok::semi)) {
@ -186,6 +186,7 @@ const error& parse::compile(const lexer& lexer) {
die(prevspan,"expected \";\""); die(prevspan,"expected \";\"");
} }
} }
root.update_span();
return err; return err;
} }
@ -368,6 +369,7 @@ ast parse::vec() {
break; break;
} }
} }
node.update_span(thisspan);
match(tok::rbracket,"expected ']' when generating vector"); match(tok::rbracket,"expected ']' when generating vector");
return node; return node;
} }
@ -385,6 +387,7 @@ ast parse::hash() {
break; break;
} }
} }
node.update_span(thisspan);
match(tok::rbrace,"expected '}' when generating hash"); match(tok::rbrace,"expected '}' when generating hash");
return node; return node;
} }
@ -400,6 +403,7 @@ ast parse::pair() {
} }
match(tok::colon); match(tok::colon);
node.add(calc()); node.add(calc());
node.update_span();
return node; return node;
} }
@ -414,6 +418,7 @@ ast parse::func() {
} }
node.add(exprs()); node.add(exprs());
--in_func; --in_func;
node.update_span();
return node; return node;
} }
@ -446,6 +451,7 @@ ast parse::params() {
break; break;
} }
} }
node.update_span(thisspan);
match(tok::rcurve,"expected ')' after parameter list"); match(tok::rcurve,"expected ')' after parameter list");
return node; return node;
} }
@ -493,6 +499,8 @@ ast parse::expr() {
next(); next();
break; break;
} }
// unreachable
return {toks[ptr].loc,ast_null}; return {toks[ptr].loc,ast_null};
} }
@ -519,6 +527,7 @@ ast parse::exprs() {
if (lookahead(tok::semi)) if (lookahead(tok::semi))
match(tok::semi); match(tok::semi);
} }
node.update_span();
return node; return node;
} }
@ -547,6 +556,7 @@ ast parse::calc() {
tmp.add(calc()); tmp.add(calc());
node=std::move(tmp); node=std::move(tmp);
} }
node.update_span();
return node; return node;
} }
@ -557,8 +567,10 @@ ast parse::bitwise_or() {
tmp.add(std::move(node)); tmp.add(std::move(node));
match(tok::btor); match(tok::btor);
tmp.add(bitwise_xor()); tmp.add(bitwise_xor());
tmp.update_span();
node=std::move(tmp); node=std::move(tmp);
} }
node.update_span();
return node; return node;
} }
@ -569,8 +581,10 @@ ast parse::bitwise_xor() {
tmp.add(std::move(node)); tmp.add(std::move(node));
match(tok::btxor); match(tok::btxor);
tmp.add(bitwise_and()); tmp.add(bitwise_and());
tmp.update_span();
node=std::move(tmp); node=std::move(tmp);
} }
node.update_span();
return node; return node;
} }
@ -581,8 +595,10 @@ ast parse::bitwise_and() {
tmp.add(std::move(node)); tmp.add(std::move(node));
match(tok::btand); match(tok::btand);
tmp.add(or_expr()); tmp.add(or_expr());
tmp.update_span();
node=std::move(tmp); node=std::move(tmp);
} }
node.update_span();
return node; return node;
} }
@ -593,8 +609,10 @@ ast parse::or_expr() {
tmp.add(std::move(node)); tmp.add(std::move(node));
match(tok::opor); match(tok::opor);
tmp.add(and_expr()); tmp.add(and_expr());
tmp.update_span();
node=std::move(tmp); node=std::move(tmp);
} }
node.update_span();
return node; return node;
} }
@ -605,8 +623,10 @@ ast parse::and_expr() {
tmp.add(std::move(node)); tmp.add(std::move(node));
match(tok::opand); match(tok::opand);
tmp.add(cmp_expr()); tmp.add(cmp_expr());
tmp.update_span();
node=std::move(tmp); node=std::move(tmp);
} }
node.update_span();
return node; return node;
} }
@ -618,8 +638,10 @@ ast parse::cmp_expr() {
tmp.add(std::move(node)); tmp.add(std::move(node));
match(toks[ptr].type); match(toks[ptr].type);
tmp.add(additive_expr()); tmp.add(additive_expr());
tmp.update_span();
node=std::move(tmp); node=std::move(tmp);
} }
node.update_span();
return node; return node;
} }
@ -636,8 +658,10 @@ ast parse::additive_expr() {
tmp.add(std::move(node)); tmp.add(std::move(node));
match(toks[ptr].type); match(toks[ptr].type);
tmp.add(multive_expr()); tmp.add(multive_expr());
tmp.update_span();
node=std::move(tmp); node=std::move(tmp);
} }
node.update_span();
return node; return node;
} }
@ -648,8 +672,10 @@ ast parse::multive_expr() {
tmp.add(std::move(node)); tmp.add(std::move(node));
match(toks[ptr].type); match(toks[ptr].type);
tmp.add((lookahead(tok::sub) || lookahead(tok::opnot) || lookahead(tok::floater))?unary():scalar()); tmp.add((lookahead(tok::sub) || lookahead(tok::opnot) || lookahead(tok::floater))?unary():scalar());
tmp.update_span();
node=std::move(tmp); node=std::move(tmp);
} }
node.update_span();
return node; return node;
} }
@ -662,6 +688,7 @@ ast parse::unary() {
default: break; default: break;
} }
node.add((lookahead(tok::sub) || lookahead(tok::opnot) || lookahead(tok::floater))?unary():scalar()); node.add((lookahead(tok::sub) || lookahead(tok::opnot) || lookahead(tok::floater))?unary():scalar());
node.update_span();
return node; return node;
} }
@ -685,8 +712,11 @@ ast parse::scalar() {
} else if (lookahead(tok::lbrace)) { } else if (lookahead(tok::lbrace)) {
node=hash(); node=hash();
} else if (lookahead(tok::lcurve)) { } else if (lookahead(tok::lcurve)) {
const auto& loc=toks[ptr].loc;
match(tok::lcurve); match(tok::lcurve);
node=calc(); node=calc();
node.set_begin(loc.begin_line,loc.begin_column);
node.update_span(thisspan);
match(tok::rcurve); match(tok::rcurve);
} else if (lookahead(tok::var)) { } else if (lookahead(tok::var)) {
match(tok::var); match(tok::var);
@ -707,6 +737,7 @@ ast parse::scalar() {
node.add(call_scalar()); node.add(call_scalar());
} }
} }
node.update_span();
return node; return node;
} }
@ -717,7 +748,7 @@ ast parse::call_scalar() {
case tok::dot: return callh(); break; case tok::dot: return callh(); break;
default: break; default: break;
} }
// should never run this expression // unreachable
return {toks[ptr].loc,ast_nil}; return {toks[ptr].loc,ast_nil};
} }
@ -725,6 +756,7 @@ ast parse::callh() {
ast node(toks[ptr].loc,ast_callh); ast node(toks[ptr].loc,ast_callh);
match(tok::dot); match(tok::dot);
node.set_str(toks[ptr].str); node.set_str(toks[ptr].str);
node.set_end(toks[ptr].loc.end_line,toks[ptr].loc.end_column);
match(tok::id,"expected hashmap key"); // get key match(tok::id,"expected hashmap key"); // get key
return node; return node;
} }
@ -752,8 +784,9 @@ ast parse::callv() {
} }
} }
if (node.size()==0) { if (node.size()==0) {
die(node.location(),"expected index value"); die(thisspan,"expected index value");
} }
node.update_span(thisspan);
match(tok::rbracket,"expected ']' when calling vector"); match(tok::rbracket,"expected ']' when calling vector");
return node; return node;
} }
@ -780,6 +813,7 @@ ast parse::callf() {
else if (!lookahead(tok::rcurve) && !check_comma(panic)) else if (!lookahead(tok::rcurve) && !check_comma(panic))
break; break;
} }
node.update_span(thisspan);
match(tok::rcurve,"expected ')' when calling function"); match(tok::rcurve,"expected ')' when calling function");
return node; return node;
} }
@ -793,6 +827,7 @@ ast parse::subvec() {
tmp.add((lookahead(tok::comma) || lookahead(tok::rbracket))?nil():calc()); tmp.add((lookahead(tok::comma) || lookahead(tok::rbracket))?nil():calc());
node=std::move(tmp); node=std::move(tmp);
} }
node.update_span();
return node; return node;
} }
@ -814,32 +849,37 @@ ast parse::definition() {
} else { } else {
node.add(calc()); node.add(calc());
} }
node.update_span();
return node; return node;
} }
ast parse::incurve_def() { ast parse::incurve_def() {
const auto& loc=toks[ptr].loc;
match(tok::lcurve); match(tok::lcurve);
match(tok::var); match(tok::var);
ast node=multi_id(); ast node=multi_id();
node.update_span(thisspan);
match(tok::rcurve); match(tok::rcurve);
node.set_begin(loc.begin_line,loc.begin_column);
return node; return node;
} }
ast parse::outcurve_def() { ast parse::outcurve_def() {
const auto& loc=toks[ptr].loc;
match(tok::lcurve); match(tok::lcurve);
ast node=multi_id(); ast node=multi_id();
node.update_span(thisspan);
match(tok::rcurve); match(tok::rcurve);
node.set_begin(loc.begin_line,loc.begin_column);
return node; return node;
} }
ast parse::multi_id() { ast parse::multi_id() {
ast node(toks[ptr].loc,ast_multi_id); ast node(toks[ptr].loc,ast_multi_id);
while(!lookahead(tok::eof)) { while(!lookahead(tok::eof)) {
node.add(id()); // only identifier is allowed here
if (is_call(toks[ptr].type)) { // but we check it at codegen stage
ast tmp=call_scalar();// recognize calls but this is still a syntax error node.add(calc());
die(tmp.location(),"cannot call identifier in multi-definition");
}
if (lookahead(tok::comma)) { if (lookahead(tok::comma)) {
match(tok::comma); match(tok::comma);
} else if (lookahead(tok::id)) { // first set of identifier } else if (lookahead(tok::id)) { // first set of identifier
@ -848,6 +888,7 @@ ast parse::multi_id() {
break; break;
} }
} }
node.update_span();
return node; return node;
} }
@ -871,6 +912,7 @@ ast parse::multi_scalar() {
break; break;
} }
} }
node.update_span(thisspan);
match(tok::rcurve,"expected ')' after multi-scalar"); match(tok::rcurve,"expected ')' after multi-scalar");
return node; return node;
} }
@ -888,6 +930,7 @@ ast parse::multi_assgin() {
} else { } else {
node.add(calc()); node.add(calc());
} }
node.update_span();
return node; return node;
} }
@ -912,6 +955,7 @@ ast parse::while_loop() {
node.add(calc()); node.add(calc());
match(tok::rcurve); match(tok::rcurve);
node.add(exprs()); node.add(exprs());
node.update_span();
return node; return node;
} }
@ -954,6 +998,7 @@ ast parse::for_loop() {
} }
match(tok::rcurve); match(tok::rcurve);
node.add(exprs()); node.add(exprs());
node.update_span();
return node; return node;
} }
@ -978,6 +1023,7 @@ ast parse::forei_loop() {
node.add(calc()); node.add(calc());
match(tok::rcurve); match(tok::rcurve);
node.add(exprs()); node.add(exprs());
node.update_span();
return node; return node;
} }
@ -994,18 +1040,24 @@ ast parse::iter_gen() {
node.add(call_scalar()); node.add(call_scalar());
} }
} }
node.update_span();
return node; return node;
} }
ast parse::cond() { ast parse::cond() {
ast node(toks[ptr].loc,ast_cond); ast node(toks[ptr].loc,ast_cond);
// generate if
ast ifnode(toks[ptr].loc,ast_if); ast ifnode(toks[ptr].loc,ast_if);
match(tok::rif); match(tok::rif);
match(tok::lcurve); match(tok::lcurve);
ifnode.add(calc()); ifnode.add(calc());
match(tok::rcurve); match(tok::rcurve);
ifnode.add(exprs()); ifnode.add(exprs());
ifnode.update_span();
node.add(std::move(ifnode)); node.add(std::move(ifnode));
// generate elsif
while(lookahead(tok::elsif)) { while(lookahead(tok::elsif)) {
ast elsifnode(toks[ptr].loc,ast_elsif); ast elsifnode(toks[ptr].loc,ast_elsif);
match(tok::elsif); match(tok::elsif);
@ -1013,14 +1065,19 @@ ast parse::cond() {
elsifnode.add(calc()); elsifnode.add(calc());
match(tok::rcurve); match(tok::rcurve);
elsifnode.add(exprs()); elsifnode.add(exprs());
elsifnode.update_span();
node.add(std::move(elsifnode)); node.add(std::move(elsifnode));
} }
// generate else
if (lookahead(tok::relse)) { if (lookahead(tok::relse)) {
ast elsenode(toks[ptr].loc,ast_else); ast elsenode(toks[ptr].loc,ast_else);
match(tok::relse); match(tok::relse);
elsenode.add(exprs()); elsenode.add(exprs());
elsenode.update_span();
node.add(std::move(elsenode)); node.add(std::move(elsenode));
} }
node.update_span();
return node; return node;
} }
@ -1046,5 +1103,6 @@ ast parse::ret_expr() {
) { ) {
node.add(calc()); node.add(calc());
} }
node.update_span();
return node; return node;
} }

View File

@ -194,9 +194,9 @@ var bp_example=func() {
# last 2 column is useless, only used to make sure bp runs correctly # last 2 column is useless, only used to make sure bp runs correctly
var expect=[ var expect=[
{width:3,height:1,mat:[0,0,0]}, {width:3,height:1,mat:[0,0,0]},
{width:3,height:1,mat:[1,0,0]}, {width:3,height:1,mat:[1,0,1]},
{width:3,height:1,mat:[1,0,0]}, {width:3,height:1,mat:[1,1,0]},
{width:3,height:1,mat:[0,0,0]} {width:3,height:1,mat:[0,1,1]}
]; ];
var hidden={ var hidden={
weight:mat(4,2), weight:mat(4,2),