optimize error report info

This commit is contained in:
ValKmjolnir 2023-07-17 00:38:33 +08:00
parent fe3847d69c
commit 4b597000ba
11 changed files with 61 additions and 70 deletions

View File

@ -105,11 +105,10 @@ void execute(
using clk = std::chrono::high_resolution_clock; using clk = std::chrono::high_resolution_clock;
const auto den = clk::duration::period::den; const auto den = clk::duration::period::den;
error err; lexer lex;
lexer lex(err); parse parse;
parse parse(err); linker ld;
linker ld(err); codegen gen;
codegen gen(err);
vm ctx; vm ctx;
// lexer scans file to get tokens // lexer scans file to get tokens
@ -151,7 +150,7 @@ void execute(
// run // run
auto start = clk::now(); auto start = clk::now();
if (cmd&VM_DEBUG) { if (cmd&VM_DEBUG) {
dbg(err).run(gen, ld, argv); dbg().run(gen, ld, argv);
} else if (cmd&VM_TIME || cmd&VM_EXEC) { } else if (cmd&VM_TIME || cmd&VM_EXEC) {
ctx.run(gen, ld, argv, cmd&VM_DETAIL); ctx.run(gen, ld, argv, cmd&VM_DETAIL);
} }

View File

@ -232,9 +232,9 @@ void codegen::func_gen(function* node) {
} }
add_symbol(arg); add_symbol(arg);
in_iterloop.push(0); in_loop_level.push_back(0);
block_gen(block); block_gen(block);
in_iterloop.pop(); in_loop_level.pop_back();
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: " + die("too many local variants: " +
@ -775,9 +775,9 @@ void codegen::forei_gen(forei_expr* node) {
gen(op_meq, 1, node->get_iterator()->get_line()); gen(op_meq, 1, node->get_iterator()->get_line());
} }
} }
++in_iterloop.top(); ++in_loop_level.back();
block_gen(node->get_code_block()); block_gen(node->get_code_block());
--in_iterloop.top(); --in_loop_level.back();
gen(op_jmp, ptr, node->get_line()); gen(op_jmp, ptr, node->get_line());
code[ptr].num=code.size(); code[ptr].num=code.size();
load_continue_break(code.size()-1, code.size()); load_continue_break(code.size()-1, code.size());
@ -1100,7 +1100,7 @@ void codegen::block_gen(code_block* node) {
} }
void codegen::ret_gen(return_expr* node) { void codegen::ret_gen(return_expr* node) {
for(u32 i = 0; i<in_iterloop.top(); ++i) { for(u32 i = 0; i<in_loop_level.back(); ++i) {
gen(op_pop, 0, node->get_line()); gen(op_pop, 0, node->get_line());
gen(op_pop, 0, node->get_line()); gen(op_pop, 0, node->get_line());
} }
@ -1110,8 +1110,8 @@ void codegen::ret_gen(return_expr* node) {
const error& codegen::compile(parse& parse, linker& import) { const error& codegen::compile(parse& parse, linker& import) {
fileindex = 0; fileindex = 0;
file = import.filelist().data(); file = import.filelist();
in_iterloop.push(0); in_loop_level.push_back(0);
// add special symbol globals, which is a hash stores all global variables // add special symbol globals, which is a hash stores all global variables
add_symbol("globals"); add_symbol("globals");
@ -1124,7 +1124,6 @@ const error& codegen::compile(parse& parse, linker& import) {
gen(op_exit, 0, 0); gen(op_exit, 0, 0);
// size out of bound check // size out of bound check
err.load(file[0]); // load main execute file
if (const_number_table.size()>0xffffff) { if (const_number_table.size()>0xffffff) {
err.err("code", err.err("code",
"too many constant numbers: " + "too many constant numbers: " +

View File

@ -23,9 +23,9 @@
class codegen { class codegen {
private: private:
u16 fileindex; u16 fileindex;
error& err; error err;
const std::string* file; std::vector<std::string> file;
std::stack<u32> in_iterloop; std::vector<u32> in_loop_level;
std::unordered_map<f64, u32> const_number_map; std::unordered_map<f64, u32> const_number_map;
std::unordered_map<std::string, u32> const_string_map; std::unordered_map<std::string, u32> const_string_map;
std::vector<f64> const_number_table; std::vector<f64> const_number_table;
@ -105,7 +105,7 @@ public:
} }
public: public:
codegen(error& e): fileindex(0), err(e), file(nullptr) {} codegen(): fileindex(0) {}
const error& compile(parse&, linker&); const error& compile(parse&, linker&);
void print(std::ostream&); void print(std::ostream&);
}; };

View File

@ -60,11 +60,11 @@ private:
} }
private: private:
bool next; bool next;
usize fsize; usize fsize;
u16 bk_fidx; u16 bk_fidx;
u32 bk_line; u32 bk_line;
error& src; error src;
std::vector<std::string> parse(const std::string&); std::vector<std::string> parse(const std::string&);
u16 file_index(const std::string&) const; u16 file_index(const std::string&) const;
@ -76,10 +76,7 @@ private:
void interact(); void interact();
public: public:
dbg(error& err): dbg(): next(false), fsize(0), bk_fidx(0), bk_line(0) {}
next(false), fsize(0),
bk_fidx(0), bk_line(0),
src(err) {}
void run( void run(
const codegen&, const codegen&,
const linker&, const linker&,

View File

@ -86,23 +86,13 @@ void flstream::load(const std::string& f) {
} }
void error::fatal(const std::string& stage, const std::string& info) { void error::fatal(const std::string& stage, const std::string& info) {
std::cerr << red << stage << ": " << white << info << reset << "\n"; std::cerr << red << stage << ": " << white << info << reset << "\n\n";
if (file.length()) {
std::cerr << cyan << " --> " << red << file << reset << "\n\n";
} else {
std::cerr << reset << "\n";
}
std::exit(1); std::exit(1);
} }
void error::err(const std::string& stage, const std::string& info) { void error::err(const std::string& stage, const std::string& info) {
++cnt; ++cnt;
std::cerr << red << stage << ": " << white << info << reset << "\n"; std::cerr << red << stage << ": " << white << info << reset << "\n\n";
if (file.length()) {
std::cerr << cyan << " --> " << red << file << reset << "\n\n";
} else {
std::cerr << reset << "\n";
}
} }
void error::err( void error::err(

View File

@ -60,4 +60,5 @@ public:
std::exit(1); std::exit(1);
} }
} }
u32 geterr() const {return cnt;}
}; };

View File

@ -1,7 +1,6 @@
#include "nasal_import.h" #include "nasal_import.h"
linker::linker(error& e): linker::linker(): show_path(false), lib_loaded(false) {
show_path(false), lib_loaded(false), err(e) {
char sep = is_windows()? ';':':'; char sep = is_windows()? ';':':';
std::string PATH = getenv("PATH"); std::string PATH = getenv("PATH");
usize last = 0, pos = PATH.find(sep, 0); usize last = 0, pos = PATH.find(sep, 0);
@ -54,16 +53,19 @@ std::string linker::find_file(
find_file("std/lib.nas", location); find_file("std/lib.nas", location);
} }
if (!show_path) { if (!show_path) {
err.load(location.file); err.err("link",
err.err("link", "cannot find file <" + filename + ">"); "in <" + location.file + ">: " +
"cannot find file <" + filename + ">\n");
err.err("link", "use <-d> to get detail search path");
return ""; return "";
} }
std::string paths = ""; std::string paths = "";
for(const auto& i : fpath) { for(const auto& i : fpath) {
paths += " " + i + "\n"; paths += " -> " + i + "\n";
} }
err.load(location.file); err.err("link",
err.err("link", "cannot find file <" + filename + "> in these paths:\n" + paths); "in <" + location.file + ">: " +
"cannot find file <" + filename + "> in these paths:\n" + paths);
return ""; return "";
} }
@ -140,8 +142,8 @@ void linker::link(code_block* new_tree_root, code_block* old_tree_root) {
} }
code_block* linker::import_regular_file(call_expr* node) { code_block* linker::import_regular_file(call_expr* node) {
lexer lex(err); lexer lex;
parse par(err); parse par;
// get filename // get filename
auto filename = get_path(node); auto filename = get_path(node);
// clear this node // clear this node
@ -160,8 +162,12 @@ code_block* linker::import_regular_file(call_expr* node) {
} }
// start importing... // start importing...
lex.scan(filename); if (lex.scan(filename).geterr()) {
par.compile(lex); err.err("link", "error occurred when analysing <" + filename + ">");
}
if (par.compile(lex).geterr()) {
err.err("link", "error occurred when analysing <" + filename + ">");
}
auto tmp = par.swap(nullptr); auto tmp = par.swap(nullptr);
// check if tmp has 'import' // check if tmp has 'import'
@ -169,8 +175,8 @@ code_block* linker::import_regular_file(call_expr* node) {
} }
code_block* linker::import_nasal_lib() { code_block* linker::import_nasal_lib() {
lexer lex(err); lexer lex;
parse par(err); parse par;
auto filename = find_file("lib.nas", {0, 0, 0, 0, files[0]}); auto filename = find_file("lib.nas", {0, 0, 0, 0, files[0]});
if (!filename.length()) { if (!filename.length()) {
return new code_block({0, 0, 0, 0, filename}); return new code_block({0, 0, 0, 0, filename});
@ -182,8 +188,12 @@ code_block* linker::import_nasal_lib() {
} }
// start importing... // start importing...
lex.scan(filename); if (lex.scan(filename).geterr()) {
par.compile(lex); err.err("link", "error occurred when analysing library <" + filename + ">");
}
if (par.compile(lex).geterr()) {
err.err("link", "error occurred when analysing library <" + filename + ">");
}
auto tmp = par.swap(nullptr); auto tmp = par.swap(nullptr);
// check if tmp has 'import' // check if tmp has 'import'

View File

@ -21,7 +21,7 @@ class linker{
private: private:
bool show_path; bool show_path;
bool lib_loaded; bool lib_loaded;
error& err; error err;
std::vector<std::string> files; std::vector<std::string> files;
std::vector<std::string> envpath; std::vector<std::string> envpath;
@ -34,7 +34,7 @@ private:
code_block* import_nasal_lib(); code_block* import_nasal_lib();
code_block* load(code_block*, u16); code_block* load(code_block*, u16);
public: public:
linker(error&); linker();
const error& link(parse&, const std::string&, bool); const error& link(parse&, const std::string&, bool);
const std::vector<std::string>& filelist() const {return files;} const std::vector<std::string>& filelist() const {return files;}
}; };

View File

@ -74,9 +74,10 @@ void lexer::open(const std::string& file) {
std::ifstream in(file, std::ios::binary); std::ifstream in(file, std::ios::binary);
if (in.fail()) { if (in.fail()) {
err.err("lexer", "failed to open <" + file + ">"); err.err("lexer", "failed to open <" + file + ">");
} else { res = "";
err.load(file); return;
} }
err.load(file);
std::stringstream ss; std::stringstream ss;
ss << in.rdbuf(); ss << in.rdbuf();
res = ss.str(); res = ss.str();

View File

@ -90,12 +90,12 @@ struct token {
class lexer { class lexer {
private: private:
u32 line; u32 line;
u32 column; u32 column;
usize ptr; usize ptr;
std::string filename; std::string filename;
std::string res; std::string res;
error& err; error err;
std::vector<token> toks; std::vector<token> toks;
const std::unordered_map<std::string, tok> typetbl { const std::unordered_map<std::string, tok> typetbl {
{"true" ,tok::tktrue }, {"true" ,tok::tktrue },
@ -175,9 +175,7 @@ private:
token dots(); token dots();
token calc_opr(); token calc_opr();
public: public:
lexer(error& e): lexer(): line(1), column(0), ptr(0), filename(""), res("") {}
line(1), column(0),
ptr(0), filename(""), res(""), err(e) {}
const error& scan(const std::string&); const error& scan(const std::string&);
const std::vector<token>& result() const {return toks;} const std::vector<token>& result() const {return toks;}
}; };

View File

@ -18,7 +18,7 @@ private:
u32 in_loop; // count loop block u32 in_loop; // count loop block
const token* toks; const token* toks;
code_block* root; code_block* root;
error& err; error err;
private: private:
const std::unordered_map<tok, std::string> tokname { const std::unordered_map<tok, std::string> tokname {
@ -146,11 +146,7 @@ public:
} }
public: public:
parse(error& e): parse(): ptr(0), in_func(0), in_loop(0), toks(nullptr), root(nullptr) {}
ptr(0), in_func(0), in_loop(0),
toks(nullptr),
root(nullptr),
err(e) {}
~parse() { ~parse() {
if (root) { if (root) {
delete root; delete root;