🚀 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.h
STD=-std=c++11
STD=14
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)
$(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)
$(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)
$(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
@ ./nasal -o -e test/ascii-art.nas

View File

@ -1,31 +1,31 @@
.PHONY=clean all mingw-all
CPPSTANDARD=-std=c++11
STD=14
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
rm fib.o
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
del fib.o
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
rm keyboard.o
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
del keyboard.o
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
rm nasocket.o
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
del nasocket.o

View File

@ -389,7 +389,10 @@ nas_ref builtin_die(nas_ref* local,nasal_gc& gc)
nas_ref str=local[1];
if(str.type!=vm_str)
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};
}
nas_ref builtin_find(nas_ref* local,nasal_gc& gc)

View File

@ -8,8 +8,61 @@
#ifdef _WIN32
#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
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
{
protected:
@ -18,14 +71,13 @@ protected:
public:
void load(const string& f)
{
if(file==f) // don't need to load a loaded file
return;
if(file==f) return; // don't need to load a loaded file
file=f;
res.clear();
std::ifstream fin(f,std::ios::binary);
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);
}
string line;
@ -49,45 +101,30 @@ class nasal_err:public fstreamline
{
private:
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:
nasal_err():error(0){}
void err(const char* stage,const string& info)
{
++error;
printstg(stage);
std::cerr<<info<<"\n";
std::cerr<<bold_cyan<<"["<<stage<<"] "<<reset<<info<<"\n";
}
void err(const char* stage,u32 line,u32 column,const string& info)
{
++error;
const string& code=res[line-1];
printstg(stage);
std::cerr<<file<<":"<<line<<":"<<column<<" "<<info<<"\n"<<code<<"\n";
std::cerr<<bold_cyan<<"["<<stage<<"] "
<<bold_orange<<file<<":"<<line<<":"<<column<<" "
<<bold_white<<info<<reset<<"\n"<<code<<"\n";
for(i32 i=0;i<(i32)column-1;++i)
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)
{
++error;
printstg(stage);
std::cerr<<file<<":"<<line<<" "<<info<<"\n"<<res[line-1]<<'\n';
std::cerr<<bold_cyan<<"["<<stage<<"] "
<<bold_orange<<file<<":"<<line<<" "
<<bold_white<<info<<reset<<"\n"<<res[line-1]<<'\n';
}
void chkerr(){if(error)std::exit(1);}
};

View File

@ -4,6 +4,8 @@
#include <queue>
#include <unordered_map>
#include "nasal_err.h"
enum vm_type:u8{
/* none-gc object */
vm_none=0,
@ -721,7 +723,10 @@ void nasal_gc::ctxreserve()
// use to print error log and return error value
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};
}
#endif

View File

@ -4,6 +4,8 @@
#include <iomanip>
#include <stack>
#include "nasal_err.h"
class nasal_vm
{
protected:
@ -207,8 +209,9 @@ void nasal_vm::bytecodeinfo(const char* header,const u32 p)
void nasal_vm::traceback()
{
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;
for(nas_ref* i=bottom;i<=top;++i)
for(nas_ref* i=bottom;i<=main_ctx_top;++i)
if(i->type==vm_ret)
ret.push(i->ret());
ret.push(pc); // store the position program crashed
@ -314,7 +317,10 @@ void nasal_vm::detail()
[[noreturn]]
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();
stackinfo();
if(detail_info)