diff --git a/module/nasocket.cpp b/module/nasocket.cpp index 71b95c8..7dba4c1 100644 --- a/module/nasocket.cpp +++ b/module/nasocket.cpp @@ -8,7 +8,7 @@ #include #pragma comment(lib,"ws2_32") -class WSAmanager{ +class WSAmanager { private: WSAData data; public: diff --git a/src/nasal_err.cpp b/src/nasal_err.cpp index d13471f..5075e71 100644 --- a/src/nasal_err.cpp +++ b/src/nasal_err.cpp @@ -1,4 +1,5 @@ #include "nasal_err.h" + #ifdef _WIN32 #include // use SetConsoleTextAttribute struct for_reset { @@ -6,7 +7,11 @@ struct for_reset { for_reset() { GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &scr); } -} reset_ter_color; + static for_reset* singleton() { + static for_reset windows_set; + return &windows_set; + } +}; #endif std::ostream& back_white(std::ostream& s) { @@ -57,7 +62,7 @@ std::ostream& white(std::ostream& s) { std::ostream& reset(std::ostream& s) { #ifdef _WIN32 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - reset_ter_color.scr.wAttributes); + for_reset::singleton()->scr.wAttributes); #else s << "\033[0m"; #endif @@ -68,7 +73,22 @@ void flstream::load(const std::string& f) { if (file==f) { // don't need to load a loaded file return; } else { - file=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; + res = {}; + size_t pos = 0, last = 0; + while ((pos = source.find("\n", last))!=std::string::npos) { + res.push_back(source.substr(last, pos - last)); + last = pos + 1; + } + if (lastin_repl_mode && + repl_file_info::instance()->repl_file_name==file) { + err.load(file); + filename = file; + res = repl_file_info::instance()->repl_file_source; + return; + } + // check file exsits and it is a regular file struct stat buffer; if (stat(file.c_str(), &buffer)==0 && !S_ISREG(buffer.st_mode)) { diff --git a/src/repl.cpp b/src/repl.cpp index 3be8f19..ef8fea3 100644 --- a/src/repl.cpp +++ b/src/repl.cpp @@ -20,16 +20,14 @@ void repl::update_temp_file() { for(const auto& i : source) { content += i + "\n"; } - - std::ofstream out(".temp.nas", std::ios::binary); - out << content; + repl_file_info::instance()->repl_file_source = content; } bool repl::check_need_more_input() { while(true) { update_temp_file(); auto nasal_lexer = std::unique_ptr(new lexer); - if (nasal_lexer->scan(".temp.nas").geterr()) { + if (nasal_lexer->scan("").geterr()) { return false; } @@ -67,6 +65,10 @@ void repl::help() { bool repl::run() { update_temp_file(); + using clk = std::chrono::high_resolution_clock; + const auto den = clk::duration::period::den; + auto start = clk::now(); + auto nasal_lexer = std::unique_ptr(new lexer); auto nasal_parser = std::unique_ptr(new parse); auto nasal_linker = std::unique_ptr(new linker); @@ -74,7 +76,7 @@ bool repl::run() { auto nasal_codegen = std::unique_ptr(new codegen); auto nasal_runtime = std::unique_ptr(new vm); - if (nasal_lexer->scan(".temp.nas").geterr()) { + if (nasal_lexer->scan("").geterr()) { return false; } @@ -82,7 +84,7 @@ bool repl::run() { return false; } - if (nasal_linker->link(*nasal_parser, ".temp.nas", true).geterr()) { + if (nasal_linker->link(*nasal_parser, "", true).geterr()) { return false; } @@ -91,6 +93,8 @@ bool repl::run() { return false; } + auto end = clk::now(); + std::clog << "[compile time: " << (end-start).count()*1.0/den << "s]\n"; nasal_runtime->run(*nasal_codegen, *nasal_linker, {}, false); return true; @@ -98,6 +102,9 @@ bool repl::run() { void repl::execute() { source = {}; + auto repl_file_handle = repl_file_info::instance(); + repl_file_handle->in_repl_mode = true; + std::cout << "Nasal REPL interpreter(experimental).\n"; help(); @@ -127,9 +134,11 @@ void repl::execute() { continue; } + // run program if (!run()) { source.pop_back(); } + std::cout << "\n"; } }