⚡ optimize error report info
This commit is contained in:
parent
fe3847d69c
commit
4b597000ba
11
src/main.cpp
11
src/main.cpp
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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: " +
|
||||||
|
|
|
@ -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&);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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&,
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -60,4 +60,5 @@ public:
|
||||||
std::exit(1);
|
std::exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
u32 geterr() const {return cnt;}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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;}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue