diff --git a/nasal.h b/nasal.h index 5d57cbe..d4c76fe 100644 --- a/nasal.h +++ b/nasal.h @@ -140,8 +140,7 @@ string rawstr(const string& str,const usize maxlen=0) { string ret(""); for(auto i:str) { #ifdef _WIN32 - // windows ps or cmd doesn't output unicode normally - // if 'chcp65001' is not enabled, we output the hex + // windows doesn't output unicode normally, so we output the hex if (i<=0) { ret+="\\x"+chrhex(i); continue; diff --git a/nasal_ast.h b/nasal_ast.h index 593a982..518abea 100644 --- a/nasal_ast.h +++ b/nasal_ast.h @@ -3,6 +3,8 @@ #include #include +#include "nasal.h" + enum ast_node:u32 { ast_null=0, // null node ast_root, // mark the root node of ast diff --git a/nasal_builtin.h b/nasal_builtin.h index 69f7126..776bb9f 100644 --- a/nasal_builtin.h +++ b/nasal_builtin.h @@ -1,5 +1,6 @@ #pragma once +#include "nasal.h" #include "nasal_gc.h" #ifndef _MSC_VER diff --git a/nasal_codegen.h b/nasal_codegen.h index d0316a8..511be84 100644 --- a/nasal_codegen.h +++ b/nasal_codegen.h @@ -1,6 +1,8 @@ #pragma once #include "nasal_err.h" +#include "nasal_builtin.h" + #include #include #include diff --git a/nasal_dbg.h b/nasal_dbg.h index 74fe21e..af42135 100644 --- a/nasal_dbg.h +++ b/nasal_dbg.h @@ -1,5 +1,6 @@ #pragma once +#include "nasal_import.h" #include "nasal_err.h" #include "nasal_vm.h" #include diff --git a/nasal_err.h b/nasal_err.h index 43901ce..8a66064 100644 --- a/nasal_err.h +++ b/nasal_err.h @@ -4,6 +4,9 @@ #include #include // MSVC need this to use std::getline #include +#include + +#include "nasal.h" #ifdef _WIN32 #include // use SetConsoleTextAttribute diff --git a/nasal_gc.h b/nasal_gc.h index 1fe6f77..3c7c0bf 100644 --- a/nasal_gc.h +++ b/nasal_gc.h @@ -20,6 +20,7 @@ #include #include +#include "nasal.h" #include "nasal_err.h" enum vm_type:u8 { diff --git a/nasal_import.h b/nasal_import.h index 92b8d08..37a1273 100644 --- a/nasal_import.h +++ b/nasal_import.h @@ -12,6 +12,10 @@ #define F_OK 0 #endif +#include "nasal_ast.h" +#include "nasal_lexer.h" +#include "nasal_parse.h" + class linker{ private: bool show_path; diff --git a/nasal_lexer.h b/nasal_lexer.h index 8ef3314..d09481b 100644 --- a/nasal_lexer.h +++ b/nasal_lexer.h @@ -1,9 +1,14 @@ #pragma once +#include #include +#include #include #include +#include "nasal.h" +#include "nasal_err.h" + #ifdef _MSC_VER #define S_ISREG(m) (((m)&0xF000)==0x8000) #endif diff --git a/nasal_opt.h b/nasal_opt.h index 042786f..abf9eee 100644 --- a/nasal_opt.h +++ b/nasal_opt.h @@ -2,6 +2,8 @@ #include +#include "nasal_ast.h" + void const_str(ast& root) { auto& vec=root.child(); root.set_str(vec[0].str()+vec[1].str()); diff --git a/nasal_parse.h b/nasal_parse.h index 77e3aa4..11a4b63 100644 --- a/nasal_parse.h +++ b/nasal_parse.h @@ -2,6 +2,11 @@ #include +#include "nasal.h" +#include "nasal_lexer.h" +#include "nasal_ast.h" +#include "nasal_err.h" + /* _,,,_ .' `'. diff --git a/nasal_vm.h b/nasal_vm.h index 74db975..24f44fb 100644 --- a/nasal_vm.h +++ b/nasal_vm.h @@ -2,6 +2,9 @@ #include #include + +#include "nasal_import.h" +#include "nasal_gc.h" #include "nasal_codegen.h" class vm { @@ -46,7 +49,6 @@ protected: void ustate(); void detail(); void die(const string&); -#define vm_error(info) {die(info);return;} /* vm calculation functions*/ bool cond(var&); /* vm operands */ @@ -441,7 +443,10 @@ inline void vm::o_unot() { top[0]=num?zero:one; } } break; - default:vm_error("incorrect value type");break; + default:{ + die("incorrect value type"); + return; + } break; } } @@ -587,7 +592,8 @@ inline void vm::o_jf() { inline void vm::o_cnt() { if (top[0].type!=vm_vec) { - vm_error("must use vector in forindex/foreach"); + die("must use vector in forindex/foreach"); + return; } (++top)[0]={vm_cnt,(i64)-1}; } @@ -630,15 +636,18 @@ inline void vm::o_callv() { if (vec.type==vm_vec) { top[0]=vec.vec().get_val(val.tonum()); if (top[0].type==vm_none) { - vm_error("out of range:"+std::to_string(val.tonum())); + die("out of range:"+std::to_string(val.tonum())); + return; } } else if (vec.type==vm_hash) { if (val.type!=vm_str) { - vm_error("must use string as the key"); + die("must use string as the key"); + return; } top[0]=vec.hash().get_val(val.str()); if (top[0].type==vm_none) { - vm_error("cannot find member \""+val.str()+"\""); + die("cannot find member \""+val.str()+"\""); + return; } else if (top[0].type==vm_func) { top[0].func().local[0]=val; // 'me' } @@ -647,34 +656,40 @@ inline void vm::o_callv() { i32 num=val.tonum(); i32 len=str.length(); if (num<-len || num>=len) { - vm_error("out of range:"+std::to_string(val.tonum())); + die("out of range:"+std::to_string(val.tonum())); + return; } top[0]={vm_num,f64((u8)str[num>=0? num:num+len])}; } else { - vm_error("must call a vector/hash/string"); + die("must call a vector/hash/string"); + return; } } inline void vm::o_callvi() { var val=top[0]; if (val.type!=vm_vec) { - vm_error("must use a vector"); + die("must use a vector"); + return; } // cannot use operator[],because this may cause overflow (++top)[0]=val.vec().get_val(imm[pc]); if (top[0].type==vm_none) { - vm_error("out of range:"+std::to_string(imm[pc])); + die("out of range:"+std::to_string(imm[pc])); + return; } } inline void vm::o_callh() { var val=top[0]; if (val.type!=vm_hash) { - vm_error("must call a hash"); + die("must call a hash"); + return; } top[0]=val.hash().get_val(cstr[imm[pc]]); if (top[0].type==vm_none) { - vm_error("member \""+cstr[imm[pc]]+"\" does not exist"); + die("member \""+cstr[imm[pc]]+"\" does not exist"); + return; } else if (top[0].type==vm_func) { top[0].func().local[0]=val; // 'me' } @@ -684,7 +699,8 @@ inline void vm::o_callfv() { u32 argc=imm[pc]; // arguments counter var* local=top-argc+1; // arguments begin address if (local[-1].type!=vm_func) { - vm_error("must call a function"); + die("must call a function"); + return; } auto& func=local[-1].func(); var tmp=local[-1]; @@ -692,12 +708,14 @@ inline void vm::o_callfv() { funcr=tmp; // top-argc+lsize(local) +1(old pc) +1(old localr) +1(old upvalr) if (top-argc+func.lsize+3>=canary) { - vm_error("stack overflow"); + die("stack overflow"); + return; } // parameter size is func->psize-1, 1 is reserved for "me" u32 psize=func.psize-1; if (argc=canary) { - vm_error("stack overflow"); + die("stack overflow"); + return; } if (func.dpara>=0) { - vm_error("special call cannot use dynamic argument"); + die("special call cannot use dynamic argument"); + return; } var* local=top; @@ -758,7 +779,8 @@ inline void vm::o_callfh() { if (hash.count(key)) { local[i.second]=hash[key]; } else if (local[i.second].type==vm_none) { - vm_error("lack argument(s): \""+key+"\""); + die("lack argument(s): \""+key+"\""); + return; } } @@ -779,7 +801,8 @@ inline void vm::o_callb() { // (top) will be set to another context.top, instead of main_context.top top[0]=(*builtin[imm[pc]].func)(localr,ngc); if (top[0].type==vm_none) { - vm_error("native function error"); + die("native function error"); + return; } } @@ -791,7 +814,8 @@ inline void vm::o_slcbeg() { // +--------------+ (++top)[0]=ngc.alloc(vm_vec); if (top[-1].type!=vm_vec) { - vm_error("must slice a vector"); + die("must slice a vector"); + return; } } @@ -804,7 +828,8 @@ inline void vm::o_slc() { var val=(top--)[0]; var res=top[-1].vec().get_val(val.tonum()); if (res.type==vm_none) { - vm_error("out of range:"+std::to_string(val.tonum())); + die("out of range:"+std::to_string(val.tonum())); + return; } top[0].vec().elems.push_back(res); } @@ -829,10 +854,12 @@ inline void vm::o_slc2() { } if (num1<-size || num1>=size || num2<-size || num2>=size) { - vm_error("index "+std::to_string(num1)+":"+std::to_string(num2)+" out of range."); + die("index "+std::to_string(num1)+":"+std::to_string(num2)+" out of range."); + return; } else if (num1<=num2) { - for(i32 i=num1;i<=num2;++i) + for(i32 i=num1;i<=num2;++i) { aim.push_back(i>=0?ref[i]:ref[i+size]); + } } } @@ -863,11 +890,13 @@ inline void vm::o_mcallv() { if (vec.type==vm_vec) { memr=vec.vec().get_mem(val.tonum()); if (!memr) { - vm_error("out of range:"+std::to_string(val.tonum())); + die("out of range:"+std::to_string(val.tonum())); + return; } } else if (vec.type==vm_hash) { // do mcallh but use the mcallv way if (val.type!=vm_str) { - vm_error("must use string as the key"); + die("must use string as the key"); + return; } nas_hash& ref=vec.hash(); string& str=val.str(); @@ -877,14 +906,16 @@ inline void vm::o_mcallv() { memr=ref.get_mem(str); } } else { - vm_error("cannot get memory space in this type"); + die("cannot get memory space in this type"); + return; } } inline void vm::o_mcallh() { var hash=top[0]; // mcall hash, reserved on stack to avoid gc if (hash.type!=vm_hash) { - vm_error("must call a hash"); + die("must call a hash"); + return; } auto& ref=hash.hash(); auto& str=cstr[imm[pc]]; diff --git a/test/coroutine.nas b/test/coroutine.nas index ff938f0..391af2a 100644 --- a/test/coroutine.nas +++ b/test/coroutine.nas @@ -73,25 +73,30 @@ println("coroutine state:\e[91m ",coroutine.status(co),"\e[0m"); println("ok"); # pressure test -var productor=func(){ - for(var i=0;;i+=1) - coroutine.yield(i); -} -var total=1000; # ms -var co=coroutine.create(productor); -var tm=maketimestamp(); +var main=func(){ + var productor=func(){ + for(var i=0;;i+=1) + coroutine.yield(i); + } + var total=1000; # ms + var co=coroutine.create(productor); + var tm=maketimestamp(); -var counter=0; -var bar=process_bar.high_resolution_bar(40); -var consumer=func(){ - counter+=1; - for(var i=0;i<5;i+=1) - coroutine.resume(co); - var rate=(tm.elapsedMSec()+1)/total; - print(bar.bar(rate)," ",rate*100,"% \r"); + var counter=0; + var bar=process_bar.high_resolution_bar(40); + var consumer=func(){ + counter+=1; + for(var i=0;i<5;i+=1) + coroutine.resume(co); + var rate=(tm.elapsedMSec()+1)/total; + print(" ",bar.bar(rate)," ",int(rate*100),"% | ",counter," tasks \r"); + } + + tm.stamp(); + while(tm.elapsedMSec()