From d89f290a8a08c66954c92e8bbb97fad46e5e4d4a Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Thu, 7 Sep 2023 23:14:17 +0800 Subject: [PATCH] :zap: fix out of bound bug & delete fatal in lexer --- makefile | 3 ++- src/nasal_err.cpp | 14 ++++++-------- src/nasal_err.h | 13 ------------- src/nasal_lexer.cpp | 21 +++++++++++++++------ src/nasal_lexer.h | 5 ++++- src/repl.cpp | 9 ++++----- src/repl.h | 12 ++++++++++++ 7 files changed, 43 insertions(+), 34 deletions(-) diff --git a/makefile b/makefile index 1f94936..5ec7f3e 100644 --- a/makefile +++ b/makefile @@ -72,7 +72,7 @@ build/nasal_misc.o: src/nasal.h src/nasal_misc.cpp | build build/repl.o: src/nasal.h src/repl.h src/repl.cpp | build $(CXX) -std=$(STD) -c -O3 src/repl.cpp -fno-exceptions -fPIC -o build/repl.o -I . -build/nasal_err.o: src/nasal.h src/nasal_err.h src/nasal_err.cpp | build +build/nasal_err.o: src/nasal.h src/repl.h src/nasal_err.h src/nasal_err.cpp | build $(CXX) -std=$(STD) -c -O3 src/nasal_err.cpp -fno-exceptions -fPIC -o build/nasal_err.o -I . build/nasal_gc.o: src/nasal.h src/nasal_gc.h src/nasal_gc.cpp | build @@ -88,6 +88,7 @@ build/nasal_import.o: \ build/nasal_lexer.o: \ src/nasal.h\ + src/repl.h\ src/nasal_err.h\ src/nasal_lexer.h src/nasal_lexer.cpp | build $(CXX) -std=$(STD) -c -O3 src/nasal_lexer.cpp -fno-exceptions -fPIC -o build/nasal_lexer.o -I . diff --git a/src/nasal_err.cpp b/src/nasal_err.cpp index 5075e71..eca1714 100644 --- a/src/nasal_err.cpp +++ b/src/nasal_err.cpp @@ -1,4 +1,5 @@ #include "nasal_err.h" +#include "repl.h" #ifdef _WIN32 #include // use SetConsoleTextAttribute @@ -76,9 +77,9 @@ void flstream::load(const std::string& f) { file = f; } - if (repl_file_info::instance()->in_repl_mode && - repl_file_info::instance()->repl_file_name==file) { - const auto& source = repl_file_info::instance()->repl_file_source; + if (repl::info::instance()->in_repl_mode && + repl::info::instance()->repl_file_name==file) { + const auto& source = repl::info::instance()->repl_file_source; res = {}; size_t pos = 0, last = 0; while ((pos = source.find("\n", last))!=std::string::npos) { @@ -87,6 +88,8 @@ void flstream::load(const std::string& f) { } if (lastin_repl_mode && - repl_file_info::instance()->repl_file_name==file) { + if (repl::info::instance()->in_repl_mode && + repl::info::instance()->repl_file_name==file) { err.load(file); filename = file; - res = repl_file_info::instance()->repl_file_source; + res = repl::info::instance()->repl_file_source; return; } @@ -123,7 +124,7 @@ std::string lexer::utf8_gen() { err.err("lexer", {line, column-1, line, column, filename}, "invalid utf-8 <"+utf_info+">"); - err.fatal("lexer", "fatal error occurred, stop"); + ++invalid_char; } str += tmp; column += 2; // may have some problems because not all the unicode takes 2 space @@ -358,8 +359,16 @@ const error& lexer::scan(const std::string& file) { } else { err_char(); } + if (invalid_char>10) { + err.err("lexer", "too many invalid characters, stop"); + break; + } + } + if (toks.size()) { + toks.push_back({toks.back().loc, tok::eof, ""}); + } else { + toks.push_back({{line, column, line, column, filename}, tok::eof, ""}); } - toks.push_back({{line, column, line, column, filename}, tok::eof, ""}); res = ""; return err; } diff --git a/src/nasal_lexer.h b/src/nasal_lexer.h index b824ce9..5317a06 100644 --- a/src/nasal_lexer.h +++ b/src/nasal_lexer.h @@ -95,8 +95,11 @@ private: usize ptr; std::string filename; std::string res; + error err; + u64 invalid_char; std::vector toks; + const std::unordered_map typetbl { {"true" ,tok::tktrue }, {"false" ,tok::tkfalse }, @@ -175,7 +178,7 @@ private: token dots(); token calc_opr(); public: - lexer(): line(1), column(0), ptr(0), filename(""), res("") {} + lexer(): line(1), column(0), ptr(0), filename(""), res(""), invalid_char(0) {} const error& scan(const std::string&); const std::vector& result() const {return toks;} }; diff --git a/src/repl.cpp b/src/repl.cpp index ef8fea3..8982547 100644 --- a/src/repl.cpp +++ b/src/repl.cpp @@ -20,7 +20,7 @@ void repl::update_temp_file() { for(const auto& i : source) { content += i + "\n"; } - repl_file_info::instance()->repl_file_source = content; + info::instance()->repl_file_source = content; } bool repl::check_need_more_input() { @@ -45,7 +45,7 @@ bool repl::check_need_more_input() { default: break; } } - if (!in_curve && !in_bracket && !in_brace) { + if (in_curve<=0 && in_bracket<=0 && in_brace<=0) { break; } auto line = readline("... "); @@ -94,7 +94,7 @@ bool repl::run() { } auto end = clk::now(); - std::clog << "[compile time: " << (end-start).count()*1.0/den << "s]\n"; + std::clog << "[compile time: " << (end-start).count()*1000.0/den << " ms]\n"; nasal_runtime->run(*nasal_codegen, *nasal_linker, {}, false); return true; @@ -102,8 +102,7 @@ bool repl::run() { void repl::execute() { source = {}; - auto repl_file_handle = repl_file_info::instance(); - repl_file_handle->in_repl_mode = true; + info::instance()->in_repl_mode = true; std::cout << "Nasal REPL interpreter(experimental).\n"; help(); diff --git a/src/repl.h b/src/repl.h index 3a2ef8a..f1c9b9c 100644 --- a/src/repl.h +++ b/src/repl.h @@ -10,6 +10,18 @@ namespace repl { +struct info { + bool in_repl_mode = false; + std::string repl_file_name = ""; + std::string repl_file_source = ""; + + // singleton + static info* instance() { + static info info; + return &info; + } +}; + class repl { private: std::vector source;