diff --git a/.gitignore b/.gitignore index ed501c9..cd32b92 100644 --- a/.gitignore +++ b/.gitignore @@ -47,6 +47,9 @@ nasal.exe .vscode dump +# build dir +build + # macOS special cache directory .DS_Store diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..706880d --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,27 @@ +cmake_minimum_required(VERSION 3.10) + +project(nasal VERSION 10.1) + +# -std=c++14 -Wshadow -Wall +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED True) +set(CMAKE_CXX_FLAGS_RELEASE_INIT "-Wshadow -Wall") + +# generate release executables +set(CMAKE_BUILD_TYPE "Release") + +add_library(fib SHARED ${CMAKE_SOURCE_DIR}/module/fib.cpp) +target_include_directories(fib PRIVATE ${CMAKE_SOURCE_DIR}) + +add_library(key SHARED ${CMAKE_SOURCE_DIR}/module/keyboard.cpp) +target_include_directories(key PRIVATE ${CMAKE_SOURCE_DIR}) + +add_library(mat SHARED ${CMAKE_SOURCE_DIR}/module/matrix.cpp) +target_include_directories(mat PRIVATE ${CMAKE_SOURCE_DIR}) + +add_library(nasock SHARED ${CMAKE_SOURCE_DIR}/module/nasocket.cpp) +target_include_directories(nasock PRIVATE ${CMAKE_SOURCE_DIR}) + +add_executable(nasal main.cpp) +target_link_libraries(nasal dl) +target_include_directories(nasal PRIVATE ${CMAKE_SOURCE_DIR}) \ No newline at end of file diff --git a/main.cpp b/main.cpp index 9718d9b..aef7268 100644 --- a/main.cpp +++ b/main.cpp @@ -70,7 +70,11 @@ void err() { std::exit(1); } -void execute(const string& file, const std::vector& argv, const u32 cmd) { +void execute( + const string& file, + const std::vector& argv, + const u32 cmd +) { using clk=std::chrono::high_resolution_clock; const auto den=clk::duration::period::den; @@ -96,8 +100,8 @@ void execute(const string& file, const std::vector& argv, const u32 cmd) parse.tree().dump(); } - // code generator gets parser's ast and linker's import file list to generate code - gen.compile(parse,ld).chkerr(); + // code generator gets parser's ast and import file list to generate code + gen.compile(parse, ld).chkerr(); if (cmd&VM_CODE) { gen.print(); } @@ -109,6 +113,8 @@ void execute(const string& file, const std::vector& argv, const u32 cmd) } else if (cmd&VM_TIME || cmd&VM_EXEC) { ctx.run(gen, ld, argv, cmd&VM_DETAIL); } + + // get running time if (cmd&VM_TIME) { f64 tm=(clk::now()-start).count()*1.0/den; std::clog<<"process exited after "< cmdlst={ - {"--ast",VM_AST}, - {"-a",VM_AST}, - {"--code",VM_CODE}, - {"-c",VM_CODE}, - {"--exec",VM_EXEC}, - {"-e",VM_EXEC}, - {"--time",VM_TIME|VM_EXEC}, - {"-t",VM_TIME|VM_EXEC}, - {"--detail",VM_DETAIL|VM_EXEC}, - {"-d",VM_DETAIL|VM_EXEC}, - {"--debug",VM_DEBUG}, - {"-dbg",VM_DEBUG} + {"--ast", VM_AST}, + {"-a", VM_AST}, + {"--code", VM_CODE}, + {"-c", VM_CODE}, + {"--exec", VM_EXEC}, + {"-e", VM_EXEC}, + {"--time", VM_TIME|VM_EXEC}, + {"-t", VM_TIME|VM_EXEC}, + {"--detail", VM_DETAIL|VM_EXEC}, + {"-d", VM_DETAIL|VM_EXEC}, + {"--debug", VM_DEBUG}, + {"-dbg", VM_DEBUG} }; u32 cmd=0; string filename=""; std::vector vm_argv; - for(i32 i=1;i -var nas_vec2(var* args,usize size,gc* ngc) { +var nas_vec2(var* args, usize size, gc* ngc) { var res=ngc->alloc(vm_vec); res.vec().elems.push_back(args[0]); res.vec().elems.push_back(args[1]); return res; } -var nas_vec3(var* args,usize size,gc* ngc) { +var nas_vec3(var* args, usize size, gc* ngc) { var res=ngc->alloc(vm_vec); res.vec().elems.push_back(args[0]); res.vec().elems.push_back(args[1]); @@ -16,7 +16,7 @@ var nas_vec3(var* args,usize size,gc* ngc) { return res; } -var nas_vec2_add(var* args,usize size,gc* ngc) { +var nas_vec2_add(var* args, usize size, gc* ngc) { if (args[0].type!=vm_vec || args[1].type!=vm_vec) return nil; auto& v0=args[0].vec().elems; @@ -29,7 +29,7 @@ var nas_vec2_add(var* args,usize size,gc* ngc) { return res; } -var nas_vec2_sub(var* args,usize size,gc* ngc) { +var nas_vec2_sub(var* args, usize size, gc* ngc) { if (args[0].type!=vm_vec || args[1].type!=vm_vec) return nil; auto& v0=args[0].vec().elems; @@ -42,7 +42,7 @@ var nas_vec2_sub(var* args,usize size,gc* ngc) { return res; } -var nas_vec2_mult(var* args,usize size,gc* ngc) { +var nas_vec2_mult(var* args, usize size, gc* ngc) { if (args[0].type!=vm_vec || args[1].type!=vm_vec) return nil; auto& v0=args[0].vec().elems; @@ -55,7 +55,7 @@ var nas_vec2_mult(var* args,usize size,gc* ngc) { return res; } -var nas_vec2_div(var* args,usize size,gc* ngc) { +var nas_vec2_div(var* args, usize size, gc* ngc) { if (args[0].type!=vm_vec || args[1].type!=vm_vec) return nil; auto& v0=args[0].vec().elems; @@ -68,7 +68,7 @@ var nas_vec2_div(var* args,usize size,gc* ngc) { return res; } -var nas_vec2_neg(var* args,usize size,gc* ngc) { +var nas_vec2_neg(var* args, usize size, gc* ngc) { if (args[0].type!=vm_vec) return nil; auto& v0=args[0].vec().elems; @@ -80,7 +80,7 @@ var nas_vec2_neg(var* args,usize size,gc* ngc) { return res; } -var nas_vec2_norm(var* args,usize size,gc* ngc) { +var nas_vec2_norm(var* args, usize size, gc* ngc) { if (args[0].type!=vm_vec) return nil; auto& v0=args[0].vec().elems; @@ -95,7 +95,7 @@ var nas_vec2_norm(var* args,usize size,gc* ngc) { return res; } -var nas_vec2_len(var* args,usize size,gc* ngc) { +var nas_vec2_len(var* args, usize size, gc* ngc) { if (args[0].type!=vm_vec) return nil; auto& v0=args[0].vec().elems; @@ -106,7 +106,7 @@ var nas_vec2_len(var* args,usize size,gc* ngc) { return var::num(std::sqrt(x*x+y*y)); } -var nas_vec2_dot(var* args,usize size,gc* ngc) { +var nas_vec2_dot(var* args, usize size, gc* ngc) { if (args[0].type!=vm_vec || args[1].type!=vm_vec) return nil; auto& v0=args[0].vec().elems; @@ -116,7 +116,7 @@ var nas_vec2_dot(var* args,usize size,gc* ngc) { return var::num(v0[0].num()*v1[0].num()+v0[1].num()*v1[1].num()); } -var nas_vec3_add(var* args,usize size,gc* ngc) { +var nas_vec3_add(var* args, usize size, gc* ngc) { if (args[0].type!=vm_vec || args[1].type!=vm_vec) return nil; auto& v0=args[0].vec().elems; @@ -130,7 +130,7 @@ var nas_vec3_add(var* args,usize size,gc* ngc) { return res; } -var nas_vec3_sub(var* args,usize size,gc* ngc) { +var nas_vec3_sub(var* args, usize size, gc* ngc) { if (args[0].type!=vm_vec || args[1].type!=vm_vec) return nil; auto& v0=args[0].vec().elems; @@ -144,7 +144,7 @@ var nas_vec3_sub(var* args,usize size,gc* ngc) { return res; } -var nas_vec3_mult(var* args,usize size,gc* ngc) { +var nas_vec3_mult(var* args, usize size, gc* ngc) { if (args[0].type!=vm_vec || args[1].type!=vm_vec) return nil; auto& v0=args[0].vec().elems; @@ -158,7 +158,7 @@ var nas_vec3_mult(var* args,usize size,gc* ngc) { return res; } -var nas_vec3_div(var* args,usize size,gc* ngc) { +var nas_vec3_div(var* args, usize size, gc* ngc) { if (args[0].type!=vm_vec || args[1].type!=vm_vec) return nil; auto& v0=args[0].vec().elems; @@ -172,7 +172,7 @@ var nas_vec3_div(var* args,usize size,gc* ngc) { return res; } -var nas_vec3_neg(var* args,usize size,gc* ngc) { +var nas_vec3_neg(var* args, usize size, gc* ngc) { if (args[0].type!=vm_vec) return nil; auto& v0=args[0].vec().elems; @@ -185,7 +185,7 @@ var nas_vec3_neg(var* args,usize size,gc* ngc) { return res; } -var nas_vec3_norm(var* args,usize size,gc* ngc) { +var nas_vec3_norm(var* args, usize size, gc* ngc) { if (args[0].type!=vm_vec) return nil; auto& v0=args[0].vec().elems; @@ -202,7 +202,7 @@ var nas_vec3_norm(var* args,usize size,gc* ngc) { return res; } -var nas_vec3_len(var* args,usize size,gc* ngc) { +var nas_vec3_len(var* args, usize size, gc* ngc) { if (args[0].type!=vm_vec) return nil; auto& v0=args[0].vec().elems; @@ -214,7 +214,7 @@ var nas_vec3_len(var* args,usize size,gc* ngc) { return var::num(std::sqrt(x*x+y*y+z*z)); } -var nas_rotate_x(var* args,usize size,gc* ngc) { +var nas_rotate_x(var* args, usize size, gc* ngc) { if (args[0].type!=vm_vec) return nil; auto& v0=args[0].vec().elems; @@ -228,7 +228,7 @@ var nas_rotate_x(var* args,usize size,gc* ngc) { return res; } -var nas_rotate_y(var* args,usize size,gc* ngc) { +var nas_rotate_y(var* args, usize size, gc* ngc) { if (args[0].type!=vm_vec) return nil; auto& v0=args[0].vec().elems; @@ -242,7 +242,7 @@ var nas_rotate_y(var* args,usize size,gc* ngc) { return res; } -var nas_rotate_z(var* args,usize size,gc* ngc) { +var nas_rotate_z(var* args, usize size, gc* ngc) { if (args[0].type!=vm_vec) return nil; auto& v0=args[0].vec().elems; @@ -256,7 +256,7 @@ var nas_rotate_z(var* args,usize size,gc* ngc) { return res; } -var nas_vec3_dot(var* args,usize size,gc* ngc) { +var nas_vec3_dot(var* args, usize size, gc* ngc) { if (args[0].type!=vm_vec || args[1].type!=vm_vec) return nil; auto& v0=args[0].vec().elems; diff --git a/module/nasocket.cpp b/module/nasocket.cpp index 92c03a9..3d4fa9b 100644 --- a/module/nasocket.cpp +++ b/module/nasocket.cpp @@ -10,7 +10,7 @@ private: WSAData data; public: WSAmanager() { - WSAStartup(0x1010,&data); + WSAStartup(0x1010, &data); } ~WSAmanager() { WSACleanup(); @@ -25,14 +25,14 @@ static WSAmanager win; #include #endif -var nas_socket(var* args,usize size,gc* ngc) { +var nas_socket(var* args, usize size, gc* ngc) { if (args[0].type!=vm_num || args[1].type!=vm_num || args[2].type!=vm_num) return nas_err("socket","\"af\", \"type\", \"protocol\" should be number"); int sd=socket(args[0].num(),args[1].num(),args[2].num()); return var::num((double)sd); } -var nas_closesocket(var* args,usize size,gc* ngc) { +var nas_closesocket(var* args, usize size, gc* ngc) { if (args[0].type!=vm_num) return nas_err("closesocket","\"sd\" should be number"); #ifdef _WIN32 @@ -42,7 +42,7 @@ var nas_closesocket(var* args,usize size,gc* ngc) { #endif } -var nas_shutdown(var* args,usize size,gc* ngc) { +var nas_shutdown(var* args, usize size, gc* ngc) { if (args[0].type!=vm_num) return nas_err("shutdown","\"sd\" must be a number"); if (args[1].type!=vm_num) @@ -50,7 +50,7 @@ var nas_shutdown(var* args,usize size,gc* ngc) { return var::num((double)shutdown(args[0].num(),args[1].num())); } -var nas_bind(var* args,usize size,gc* ngc) { +var nas_bind(var* args, usize size, gc* ngc) { if (args[0].type!=vm_num) return nas_err("bind","\"sd\" muse be a number"); if (args[1].type!=vm_str) @@ -65,7 +65,7 @@ var nas_bind(var* args,usize size,gc* ngc) { return var::num((double)bind(args[0].num(),(sockaddr*)&server,sizeof(server))); } -var nas_listen(var* args,usize size,gc* ngc) { +var nas_listen(var* args, usize size, gc* ngc) { if (args[0].type!=vm_num) return nas_err("listen","\"sd\" must be a number"); if (args[1].type!=vm_num) @@ -73,7 +73,7 @@ var nas_listen(var* args,usize size,gc* ngc) { return var::num((double)listen(args[0].num(),args[1].num())); } -var nas_connect(var* args,usize size,gc* ngc) { +var nas_connect(var* args, usize size, gc* ngc) { if (args[0].type!=vm_num) return nas_err("connect","\"sd\" must be a number"); if (args[1].type!=vm_str) @@ -89,7 +89,7 @@ var nas_connect(var* args,usize size,gc* ngc) { return var::num((double)connect(args[0].num(),(sockaddr*)&addr,sizeof(sockaddr_in))); } -var nas_accept(var* args,usize size,gc* ngc) { +var nas_accept(var* args, usize size, gc* ngc) { if (args[0].type!=vm_num) return nas_err("accept","\"sd\" must be a number"); sockaddr_in client; @@ -107,7 +107,7 @@ var nas_accept(var* args,usize size,gc* ngc) { return res; } -var nas_send(var* args,usize size,gc* ngc) { +var nas_send(var* args, usize size, gc* ngc) { if (args[0].type!=vm_num) return nas_err("send","\"sd\" must be a number"); if (args[1].type!=vm_str) @@ -117,7 +117,7 @@ var nas_send(var* args,usize size,gc* ngc) { return var::num((double)send(args[0].num(),args[1].str().c_str(),args[1].str().length(),args[2].num())); } -var nas_sendto(var* args,usize size,gc* ngc) { +var nas_sendto(var* args, usize size, gc* ngc) { if (args[0].type!=vm_num) return nas_err("sendto","\"sd\" must be a number"); if (args[1].type!=vm_str) @@ -137,7 +137,7 @@ var nas_sendto(var* args,usize size,gc* ngc) { return var::num((double)sendto(args[0].num(),args[3].str().c_str(),args[3].str().length(),args[4].num(),(sockaddr*)&addr,sizeof(sockaddr_in))); } -var nas_recv(var* args,usize size,gc* ngc) { +var nas_recv(var* args, usize size, gc* ngc) { if (args[0].type!=vm_num) return nas_err("recv","\"sd\" must be a number"); if (args[1].type!=vm_num) @@ -158,7 +158,7 @@ var nas_recv(var* args,usize size,gc* ngc) { return res; } -var nas_recvfrom(var* args,usize size,gc* ngc) { +var nas_recvfrom(var* args, usize size, gc* ngc) { if (args[0].type!=vm_num) return nas_err("recvfrom","\"sd\" must be a number"); if (args[1].type!=vm_num) @@ -186,7 +186,7 @@ var nas_recvfrom(var* args,usize size,gc* ngc) { return res; } -var nas_errno(var* args,usize size,gc* ngc) { +var nas_errno(var* args, usize size, gc* ngc) { return ngc->newstr(strerror(errno)); } diff --git a/nasal.h b/nasal.h index 4fee657..9624c35 100644 --- a/nasal.h +++ b/nasal.h @@ -109,7 +109,7 @@ const u32 STACK_DEPTH=1024; f64 hex2f(const char* str) { f64 ret=0; - for(;*str;++str) { + for(; *str; ++str) { if ('0'<=*str && *str<='9') { ret=ret*16+(*str-'0'); } else if ('a'<=*str && *str<='f') { @@ -134,10 +134,12 @@ f64 oct2f(const char* str) { return ret; } -// we have the same reason not using atof here just as andy's interpreter does. +// we have the same reason not using atof here +// just as andy's interpreter does. // it is not platform independent, and may have strange output. // so we write a new function here to convert str to number manually. -// but this also makes 0.1+0.2==0.3, not another result that you may get in other languages. +// but this also makes 0.1+0.2==0.3, +// not another result that you may get in other languages. f64 dec2f(const char* str) { f64 ret=0,negative=1,num_pow=0; while('0'<=*str && *str<='9') { @@ -220,7 +222,7 @@ string chrhex(const char c) { return {hextbl[(c&0xf0)>>4],hextbl[c&0x0f]}; } -string rawstr(const string& str,const usize maxlen=0) { +string rawstr(const string& str, const usize maxlen=0) { string ret(""); for(auto i:str) { // windows doesn't output unicode normally, so we output the hex diff --git a/nasal_ast.h b/nasal_ast.h index 05e1762..c424854 100644 --- a/nasal_ast.h +++ b/nasal_ast.h @@ -151,8 +151,9 @@ public: ast(ast&&) = default; ast& operator=(ast&&) = default; + private: - void print(u32,bool,std::vector&) const; + void print(u32, bool, std::vector&) const; private: span loc; @@ -162,23 +163,27 @@ private: std::vector nd_child; public: - ast(const span& s,const u32 t) - : loc(s),nd_type(t),nd_num(0),nd_str("") {} + ast(const span& s, const u32 t) + : loc(s), nd_type(t), nd_num(0), nd_str("") {} +public: void dump() const; void clear(); +public: ast& operator[](usize n) {return nd_child[n];} const ast& operator[](usize n) const {return nd_child[n];} usize size() const {return nd_child.size();} - + +public: void add(ast&& node) {nd_child.push_back(std::move(node));} - void set_begin(const u32,const u32); - void set_end(const u32,const u32); + void set_begin(const u32, const u32); + void set_end(const u32, const u32); void set_type(const u32 t) {nd_type=t;} void set_str(const string& s) {nd_str=s;} void set_num(const f64 n) {nd_num=n;} +public: u32 line() const {return loc.end_line;} u32 type() const {return nd_type;} f64 num() const {return nd_num;} @@ -193,18 +198,18 @@ public: void update_span(const span&); }; -void ast::set_begin(const u32 l,const u32 c) { +void ast::set_begin(const u32 l, const u32 c) { loc.begin_line=l; loc.begin_column=c; } -void ast::set_end(const u32 l,const u32 c) { +void ast::set_end(const u32 l, const u32 c) { loc.end_line=l; loc.end_column=c; } void ast::clear() { - loc={0,0,0,0,""}; + loc={0, 0, 0, 0, ""}; nd_num=0; nd_str.clear(); nd_type=ast_null; @@ -213,10 +218,10 @@ void ast::clear() { void ast::dump() const{ std::vector tmp; - print(0,false,tmp); + print(0, false, tmp); } -void ast::print(u32 depth,bool last,std::vector& indent) const{ +void ast::print(u32 depth, bool last, std::vector& indent) const{ // output the indentation first for(auto& i:indent) { std::cout<& indent) const{ } else if (!last && depth) { indent.back()=is_windows()? "| ":"│ "; } - for(u32 i=0;i1 || !end.str().length()) { std::cin>>ret.str(); } else { - std::getline(std::cin,ret.str(),end.str()[0]); + std::getline(std::cin, ret.str(), end.str()[0]); } return ret; } -var builtin_readfile(var* local,gc& ngc) { +var builtin_readfile(var* local, gc& ngc) { var val=local[1]; if (val.type!=vm_str) { - return nas_err("io::readfile","\"filename\" must be string"); + return nas_err("io::readfile", "\"filename\" must be string"); } - std::ifstream in(val.str(),std::ios::binary); + std::ifstream in(val.str(), std::ios::binary); std::stringstream rd; if (!in.fail()) { rd<"); + return nas_err("io::fout", "cannot open <"+val.str()+">"); } out<last) { - vec.push_back(ngc.newstr(s.substr(last,pos-last))); + vec.push_back(ngc.newstr(s.substr(last, pos-last))); } last=pos+deli.length(); - pos=s.find(deli,last); + pos=s.find(deli, last); } if (last!=s.length()) { vec.push_back(ngc.newstr(s.substr(last))); @@ -167,10 +168,10 @@ var builtin_split(var* local,gc& ngc) { return res; } -var builtin_rand(var* local,gc& ngc) { +var builtin_rand(var* local, gc& ngc) { var val=local[1]; if (val.type!=vm_num && val.type!=vm_nil) { - return nas_err("rand","\"seed\" must be nil or number"); + return nas_err("rand", "\"seed\" must be nil or number"); } if (val.type==vm_num) { srand((u32)val.num()); @@ -183,7 +184,7 @@ var builtin_rand(var* local,gc& ngc) { return var::num(num); } -var builtin_id(var* local,gc& ngc) { +var builtin_id(var* local, gc& ngc) { var val=local[1]; std::stringstream ss; ss<<"0"; @@ -193,7 +194,7 @@ var builtin_id(var* local,gc& ngc) { return ngc.newstr(ss.str()); } -var builtin_int(var* local,gc& ngc) { +var builtin_int(var* local, gc& ngc) { var val=local[1]; if (val.type!=vm_num && val.type!=vm_str) { return nil; @@ -201,12 +202,12 @@ var builtin_int(var* local,gc& ngc) { return var::num(f64((i32)val.tonum())); } -var builtin_floor(var* local,gc& ngc) { +var builtin_floor(var* local, gc& ngc) { var val=local[1]; return var::num(std::floor(val.num())); } -var builtin_num(var* local,gc& ngc) { +var builtin_num(var* local, gc& ngc) { var val=local[1]; if (val.type==vm_num) { return val; @@ -221,10 +222,10 @@ var builtin_num(var* local,gc& ngc) { return var::num(res); } -var builtin_pop(var* local,gc& ngc) { +var builtin_pop(var* local, gc& ngc) { var val=local[1]; if (val.type!=vm_vec) { - return nas_err("pop","\"vec\" must be vector"); + return nas_err("pop", "\"vec\" must be vector"); } auto& vec=val.vec().elems; if (vec.size()) { @@ -235,11 +236,11 @@ var builtin_pop(var* local,gc& ngc) { return nil; } -var builtin_str(var* local,gc& ngc) { +var builtin_str(var* local, gc& ngc) { return ngc.newstr(local[1].tostr()); } -var builtin_size(var* local,gc& ngc) { +var builtin_size(var* local, gc& ngc) { var val=local[1]; f64 num=0; switch(val.type) { @@ -251,94 +252,94 @@ var builtin_size(var* local,gc& ngc) { return var::num(num); } -var builtin_u32xor(var* local,gc& ngc) { +var builtin_u32xor(var* local, gc& ngc) { return var::num((f64)(u32(local[1].num())^u32(local[2].num()))); } -var builtin_u32and(var* local,gc& ngc) { +var builtin_u32and(var* local, gc& ngc) { return var::num((f64)(u32(local[1].num())&u32(local[2].num()))); } -var builtin_u32or(var* local,gc& ngc) { +var builtin_u32or(var* local, gc& ngc) { return var::num((f64)(u32(local[1].num())|u32(local[2].num()))); } -var builtin_u32nand(var* local,gc& ngc) { +var builtin_u32nand(var* local, gc& ngc) { return var::num((f64)(u32)(~(u32(local[1].num())&u32(local[2].num())))); } -var builtin_u32not(var* local,gc& ngc) { +var builtin_u32not(var* local, gc& ngc) { return var::num((f64)(u32)(~u32(local[1].num()))); } -var builtin_pow(var* local,gc& ngc) { +var builtin_pow(var* local, gc& ngc) { var x=local[1]; var y=local[2]; if (x.type!=vm_num || y.type!=vm_num) { return var::num(std::nan("")); } - return var::num(std::pow(x.num(),y.num())); + return var::num(std::pow(x.num(), y.num())); } -var builtin_sin(var* local,gc& ngc) { +var builtin_sin(var* local, gc& ngc) { var val=local[1]; return var::num(val.type==vm_num?sin(val.num()):std::nan("")); } -var builtin_cos(var* local,gc& ngc) { +var builtin_cos(var* local, gc& ngc) { var val=local[1]; return var::num(val.type==vm_num?cos(val.num()):std::nan("")); } -var builtin_tan(var* local,gc& ngc) { +var builtin_tan(var* local, gc& ngc) { var val=local[1]; return var::num(val.type==vm_num?tan(val.num()):std::nan("")); } -var builtin_exp(var* local,gc& ngc) { +var builtin_exp(var* local, gc& ngc) { var val=local[1]; return var::num(val.type==vm_num?exp(val.num()):std::nan("")); } -var builtin_lg(var* local,gc& ngc) { +var builtin_lg(var* local, gc& ngc) { var val=local[1]; return var::num(val.type==vm_num?log(val.num())/log(10.0):std::nan("")); } -var builtin_ln(var* local,gc& ngc) { +var builtin_ln(var* local, gc& ngc) { var val=local[1]; return var::num(val.type==vm_num?log(val.num()):std::nan("")); } -var builtin_sqrt(var* local,gc& ngc) { +var builtin_sqrt(var* local, gc& ngc) { var val=local[1]; return var::num(val.type==vm_num?sqrt(val.num()):std::nan("")); } -var builtin_atan2(var* local,gc& ngc) { +var builtin_atan2(var* local, gc& ngc) { var x=local[1]; var y=local[2]; if (x.type!=vm_num || y.type!=vm_num) { return var::num(std::nan("")); } - return var::num(atan2(y.num(),x.num())); + return var::num(atan2(y.num(), x.num())); } -var builtin_isnan(var* local,gc& ngc) { +var builtin_isnan(var* local, gc& ngc) { var x=local[1]; return (x.type==vm_num && std::isnan(x.num()))?one:zero; } -var builtin_time(var* local,gc& ngc) { +var builtin_time(var* local, gc& ngc) { var val=local[1]; if (val.type!=vm_num) { - return nas_err("time","\"begin\" must be number"); + return nas_err("time", "\"begin\" must be number"); } time_t begin=(time_t)val.num(); return var::num((f64)time(&begin)); } -var builtin_contains(var* local,gc& ngc) { +var builtin_contains(var* local, gc& ngc) { var hash=local[1]; var key=local[2]; if (hash.type!=vm_hash || key.type!=vm_str) { @@ -347,11 +348,11 @@ var builtin_contains(var* local,gc& ngc) { return hash.hash().elems.count(key.str())?one:zero; } -var builtin_delete(var* local,gc& ngc) { +var builtin_delete(var* local, gc& ngc) { var hash=local[1]; var key=local[2]; if (hash.type!=vm_hash) { - return nas_err("delete","\"hash\" must be hash"); + return nas_err("delete", "\"hash\" must be hash"); } if (key.type!=vm_str) { return nil; @@ -362,10 +363,10 @@ var builtin_delete(var* local,gc& ngc) { return nil; } -var builtin_keys(var* local,gc& ngc) { +var builtin_keys(var* local, gc& ngc) { var hash=local[1]; if (hash.type!=vm_hash) { - return nas_err("keys","\"hash\" must be hash"); + return nas_err("keys", "\"hash\" must be hash"); } // avoid being sweeped var res=ngc.temp=ngc.alloc(vm_vec); @@ -377,11 +378,11 @@ var builtin_keys(var* local,gc& ngc) { return res; } -var builtin_die(var* local,gc& ngc) { - return nas_err("error",local[1].tostr()); +var builtin_die(var* local, gc& ngc) { + return nas_err("error", local[1].tostr()); } -var builtin_find(var* local,gc& ngc) { +var builtin_find(var* local, gc& ngc) { var needle=local[1]; var haystack=local[2]; usize pos=haystack.tostr().find(needle.tostr()); @@ -391,7 +392,7 @@ var builtin_find(var* local,gc& ngc) { return var::num((f64)pos); } -var builtin_type(var* local,gc& ngc) { +var builtin_type(var* local, gc& ngc) { switch(local[1].type) { case vm_none: return ngc.newstr("undefined");break; case vm_nil: return ngc.newstr("nil"); break; @@ -406,41 +407,41 @@ var builtin_type(var* local,gc& ngc) { return nil; } -var builtin_substr(var* local,gc& ngc) { +var builtin_substr(var* local, gc& ngc) { var str=local[1]; var beg=local[2]; var len=local[3]; if (str.type!=vm_str) { - return nas_err("substr","\"str\" must be string"); + return nas_err("substr", "\"str\" must be string"); } if (beg.type!=vm_num || beg.num()<0) { - return nas_err("substr","\"begin\" should be number >= 0"); + return nas_err("substr", "\"begin\" should be number >= 0"); } if (len.type!=vm_num || len.num()<0) { - return nas_err("substr","\"length\" should be number >= 0"); + return nas_err("substr", "\"length\" should be number >= 0"); } usize begin=(usize)beg.num(); usize length=(usize)len.num(); if (begin>=str.str().length()) { - return nas_err("susbtr","begin index out of range: "+std::to_string(begin)); + return nas_err("susbtr", "begin index out of range: "+std::to_string(begin)); } return ngc.newstr(str.str().substr(begin,length)); } -var builtin_streq(var* local,gc& ngc) { +var builtin_streq(var* local, gc& ngc) { var a=local[1]; var b=local[2]; return var::num(f64((a.type!=vm_str || b.type!=vm_str)?0:(a.str()==b.str()))); } -var builtin_left(var* local,gc& ngc) { +var builtin_left(var* local, gc& ngc) { var str=local[1]; var len=local[2]; if (str.type!=vm_str) { - return nas_err("left","\"string\" must be string"); + return nas_err("left", "\"string\" must be string"); } if (len.type!=vm_num) { - return nas_err("left","\"length\" must be number"); + return nas_err("left", "\"length\" must be number"); } if (len.num()<0) { return ngc.newstr(""); @@ -448,14 +449,14 @@ var builtin_left(var* local,gc& ngc) { return ngc.newstr(str.str().substr(0,len.num())); } -var builtin_right(var* local,gc& ngc) { +var builtin_right(var* local, gc& ngc) { var str=local[1]; var len=local[2]; if (str.type!=vm_str) { - return nas_err("right","\"string\" must be string"); + return nas_err("right", "\"string\" must be string"); } if (len.type!=vm_num) { - return nas_err("right","\"length\" must be number"); + return nas_err("right", "\"length\" must be number"); } i32 length=(i32)len.num(); i32 srclen=str.str().length(); @@ -465,19 +466,19 @@ var builtin_right(var* local,gc& ngc) { if (length<0) { length=0; } - return ngc.newstr(str.str().substr(srclen-length,srclen)); + return ngc.newstr(str.str().substr(srclen-length, srclen)); } -var builtin_cmp(var* local,gc& ngc) { +var builtin_cmp(var* local, gc& ngc) { var a=local[1]; var b=local[2]; if (a.type!=vm_str || b.type!=vm_str) { - return nas_err("cmp","\"a\" and \"b\" must be string"); + return nas_err("cmp", "\"a\" and \"b\" must be string"); } - return var::num((f64)strcmp(a.str().c_str(),b.str().c_str())); + return var::num((f64)strcmp(a.str().c_str(), b.str().c_str())); } -var builtin_chr(var* local,gc& ngc) { +var builtin_chr(var* local, gc& ngc) { const char* extend[]={ "€"," ","‚","ƒ","„","…","†","‡", "ˆ","‰","Š","‹","Œ"," ","Ž"," ", @@ -505,14 +506,14 @@ var builtin_chr(var* local,gc& ngc) { return ngc.newstr(" "); } -var builtin_char(var* local,gc& ngc) { +var builtin_char(var* local, gc& ngc) { return ngc.newstr((unsigned char)local[1].num()); } -var builtin_values(var* local,gc& ngc) { +var builtin_values(var* local, gc& ngc) { var hash=local[1]; if (hash.type!=vm_hash) { - return nas_err("values","\"hash\" must be hash"); + return nas_err("values", "\"hash\" must be hash"); } var vec=ngc.alloc(vm_vec); auto& v=vec.vec().elems; @@ -522,101 +523,101 @@ var builtin_values(var* local,gc& ngc) { return vec; } -var builtin_exists(var* local,gc& ngc) { +var builtin_exists(var* local, gc& ngc) { if (local[1].type!=vm_str) { return zero; } - return access(local[1].str().c_str(),F_OK)!=-1?one:zero; + return access(local[1].str().c_str(), F_OK)!=-1?one:zero; } -var builtin_open(var* local,gc& ngc) { +var builtin_open(var* local, gc& ngc) { var name=local[1]; var mode=local[2]; if (name.type!=vm_str) { - return nas_err("open","\"filename\" must be string"); + return nas_err("open", "\"filename\" must be string"); } if (mode.type!=vm_str) { - return nas_err("open","\"mode\" must be string"); + return nas_err("open", "\"mode\" must be string"); } - FILE* res=fopen(name.str().c_str(),mode.str().c_str()); + FILE* res=fopen(name.str().c_str(), mode.str().c_str()); if (!res) { - return nas_err("open","failed to open file <"+name.str()+">"); + return nas_err("open", "failed to open file <"+name.str()+">"); } var ret=ngc.alloc(vm_obj); - ret.obj().set(obj_type::file,res); + ret.obj().set(obj_type::file, res); return ret; } -var builtin_close(var* local,gc& ngc) { +var builtin_close(var* local, gc& ngc) { var fd=local[1]; if (!fd.objchk(obj_type::file)) { - return nas_err("close","not a valid filehandle"); + return nas_err("close", "not a valid filehandle"); } fd.obj().clear(); return nil; } -var builtin_read(var* local,gc& ngc) { +var builtin_read(var* local, gc& ngc) { var fd=local[1]; var buf=local[2]; var len=local[3]; if (!fd.objchk(obj_type::file)) { - return nas_err("read","not a valid filehandle"); + return nas_err("read", "not a valid filehandle"); } if (buf.type!=vm_str || buf.val.gcobj->unmut) { - return nas_err("read","\"buf\" must be mutable string"); + return nas_err("read", "\"buf\" must be mutable string"); } if (len.type!=vm_num) { - return nas_err("read","\"len\" must be number"); + return nas_err("read", "\"len\" must be number"); } if (len.num()<=0 || len.num()>=(1<<30)) { - return nas_err("read","\"len\" less than 1 or too large"); + return nas_err("read", "\"len\" less than 1 or too large"); } char* buff=new char[(usize)len.num()+1]; if (!buff) { - return nas_err("read","malloc failed"); + return nas_err("read", "malloc failed"); } - f64 res=fread(buff,1,len.num(),(FILE*)fd.obj().ptr); + f64 res=fread(buff,1,len.num(), (FILE*)fd.obj().ptr); buf.str()=buff; buf.val.gcobj->unmut=true; delete []buff; return var::num(res); } -var builtin_write(var* local,gc& ngc) { +var builtin_write(var* local, gc& ngc) { var fd=local[1]; var str=local[2]; if (!fd.objchk(obj_type::file)) { - return nas_err("write","not a valid filehandle"); + return nas_err("write", "not a valid filehandle"); } if (str.type!=vm_str) { - return nas_err("write","\"str\" must be string"); + return nas_err("write", "\"str\" must be string"); } - return var::num((f64)fwrite(str.str().c_str(),1,str.str().length(),(FILE*)fd.obj().ptr)); + return var::num((f64)fwrite(str.str().c_str(), 1, str.str().length(), (FILE*)fd.obj().ptr)); } -var builtin_seek(var* local,gc& ngc) { +var builtin_seek(var* local, gc& ngc) { var fd=local[1]; var pos=local[2]; var whence=local[3]; if (!fd.objchk(obj_type::file)) { - return nas_err("seek","not a valid filehandle"); + return nas_err("seek", "not a valid filehandle"); } - return var::num((f64)fseek((FILE*)fd.obj().ptr,pos.num(),whence.num())); + return var::num((f64)fseek((FILE*)fd.obj().ptr, pos.num(), whence.num())); } -var builtin_tell(var* local,gc& ngc) { +var builtin_tell(var* local, gc& ngc) { var fd=local[1]; if (!fd.objchk(obj_type::file)) { - return nas_err("tell","not a valid filehandle"); + return nas_err("tell", "not a valid filehandle"); } return var::num((f64)ftell((FILE*)fd.obj().ptr)); } -var builtin_readln(var* local,gc& ngc) { +var builtin_readln(var* local, gc& ngc) { var fd=local[1]; if (!fd.objchk(obj_type::file)) { - return nas_err("readln","not a valid filehandle"); + return nas_err("readln", "not a valid filehandle"); } var str=ngc.alloc(vm_str); char c; @@ -635,14 +636,14 @@ var builtin_readln(var* local,gc& ngc) { return nil; } -var builtin_stat(var* local,gc& ngc) { +var builtin_stat(var* local, gc& ngc) { var name=local[1]; if (name.type!=vm_str) { - return nas_err("stat","\"filename\" must be string"); + return nas_err("stat", "\"filename\" must be string"); } struct stat buf; if (stat(name.str().c_str(),&buf)<0) { - return nas_err("stat","failed to open file <"+name.str()+">"); + return nas_err("stat", "failed to open file <"+name.str()+">"); } var ret=ngc.alloc(vm_vec); ret.vec().elems={ @@ -661,15 +662,15 @@ var builtin_stat(var* local,gc& ngc) { return ret; } -var builtin_eof(var* local,gc& ngc) { +var builtin_eof(var* local, gc& ngc) { var fd=local[1]; if (!fd.objchk(obj_type::file)) { - return nas_err("readln","not a valid filehandle"); + return nas_err("readln", "not a valid filehandle"); } return var::num((f64)feof((FILE*)fd.obj().ptr)); } -var builtin_fld(var* local,gc& ngc) { +var builtin_fld(var* local, gc& ngc) { // bits.fld(s,0,3); // if s stores 10100010(162) // will get 101(5) @@ -677,15 +678,15 @@ var builtin_fld(var* local,gc& ngc) { var startbit=local[2]; var length=local[3]; if (str.type!=vm_str || str.val.gcobj->unmut) { - return nas_err("fld","\"str\" must be mutable string"); + return nas_err("fld", "\"str\" must be mutable string"); } if (startbit.type!=vm_num || length.type!=vm_num) { - return nas_err("fld","\"startbit\",\"len\" must be number"); + return nas_err("fld", "\"startbit\",\"len\" must be number"); } u32 bit=(u32)startbit.num(); u32 len=(u32)length.num(); if (bit+len>8*str.str().length()) { - return nas_err("fld","bitfield out of bounds"); + return nas_err("fld", "bitfield out of bounds"); } u32 res=0; auto& s=str.str(); @@ -697,7 +698,7 @@ var builtin_fld(var* local,gc& ngc) { return var::num((f64)res); } -var builtin_sfld(var* local,gc& ngc) { +var builtin_sfld(var* local, gc& ngc) { // bits.sfld(s,0,3); // if s stores 10100010(162) // will get 101(5) then this will be signed extended to @@ -706,15 +707,15 @@ var builtin_sfld(var* local,gc& ngc) { var startbit=local[2]; var length=local[3]; if (str.type!=vm_str || str.val.gcobj->unmut) { - return nas_err("sfld","\"str\" must be mutable string"); + return nas_err("sfld", "\"str\" must be mutable string"); } if (startbit.type!=vm_num || length.type!=vm_num) { - return nas_err("sfld","\"startbit\",\"len\" must be number"); + return nas_err("sfld", "\"startbit\",\"len\" must be number"); } u32 bit=(u32)startbit.num(); u32 len=(u32)length.num(); if (bit+len>8*str.str().length()) { - return nas_err("sfld","bitfield out of bounds"); + return nas_err("sfld", "bitfield out of bounds"); } u32 res=0; auto& s=str.str(); @@ -729,7 +730,7 @@ var builtin_sfld(var* local,gc& ngc) { return var::num((f64)((i32)res)); } -var builtin_setfld(var* local,gc& ngc) { +var builtin_setfld(var* local, gc& ngc) { // bits.setfld(s,0,8,69); // set 01000101(69) to string will get this: // 10100010(162) @@ -739,16 +740,16 @@ var builtin_setfld(var* local,gc& ngc) { var length=local[3]; var value=local[4]; if (str.type!=vm_str || str.val.gcobj->unmut) { - return nas_err("setfld","\"str\" must be mutable string"); + return nas_err("setfld", "\"str\" must be mutable string"); } if (startbit.type!=vm_num || length.type!=vm_num || value.type!=vm_num) { - return nas_err("setfld","\"startbit\",\"len\",\"val\" must be number"); + return nas_err("setfld", "\"startbit\",\"len\",\"val\" must be number"); } u32 bit=(u32)startbit.num(); u32 len=(u32)length.num(); u64 val=(u64)value.num(); if (bit+len>8*str.str().length()) { - return nas_err("setfld","bitfield out of bounds"); + return nas_err("setfld", "bitfield out of bounds"); } auto& s=str.str(); for(u32 i=bit;i"); + return nas_err("opendir", "cannot open dir <"+path.str()+">"); } #else DIR* p=opendir(path.str().c_str()); if (!p) { - return nas_err("opendir","cannot open dir <"+path.str()+">"); + return nas_err("opendir", "cannot open dir <"+path.str()+">"); } #endif var ret=ngc.alloc(vm_obj); @@ -852,10 +853,10 @@ var builtin_opendir(var* local,gc& ngc) { return ret; } -var builtin_readdir(var* local,gc& ngc) { +var builtin_readdir(var* local, gc& ngc) { var handle=local[1]; if (!handle.objchk(obj_type::dir)) { - return nas_err("readdir","not a valid dir handle"); + return nas_err("readdir", "not a valid dir handle"); } #ifdef _MSC_VER WIN32_FIND_DATAA data; @@ -869,16 +870,16 @@ var builtin_readdir(var* local,gc& ngc) { #endif } -var builtin_closedir(var* local,gc& ngc) { +var builtin_closedir(var* local, gc& ngc) { var handle=local[1]; if (!handle.objchk(obj_type::dir)) { - return nas_err("closedir","not a valid dir handle"); + return nas_err("closedir", "not a valid dir handle"); } handle.obj().clear(); return nil; } -var builtin_chdir(var* local,gc& ngc) { +var builtin_chdir(var* local, gc& ngc) { var path=local[1]; if (path.type!=vm_str) { return var::num((f64)-1); @@ -886,7 +887,7 @@ var builtin_chdir(var* local,gc& ngc) { return var::num((f64)chdir(path.str().c_str())); } -var builtin_environ(var* local,gc& ngc) { +var builtin_environ(var* local, gc& ngc) { var res=ngc.temp=ngc.alloc(vm_vec); auto& vec=res.vec().elems; for(char** env=environ;*env;++env) { @@ -896,7 +897,7 @@ var builtin_environ(var* local,gc& ngc) { return res; } -var builtin_getcwd(var* local,gc& ngc) { +var builtin_getcwd(var* local, gc& ngc) { char buf[1024]; if (!getcwd(buf,sizeof(buf))) { return nil; @@ -904,57 +905,57 @@ var builtin_getcwd(var* local,gc& ngc) { return ngc.newstr(buf); } -var builtin_getenv(var* local,gc& ngc) { +var builtin_getenv(var* local, gc& ngc) { var envvar=local[1]; if (envvar.type!=vm_str) { - return nas_err("getenv","\"envvar\" must be string"); + return nas_err("getenv", "\"envvar\" must be string"); } char* res=getenv(envvar.str().c_str()); return res?ngc.newstr(res):nil; } -var builtin_dlopen(var* local,gc& ngc) { +var builtin_dlopen(var* local, gc& ngc) { var dlname=local[1]; if (dlname.type!=vm_str) { - return nas_err("dlopen","\"libname\" must be string"); + return nas_err("dlopen", "\"libname\" must be string"); } #ifdef _WIN32 wchar_t* str=new wchar_t[dlname.str().size()+1]; if (!str) { - return nas_err("dlopen","malloc failed"); + return nas_err("dlopen", "malloc failed"); } - memset(str,0,sizeof(wchar_t)*dlname.str().size()+1); - mbstowcs(str,dlname.str().c_str(),dlname.str().size()+1); + memset(str, 0, sizeof(wchar_t)*dlname.str().size()+1); + mbstowcs(str, dlname.str().c_str(),dlname.str().size()+1); void* ptr=LoadLibraryA(dlname.str().c_str()); delete []str; #else - void* ptr=dlopen(dlname.str().c_str(),RTLD_LOCAL|RTLD_LAZY); + void* ptr=dlopen(dlname.str().c_str(), RTLD_LOCAL|RTLD_LAZY); #endif if (!ptr) { - return nas_err("dlopen","cannot open dynamic lib <"+dlname.str()+">"); + return nas_err("dlopen", "cannot open dynamic lib <"+dlname.str()+">"); } var ret=ngc.temp=ngc.alloc(vm_hash); var lib=ngc.alloc(vm_obj); - lib.obj().set(obj_type::dylib,ptr); + lib.obj().set(obj_type::dylib, ptr); ret.hash().elems["lib"]=lib; #ifdef _WIN32 - void* func=(void*)GetProcAddress((HMODULE)lib.obj().ptr,"get"); + void* func=(void*)GetProcAddress((HMODULE)lib.obj().ptr, "get"); #else - void* func=dlsym(lib.obj().ptr,"get"); + void* func=dlsym(lib.obj().ptr, "get"); #endif if (!func) { - return nas_err("dlopen","cannot find function"); + return nas_err("dlopen", "cannot find function"); } // get function pointer by name mod_func* tbl=(mod_func*)((getptr)func)(); if (!tbl) { - return nas_err("dlopen","failed to get module functions"); + return nas_err("dlopen", "failed to get module functions"); } for(u32 i=0;tbl[i].name;++i) { void* p=(void*)tbl[i].fd; var tmp=ngc.alloc(vm_obj); - tmp.obj().set(obj_type::faddr,p); + tmp.obj().set(obj_type::faddr, p); ret.hash().elems[tbl[i].name]=tmp; } @@ -962,29 +963,29 @@ var builtin_dlopen(var* local,gc& ngc) { return ret; } -var builtin_dlclose(var* local,gc& ngc) { +var builtin_dlclose(var* local, gc& ngc) { var libptr=local[1]; if (!libptr.objchk(obj_type::dylib)) { - return nas_err("dlclose","\"lib\" is not a valid dynamic lib"); + return nas_err("dlclose", "\"lib\" is not a valid dynamic lib"); } libptr.obj().clear(); return nil; } -var builtin_dlcallv(var* local,gc& ngc) { +var builtin_dlcallv(var* local, gc& ngc) { var fp=local[1]; var args=local[2]; if (!fp.objchk(obj_type::faddr)) { - return nas_err("dlcall","\"ptr\" is not a valid function pointer"); + return nas_err("dlcall", "\"ptr\" is not a valid function pointer"); } auto& vec=args.vec().elems; - return ((mod)fp.obj().ptr)(vec.data(),vec.size(),&ngc); + return ((mod)fp.obj().ptr)(vec.data(), vec.size(), &ngc); } -var builtin_dlcall(var* local,gc& ngc) { +var builtin_dlcall(var* local, gc& ngc) { var fp=local[1]; if (!fp.objchk(obj_type::faddr)) { - return nas_err("dlcall","\"ptr\" is not a valid function pointer"); + return nas_err("dlcall", "\"ptr\" is not a valid function pointer"); } var* local_frame_start=local+2; @@ -997,7 +998,7 @@ var builtin_dlcall(var* local,gc& ngc) { ); } -var builtin_platform(var* local,gc& ngc) { +var builtin_platform(var* local, gc& ngc) { if (is_windows()) { return ngc.newstr("windows"); } else if (is_linux()) { @@ -1008,7 +1009,7 @@ var builtin_platform(var* local,gc& ngc) { return ngc.newstr("unknown"); } -var builtin_arch(var* local,gc& ngc) { +var builtin_arch(var* local, gc& ngc) { if (is_x86()) { return ngc.newstr("x86"); } else if (is_x86_64()) { @@ -1033,7 +1034,7 @@ var builtin_arch(var* local,gc& ngc) { string tohex(u32 num) { const char str16[]="0123456789abcdef"; string str=""; - for(u32 i=0;i<4;i++,num>>=8) { + for(u32 i=0;i<4;i++, num>>=8) { string tmp=""; for(u32 j=0,b=num&0xff;j<2;j++,b>>=4) { tmp.insert(0,1,str16[b&0xf]); @@ -1097,7 +1098,7 @@ string md5(const string& src) { if (j<16) f=md5f(b,c,d); else if (j<32) f=md5g(b,c,d); else if (j<48) f=md5h(b,c,d); - else f=md5i(b,c,d); + else f=md5i(b,c,d); u32 tmp=d; d=c; c=b; @@ -1112,15 +1113,15 @@ string md5(const string& src) { return tohex(atmp)+tohex(btmp)+tohex(ctmp)+tohex(dtmp); } -var builtin_md5(var* local,gc& ngc) { +var builtin_md5(var* local, gc& ngc) { var str=local[1]; if (str.type!=vm_str) { - return nas_err("md5","\"str\" must be string"); + return nas_err("md5", "\"str\" must be string"); } return ngc.newstr(md5(str.str())); } -var builtin_cocreate(var* local,gc& ngc) { +var builtin_cocreate(var* local, gc& ngc) { // +-------------+ // | old pc | <- top[0] // +-------------+ @@ -1135,10 +1136,10 @@ var builtin_cocreate(var* local,gc& ngc) { // +-------------+ var func=local[1]; if (func.type!=vm_func) { - return nas_err("coroutine::create","must use a function to create coroutine"); + return nas_err("coroutine::create", "must use a function to create coroutine"); } if (ngc.cort) { - return nas_err("coroutine::create","cannot create another coroutine in a coroutine"); + return nas_err("coroutine::create", "cannot create another coroutine in a coroutine"); } var co=ngc.alloc(vm_co); nas_co& cort=co.co(); @@ -1160,9 +1161,9 @@ var builtin_cocreate(var* local,gc& ngc) { return co; } -var builtin_coresume(var* local,gc& ngc) { +var builtin_coresume(var* local, gc& ngc) { if (ngc.cort) { - return nas_err("coroutine::resume","cannot start another coroutine when one is running"); + return nas_err("coroutine::resume", "cannot start another coroutine when one is running"); } var co=local[1]; // return nil if is not a coroutine object @@ -1194,9 +1195,9 @@ var builtin_coresume(var* local,gc& ngc) { return local[2]; } -var builtin_coyield(var* local,gc& ngc) { +var builtin_coyield(var* local, gc& ngc) { if (!ngc.cort) { - return nas_err("coroutine::yield","no coroutine is running"); + return nas_err("coroutine::yield", "no coroutine is running"); } // this will set to main stack top @@ -1209,7 +1210,7 @@ var builtin_coyield(var* local,gc& ngc) { return local[1]; } -var builtin_costatus(var* local,gc& ngc) { +var builtin_costatus(var* local, gc& ngc) { var co=local[1]; if (co.type!=vm_co) { return ngc.newstr("error"); @@ -1222,24 +1223,24 @@ var builtin_costatus(var* local,gc& ngc) { return nil; } -var builtin_corun(var* local,gc& ngc) { +var builtin_corun(var* local, gc& ngc) { return ngc.cort?one:zero; } -var builtin_millisec(var* local,gc& ngc) { +var builtin_millisec(var* local, gc& ngc) { f64 res=std::chrono::duration_cast (std::chrono::high_resolution_clock::now().time_since_epoch()) .count(); return var::num(res); } -var builtin_sysargv(var* local,gc& ngc) { +var builtin_sysargv(var* local, gc& ngc) { var res=ngc.alloc(vm_vec); res.vec().elems=ngc.env_argv; return res; } -var builtin_gcextend(var* local,gc& ngc) { +var builtin_gcextend(var* local, gc& ngc) { var type=local[1]; if (type.type!=vm_str) { return nil; @@ -1263,7 +1264,7 @@ var builtin_gcextend(var* local,gc& ngc) { return nil; } -var builtin_logtime(var* local,gc& ngc) { +var builtin_logtime(var* local, gc& ngc) { time_t t=time(nullptr); tm* tm_t=localtime(&t); char s[64]; diff --git a/nasal_codegen.h b/nasal_codegen.h index aab6dd0..2fb16a6 100644 --- a/nasal_codegen.h +++ b/nasal_codegen.h @@ -33,8 +33,8 @@ private: bool check_memory_reachable(const ast&); void check_id_exist(const ast&); - void die(const string& info,const span& loc) { - err.err("code",loc,info); + void die(const string& info, const span& loc) { + err.err("code", loc, info); } void regist_num(const f64); @@ -45,7 +45,7 @@ private: i32 global_find(const string&); i32 upvalue_find(const string&); - void gen(u8,u32,u32); + void gen(u8, u32, u32); void num_gen(const ast&); void str_gen(const ast&); @@ -68,7 +68,7 @@ private: void multi_assign_gen(const ast&); void cond_gen(const ast&); void loop_gen(const ast&); - void load_continue_break(i32,i32); + void load_continue_break(i32, i32); void while_gen(const ast&); void for_gen(const ast&); void expr_gen(const ast&); @@ -82,8 +82,8 @@ private: void ret_gen(const ast&); public: - codegen(error& e):fileindex(0),err(e),file(nullptr) {} - const error& compile(const parse&,const linker&); + codegen(error& e): fileindex(0), err(e), file(nullptr) {} + const error& compile(const parse&, const linker&); void print(); const std::vector& strs() const {return str_res;} const std::vector& nums() const {return num_res;} @@ -94,15 +94,15 @@ bool codegen::check_memory_reachable(const ast& node) { if (node.type()==ast_call) { const ast& tmp=node.child().back(); if (tmp.type()==ast_callf) { - die("bad left-value with function call",node.location()); + die("bad left-value with function call", node.location()); return false; } if (tmp.type()==ast_callv && (tmp.size()==0 || tmp.size()>1 || tmp[0].type()==ast_subvec)) { - die("bad left-value with subvec",node.location()); + die("bad left-value with subvec", node.location()); return false; } } else if (node.type()!=ast_id) { - die("bad left-value",node.location()); + die("bad left-value", node.location()); return false; } return true; @@ -113,7 +113,7 @@ void codegen::check_id_exist(const ast& node) { for(u32 i=0;builtin[i].name;++i) { if (builtin[i].name==str) { if (local.empty()) { - die("useless native function used in global scope",node.location()); + die("useless native function used in global scope", node.location()); } return; } @@ -128,7 +128,7 @@ void codegen::check_id_exist(const ast& node) { if (global_find(str)>=0) { return; } - die("undefined symbol \""+str+"\", and this symbol is useless here",node.location()); + die("undefined symbol \""+str+"\", and this symbol is useless here", node.location()); } void codegen::regist_num(const f64 num) { @@ -213,41 +213,41 @@ i32 codegen::upvalue_find(const string& name) { return index; } -void codegen::gen(u8 op,u32 num,u32 line) { - code.push_back({op,fileindex,num,line}); +void codegen::gen(u8 op, u32 num, u32 line) { + code.push_back({op, fileindex, num, line}); } void codegen::num_gen(const ast& node) { f64 num=node.num(); regist_num(num); - gen(op_pnum,num_table[num],node.line()); + gen(op_pnum,num_table[num], node.line()); } void codegen::str_gen(const ast& node) { regist_str(node.str()); - gen(op_pstr,str_table[node.str()],node.line()); + gen(op_pstr, str_table[node.str()], node.line()); } void codegen::bool_gen(const ast& node) { f64 num=node.str()=="true"?1:0; regist_num(num); - gen(op_pnum,num_table[num],node.line()); + gen(op_pnum, num_table[num], node.line()); } void codegen::vec_gen(const ast& node) { for(auto& child:node.child()) { calc_gen(child); } - gen(op_newv,node.size(),node.line()); + gen(op_newv, node.size(), node.line()); } void codegen::hash_gen(const ast& node) { - gen(op_newh,0,node.line()); + gen(op_newh, 0, node.line()); for(auto& child:node.child()) { calc_gen(child[1]); const string& str=child[0].str(); regist_str(str); - gen(op_happ,str_table[str],child.line()); + gen(op_happ, str_table[str], child.line()); } } @@ -264,53 +264,57 @@ void codegen::func_gen(const ast& node) { } // check default parameter and dynamic parameter if (checked_default && tmp.type()!=ast_default) { - die("must use default parameters here",tmp.location()); + die("must use default parameters here", tmp.location()); } if (checked_dynamic && &tmp!=&node[0].child().back()) { - die("dynamic parameter must be the last one",tmp.location()); + die("dynamic parameter must be the last one", tmp.location()); } // check redefinition string name=tmp.str(); if (argname.count(name)) { - die("redefinition of parameter: "+name,tmp.location()); + die("redefinition of parameter: "+name, tmp.location()); } else { argname[name]=true; } } usize newf=code.size(); - gen(op_newf,0,node.line()); + gen(op_newf, 0, node.line()); usize lsize=code.size(); - gen(op_intl,0,node.line()); + gen(op_intl, 0, node.line()); // add special keyword 'me' into symbol table // this symbol is only used in local scope(function's scope) // this keyword is set to nil as default value // after calling a hash, this keyword is set to this hash // this symbol's index will be 0 - local.push_back({{"me",0}}); + local.push_back({{"me", 0}}); // generate parameter list for(auto& tmp:node[0].child()) { const string& str=tmp.str(); if (str=="me") { - die("\"me\" should not be a parameter",tmp.location()); + die("\"me\" should not be a parameter", tmp.location()); } regist_str(str); switch(tmp.type()) { - case ast_id:gen(op_para,str_table[str],tmp.line());break; + case ast_id: + gen(op_para, str_table[str], tmp.line()); + break; case ast_default: calc_gen(tmp[0]); - gen(op_deft,str_table[str],tmp.line()); + gen(op_deft, str_table[str], tmp.line()); + break; + case ast_dynamic: + gen(op_dyn, str_table[str], tmp.line()); break; - case ast_dynamic:gen(op_dyn,str_table[str],tmp.line());break; } add_sym(str); } code[newf].num=code.size()+1; // entry usize jmp_ptr=code.size(); - gen(op_jmp,0,node.line()); + gen(op_jmp, 0, node.line()); const ast& block=node[1]; // search symbols first, must use after loading parameters @@ -321,13 +325,13 @@ void codegen::func_gen(const ast& node) { in_iterloop.pop(); code[lsize].num=local.back().size(); if (local.back().size()>=STACK_DEPTH) { - die("too many local variants: "+std::to_string(local.back().size()),block.location()); + die("too many local variants: "+std::to_string(local.back().size()), block.location()); } local.pop_back(); if (!block.size() || block.child().back().type()!=ast_ret) { - gen(op_pnil,0,block.line()); - gen(op_ret,0,block.line()); + gen(op_pnil, 0, block.line()); + gen(op_ret, 0, block.line()); } code[jmp_ptr].num=code.size(); } @@ -351,66 +355,66 @@ void codegen::call_id(const ast& node) { const string& str=node.str(); for(u32 i=0;builtin[i].name;++i) { if (builtin[i].name==str) { - gen(op_callb,i,node.line()); + gen(op_callb, i, node.line()); if (local.empty()) { - die("should warp native function in local scope",node.location()); + die("should warp native function in local scope", node.location()); } return; } } i32 index; if ((index=local_find(str))>=0) { - gen(op_calll,index,node.line()); + gen(op_calll, index, node.line()); return; } if ((index=upvalue_find(str))>=0) { - gen(op_upval,index,node.line()); + gen(op_upval, index, node.line()); return; } if ((index=global_find(str))>=0) { - gen(op_callg,index,node.line()); + gen(op_callg, index, node.line()); return; } - die("undefined symbol \""+str+"\"",node.location()); + die("undefined symbol \""+str+"\"", node.location()); } void codegen::call_hash(const ast& node) { regist_str(node.str()); - gen(op_callh,str_table[node.str()],node.line()); + gen(op_callh, str_table[node.str()], node.line()); } void codegen::call_vec(const ast& node) { // maybe this place can use callv-const if ast's first child is ast_num if (node.size()==1 && node[0].type()!=ast_subvec) { calc_gen(node[0]); - gen(op_callv,0,node[0].line()); + gen(op_callv, 0, node[0].line()); return; } gen(op_slcbeg,0,node.line()); for(auto& tmp:node.child()) { if (tmp.type()!=ast_subvec) { calc_gen(tmp); - gen(op_slc,0,tmp.line()); + gen(op_slc, 0, tmp.line()); } else { calc_gen(tmp[0]); calc_gen(tmp[1]); - gen(op_slc2,0,tmp.line()); + gen(op_slc2, 0, tmp.line()); } } - gen(op_slcend,0,node.line()); + gen(op_slcend, 0, node.line()); } void codegen::call_func(const ast& node) { if (!node.size()) { - gen(op_callfv,0,node.line()); + gen(op_callfv, 0, node.line()); } else if (node[0].type()==ast_pair) { hash_gen(node); - gen(op_callfh,0,node.line()); + gen(op_callfh, 0, node.line()); } else { for(auto& child:node.child()) { calc_gen(child); } - gen(op_callfv,node.size(),node.line()); + gen(op_callfv, node.size(), node.line()); } } @@ -455,42 +459,42 @@ void codegen::mcall_id(const ast& node) { const string& str=node.str(); for(u32 i=0;builtin[i].name;++i) { if (builtin[i].name==str) { - die("cannot modify native function",node.location()); + die("cannot modify native function", node.location()); return; } } i32 index; if ((index=local_find(str))>=0) { - gen(op_mcalll,index,node.line()); + gen(op_mcalll, index, node.line()); return; } if ((index=upvalue_find(str))>=0) { - gen(op_mupval,index,node.line()); + gen(op_mupval, index, node.line()); return; } if ((index=global_find(str))>=0) { - gen(op_mcallg,index,node.line()); + gen(op_mcallg, index, node.line()); return; } - die("undefined symbol \""+str+"\"",node.location()); + die("undefined symbol \""+str+"\"", node.location()); } void codegen::mcall_vec(const ast& node) { calc_gen(node[0]); - gen(op_mcallv,0,node.line()); + gen(op_mcallv, 0, node.line()); } void codegen::mcall_hash(const ast& node) { regist_str(node.str()); - gen(op_mcallh,str_table[node.str()],node.line()); + gen(op_mcallh, str_table[node.str()], node.line()); } void codegen::single_def(const ast& node) { const string& str=node[0].str(); calc_gen(node[1]); local.empty()? - gen(op_loadg,global_find(str),node.line()): - gen(op_loadl,local_find(str),node.line()); + gen(op_loadg, global_find(str), node.line()): + gen(op_loadl, local_find(str), node.line()); } void codegen::multi_def(const ast& node) { auto& ids=node[0].child(); @@ -500,49 +504,49 @@ void codegen::multi_def(const ast& node) { for(usize i=0;inode[1].size()) { - die("too many values in multi-definition",node[1].location()); + die("too many values in multi-definition", node[1].location()); } node[0].type()==ast_id?single_def(node):multi_def(node); } void codegen::multi_assign_gen(const ast& node) { if (node[1].type()==ast_tuple && node[0].size()node[1].size()) { - die("too many values in multi-assignment",node[1].location()); + die("too many values in multi-assignment", node[1].location()); } i32 size=node[0].size(); if (node[1].type()==ast_tuple) { @@ -560,13 +564,13 @@ void codegen::multi_assign_gen(const ast& node) { } else if (code.back().op==op_mcallg) { code.back().op=op_loadg; } else { - gen(op_meq,1,node[0][i].line()); + gen(op_meq, 1, node[0][i].line()); } } } else { calc_gen(node[1]); for(i32 i=0;i()); - break_ptr.push_front(std::vector()); + continue_ptr.push_front({}); + break_ptr.push_front({}); switch(node.type()) { case ast_while: while_gen(node); break; case ast_for: for_gen(node); break; @@ -634,32 +638,32 @@ void codegen::while_gen(const ast& node) { usize loop_ptr=code.size(); calc_gen(node[0]); usize condition_ptr=code.size(); - gen(op_jf,0,node[0].line()); + gen(op_jf, 0, node[0].line()); block_gen(node[1]); - gen(op_jmp,loop_ptr,node[1].line()); + gen(op_jmp, loop_ptr, node[1].line()); code[condition_ptr].num=code.size(); - load_continue_break(code.size()-1,code.size()); + load_continue_break(code.size()-1, code.size()); } void codegen::for_gen(const ast& node) { expr_gen(node[0]); usize jmp_place=code.size(); if (node[1].type()==ast_null) { - gen(op_pnum,num_table[1],node[1].line()); + gen(op_pnum, num_table[1], node[1].line()); } else { calc_gen(node[1]); } usize label_exit=code.size(); - gen(op_jf,0,node[1].line()); + gen(op_jf, 0, node[1].line()); block_gen(node[3]); usize continue_place=code.size(); expr_gen(node[2]); - gen(op_jmp,jmp_place,node[2].line()); + gen(op_jmp, jmp_place, node[2].line()); code[label_exit].num=code.size(); - load_continue_break(continue_place,code.size()); + load_continue_break(continue_place, code.size()); } void codegen::expr_gen(const ast& node) { @@ -676,7 +680,7 @@ void codegen::expr_gen(const ast& node) { } else if (op_addeqc<=code.back().op && code.back().op<=op_lnkeqc) { code.back().op=code.back().op-op_addeqc+op_addecp; } else { - gen(op_pop,0,node.line()); + gen(op_pop, 0, node.line()); } break; case ast_nil:case ast_num:case ast_str:case ast_bool:break; @@ -692,7 +696,7 @@ void codegen::expr_gen(const ast& node) { if (code.back().op==op_meq) { code.back().num=1; } else { - gen(op_pop,0,node.line()); + gen(op_pop, 0, node.line()); } break; case ast_equal: @@ -712,7 +716,7 @@ void codegen::expr_gen(const ast& node) { if (code.back().op==op_meq) { code.back().num=1; } else { - gen(op_pop,0,node.line()); + gen(op_pop, 0, node.line()); } } break; @@ -721,14 +725,14 @@ void codegen::expr_gen(const ast& node) { void codegen::forindex_gen(const ast& node) { calc_gen(node[1]); - gen(op_cnt,0,node[1].line()); + gen(op_cnt, 0, node[1].line()); usize ptr=code.size(); - gen(op_findex,0,node.line()); + gen(op_findex, 0, node.line()); if (node[0].type()==ast_iter) { // define a new iterator const string& str=node[0][0].str(); local.empty()? - gen(op_loadg,global_find(str),node[0][0].line()): - gen(op_loadl,local_find(str),node[0][0].line()); + gen(op_loadg, global_find(str), node[0][0].line()): + gen(op_loadl, local_find(str), node[0][0].line()); } else { // use exist variable as the iterator mcall(node[0]); if (code.back().op==op_mcallg) { @@ -738,29 +742,29 @@ void codegen::forindex_gen(const ast& node) { } else if (code.back().op==op_mupval) { code.back().op=op_loadu; } else { - gen(op_meq,1,node[0].line()); + gen(op_meq, 1, node[0].line()); } } ++in_iterloop.top(); block_gen(node[2]); --in_iterloop.top(); - gen(op_jmp,ptr,node.line()); + gen(op_jmp, ptr, node.line()); code[ptr].num=code.size(); - load_continue_break(code.size()-1,code.size()); - gen(op_pop,0,node[1].line());// pop vector - gen(op_pop,0,node.line());// pop iterator + load_continue_break(code.size()-1, code.size()); + gen(op_pop, 0, node[1].line());// pop vector + gen(op_pop, 0, node.line());// pop iterator } void codegen::foreach_gen(const ast& node) { calc_gen(node[1]); - gen(op_cnt,0,node.line()); + gen(op_cnt, 0, node.line()); usize ptr=code.size(); - gen(op_feach,0,node.line()); + gen(op_feach, 0, node.line()); if (node[0].type()==ast_iter) { // define a new iterator const string& str=node[0][0].str(); local.empty()? - gen(op_loadg,global_find(str),node[0][0].line()): - gen(op_loadl,local_find(str),node[0][0].line()); + gen(op_loadg, global_find(str), node[0][0].line()): + gen(op_loadl, local_find(str), node[0][0].line()); } else { // use exist variable as the iterator mcall(node[0]); if (code.back().op==op_mcallg) { @@ -770,59 +774,59 @@ void codegen::foreach_gen(const ast& node) { } else if (code.back().op==op_mupval) { code.back().op=op_loadu; } else { - gen(op_meq,1,node[0].line()); + gen(op_meq, 1, node[0].line()); } } ++in_iterloop.top(); block_gen(node[2]); --in_iterloop.top(); - gen(op_jmp,ptr,node.line()); + gen(op_jmp, ptr, node.line()); code[ptr].num=code.size(); - load_continue_break(code.size()-1,code.size()); - gen(op_pop,0,node[1].line());// pop vector - gen(op_pop,0,node.line());// pop iterator + load_continue_break(code.size()-1, code.size()); + gen(op_pop, 0, node[1].line());// pop vector + gen(op_pop, 0, node.line());// pop iterator } void codegen::or_gen(const ast& node) { calc_gen(node[0]); usize l1=code.size(); - gen(op_jt,0,node[0].line()); + gen(op_jt, 0, node[0].line()); - gen(op_pop,0,node[0].line()); + gen(op_pop, 0, node[0].line()); calc_gen(node[1]); usize l2=code.size(); - gen(op_jt,0,node[1].line()); + gen(op_jt, 0, node[1].line()); - gen(op_pop,0,node[1].line()); - gen(op_pnil,0,node[1].line()); + gen(op_pop, 0, node[1].line()); + gen(op_pnil, 0, node[1].line()); code[l1].num=code[l2].num=code.size(); } void codegen::and_gen(const ast& node) { calc_gen(node[0]); - gen(op_jt,code.size()+2,node[0].line()); + gen(op_jt, code.size()+2, node[0].line()); usize lfalse=code.size(); - gen(op_jmp,0,node[0].line()); - gen(op_pop,0,node[1].line());// jt jumps here + gen(op_jmp, 0, node[0].line()); + gen(op_pop, 0, node[1].line());// jt jumps here calc_gen(node[1]); - gen(op_jt,code.size()+3,node[1].line()); + gen(op_jt, code.size()+3, node[1].line()); code[lfalse].num=code.size(); - gen(op_pop,0,node[1].line()); - gen(op_pnil,0,node[1].line()); - //jt jumps here + gen(op_pop, 0, node[1].line()); + gen(op_pnil, 0, node[1].line()); + // jt jumps here } void codegen::trino_gen(const ast& node) { calc_gen(node[0]); usize lfalse=code.size(); - gen(op_jf,0,node[0].line()); + gen(op_jf, 0, node[0].line()); calc_gen(node[1]); usize lexit=code.size(); - gen(op_jmp,0,node[1].line()); + gen(op_jmp, 0, node[1].line()); code[lfalse].num=code.size(); calc_gen(node[2]); code[lexit].num=code.size(); @@ -842,7 +846,7 @@ void codegen::calc_gen(const ast& node) { case ast_equal: calc_gen(node[1]); mcall(node[0]); - gen(op_meq,0,node.line()); + gen(op_meq, 0, node.line()); break; // ast_addeq(22)~ast_lnkeq(26) op_addeq(23)~op_lnkeq(27) case ast_addeq:case ast_subeq:case ast_multeq:case ast_diveq: @@ -851,10 +855,10 @@ void codegen::calc_gen(const ast& node) { } mcall(node[0]); if (node[1].type()!=ast_num) { - gen(node.type()-ast_addeq+op_addeq,0,node.line()); + gen(node.type()-ast_addeq+op_addeq, 0, node.line()); } else { regist_num(node[1].num()); - gen(node.type()-ast_addeq+op_addeqc,num_table[node[1].num()],node.line()); + gen(node.type()-ast_addeq+op_addeqc, num_table[node[1].num()], node.line()); } break; case ast_lnkeq: @@ -865,15 +869,15 @@ void codegen::calc_gen(const ast& node) { } mcall(node[0]); if (node[1].type()!=ast_str) { - gen(op_lnkeq,0,node.line()); + gen(op_lnkeq, 0, node.line()); } else { - gen(op_lnkeqc,str_table[node[1].str()],node.line()); + gen(op_lnkeqc, str_table[node[1].str()], node.line()); } break; case ast_btandeq:case ast_btoreq:case ast_btxoreq: calc_gen(node[1]); mcall(node[0]); - gen(node.type()-ast_btandeq+op_btandeq,0,node.line()); + gen(node.type()-ast_btandeq+op_btandeq, 0, node.line()); break; case ast_or:or_gen(node);break; case ast_and:and_gen(node);break; @@ -882,65 +886,65 @@ void codegen::calc_gen(const ast& node) { calc_gen(node[0]); if (node[1].type()!=ast_num) { calc_gen(node[1]); - gen(node.type()-ast_add+op_add,0,node.line()); + gen(node.type()-ast_add+op_add, 0, node.line()); } else { regist_num(node[1].num()); - gen(node.type()-ast_add+op_addc,num_table[node[1].num()],node.line()); + gen(node.type()-ast_add+op_addc, num_table[node[1].num()], node.line()); } break; case ast_link: calc_gen(node[0]); if (node[1].type()!=ast_str) { calc_gen(node[1]); - gen(op_lnk,0,node.line()); + gen(op_lnk, 0, node.line()); } else { regist_str(node[1].str()); - gen(op_lnkc,str_table[node[1].str()],node.line()); + gen(op_lnkc, str_table[node[1].str()], node.line()); } break; // ast_cmpeq(27)~ast_geq(32) op_eq(29)~op_geq(34) case ast_cmpeq:case ast_neq: calc_gen(node[0]); calc_gen(node[1]); - gen(node.type()-ast_cmpeq+op_eq,0,node.line()); + gen(node.type()-ast_cmpeq+op_eq, 0, node.line()); break; case ast_less:case ast_leq:case ast_grt:case ast_geq: calc_gen(node[0]); if (node[1].type()!=ast_num) { calc_gen(node[1]); - gen(node.type()-ast_less+op_less,0,node.line()); + gen(node.type()-ast_less+op_less, 0, node.line()); } else { regist_num(node[1].num()); - gen(node.type()-ast_less+op_lessc,num_table[node[1].num()],node.line()); + gen(node.type()-ast_less+op_lessc, num_table[node[1].num()], node.line()); } break; case ast_trino:trino_gen(node);break; case ast_neg: calc_gen(node[0]); - gen(op_usub,0,node.line()); + gen(op_usub, 0, node.line()); break; case ast_lnot: calc_gen(node[0]); - gen(op_lnot,0,node.line()); + gen(op_lnot, 0, node.line()); break; case ast_bnot: calc_gen(node[0]); - gen(op_bnot,0,node.line()); + gen(op_bnot, 0, node.line()); break; case ast_bitor: calc_gen(node[0]); calc_gen(node[1]); - gen(op_btor,0,node.line()); + gen(op_btor, 0, node.line()); break; case ast_bitxor: calc_gen(node[0]); calc_gen(node[1]); - gen(op_btxor,0,node.line()); + gen(op_btxor, 0, node.line()); break; case ast_bitand: calc_gen(node[0]); calc_gen(node[1]); - gen(op_btand,0,node.line()); + gen(op_btand, 0, node.line()); break; case ast_def: single_def(node); @@ -959,11 +963,11 @@ void codegen::block_gen(const ast& node) { case ast_cond:cond_gen(tmp);break; case ast_continue: continue_ptr.front().push_back(code.size()); - gen(op_jmp,0,tmp.line()); + gen(op_jmp, 0, tmp.line()); break; case ast_break: break_ptr.front().push_back(code.size()); - gen(op_jmp,0,tmp.line()); + gen(op_jmp, 0, tmp.line()); break; case ast_while: case ast_for: @@ -992,42 +996,42 @@ void codegen::block_gen(const ast& node) { void codegen::ret_gen(const ast& node) { for(u32 i=0;i0xffffff) { err.load(file[0]); // load main execute file - err.err("code","too many constant numbers: "+std::to_string(num_res.size())); + err.err("code", "too many constant numbers: "+std::to_string(num_res.size())); } if (str_res.size()>0xffffff) { err.load(file[0]); // load main execute file - err.err("code","too many constant strings: "+std::to_string(str_res.size())); + err.err("code", "too many constant strings: "+std::to_string(str_res.size())); } if (global.size()>=STACK_DEPTH) { err.load(file[0]); // load main execute file - err.err("code","too many global variants: "+std::to_string(global.size())); + err.err("code", "too many global variants: "+std::to_string(global.size())); } if (code.size()>0xffffff) { err.load(file[0]); // load main execute file - err.err("code","bytecode size overflow: "+std::to_string(code.size())); + err.err("code", "bytecode size overflow: "+std::to_string(code.size())); } return err; } @@ -1049,7 +1053,7 @@ void codegen::print() { // print code std::cout<<"\n"; - codestream::set(num_res.data(),str_res.data()); + codestream::set(num_res.data(), str_res.data()); for(u32 i=0;i dbg::parse(const string& cmd) { std::vector res; - usize last=0,pos=cmd.find(" ",0); + usize last=0; + usize pos=cmd.find(" ", 0); while(pos!=string::npos) { if (pos>last) { - res.push_back(cmd.substr(last,pos-last)); + res.push_back(cmd.substr(last, pos-last)); } last=pos+1; - pos=cmd.find(" ",last); + pos=cmd.find(" ", last); } if (lastb.second;} + std::sort(opcall.begin(), opcall.end(), + [](const op& a, const op& b) {return a.second>b.second;} ); std::clog<<"\noperands call info (<1% ignored)\n"; for(auto& i:opcall) { @@ -116,13 +117,13 @@ void dbg::stepinfo() { begin=(ctx.pc>>3)==0?0:((ctx.pc>>3)<<3); end=(1+(ctx.pc>>3))<<3; - codestream::set(cnum,cstr,files); + codestream::set(cnum, cstr, files); std::cout<<"next bytecode:\n"; for(u32 i=begin;i ":" ") - <> "; - std::getline(std::cin,cmd); + std::getline(std::cin, cmd); auto res=parse(cmd); if (res.size()==0) { stepinfo(); @@ -200,11 +201,11 @@ void dbg::interact() { void dbg::run( const codegen& gen, const linker& linker, - const std::vector& argv) -{ + const std::vector& argv +) { verbose=true; fsize=linker.filelist().size(); - init(gen.strs(),gen.nums(),gen.codes(),linker.filelist(),argv); + init(gen.strs(), gen.nums(), gen.codes(), linker.filelist(), argv); u64 count[op_ret+1]={0}; typedef void (dbg::*nafunc)(); const nafunc oprs[]={ diff --git a/nasal_err.h b/nasal_err.h index 37578e5..c2f4545 100644 --- a/nasal_err.h +++ b/nasal_err.h @@ -21,14 +21,14 @@ struct span { struct for_reset { CONSOLE_SCREEN_BUFFER_INFO scr; for_reset() { - GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),&scr); + GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &scr); } } reset_ter_color; #endif std::ostream& back_white(std::ostream& s) { #ifdef _WIN32 - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),0xf0); + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0xf0); #else s<<"\033[7m"; #endif @@ -37,7 +37,7 @@ std::ostream& back_white(std::ostream& s) { std::ostream& red(std::ostream& s) { #ifdef _WIN32 - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),0x0c); + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0c); #else s<<"\033[91;1m"; #endif @@ -46,7 +46,7 @@ std::ostream& red(std::ostream& s) { std::ostream& cyan(std::ostream& s) { #ifdef _WIN32 - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),0x03); + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x03); #else s<<"\033[36;1m"; #endif @@ -55,7 +55,7 @@ std::ostream& cyan(std::ostream& s) { std::ostream& orange(std::ostream& s) { #ifdef _WIN32 - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),0x0e); + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0e); #else s<<"\033[93;1m"; #endif @@ -64,7 +64,7 @@ std::ostream& orange(std::ostream& s) { std::ostream& white(std::ostream& s) { #ifdef _WIN32 - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),0x0f); + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0f); #else s<<"\033[0m\033[1m"; #endif @@ -73,7 +73,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); + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), reset_ter_color.scr.wAttributes); #else s<<"\033[0m"; #endif @@ -99,7 +99,7 @@ private: string identation(usize len) { return string(len,' '); } - string leftpad(u32 num,usize len) { + string leftpad(u32 num, usize len) { string tmp=std::to_string(num); while(tmp.length()\n"; std::exit(1); @@ -136,12 +136,12 @@ void flstream::load(const string& f) { while(!in.eof()) { string line; - std::getline(in,line); + std::getline(in, line); res.push_back(line); } } -void error::fatal(const string& stage,const string& info) { +void error::fatal(const string& stage, const string& info) { std::cerr< "< upval; // closure std::unordered_map keys; // parameter table, u32 begins from 1 - nas_func():dpara(-1),entry(0),psize(0),lsize(0) {} + nas_func(): dpara(-1), entry(0), psize(0), lsize(0) {} void clear(); }; @@ -186,9 +186,9 @@ private: void dylib_dtor(); public: - nas_obj():type(obj_type::null),ptr(nullptr) {} + nas_obj(): type(obj_type::null), ptr(nullptr) {} ~nas_obj() {clear();} - void set(obj_type,void*); + void set(obj_type, void*); void clear(); }; @@ -247,7 +247,7 @@ var* nas_vec::get_mem(const i32 n) { return &elems[n>=0?n:n+size]; } -std::ostream& operator<<(std::ostream& out,nas_vec& vec) { +std::ostream& operator<<(std::ostream& out, nas_vec& vec) { if (!vec.elems.size() || vec.printed) { out<<(vec.elems.size()?"[..]":"[]"); return out; @@ -306,7 +306,7 @@ var* nas_hash::get_mem(const string& key) { return addr; } -std::ostream& operator<<(std::ostream& out,nas_hash& hash) { +std::ostream& operator<<(std::ostream& out, nas_hash& hash) { if (!hash.elems.size() || hash.printed) { out<<(hash.elems.size()?"{..}":"{}"); return out; @@ -328,7 +328,7 @@ void nas_func::clear() { keys.clear(); } -void nas_obj::set(obj_type t,void* p) { +void nas_obj::set(obj_type t, void* p) { type=t; ptr=p; } @@ -352,6 +352,7 @@ void nas_obj::file_dtor() { } fclose((FILE*)ptr); } + void nas_obj::dir_dtor() { #ifndef _MSC_VER closedir((DIR*)ptr); @@ -359,6 +360,7 @@ void nas_obj::dir_dtor() { FindClose(ptr); #endif } + void nas_obj::dylib_dtor() { #ifdef _WIN32 FreeLibrary((HMODULE)ptr); @@ -432,14 +434,14 @@ string var::tostr() { return str(); } else if (type==vm_num) { string tmp=std::to_string(num()); - tmp.erase(tmp.find_last_not_of('0')+1,string::npos); - tmp.erase(tmp.find_last_not_of('.')+1,string::npos); + tmp.erase(tmp.find_last_not_of('0')+1, string::npos); + tmp.erase(tmp.find_last_not_of('.')+1, string::npos); return tmp; } return ""; } -std::ostream& operator<<(std::ostream& out,var& ref) { +std::ostream& operator<<(std::ostream& out, var& ref) { switch(ref.type) { case vm_none: out<<"undefined"; break; case vm_nil: out<<"nil"; break; @@ -459,31 +461,31 @@ bool var::objchk(obj_type objtype) { } var var::none() { - return {vm_none,(u32)0}; + return {vm_none, (u32)0}; } var var::nil() { - return {vm_nil,(u32)0}; + return {vm_nil, (u32)0}; } var var::ret(u32 pc) { - return {vm_ret,pc}; + return {vm_ret, pc}; } var var::cnt(i64 n) { - return {vm_cnt,n}; + return {vm_cnt, n}; } var var::num(f64 n) { - return {vm_num,n}; + return {vm_num, n}; } var var::gcobj(nas_val* p) { - return {p->type,p}; + return {p->type, p}; } var var::addr(var* p) { - return {vm_addr,p}; + return {vm_addr, p}; } var* var::addr () {return val.addr; } @@ -542,17 +544,17 @@ private: /* gc functions */ void mark(); void mark_context(std::vector&); - void mark_var(std::vector&,var&); - inline void mark_vec(std::vector&,nas_vec&); - inline void mark_hash(std::vector&,nas_hash&); - inline void mark_func(std::vector&,nas_func&); - inline void mark_upval(std::vector&,nas_upval&); - inline void mark_co(std::vector&,nas_co&); + void mark_var(std::vector&, var&); + inline void mark_vec(std::vector&, nas_vec&); + inline void mark_hash(std::vector&, nas_hash&); + inline void mark_func(std::vector&, nas_func&); + inline void mark_upval(std::vector&, nas_upval&); + inline void mark_co(std::vector&, nas_co&); void sweep(); public: void extend(u8); - void init(const std::vector&,const std::vector&); + void init(const std::vector&, const std::vector&); void clear(); void info(); var alloc(const u8); @@ -574,7 +576,7 @@ void gc::mark() { value.val.gcobj->mark!=gc_status::uncollected) { continue; } - mark_var(bfs,value); + mark_var(bfs, value); } } @@ -600,31 +602,31 @@ void gc::mark_context(std::vector& bfs_queue) { bfs_queue.push_back(mctx.upvalr); } -void gc::mark_var(std::vector& bfs_queue,var& value) { +void gc::mark_var(std::vector& bfs_queue, var& value) { value.val.gcobj->mark=gc_status::found; switch(value.type) { - case vm_vec: mark_vec(bfs_queue,value.vec()); break; - case vm_hash: mark_hash(bfs_queue,value.hash()); break; - case vm_func: mark_func(bfs_queue,value.func()); break; - case vm_upval: mark_upval(bfs_queue,value.upval()); break; - case vm_co: mark_co(bfs_queue,value.co()); break; + case vm_vec: mark_vec(bfs_queue, value.vec()); break; + case vm_hash: mark_hash(bfs_queue, value.hash()); break; + case vm_func: mark_func(bfs_queue, value.func()); break; + case vm_upval: mark_upval(bfs_queue, value.upval()); break; + case vm_co: mark_co(bfs_queue, value.co()); break; default: break; } } -void gc::mark_vec(std::vector& bfs_queue,nas_vec& vec) { +void gc::mark_vec(std::vector& bfs_queue, nas_vec& vec) { for(auto& i:vec.elems) { bfs_queue.push_back(i); } } -void gc::mark_hash(std::vector& bfs_queue,nas_hash& hash) { +void gc::mark_hash(std::vector& bfs_queue, nas_hash& hash) { for(auto& i:hash.elems) { bfs_queue.push_back(i.second); } } -void gc::mark_func(std::vector& bfs_queue,nas_func& function) { +void gc::mark_func(std::vector& bfs_queue, nas_func& function) { for(auto& i:function.local) { bfs_queue.push_back(i); } @@ -633,13 +635,13 @@ void gc::mark_func(std::vector& bfs_queue,nas_func& function) { } } -void gc::mark_upval(std::vector& bfs_queue,nas_upval& upval) { +void gc::mark_upval(std::vector& bfs_queue, nas_upval& upval) { for(auto& i:upval.elems) { bfs_queue.push_back(i); } } -void gc::mark_co(std::vector& bfs_queue,nas_co& co) { +void gc::mark_co(std::vector& bfs_queue, nas_co& co) { bfs_queue.push_back(co.ctx.funcr); bfs_queue.push_back(co.ctx.upvalr); for(var* i=co.stack;i<=co.ctx.top;++i) { @@ -679,7 +681,7 @@ void gc::extend(u8 type) { incr[index]*=2; } -void gc::init(const std::vector& s,const std::vector& argv) { +void gc::init(const std::vector& s, const std::vector& argv) { // initialize function register rctx->funcr=nil; worktime=0; @@ -838,13 +840,13 @@ void gc::ctxreserve() { } // use to print error log and return error value -var nas_err(const string& err_f,const string& info) { +var nas_err(const string& err_f, const string& info) { std::cerr<<"[vm] "<& filelist() const {return files;} }; -linker::linker(error& e):show_path(false),lib_loaded(false),err(e) { +linker::linker(error& e): show_path(false), lib_loaded(false), err(e) { char sep=is_windows()? ';':':'; string PATH=getenv("PATH"); - usize last=0,pos=PATH.find(sep,0); + usize last=0; + usize pos=PATH.find(sep, 0); while(pos!=string::npos) { - string dirpath=PATH.substr(last,pos-last); + string dirpath=PATH.substr(last, pos-last); if (dirpath.length()) { envpath.push_back(dirpath); } last=pos+1; - pos=PATH.find(sep,last); + pos=PATH.find(sep, last); } if (last!=PATH.length()) { envpath.push_back(PATH.substr(last)); @@ -78,7 +79,7 @@ string linker::findf(const string& fname) { // search file for(auto& i:fpath) { - if (access(i.c_str(),F_OK)!=-1) { + if (access(i.c_str(), F_OK)!=-1) { return i; } } @@ -88,14 +89,14 @@ string linker::findf(const string& fname) { return is_windows()? findf("stl\\lib.nas"):findf("stl/lib.nas"); } if (!show_path) { - err.err("link","cannot find file <"+fname+">"); + err.err("link", "cannot find file <"+fname+">"); return ""; } string paths=""; for(auto& i:fpath) { paths+=" "+i+"\n"; } - err.err("link","cannot find file <"+fname+"> in these paths:\n"+paths); + err.err("link", "cannot find file <"+fname+"> in these paths:\n"+paths); return ""; } @@ -142,7 +143,7 @@ bool linker::exist(const string& file) { return false; } -void linker::link(ast& root,ast&& add_root) { +void linker::link(ast& root, ast&& add_root) { // add children of add_root to the back of root for(auto& i:add_root.child()) { root.add(std::move(i)); @@ -159,7 +160,7 @@ ast linker::fimpt(ast& node) { // avoid infinite loading loop filename=findf(filename); if (!filename.length() || exist(filename)) { - return {{0,0,0,0,filename},ast_root}; + return {{0, 0, 0, 0, filename}, ast_root}; } // start importing... @@ -168,7 +169,7 @@ ast linker::fimpt(ast& node) { ast tmp=std::move(par.tree()); // check if tmp has 'import' - return load(tmp,files.size()-1); + return load(tmp, files.size()-1); } ast linker::libimpt() { @@ -176,12 +177,12 @@ ast linker::libimpt() { parse par(err); string filename=findf("lib.nas"); if (!filename.length()) { - return {{0,0,0,0,filename},ast_root}; + return {{0, 0, 0, 0, filename}, ast_root}; } // avoid infinite loading loop if (exist(filename)) { - return {{0,0,0,0,filename},ast_root}; + return {{0, 0, 0, 0, filename}, ast_root}; } // start importing... @@ -190,36 +191,36 @@ ast linker::libimpt() { ast tmp=std::move(par.tree()); // check if tmp has 'import' - return load(tmp,files.size()-1); + return load(tmp, files.size()-1); } -ast linker::load(ast& root,u16 fileindex) { - ast tree({0,0,0,0,files[fileindex]},ast_root); +ast linker::load(ast& root, u16 fileindex) { + ast tree({0, 0, 0, 0, files[fileindex]}, ast_root); if (!lib_loaded) { - link(tree,libimpt()); + link(tree, libimpt()); lib_loaded=true; } for(auto& i:root.child()) { if (imptchk(i)) { - link(tree,fimpt(i)); + link(tree, fimpt(i)); } else { break; } } // add root to the back of tree - ast file_head({0,0,0,0,files[fileindex]},ast_file); + ast file_head({0, 0, 0, 0, files[fileindex]}, ast_file); file_head.set_num(fileindex); tree.add(std::move(file_head)); - link(tree,std::move(root)); + link(tree, std::move(root)); return tree; } -const error& linker::link(parse& parse,const string& self,bool spath=false) { +const error& linker::link(parse& parse, const string& self, bool spath=false) { show_path=spath; // initializing files={self}; // scan root and import files,then generate a new ast and return to import_ast // the main file's index is 0 - parse.tree()=load(parse.tree(),0); + parse.tree()=load(parse.tree(), 0); return err; } diff --git a/nasal_lexer.h b/nasal_lexer.h index badec81..27813ed 100644 --- a/nasal_lexer.h +++ b/nasal_lexer.h @@ -169,7 +169,7 @@ private: token dots(); token calc_opr(); public: - lexer(error& e): line(1),column(0),ptr(0),filename(""),res(""),err(e) {} + lexer(error& e): line(1), column(0), ptr(0), filename(""), res(""), err(e) {} const error& scan(const string&); const std::vector& result() const {return toks;} }; @@ -223,23 +223,23 @@ void lexer::skip_note() { void lexer::err_char() { ++column; char c=res[ptr++]; - err.err("lexer",{line,column-1,line,column,filename},"invalid character 0x"+chrhex(c)); - err.fatal("lexer","fatal error occurred, stop"); + err.err("lexer", {line, column-1, line, column, filename}, "invalid character 0x"+chrhex(c)); + err.fatal("lexer", "fatal error occurred, stop"); } void lexer::open(const string& file) { // check file exsits and it is a regular file struct stat buffer; - if (stat(file.c_str(),&buffer)==0 && !S_ISREG(buffer.st_mode)) { - err.err("lexer","<"+file+"> is not a regular file"); + if (stat(file.c_str(), &buffer)==0 && !S_ISREG(buffer.st_mode)) { + err.err("lexer", "<"+file+"> is not a regular file"); err.chkerr(); } // load filename=file; - std::ifstream in(file,std::ios::binary); + std::ifstream in(file, std::ios::binary); if (in.fail()) { - err.err("lexer","failed to open <"+file+">"); + err.err("lexer", "failed to open <"+file+">"); } else { err.load(file); } @@ -277,8 +277,8 @@ string lexer::utf8_gen() { for(u32 i=1;i"); - err.fatal("lexer","fatal error occurred, stop"); + err.err("lexer", {line, column-1, line, column, filename}, "invalid utf-8 <"+utf_info+">"); + err.fatal("lexer", "fatal error occurred, stop"); } str+=tmp; column+=2; // may have some problems because not all the unicode takes 2 space @@ -299,7 +299,7 @@ token lexer::id_gen() { } } tok type=get_type(str); - return {{begin_line,begin_column,line,column,filename},(type!=tok::null)?type:tok::id,str}; + return {{begin_line, begin_column, line, column, filename}, (type!=tok::null)?type:tok::id, str}; } token lexer::num_gen() { @@ -314,9 +314,9 @@ token lexer::num_gen() { } column+=str.length(); if (str.length()<3) { // "0x" - err.err("lexer",{begin_line,begin_column,line,column,filename},"invalid number `"+str+"`"); + err.err("lexer", {begin_line, begin_column, line, column, filename}, "invalid number `"+str+"`"); } - return {{begin_line,begin_column,line,column,filename},tok::num,str}; + return {{begin_line, begin_column, line, column, filename}, tok::num, str}; } else if (ptr+1 [0~9][0~9]*(.[0~9]*)(e|E(+|-)0|[1~9][0~9]*) @@ -348,8 +348,8 @@ token lexer::num_gen() { // "xxxx." is not a correct number if (str.back()=='.') { column+=str.length(); - err.err("lexer",{begin_line,begin_column,line,column,filename},"invalid number `"+str+"`"); - return {{begin_line,begin_column,line,column,filename},tok::num,"0"}; + err.err("lexer",{begin_line, begin_column, line, column, filename}, "invalid number `"+str+"`"); + return {{begin_line, begin_column, line, column, filename}, tok::num, "0"}; } } if (ptr=res.size()) { - err.err("lexer",{begin_line,begin_column,line,column,filename},"get EOF when generating string"); - return {{begin_line,begin_column,line,column,filename},tok::str,str}; + err.err("lexer", {begin_line, begin_column, line, column, filename}, "get EOF when generating string"); + return {{begin_line, begin_column, line, column, filename}, tok::str, str}; } ++column; if (begin=='`' && str.length()!=1) { - err.err("lexer",{begin_line,begin_column,line,column,filename},"\'`\' is used for string including one character"); + err.err("lexer", {begin_line, begin_column, line, column, filename}, "\'`\' is used for string including one character"); } - return {{begin_line,begin_column,line,column,filename},tok::str,str}; + return {{begin_line, begin_column, line, column, filename}, tok::str, str}; } token lexer::single_opr() { @@ -429,10 +429,10 @@ token lexer::single_opr() { ++column; tok type=get_type(str); if (type==tok::null) { - err.err("lexer",{begin_line,begin_column,line,column,filename},"invalid operator `"+str+"`"); + err.err("lexer", {begin_line, begin_column, line, column, filename}, "invalid operator `"+str+"`"); } ++ptr; - return {{begin_line,begin_column,line,column,filename},type,str}; + return {{begin_line, begin_column, line, column, filename}, type, str}; } token lexer::dots() { @@ -444,7 +444,7 @@ token lexer::dots() { } ptr+=str.length(); column+=str.length(); - return {{begin_line,begin_column,line,column,filename},get_type(str),str}; + return {{begin_line, begin_column, line, column, filename}, get_type(str), str}; } token lexer::calc_opr() { @@ -456,7 +456,7 @@ token lexer::calc_opr() { str+=res[ptr++]; } column+=str.length(); - return {{begin_line,begin_column,line,column,filename},get_type(str),str}; + return {{begin_line, begin_column, line, column, filename}, get_type(str), str}; } const error& lexer::scan(const string& file) { @@ -495,7 +495,7 @@ const error& lexer::scan(const string& file) { err_char(); } } - 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/nasal_opcode.h b/nasal_opcode.h index f006ed1..8c5c270 100644 --- a/nasal_opcode.h +++ b/nasal_opcode.h @@ -138,8 +138,8 @@ private: static const string* strs; static const string* files; public: - codestream(const opcode& c,const u32 i):code(c),index(i) {} - static void set(const f64*,const string*,const string*); + codestream(const opcode& c, const u32 i): code(c), index(i) {} + static void set(const f64*, const string*, const string*); void dump(std::ostream&) const; }; @@ -182,12 +182,12 @@ void codestream::dump(std::ostream& out) const { case op_muleqc:case op_diveqc: out<"); + die(thisspan, "incorrect token <"+toks[ptr].str+">"); next(); break; } // unreachable - return {toks[ptr].loc,ast_null}; + return {toks[ptr].loc, ast_null}; } ast parse::exprs() { if (lookahead(tok::eof)) { - die(thisspan,"expected expression block"); + die(thisspan, "expected expression block"); return null(); } - ast node(toks[ptr].loc,ast_block); + ast node(toks[ptr].loc, ast_block); if (lookahead(tok::lbrace)) { match(tok::lbrace); while(!lookahead(tok::rbrace) && !lookahead(tok::eof)) { @@ -518,10 +518,10 @@ ast parse::exprs() { match(tok::semi); } else if (need_semi_check(node.child().back()) && !lookahead(tok::rbrace)) { // the last expression can be recognized without semi - die(prevspan,"expected ';'"); + die(prevspan, "expected ';'"); } } - match(tok::rbrace,"expected '}' when generating expressions"); + match(tok::rbrace, "expected '}' when generating expressions"); } else { node.add(expr()); if (lookahead(tok::semi)) @@ -535,7 +535,7 @@ ast parse::calc() { ast node=bitwise_or(); if (lookahead(tok::quesmark)) { // trinocular calculation - ast tmp(toks[ptr].loc,ast_trino); + ast tmp(toks[ptr].loc, ast_trino); match(tok::quesmark); tmp.add(std::move(node)); tmp.add(calc()); @@ -544,13 +544,13 @@ ast parse::calc() { node=std::move(tmp); } else if (tok::eq<=toks[ptr].type && toks[ptr].type<=tok::lnkeq) { // tok::eq~tok::lnkeq is 37 to 42,ast_equal~ast_lnkeq is 21~26 - ast tmp(toks[ptr].loc,(u32)toks[ptr].type-(u32)tok::eq+ast_equal); + ast tmp(toks[ptr].loc, (u32)toks[ptr].type-(u32)tok::eq+ast_equal); tmp.add(std::move(node)); match(toks[ptr].type); tmp.add(calc()); node=std::move(tmp); } else if (toks[ptr].type==tok::btandeq || toks[ptr].type==tok::btoreq || toks[ptr].type==tok::btxoreq) { - ast tmp(toks[ptr].loc,(u32)toks[ptr].type-(u32)tok::btandeq+ast_btandeq); + ast tmp(toks[ptr].loc, (u32)toks[ptr].type-(u32)tok::btandeq+ast_btandeq); tmp.add(std::move(node)); match(toks[ptr].type); tmp.add(calc()); @@ -563,7 +563,7 @@ ast parse::calc() { ast parse::bitwise_or() { ast node=bitwise_xor(); while(lookahead(tok::btor)) { - ast tmp(toks[ptr].loc,ast_bitor); + ast tmp(toks[ptr].loc, ast_bitor); tmp.add(std::move(node)); match(tok::btor); tmp.add(bitwise_xor()); @@ -577,7 +577,7 @@ ast parse::bitwise_or() { ast parse::bitwise_xor() { ast node=bitwise_and(); while(lookahead(tok::btxor)) { - ast tmp(toks[ptr].loc,ast_bitxor); + ast tmp(toks[ptr].loc, ast_bitxor); tmp.add(std::move(node)); match(tok::btxor); tmp.add(bitwise_and()); @@ -591,7 +591,7 @@ ast parse::bitwise_xor() { ast parse::bitwise_and() { ast node=or_expr(); while(lookahead(tok::btand)) { - ast tmp(toks[ptr].loc,ast_bitand); + ast tmp(toks[ptr].loc, ast_bitand); tmp.add(std::move(node)); match(tok::btand); tmp.add(or_expr()); @@ -605,7 +605,7 @@ ast parse::bitwise_and() { ast parse::or_expr() { ast node=and_expr(); while(lookahead(tok::opor)) { - ast tmp(toks[ptr].loc,ast_or); + ast tmp(toks[ptr].loc, ast_or); tmp.add(std::move(node)); match(tok::opor); tmp.add(and_expr()); @@ -619,7 +619,7 @@ ast parse::or_expr() { ast parse::and_expr() { ast node=cmp_expr(); while(lookahead(tok::opand)) { - ast tmp(toks[ptr].loc,ast_and); + ast tmp(toks[ptr].loc, ast_and); tmp.add(std::move(node)); match(tok::opand); tmp.add(cmp_expr()); @@ -634,7 +634,7 @@ ast parse::cmp_expr() { ast node=additive_expr(); while(tok::cmpeq<=toks[ptr].type && toks[ptr].type<=tok::geq) { // tok::cmpeq~tok::geq is 43~48,ast_cmpeq~ast_geq is 27~32 - ast tmp(toks[ptr].loc,(u32)toks[ptr].type-(u32)tok::cmpeq+ast_cmpeq); + ast tmp(toks[ptr].loc, (u32)toks[ptr].type-(u32)tok::cmpeq+ast_cmpeq); tmp.add(std::move(node)); match(toks[ptr].type); tmp.add(additive_expr()); @@ -648,7 +648,7 @@ ast parse::cmp_expr() { ast parse::additive_expr() { ast node=multive_expr(); while(lookahead(tok::add) || lookahead(tok::sub) || lookahead(tok::floater)) { - ast tmp(toks[ptr].loc,ast_null); + ast tmp(toks[ptr].loc, ast_null); switch(toks[ptr].type) { case tok::add: tmp.set_type(ast_add); break; case tok::sub: tmp.set_type(ast_sub); break; @@ -668,7 +668,7 @@ ast parse::additive_expr() { ast parse::multive_expr() { ast node=(lookahead(tok::sub) || lookahead(tok::opnot) || lookahead(tok::floater))?unary():scalar(); while(lookahead(tok::mult) || lookahead(tok::div)) { - ast tmp(toks[ptr].loc,(u32)toks[ptr].type-(u32)tok::mult+ast_mult); + ast tmp(toks[ptr].loc, (u32)toks[ptr].type-(u32)tok::mult+ast_mult); tmp.add(std::move(node)); match(toks[ptr].type); tmp.add((lookahead(tok::sub) || lookahead(tok::opnot) || lookahead(tok::floater))?unary():scalar()); @@ -693,7 +693,7 @@ ast parse::unary() { } ast parse::scalar() { - ast node(toks[ptr].loc,ast_null); + ast node(toks[ptr].loc, ast_null); if (lookahead(tok::tknil)) { node=nil(); match(tok::tknil); @@ -715,7 +715,7 @@ ast parse::scalar() { const auto& loc=toks[ptr].loc; match(tok::lcurve); node=calc(); - node.set_begin(loc.begin_line,loc.begin_column); + node.set_begin(loc.begin_line, loc.begin_column); node.update_span(thisspan); match(tok::rcurve); } else if (lookahead(tok::var)) { @@ -725,13 +725,13 @@ ast parse::scalar() { match(tok::eq); node.add(calc()); } else { - die(thisspan,"expected scalar"); + die(thisspan, "expected scalar"); return node; } // check call and avoid ambiguous syntax if (is_call(toks[ptr].type) && !(lookahead(tok::lcurve) && toks[ptr+1].type==tok::var)) { ast tmp=std::move(node); - node={toks[ptr].loc,ast_call}; + node={toks[ptr].loc, ast_call}; node.add(std::move(tmp)); while(is_call(toks[ptr].type)) { node.add(call_scalar()); @@ -749,15 +749,15 @@ ast parse::call_scalar() { default: break; } // unreachable - return {toks[ptr].loc,ast_nil}; + return {toks[ptr].loc, ast_nil}; } ast parse::callh() { - ast node(toks[ptr].loc,ast_callh); + ast node(toks[ptr].loc, ast_callh); match(tok::dot); node.set_str(toks[ptr].str); - node.set_end(toks[ptr].loc.end_line,toks[ptr].loc.end_column); - match(tok::id,"expected hashmap key"); // get key + node.set_end(toks[ptr].loc.end_line, toks[ptr].loc.end_column); + match(tok::id, "expected hashmap key"); // get key return node; } @@ -771,7 +771,7 @@ ast parse::callv() { tok::func,tok::var,tok::lcurve,tok::floater, tok::lbrace,tok::lbracket,tok::colon,tok::null }; - ast node(toks[ptr].loc,ast_callv); + ast node(toks[ptr].loc, ast_callv); match(tok::lbracket); while(!lookahead(tok::rbracket)) { node.add(subvec()); @@ -784,10 +784,10 @@ ast parse::callv() { } } if (node.size()==0) { - die(thisspan,"expected index value"); + die(thisspan, "expected index value"); } node.update_span(thisspan); - match(tok::rbracket,"expected ']' when calling vector"); + match(tok::rbracket, "expected ']' when calling vector"); return node; } @@ -801,7 +801,7 @@ ast parse::callf() { tok::func,tok::var,tok::lcurve,tok::floater, tok::lbrace,tok::lbracket,tok::null }; - ast node(toks[ptr].loc,ast_callf); + ast node(toks[ptr].loc, ast_callf); bool special_call=check_special_call(); match(tok::lcurve); while(!lookahead(tok::rcurve)) { @@ -814,14 +814,14 @@ ast parse::callf() { break; } node.update_span(thisspan); - match(tok::rcurve,"expected ')' when calling function"); + match(tok::rcurve, "expected ')' when calling function"); return node; } ast parse::subvec() { ast node=lookahead(tok::colon)?nil():calc(); if (lookahead(tok::colon)) { - ast tmp(toks[ptr].loc,ast_subvec); + ast tmp(toks[ptr].loc, ast_subvec); match(tok::colon); tmp.add(std::move(node)); tmp.add((lookahead(tok::comma) || lookahead(tok::rbracket))?nil():calc()); @@ -832,13 +832,13 @@ ast parse::subvec() { } ast parse::definition() { - ast node(toks[ptr].loc,ast_def); + ast node(toks[ptr].loc, ast_def); if (lookahead(tok::var)) { match(tok::var); switch(toks[ptr].type) { case tok::id: node.add(id());break; case tok::lcurve: node.add(outcurve_def());break; - default: die(thisspan,"expected identifier");break; + default: die(thisspan, "expected identifier");break; } } else if (lookahead(tok::lcurve)) { node.add(incurve_def()); @@ -860,7 +860,7 @@ ast parse::incurve_def() { ast node=multi_id(); node.update_span(thisspan); match(tok::rcurve); - node.set_begin(loc.begin_line,loc.begin_column); + node.set_begin(loc.begin_line, loc.begin_column); return node; } @@ -870,12 +870,12 @@ ast parse::outcurve_def() { ast node=multi_id(); node.update_span(thisspan); match(tok::rcurve); - node.set_begin(loc.begin_line,loc.begin_column); + node.set_begin(loc.begin_line, loc.begin_column); return node; } ast parse::multi_id() { - ast node(toks[ptr].loc,ast_multi_id); + ast node(toks[ptr].loc, ast_multi_id); while(!lookahead(tok::eof)) { // only identifier is allowed here // but we check it at codegen stage @@ -883,7 +883,7 @@ ast parse::multi_id() { if (lookahead(tok::comma)) { match(tok::comma); } else if (lookahead(tok::id)) { // first set of identifier - die(prevspan,"expected ',' between identifiers"); + die(prevspan, "expected ',' between identifiers"); } else { break; } @@ -900,7 +900,7 @@ ast parse::multi_scalar() { tok::func,tok::var,tok::lcurve,tok::floater, tok::lbrace,tok::lbracket,tok::null }; - ast node(toks[ptr].loc,ast_tuple); + ast node(toks[ptr].loc, ast_tuple); match(tok::lcurve); while(!lookahead(tok::rcurve)) { node.add(calc()); @@ -913,16 +913,16 @@ ast parse::multi_scalar() { } } node.update_span(thisspan); - match(tok::rcurve,"expected ')' after multi-scalar"); + match(tok::rcurve, "expected ')' after multi-scalar"); return node; } ast parse::multi_assgin() { - ast node(toks[ptr].loc,ast_multi_assign); + ast node(toks[ptr].loc, ast_multi_assign); node.add(multi_scalar()); match(tok::eq); if (lookahead(tok::eof)) { - die(thisspan,"expected value list"); + die(thisspan, "expected value list"); return node; } if (lookahead(tok::lcurve)) { @@ -936,7 +936,7 @@ ast parse::multi_assgin() { ast parse::loop() { ++in_loop; - ast node(toks[ptr].loc,ast_null); + ast node(toks[ptr].loc, ast_null); switch(toks[ptr].type) { case tok::rwhile: node=while_loop(); break; case tok::rfor: node=for_loop(); break; @@ -949,7 +949,7 @@ ast parse::loop() { } ast parse::while_loop() { - ast node(toks[ptr].loc,ast_while); + ast node(toks[ptr].loc, ast_while); match(tok::rwhile); match(tok::lcurve); node.add(calc()); @@ -960,12 +960,12 @@ ast parse::while_loop() { } ast parse::for_loop() { - ast node(toks[ptr].loc,ast_for); + ast node(toks[ptr].loc, ast_for); match(tok::rfor); match(tok::lcurve); // first expression if (lookahead(tok::eof)) { - die(thisspan,"expected definition"); + die(thisspan, "expected definition"); } if (lookahead(tok::semi)) { node.add(null()); @@ -976,20 +976,20 @@ ast parse::for_loop() { } else { node.add(calc()); } - match(tok::semi,"expected ';' in for(;;)"); + match(tok::semi, "expected ';' in for(;;)"); // conditional expression if (lookahead(tok::eof)) { - die(thisspan,"expected conditional expr"); + die(thisspan, "expected conditional expr"); } if (lookahead(tok::semi)) { node.add(null()); } else { node.add(calc()); } - match(tok::semi,"expected ';' in for(;;)"); + match(tok::semi, "expected ';' in for(;;)"); //after loop expression if (lookahead(tok::eof)) { - die(thisspan,"expected calculation"); + die(thisspan, "expected calculation"); } if (lookahead(tok::rcurve)) { node.add(null()); @@ -1003,7 +1003,7 @@ ast parse::for_loop() { } ast parse::forei_loop() { - ast node(toks[ptr].loc,ast_null); + ast node(toks[ptr].loc, ast_null); switch(toks[ptr].type) { case tok::forindex:node.set_type(ast_forindex);match(tok::forindex);break; case tok::foreach: node.set_type(ast_foreach); match(tok::foreach); break; @@ -1013,12 +1013,12 @@ ast parse::forei_loop() { // first expression // foreach/forindex must have an iterator to loop through if (!lookahead(tok::var) && !lookahead(tok::id)) { - die(thisspan,"expected iterator"); + die(thisspan, "expected iterator"); } node.add(iter_gen()); - match(tok::semi,"expected ';' in foreach/forindex(iter;vector)"); + match(tok::semi, "expected ';' in foreach/forindex(iter;vector)"); if (lookahead(tok::eof)) { - die(thisspan,"expected vector"); + die(thisspan, "expected vector"); } node.add(calc()); match(tok::rcurve); @@ -1028,7 +1028,7 @@ ast parse::forei_loop() { } ast parse::iter_gen() { - ast node(toks[ptr].loc,ast_null); + ast node(toks[ptr].loc, ast_null); if (lookahead(tok::var)) { match(tok::var); node.set_type(ast_iter); @@ -1045,10 +1045,10 @@ ast parse::iter_gen() { } ast parse::cond() { - ast node(toks[ptr].loc,ast_cond); + ast node(toks[ptr].loc, ast_cond); // generate if - ast ifnode(toks[ptr].loc,ast_if); + ast ifnode(toks[ptr].loc, ast_if); match(tok::rif); match(tok::lcurve); ifnode.add(calc()); @@ -1059,7 +1059,7 @@ ast parse::cond() { // generate elsif while(lookahead(tok::elsif)) { - ast elsifnode(toks[ptr].loc,ast_elsif); + ast elsifnode(toks[ptr].loc, ast_elsif); match(tok::elsif); match(tok::lcurve); elsifnode.add(calc()); @@ -1071,7 +1071,7 @@ ast parse::cond() { // generate else if (lookahead(tok::relse)) { - ast elsenode(toks[ptr].loc,ast_else); + ast elsenode(toks[ptr].loc, ast_else); match(tok::relse); elsenode.add(exprs()); elsenode.update_span(); @@ -1082,19 +1082,19 @@ ast parse::cond() { } ast parse::continue_expr() { - ast node(toks[ptr].loc,ast_continue); + ast node(toks[ptr].loc, ast_continue); match(tok::cont); return node; } ast parse::break_expr() { - ast node(toks[ptr].loc,ast_break); + ast node(toks[ptr].loc, ast_break); match(tok::brk); return node; } ast parse::ret_expr() { - ast node(toks[ptr].loc,ast_ret); + ast node(toks[ptr].loc, ast_ret); match(tok::ret); tok type=toks[ptr].type; if (type==tok::tknil || type==tok::num || diff --git a/nasal_vm.h b/nasal_vm.h index 6bc32d5..a90a862 100644 --- a/nasal_vm.h +++ b/nasal_vm.h @@ -141,7 +141,7 @@ protected: public: /* constructor of vm instance */ - vm():ngc(&ctx),verbose(false) {} + vm(): ngc(&ctx), verbose(false) {} /* execution entry */ void run( @@ -229,7 +229,7 @@ void vm::traceback() { } ret.push(ctx.pc); // store the position program crashed std::clog<<"trace back ("<<(ngc.rctx->stack==stack?"main":"coroutine")<<")\n"; - codestream::set(cnum,cstr,files); + codestream::set(cnum, cstr, files); for(u32 p=0,same=0,prev=0xffffffff;!ret.empty();prev=p,ret.pop()) { if ((p=ret.top())==prev) { ++same; @@ -365,7 +365,7 @@ void vm::o_intg() { } void vm::o_intl() { - ctx.top[0].func().local.resize(imm[ctx.pc],nil); + ctx.top[0].func().local.resize(imm[ctx.pc], nil); ctx.top[0].func().lsize=imm[ctx.pc]; } @@ -817,7 +817,7 @@ void vm::o_callfv() { // collected incorrectly ctx.top=local+func.lsize; - u32 min_size=(std::min)(psize,argc); // avoid error in MSVC + u32 min_size=(std::min)(psize, argc); // avoid error in MSVC for(u32 i=min_size;i>=1;--i) { // load arguments local[i]=local[i-1]; } @@ -890,7 +890,7 @@ void vm::o_callb() { // if running a builtin function about coroutine // (top) will be set to another context.top, instead of main_context.top - var tmp=(*builtin[imm[ctx.pc]].func)(ctx.localr,ngc); + var tmp=(*builtin[imm[ctx.pc]].func)(ctx.localr, ngc); // so we use tmp variable to store this return value // and set it to top[0] later @@ -1073,9 +1073,10 @@ void vm::run( const codegen& gen, const linker& linker, const std::vector& argv, - const bool detail) { + const bool detail +) { verbose=detail; - init(gen.strs(),gen.nums(),gen.codes(),linker.filelist(),argv); + init(gen.strs(), gen.nums(), gen.codes(), linker.filelist(), argv); #ifndef _MSC_VER const void* oprs[]={ &&vmexit, &&intg, &&intl, &&loadg,