add detail location info in tokens

prepare for multi-line error reporter module
This commit is contained in:
ValKmjolnir 2023-01-10 22:22:27 +08:00
parent 268a03864e
commit 8df02d25ad
8 changed files with 137 additions and 139 deletions

View File

@ -39,10 +39,8 @@ std::ostream& help(std::ostream& out) {
<<" -c, --code | view bytecode.\n"
<<" -e, --exec | execute.\n"
<<" -t, --time | show execute time.\n"
<<" -d, --detail | get detail crash info.\n"
<<" | get detail path-not-found info.\n"
<<" | get detail gc info.\n"
<<" -dbg, --debug | debug mode (ignore -t -d).\n"
<<" -d, --detail | get detail info.\n"
<<" -dbg, --debug | debug mode.\n"
<<"file:\n"
<<" <filename> | execute file.\n"
<<"argv:\n"
@ -57,11 +55,11 @@ std::ostream& logo(std::ostream& out) {
<<" / \\/ / _` / __|/ _` | |\n"
<<" / /\\ / (_| \\__ \\ (_| | |\n"
<<" \\_\\ \\/ \\__,_|___/\\__,_|_|\n"
<<"version : "<<__nasver<<" ("<<__DATE__<<" "<<__TIME__<<")\n"
<<"c++ std : "<<__cplusplus<<"\n"
<<"code repo : https://github.com/ValKmjolnir/Nasal-Interpreter\n"
<<"code repo : https://gitee.com/valkmjolnir/Nasal-Interpreter\n"
<<"lang wiki : https://wiki.flightgear.org/Nasal_scripting_language\n"
<<"ver : "<<__nasver<<" ("<<__DATE__<<" "<<__TIME__<<")\n"
<<"std : c++ "<<__cplusplus<<"\n"
<<"repo : https://github.com/ValKmjolnir/Nasal-Interpreter\n"
<<"repo : https://gitee.com/valkmjolnir/Nasal-Interpreter\n"
<<"wiki : https://wiki.flightgear.org/Nasal_scripting_language\n"
<<"input <nasal -h> to get help .\n";
return out;
}
@ -84,10 +82,13 @@ void execute(const string& file,const std::vector<string>& argv,const u32 cmd) {
// lexer scans file to get tokens
lex.scan(file).chkerr();
// parser gets lexer's token list to compile
parse.compile(lex).chkerr();
// linker gets parser's ast and load import files to this ast
ld.link(parse,file,cmd&VM_DETAIL).chkerr();
// optimizer does simple optimization on ast
optimize(parse.tree());
if (cmd&VM_AST) {
@ -107,7 +108,7 @@ void execute(const string& file,const std::vector<string>& argv,const u32 cmd) {
auto start=ch_clk::now();
ctx.run(gen,ld,argv,cmd&VM_DETAIL);
auto end=ch_clk::now();
std::clog<<"process exited after "<<(end-start).count()*1.0/ch_clk::duration::period::den<<"s.\n";
std::clog<<"process exited after "<<(end-start).count()*1.0/ch_clk::duration::period::den<<"s.\n\n";
} else if (cmd&VM_EXEC) {
ctx.run(gen,ld,argv,cmd&VM_DETAIL);
}

View File

@ -67,7 +67,7 @@ enum ast_node:u32 {
};
const char* ast_name[]={
"NullNode",
"Null",
"AbstractSyntaxTreeRoot",
"CodeBlock",
"FileIndex",
@ -114,17 +114,17 @@ const char* ast_name[]={
"ForeachLoop",
"WhileLoop",
"Iterator",
"ConditionExpression",
"IfExpression",
"ElsifExpression",
"ElseExpression",
"ConditionStatement",
"IfStatement",
"ElsifStatement",
"ElseStatement",
"LeftTuple",
"Tuple",
"Definition",
"MultipleAssignment",
"ContinueExpression",
"BreakExpression",
"ReturnExpression"
"Continue",
"Break",
"ReturnStatement"
};
class ast {
@ -133,19 +133,21 @@ private:
u32 nd_col;
u32 nd_type;
f64 nd_num;
string nd_file;
string nd_str;
std::vector<ast> nd_child;
public:
ast(const u32 l,const u32 c,const u32 t)
: nd_line(l),nd_col(c),nd_type(t),nd_num(0) {}
ast(const ast&);
ast(ast&&);
ast(const u32 l,const u32 c,const u32 t,const std::string& f)
: nd_line(l),nd_col(c),nd_type(t),nd_num(0),nd_file(f),nd_str("") {}
ast(const ast&) = default;
ast(ast&&) = default;
ast& operator=(const ast&) = default;
ast& operator=(ast&&) = default;
void dump() const;
void print(u32,bool,std::vector<string>&) const;
void clear();
ast& operator=(const ast&);
ast& operator=(ast&&);
ast& operator[](usize n) {return nd_child[n];}
const ast& operator[](usize n) const {return nd_child[n];}
usize size() const {return nd_child.size();}
@ -166,43 +168,6 @@ public:
std::vector<ast>& child() {return nd_child;}
};
ast::ast(const ast& tmp):
nd_str(tmp.nd_str),nd_child(tmp.nd_child) {
nd_line=tmp.nd_line;
nd_col=tmp.nd_col;
nd_type=tmp.nd_type;
nd_num =tmp.nd_num;
}
ast::ast(ast&& tmp) {
nd_line=tmp.nd_line;
nd_col=tmp.nd_col;
nd_type=tmp.nd_type;
nd_num =tmp.nd_num;
nd_str.swap(tmp.nd_str);
nd_child.swap(tmp.nd_child);
}
ast& ast::operator=(const ast& tmp) {
nd_line=tmp.nd_line;
nd_col=tmp.nd_col;
nd_type=tmp.nd_type;
nd_num=tmp.nd_num;
nd_str=tmp.nd_str;
nd_child=tmp.nd_child;
return *this;
}
ast& ast::operator=(ast&& tmp) {
nd_line=tmp.nd_line;
nd_col=tmp.nd_col;
nd_type=tmp.nd_type;
nd_num=tmp.nd_num;
nd_str.swap(tmp.nd_str);
nd_child.swap(tmp.nd_child);
return *this;
}
void ast::clear() {
nd_line=nd_col=0;
nd_num=0;
@ -230,7 +195,7 @@ void ast::print(u32 depth,bool last,std::vector<string>& indent) const{
} else if (nd_type==ast_num || nd_type==ast_file) {
std::cout<<":"<<nd_num;
}
std::cout<<" -> "<<nd_line<<":"<<nd_col<<"\n";
std::cout<<" --> "<<nd_file<<":"<<nd_line<<":"<<nd_col<<"\n";
if (last && depth) {
indent.back()=" ";
} else if (!last && depth) {

View File

@ -441,8 +441,8 @@ var builtin_substr(var* local,gc& ngc) {
}
usize begin=(usize)beg.num();
usize length=(usize)len.num();
if (begin>=str.str().length() || begin+length>str.str().length()) {
return nas_err("susbtr","index out of range");
if (begin>=str.str().length()) {
return nas_err("susbtr","begin index out of range: "+std::to_string(begin));
}
return ngc.newstr(str.str().substr(begin,length));
}

View File

@ -294,6 +294,7 @@ void debugger::run(
vmexit:
callsort(count);
ngc.info();
ngc.clear();
imm.clear();
std::cout<<cyan<<"[debug] "<<reset<<"debugger exited\n";

View File

@ -638,9 +638,13 @@ void gc::extend(u8 type) {
size[index]+=incr[index];
for(u32 i=0;i<incr[index];++i) {
nas_val* tmp=new nas_val(type);
// failed to allocate new memory
if (!tmp) {
std::exit(-1);
}
// add to heap
memory.push_back(tmp);
unused[index].push_back(tmp);
}
@ -718,6 +722,7 @@ void gc::info() {
if (total) {
std::clog<<" avg | "<<sec/total*1000<<" ms\n";
}
std::clog<<"\n";
}
var gc::alloc(u8 type) {
@ -777,6 +782,8 @@ void gc::ctxchg(nas_co& ctx) {
upvalr=ctx.upvalr;
canary=ctx.canary;
stack=ctx.stack;
// set coroutine pointer
cort=&ctx;
// set coroutine state to running
@ -805,6 +812,8 @@ void gc::ctxreserve() {
canary=mctx.canary;
top=mctx.top;
stack=mctx.stack;
// set coroutine pointer to nullptr
cort=nullptr;
}

View File

@ -167,13 +167,14 @@ ast linker::fimpt(ast& node) {
// avoid infinite loading loop
filename=findf(filename);
if (!filename.length() || exist(filename)) {
return {0,0,ast_root};
return {0,0,ast_root,filename};
}
// start importing...
lex.scan(filename);
par.compile(lex);
ast tmp=std::move(par.tree());
// check if tmp has 'import'
return load(tmp,files.size()-1);
}
@ -183,24 +184,25 @@ ast linker::libimpt() {
parse par(err);
string filename=findf("lib.nas");
if (!filename.length()) {
return {0,0,ast_root};
return {0,0,ast_root,filename};
}
// avoid infinite loading loop
if (exist(filename)) {
return {0,0,ast_root};
return {0,0,ast_root,filename};
}
// start importing...
lex.scan(filename);
par.compile(lex);
ast tmp=std::move(par.tree());
// check if tmp has 'import'
return load(tmp,files.size()-1);
}
ast linker::load(ast& root,u16 fileindex) {
ast tree(0,0,ast_root);
ast tree(0,0,ast_root,files[fileindex]);
if (!lib_loaded) {
link(tree,libimpt());
lib_loaded=true;
@ -213,7 +215,7 @@ ast linker::load(ast& root,u16 fileindex) {
}
}
// add root to the back of tree
ast file_head(0,0,ast_file);
ast file_head(0,0,ast_file,files[fileindex]);
file_head.set_num(fileindex);
tree.add(std::move(file_head));
link(tree,std::move(root));

View File

@ -67,12 +67,15 @@ enum class tok:u32 {
};
struct token {
u32 line;
u32 col;
tok type;
string str;
token(u32 l=0,u32 c=0,tok t=tok::null,const string& s="")
: line(l),col(c),type(t),str(s) {}
u32 tk_begin_line; // token begin line
u32 tk_begin_column;// token begin column
u32 tk_end_line; // token end line
u32 tk_end_column; // token end column
tok type; // token type
string str; // content
string file; // scanned file path
token() = default;
token(const token&) = default;
};
class lexer {
@ -80,6 +83,7 @@ private:
u32 line;
u32 column;
usize ptr;
string filename;
string res;
error& err;
std::vector<token> toks;
@ -153,7 +157,7 @@ private:
token dots();
token calc_opr();
public:
lexer(error& e): line(1),column(0),ptr(0),res(""),err(e) {}
lexer(error& e): line(1),column(0),ptr(0),filename(""),res(""),err(e) {}
const error& scan(const string&);
const std::vector<token>& result() const {return toks;}
};
@ -213,11 +217,15 @@ void lexer::err_char() {
}
void lexer::open(const string& file) {
// check file exsits and it is a regular file
struct stat buffer;
if (stat(file.c_str(),&buffer)==0 && !S_ISREG(buffer.st_mode)) {
err.err("lexer","<"+file+"> is not a regular file");
err.chkerr();
}
// load
filename=file;
std::ifstream in(file,std::ios::binary);
if (in.fail()) {
err.err("lexer","failed to open <"+file+">");
@ -268,6 +276,8 @@ string lexer::utf8_gen() {
}
token lexer::id_gen() {
u32 begin_line=line;
u32 begin_column=column;
string str="";
while(ptr<res.size() && (is_id(res[ptr])||is_dec(res[ptr]))) {
if (res[ptr]<0) { // utf-8
@ -278,10 +288,12 @@ token lexer::id_gen() {
}
}
tok type=get_type(str);
return {line,column,(type!=tok::null)?type:tok::id,str};
return {begin_line,begin_column,line,column,(type!=tok::null)?type:tok::id,str,filename};
}
token lexer::num_gen() {
u32 begin_line=line;
u32 begin_column=column;
// generate hex number
if (ptr+1<res.size() && res[ptr]=='0' && res[ptr+1]=='x') {
string str="0x";
@ -293,7 +305,7 @@ token lexer::num_gen() {
if (str.length()<3) { // "0x"
err.err("lexer",line,column,str.length(),"invalid number `"+str+"`");
}
return {line,column,tok::num,str};
return {begin_line,begin_column,line,column,tok::num,str,filename};
} else if (ptr+1<res.size() && res[ptr]=='0' && res[ptr+1]=='o') { // generate oct number
string str="0o";
ptr+=2;
@ -309,7 +321,7 @@ token lexer::num_gen() {
if (str.length()==2 || erfmt) {
err.err("lexer",line,column,str.length(),"invalid number `"+str+"`");
}
return {line,column,tok::num,str};
return {begin_line,begin_column,line,column,tok::num,str,filename};
}
// generate dec number
// dec number -> [0~9][0~9]*(.[0~9]*)(e|E(+|-)0|[1~9][0~9]*)
@ -326,7 +338,7 @@ token lexer::num_gen() {
if (str.back()=='.') {
column+=str.length();
err.err("lexer",line,column,str.length(),"invalid number `"+str+"`");
return {line,column,tok::num,"0"};
return {begin_line,begin_column,line,column,tok::num,"0",filename};
}
}
if (ptr<res.size() && (res[ptr]=='e' || res[ptr]=='E')) {
@ -341,14 +353,16 @@ token lexer::num_gen() {
if (str.back()=='e' || str.back()=='E' || str.back()=='-' || str.back()=='+') {
column+=str.length();
err.err("lexer",line,column,str.length(),"invalid number `"+str+"`");
return {line,column,tok::num,"0"};
return {begin_line,begin_column,line,column,tok::num,"0",filename};
}
}
column+=str.length();
return {line,column,tok::num,str};
return {begin_line,begin_column,line,column,tok::num,str,filename};
}
token lexer::str_gen() {
u32 begin_line=line;
u32 begin_column=column;
string str="";
const char begin=res[ptr];
++column;
@ -384,16 +398,18 @@ token lexer::str_gen() {
// check if this string ends with a " or '
if (ptr++>=res.size()) {
err.err("lexer",line,column,1,"get EOF when generating string");
return {line,column,tok::str,str};
return {begin_line,begin_column,line,column,tok::str,str,filename};
}
++column;
if (begin=='`' && str.length()!=1) {
err.err("lexer",line,column,1,"\'`\' is used for string that includes one character");
}
return {line,column,tok::str,str};
return {begin_line,begin_column,line,column,tok::str,str,filename};
}
token lexer::single_opr() {
u32 begin_line=line;
u32 begin_column=column;
string str(1,res[ptr]);
++column;
tok type=get_type(str);
@ -401,27 +417,31 @@ token lexer::single_opr() {
err.err("lexer",line,column,str.length(),"invalid operator `"+str+"`");
}
++ptr;
return {line,column,type,str};
return {begin_line,begin_column,line,column,type,str,filename};
}
token lexer::dots() {
u32 begin_line=line;
u32 begin_column=column;
string str=".";
if (ptr+2<res.size() && res[ptr+1]=='.' && res[ptr+2]=='.') {
str+="..";
}
ptr+=str.length();
column+=str.length();
return {line,column,get_type(str),str};
return {begin_line,begin_column,line,column,get_type(str),str,filename};
}
token lexer::calc_opr() {
u32 begin_line=line;
u32 begin_column=column;
// get calculation operator
string str(1,res[ptr++]);
if (ptr<res.size() && res[ptr]=='=') {
str+=res[ptr++];
}
column+=str.length();
return {line,column,get_type(str),str};
return {begin_line,begin_column,line,column,get_type(str),str,filename};
}
const error& lexer::scan(const string& file) {
@ -460,7 +480,7 @@ const error& lexer::scan(const string& file) {
err_char();
}
}
toks.push_back({line,column,tok::eof,"<eof>"});
toks.push_back({line,column,line,column,tok::eof,"<eof>",filename});
res="";
return err;
}

View File

@ -43,8 +43,8 @@
*/
class parse {
#define thisline (toks[ptr].line)
#define thiscol (toks[ptr].col)
#define thisline (toks[ptr].tk_end_line)
#define thiscol (toks[ptr].tk_end_column)
#define thislen (toks[ptr].str.length())
private:
u32 ptr;
@ -155,7 +155,7 @@ private:
public:
parse(error& e):
ptr(0),in_func(0),in_loop(0),
toks(nullptr),root(0,0,ast_root),
toks(nullptr),root(0,0,ast_root,""),
err(e) {}
const error& compile(const lexer&);
ast& tree() {return root;}
@ -166,7 +166,7 @@ const error& parse::compile(const lexer& lexer) {
toks=lexer.result().data();
ptr=in_func=in_loop=0;
root={0,0,ast_root};
root={0,0,ast_root,toks[0].file};
while(!lookahead(tok::eof)) {
root.add(expr());
if (lookahead(tok::semi)) {
@ -187,8 +187,8 @@ void parse::die(u32 line,u32 col,u32 len,string info,bool prev=false) {
}
// used to report lack of ',' ';'
if (prev && ptr) {
line=toks[ptr-1].line;
col=toks[ptr-1].col;
line=toks[ptr-1].tk_end_line;
col=toks[ptr-1].tk_end_column;
len=toks[ptr-1].str.length();
len+=toks[ptr-1].type==tok::str?2:0;
}
@ -309,29 +309,29 @@ bool parse::need_semi_check(const ast& node) {
}
ast parse::null() {
return {toks[ptr].line,toks[ptr].col,ast_null};
return {toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_null,toks[ptr].file};
}
ast parse::nil() {
return {toks[ptr].line,toks[ptr].col,ast_nil};
return {toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_nil,toks[ptr].file};
}
ast parse::num() {
ast node(toks[ptr].line,toks[ptr].col,ast_num);
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_num,toks[ptr].file);
node.set_num(str2num(toks[ptr].str.c_str()));
match(tok::num);
return node;
}
ast parse::str() {
ast node(toks[ptr].line,toks[ptr].col,ast_str);
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_str,toks[ptr].file);
node.set_str(toks[ptr].str);
match(tok::str);
return node;
}
ast parse::id() {
ast node(toks[ptr].line,toks[ptr].col,ast_id);
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_id,toks[ptr].file);
node.set_str(toks[ptr].str);
match(tok::id);
return node;
@ -347,7 +347,7 @@ ast parse::vec() {
tok::func,tok::var,tok::lcurve,
tok::lbrace,tok::lbracket,tok::null
};
ast node(toks[ptr].line,toks[ptr].col,ast_vec);
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_vec,toks[ptr].file);
match(tok::lbracket);
while(!lookahead(tok::rbracket)) {
node.add(calc());
@ -364,7 +364,7 @@ ast parse::vec() {
}
ast parse::hash() {
ast node(toks[ptr].line,toks[ptr].col,ast_hash);
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_hash,toks[ptr].file);
match(tok::lbrace);
while(!lookahead(tok::rbrace)) {
node.add(pair());
@ -381,7 +381,7 @@ ast parse::hash() {
}
ast parse::pair() {
ast node(toks[ptr].line,toks[ptr].col,ast_pair);
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_pair,toks[ptr].file);
if (lookahead(tok::id)) {
node.add(id());
} else if (lookahead(tok::str)) {
@ -396,7 +396,7 @@ ast parse::pair() {
ast parse::func() {
++in_func;
ast node(toks[ptr].line,toks[ptr].col,ast_func);
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_func,toks[ptr].file);
match(tok::func);
if (lookahead(tok::lcurve)) {
node.add(params());
@ -409,12 +409,12 @@ ast parse::func() {
}
ast parse::params() {
ast node(toks[ptr].line,toks[ptr].col,ast_params);
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_params,toks[ptr].file);
match(tok::lcurve);
while(!lookahead(tok::rcurve)) {
ast tmp=id();
if (lookahead(tok::eq) || lookahead(tok::ellipsis)) {
ast special_arg(toks[ptr].line,toks[ptr].col,ast_null);
ast special_arg(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_null,toks[ptr].file);
if (lookahead(tok::eq)) {
match(tok::eq);
special_arg=std::move(tmp);
@ -481,7 +481,7 @@ ast parse::expr()
next();
break;
}
return {toks[ptr].line,toks[ptr].col,ast_null};
return {toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_null,toks[ptr].file};
}
ast parse::exprs() {
@ -489,7 +489,7 @@ ast parse::exprs() {
die(thisline,thiscol,thislen,"expected expression block");
return null();
}
ast node(toks[ptr].line,toks[ptr].col,ast_block);
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_block,toks[ptr].file);
if (lookahead(tok::lbrace)) {
match(tok::lbrace);
while(!lookahead(tok::rbrace) && !lookahead(tok::eof)) {
@ -514,7 +514,7 @@ ast parse::calc() {
ast node=or_expr();
if (lookahead(tok::quesmark)) {
// trinocular calculation
ast tmp(toks[ptr].line,toks[ptr].col,ast_trino);
ast tmp(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_trino,toks[ptr].file);
match(tok::quesmark);
tmp.add(std::move(node));
tmp.add(calc());
@ -523,7 +523,7 @@ ast parse::calc() {
node=std::move(tmp);
} else if (tok::eq<=toks[ptr].type && toks[ptr].type<=tok::lnkeq) {
// tok::eq~tok::lnkeq is 37 to 42,ast_equal~ast_lnkeq is 21~26
ast tmp(toks[ptr].line,toks[ptr].col,(u32)toks[ptr].type-(u32)tok::eq+ast_equal);
ast tmp(toks[ptr].tk_end_line,toks[ptr].tk_end_column,(u32)toks[ptr].type-(u32)tok::eq+ast_equal,toks[ptr].file);
tmp.add(std::move(node));
match(toks[ptr].type);
tmp.add(calc());
@ -535,7 +535,7 @@ ast parse::calc() {
ast parse::or_expr() {
ast node=and_expr();
while(lookahead(tok::opor)) {
ast tmp(toks[ptr].line,toks[ptr].col,ast_or);
ast tmp(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_or,toks[ptr].file);
tmp.add(std::move(node));
match(tok::opor);
tmp.add(and_expr());
@ -547,7 +547,7 @@ ast parse::or_expr() {
ast parse::and_expr() {
ast node=cmp_expr();
while(lookahead(tok::opand)) {
ast tmp(toks[ptr].line,toks[ptr].col,ast_and);
ast tmp(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_and,toks[ptr].file);
tmp.add(std::move(node));
match(tok::opand);
tmp.add(cmp_expr());
@ -560,7 +560,7 @@ ast parse::cmp_expr() {
ast node=additive_expr();
while(tok::cmpeq<=toks[ptr].type && toks[ptr].type<=tok::geq) {
// tok::cmpeq~tok::geq is 43~48,ast_cmpeq~ast_geq is 27~32
ast tmp(toks[ptr].line,toks[ptr].col,(u32)toks[ptr].type-(u32)tok::cmpeq+ast_cmpeq);
ast tmp(toks[ptr].tk_end_line,toks[ptr].tk_end_column,(u32)toks[ptr].type-(u32)tok::cmpeq+ast_cmpeq,toks[ptr].file);
tmp.add(std::move(node));
match(toks[ptr].type);
tmp.add(additive_expr());
@ -572,7 +572,7 @@ ast parse::cmp_expr() {
ast parse::additive_expr() {
ast node=multive_expr();
while(lookahead(tok::add) || lookahead(tok::sub) || lookahead(tok::link)) {
ast tmp(toks[ptr].line,toks[ptr].col,ast_null);
ast tmp(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_null,toks[ptr].file);
switch(toks[ptr].type) {
case tok::add: tmp.set_type(ast_add); break;
case tok::sub: tmp.set_type(ast_sub); break;
@ -590,7 +590,7 @@ ast parse::additive_expr() {
ast parse::multive_expr() {
ast node=(lookahead(tok::sub) || lookahead(tok::opnot))?unary():scalar();
while(lookahead(tok::mult) || lookahead(tok::div)) {
ast tmp(toks[ptr].line,toks[ptr].col,(u32)toks[ptr].type-(u32)tok::mult+ast_mult);
ast tmp(toks[ptr].tk_end_line,toks[ptr].tk_end_column,(u32)toks[ptr].type-(u32)tok::mult+ast_mult,toks[ptr].file);
tmp.add(std::move(node));
match(toks[ptr].type);
tmp.add((lookahead(tok::sub) || lookahead(tok::opnot))?unary():scalar());
@ -600,7 +600,7 @@ ast parse::multive_expr() {
}
ast parse::unary() {
ast node(toks[ptr].line,toks[ptr].col,ast_null);
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_null,toks[ptr].file);
switch(toks[ptr].type) {
case tok::sub: node.set_type(ast_neg);match(tok::sub);break;
case tok::opnot: node.set_type(ast_not);match(tok::opnot);break;
@ -611,7 +611,7 @@ ast parse::unary() {
}
ast parse::scalar() {
ast node(toks[ptr].line,toks[ptr].col,ast_null);
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_null,toks[ptr].file);
if (lookahead(tok::tknil)) {
node=nil();
match(tok::tknil);
@ -644,7 +644,7 @@ ast parse::scalar() {
// check call and avoid ambiguous syntax
if (is_call(toks[ptr].type) && !(lookahead(tok::lcurve) && toks[ptr+1].type==tok::var)) {
ast tmp=std::move(node);
node={toks[ptr].line,toks[ptr].col,ast_call};
node={toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_call,toks[ptr].file};
node.add(std::move(tmp));
while(is_call(toks[ptr].type)) {
node.add(call_scalar());
@ -661,11 +661,11 @@ ast parse::call_scalar() {
default: break;
}
// should never run this expression
return {toks[ptr].line,toks[ptr].col,ast_nil};
return {toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_nil,toks[ptr].file};
}
ast parse::callh() {
ast node(toks[ptr].line,toks[ptr].col,ast_callh);
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_callh,toks[ptr].file);
match(tok::dot);
node.set_str(toks[ptr].str);
match(tok::id,"expected hashmap key"); // get key
@ -683,7 +683,7 @@ ast parse::callv() {
tok::lbrace,tok::lbracket,tok::colon,
tok::null
};
ast node(toks[ptr].line,toks[ptr].col,ast_callv);
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_callv,toks[ptr].file);
match(tok::lbracket);
while(!lookahead(tok::rbracket)) {
node.add(subvec());
@ -712,7 +712,7 @@ ast parse::callf() {
tok::func,tok::var,tok::lcurve,
tok::lbrace,tok::lbracket,tok::null
};
ast node(toks[ptr].line,toks[ptr].col,ast_callf);
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_callf,toks[ptr].file);
bool special_call=check_special_call();
match(tok::lcurve);
while(!lookahead(tok::rcurve)) {
@ -731,7 +731,7 @@ ast parse::callf() {
ast parse::subvec() {
ast node=lookahead(tok::colon)?nil():calc();
if (lookahead(tok::colon)) {
ast tmp(node.line(),node.col(),ast_subvec);
ast tmp(node.line(),node.col(),ast_subvec,toks[ptr].file);
match(tok::colon);
tmp.add(std::move(node));
tmp.add((lookahead(tok::comma) || lookahead(tok::rbracket))?nil():calc());
@ -741,7 +741,7 @@ ast parse::subvec() {
}
ast parse::definition() {
ast node(toks[ptr].line,toks[ptr].col,ast_def);
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_def,toks[ptr].file);
if (lookahead(tok::var)) {
match(tok::var);
switch(toks[ptr].type) {
@ -777,7 +777,7 @@ ast parse::outcurve_def() {
}
ast parse::multi_id() {
ast node(toks[ptr].line,toks[ptr].col,ast_multi_id);
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_multi_id,toks[ptr].file);
while(!lookahead(tok::eof)) {
node.add(id());
if (is_call(toks[ptr].type)) {
@ -803,7 +803,7 @@ ast parse::multi_scalar() {
tok::func,tok::var,tok::lcurve,
tok::lbrace,tok::lbracket,tok::null
};
ast node(toks[ptr].line,toks[ptr].col,ast_tuple);
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_tuple,toks[ptr].file);
match(tok::lcurve);
while(!lookahead(tok::rcurve)) {
node.add(calc());
@ -820,7 +820,7 @@ ast parse::multi_scalar() {
}
ast parse::multi_assgin() {
ast node(toks[ptr].line,toks[ptr].col,ast_multi_assign);
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_multi_assign,toks[ptr].file);
node.add(multi_scalar());
match(tok::eq);
if (lookahead(tok::eof)) {
@ -837,7 +837,7 @@ ast parse::multi_assgin() {
ast parse::loop() {
++in_loop;
ast node(0,0,ast_null);
ast node(0,0,ast_null,toks[ptr].file);
switch(toks[ptr].type) {
case tok::rwhile: node=while_loop(); break;
case tok::rfor: node=for_loop(); break;
@ -850,7 +850,7 @@ ast parse::loop() {
}
ast parse::while_loop() {
ast node(toks[ptr].line,toks[ptr].col,ast_while);
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_while,toks[ptr].file);
match(tok::rwhile);
match(tok::lcurve);
node.add(calc());
@ -860,7 +860,7 @@ ast parse::while_loop() {
}
ast parse::for_loop() {
ast node(toks[ptr].line,toks[ptr].col,ast_for);
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_for,toks[ptr].file);
match(tok::rfor);
match(tok::lcurve);
// first expression
@ -902,7 +902,7 @@ ast parse::for_loop() {
}
ast parse::forei_loop() {
ast node(toks[ptr].line,toks[ptr].col,ast_null);
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_null,toks[ptr].file);
switch(toks[ptr].type) {
case tok::forindex:node.set_type(ast_forindex);match(tok::forindex);break;
case tok::foreach: node.set_type(ast_foreach); match(tok::foreach); break;
@ -926,7 +926,7 @@ ast parse::forei_loop() {
}
ast parse::iter_gen() {
ast node(toks[ptr].line,toks[ptr].col,ast_null);
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_null,toks[ptr].file);
if (lookahead(tok::var)) {
match(tok::var);
node.set_type(ast_iter);
@ -942,8 +942,8 @@ ast parse::iter_gen() {
}
ast parse::cond() {
ast node(toks[ptr].line,toks[ptr].col,ast_cond);
ast ifnode(toks[ptr].line,toks[ptr].col,ast_if);
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_cond,toks[ptr].file);
ast ifnode(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_if,toks[ptr].file);
match(tok::rif);
match(tok::lcurve);
ifnode.add(calc());
@ -951,7 +951,7 @@ ast parse::cond() {
ifnode.add(exprs());
node.add(std::move(ifnode));
while(lookahead(tok::elsif)) {
ast elsifnode(toks[ptr].line,toks[ptr].col,ast_elsif);
ast elsifnode(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_elsif,toks[ptr].file);
match(tok::elsif);
match(tok::lcurve);
elsifnode.add(calc());
@ -960,7 +960,7 @@ ast parse::cond() {
node.add(std::move(elsifnode));
}
if (lookahead(tok::relse)) {
ast elsenode(toks[ptr].line,toks[ptr].col,ast_else);
ast elsenode(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_else,toks[ptr].file);
match(tok::relse);
elsenode.add(exprs());
node.add(std::move(elsenode));
@ -969,19 +969,19 @@ ast parse::cond() {
}
ast parse::continue_expr() {
ast node(toks[ptr].line,toks[ptr].col,ast_continue);
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_continue,toks[ptr].file);
match(tok::cont);
return node;
}
ast parse::break_expr() {
ast node(toks[ptr].line,toks[ptr].col,ast_break);
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_break,toks[ptr].file);
match(tok::brk);
return node;
}
ast parse::ret_expr() {
ast node(toks[ptr].line,toks[ptr].col,ast_ret);
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_ret,toks[ptr].file);
match(tok::ret);
tok type=toks[ptr].type;
if (type==tok::tknil || type==tok::num || type==tok::str || type==tok::id ||