🚀 change cpp standard to c++14 & add command line colorful info output.

and fix a bug that program may crash if there's an error when coroutine is running
This commit is contained in:
ValKmjolnir 2022-08-31 23:24:41 +08:00
parent 52a38709bb
commit f86ea2445f
6 changed files with 93 additions and 42 deletions

View File

@ -15,17 +15,17 @@ SRC=\
nasal_dbg.h\ nasal_dbg.h\
nasal.h nasal.h
STD=-std=c++11 STD=14
nasal:$(SRC) nasal:$(SRC)
$(CXX) $(STD) -O3 main.cpp -o nasal -fno-exceptions -ldl -Wshadow -Wall $(CXX) -std=c++$(STD) -O3 main.cpp -o nasal -fno-exceptions -ldl -Wshadow -Wall
nasal.exe:$(SRC) nasal.exe:$(SRC)
$(CXX) $(STD) -O3 main.cpp -o nasal.exe -fno-exceptions -Wshadow -Wall -static $(CXX) -std=c++$(STD) -O3 main.cpp -o nasal.exe -fno-exceptions -Wshadow -Wall -static
stable-release:$(SRC) stable-release:$(SRC)
$(CXX) $(STD) -O2 main.cpp -o nasal -fno-exceptions -ldl -Wshadow -Wall $(CXX) -std=c++$(STD) -O2 main.cpp -o nasal -fno-exceptions -ldl -Wshadow -Wall
stable-release-mingw:$(SRC) stable-release-mingw:$(SRC)
$(CXX) $(STD) -O2 main.cpp -o nasal.exe -fno-exceptions -Wshadow -Wall -static $(CXX) -std=c++$(STD) -O2 main.cpp -o nasal.exe -fno-exceptions -Wshadow -Wall -static
test:nasal test:nasal
@ ./nasal -o -e test/ascii-art.nas @ ./nasal -o -e test/ascii-art.nas

View File

@ -1,31 +1,31 @@
.PHONY=clean all mingw-all .PHONY=clean all mingw-all
CPPSTANDARD=-std=c++11 STD=14
libfib.so: fib.cpp libfib.so: fib.cpp
$(CXX) $(CPPSTANDARD) -c -O3 fib.cpp -fPIC -o fib.o $(CXX) -std=c++$(STD) -c -O3 fib.cpp -fPIC -o fib.o
$(CXX) -shared -o libfib.so fib.o $(CXX) -shared -o libfib.so fib.o
rm fib.o rm fib.o
libfib.dll: fib.cpp libfib.dll: fib.cpp
$(CXX) $(CPPSTANDARD) -c -O3 fib.cpp -fPIC -o fib.o $(CXX) -std=c++$(STD) -c -O3 fib.cpp -fPIC -o fib.o
$(CXX) -shared -o libfib.dll fib.o $(CXX) -shared -o libfib.dll fib.o
del fib.o del fib.o
libkey.so: keyboard.cpp libkey.so: keyboard.cpp
$(CXX) $(CPPSTANDARD) -c -O3 keyboard.cpp -fPIC -o keyboard.o $(CXX) -std=c++$(STD) -c -O3 keyboard.cpp -fPIC -o keyboard.o
$(CXX) -shared -o libkey.so keyboard.o $(CXX) -shared -o libkey.so keyboard.o
rm keyboard.o rm keyboard.o
libkey.dll: keyboard.cpp libkey.dll: keyboard.cpp
$(CXX) $(CPPSTANDARD) -c -O3 keyboard.cpp -fPIC -o keyboard.o -static $(CXX) -std=c++$(STD) -c -O3 keyboard.cpp -fPIC -o keyboard.o -static
$(CXX) -shared -o libkey.dll keyboard.o -static $(CXX) -shared -o libkey.dll keyboard.o -static
del keyboard.o del keyboard.o
libnasock.so: nasocket.cpp libnasock.so: nasocket.cpp
$(CXX) $(CPPSTANDARD) -c -O3 nasocket.cpp -fPIC -o nasocket.o $(CXX) -std=c++$(STD) -c -O3 nasocket.cpp -fPIC -o nasocket.o
$(CXX) -shared -o libnasock.so nasocket.o $(CXX) -shared -o libnasock.so nasocket.o
rm nasocket.o rm nasocket.o
libnasock.dll: nasocket.cpp libnasock.dll: nasocket.cpp
$(CXX) $(CPPSTANDARD) -c -O3 nasocket.cpp -fPIC -o nasocket.o -lwsock32 -static $(CXX) -std=c++$(STD) -c -O3 nasocket.cpp -fPIC -o nasocket.o -lwsock32 -static
$(CXX) -shared -o libnasock.dll nasocket.o -lwsock32 -static $(CXX) -shared -o libnasock.dll nasocket.o -lwsock32 -static
del nasocket.o del nasocket.o

View File

@ -389,7 +389,10 @@ nas_ref builtin_die(nas_ref* local,nasal_gc& gc)
nas_ref str=local[1]; nas_ref str=local[1];
if(str.type!=vm_str) if(str.type!=vm_str)
return nas_err("die","\"str\" must be string"); return nas_err("die","\"str\" must be string");
std::cerr<<"[vm] error: "<<str.str()<<'\n'; std::cerr<<bold_cyan<<"[vm] "
<<bold_red<<"error: "
<<bold_white<<str.str()<<'\n'
<<reset;
return {vm_none}; return {vm_none};
} }
nas_ref builtin_find(nas_ref* local,nasal_gc& gc) nas_ref builtin_find(nas_ref* local,nasal_gc& gc)

View File

@ -8,8 +8,61 @@
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> // use SetConsoleTextAttribute #include <windows.h> // use SetConsoleTextAttribute
struct for_reset
{
CONSOLE_SCREEN_BUFFER_INFO scr;
for_reset(){
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),&scr);
}
}reset_ter_color;
#endif #endif
std::ostream& bold_red(std::ostream& s)
{
#ifdef _WIN32
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),0x0c);
#else
s<<"\033[91;1m";
#endif
return s;
}
std::ostream& bold_cyan(std::ostream& s)
{
#ifdef _WIN32
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),0x03);
#else
s<<"\033[36;1m";
#endif
return s;
}
std::ostream& bold_orange(std::ostream& s)
{
#ifdef _WIN32
SetConsoleTextAttribute(GetStdHandle(STD_ERROR_HANDLE),0x0e);
#else
s<<"\033[93;1m";
#endif
return s;
}
std::ostream& bold_white(std::ostream& s)
{
#ifdef _WIN32
SetConsoleTextAttribute(GetStdHandle(STD_ERROR_HANDLE),0x0f);
#else
s<<"\033[0m\033[1m";
#endif
return s;
}
std::ostream& reset(std::ostream& s)
{
#ifdef _WIN32
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),reset_ter_color.scr.wAttributes);
#else
s<<"\033[0m";
#endif
return s;
}
class fstreamline class fstreamline
{ {
protected: protected:
@ -18,14 +71,13 @@ protected:
public: public:
void load(const string& f) void load(const string& f)
{ {
if(file==f) // don't need to load a loaded file if(file==f) return; // don't need to load a loaded file
return;
file=f; file=f;
res.clear(); res.clear();
std::ifstream fin(f,std::ios::binary); std::ifstream fin(f,std::ios::binary);
if(fin.fail()) if(fin.fail())
{ {
std::cerr<<"[src] cannot open file <"<<f<<">\n"; std::cerr<<bold_cyan<<"[src] "<<reset<<"cannot open file <"<<f<<">\n";
std::exit(1); std::exit(1);
} }
string line; string line;
@ -49,45 +101,30 @@ class nasal_err:public fstreamline
{ {
private: private:
u32 error; u32 error;
void printstg(const char* stage)
{
#ifdef _WIN32
CONSOLE_SCREEN_BUFFER_INFO scrinfo;
GetConsoleScreenBufferInfo(GetStdHandle(STD_ERROR_HANDLE),&scrinfo);
SetConsoleTextAttribute(GetStdHandle(STD_ERROR_HANDLE),0x03);
std::cerr<<"[";
SetConsoleTextAttribute(GetStdHandle(STD_ERROR_HANDLE),0x0c);
std::cerr<<stage;
SetConsoleTextAttribute(GetStdHandle(STD_ERROR_HANDLE),0x03);
std::cerr<<"] ";
SetConsoleTextAttribute(GetStdHandle(STD_ERROR_HANDLE),scrinfo.wAttributes);
#else
std::cerr<<"\033[36m[\033[91m"<<stage<<"\033[36m]\033[0m ";
#endif
}
public: public:
nasal_err():error(0){} nasal_err():error(0){}
void err(const char* stage,const string& info) void err(const char* stage,const string& info)
{ {
++error; ++error;
printstg(stage); std::cerr<<bold_cyan<<"["<<stage<<"] "<<reset<<info<<"\n";
std::cerr<<info<<"\n";
} }
void err(const char* stage,u32 line,u32 column,const string& info) void err(const char* stage,u32 line,u32 column,const string& info)
{ {
++error; ++error;
const string& code=res[line-1]; const string& code=res[line-1];
printstg(stage); std::cerr<<bold_cyan<<"["<<stage<<"] "
std::cerr<<file<<":"<<line<<":"<<column<<" "<<info<<"\n"<<code<<"\n"; <<bold_orange<<file<<":"<<line<<":"<<column<<" "
<<bold_white<<info<<reset<<"\n"<<code<<"\n";
for(i32 i=0;i<(i32)column-1;++i) for(i32 i=0;i<(i32)column-1;++i)
std::cerr<<char(" \t"[code[i]=='\t']); std::cerr<<char(" \t"[code[i]=='\t']);
std::cerr<<"^\n"; std::cerr<<bold_red<<"^\n"<<reset;
} }
void err(const char* stage,u32 line,const string& info) void err(const char* stage,u32 line,const string& info)
{ {
++error; ++error;
printstg(stage); std::cerr<<bold_cyan<<"["<<stage<<"] "
std::cerr<<file<<":"<<line<<" "<<info<<"\n"<<res[line-1]<<'\n'; <<bold_orange<<file<<":"<<line<<" "
<<bold_white<<info<<reset<<"\n"<<res[line-1]<<'\n';
} }
void chkerr(){if(error)std::exit(1);} void chkerr(){if(error)std::exit(1);}
}; };

View File

@ -4,6 +4,8 @@
#include <queue> #include <queue>
#include <unordered_map> #include <unordered_map>
#include "nasal_err.h"
enum vm_type:u8{ enum vm_type:u8{
/* none-gc object */ /* none-gc object */
vm_none=0, vm_none=0,
@ -721,7 +723,10 @@ void nasal_gc::ctxreserve()
// use to print error log and return error value // use to print error log and return error value
nas_ref nas_err(const string& err_f,const string& info) nas_ref nas_err(const string& err_f,const string& info)
{ {
std::cerr<<"[vm] "<<err_f<<": "<<info<<"\n"; std::cerr<<bold_cyan<<"[vm] "
<<bold_red<<err_f<<": "
<<bold_white<<info<<"\n"
<<reset;
return {vm_none}; return {vm_none};
} }
#endif #endif

View File

@ -4,6 +4,8 @@
#include <iomanip> #include <iomanip>
#include <stack> #include <stack>
#include "nasal_err.h"
class nasal_vm class nasal_vm
{ {
protected: protected:
@ -207,8 +209,9 @@ void nasal_vm::bytecodeinfo(const char* header,const u32 p)
void nasal_vm::traceback() void nasal_vm::traceback()
{ {
nas_ref* bottom=stack+bytecode[0].num; // bytecode[0] is op_intg nas_ref* bottom=stack+bytecode[0].num; // bytecode[0] is op_intg
nas_ref* main_ctx_top=gc.stack==stack?top:gc.mctx.top; // if error occurs in coroutine, this works
std::stack<u32> ret; std::stack<u32> ret;
for(nas_ref* i=bottom;i<=top;++i) for(nas_ref* i=bottom;i<=main_ctx_top;++i)
if(i->type==vm_ret) if(i->type==vm_ret)
ret.push(i->ret()); ret.push(i->ret());
ret.push(pc); // store the position program crashed ret.push(pc); // store the position program crashed
@ -314,7 +317,10 @@ void nasal_vm::detail()
[[noreturn]] [[noreturn]]
void nasal_vm::die(const string& str) void nasal_vm::die(const string& str)
{ {
std::cout<<"[vm] "<<str<<"\n"; std::cout<<bold_cyan<<"[vm] "
<<bold_red<<"error: "
<<bold_white<<str<<"\n"
<<reset;
traceback(); traceback();
stackinfo(); stackinfo();
if(detail_info) if(detail_info)