🚀 shrink code size & now import module can search lib file from local dir and dirs in PATH

This commit is contained in:
ValKmjolnir 2022-07-08 00:42:56 +08:00
parent c1d13ecd85
commit 5d4cff0aa8
9 changed files with 70 additions and 61 deletions

View File

@ -412,7 +412,8 @@ var unix=
chdir: func(path){return __builtin_chdir(path);},
environ: func(){return __builtin_environ();},
getcwd: func(){return __builtin_getcwd();},
getenv: func(envvar){return __builtin_getenv(envvar);}
getenv: func(envvar){return __builtin_getenv(envvar);},
getpath: func(){return split(os.platform()=="windows"?";":":",unix.getenv("PATH"));}
};
# dylib is the core hashmap for developers to load their own library.

16
nasal.h
View File

@ -129,7 +129,7 @@ double str2num(const char* str)
int utf8_hdchk(char head)
{
// RFC-2279 but in fact now we use RFC-3629 so nbytes is less than 4
// RFC-2279 but now we use RFC-3629 so nbytes is less than 4
uint8_t c=(uint8_t)head;
uint32_t nbytes=0;
if((c>>5)==0x06) // 110x xxxx (10xx xxxx)^1
@ -138,13 +138,6 @@ int utf8_hdchk(char head)
nbytes=2;
if((c>>3)==0x1e) // 1111 0xxx (10xx xxxx)^3
nbytes=3;
// these should not be true
if((c>>2)==0x3e) // 1111 10xx (10xx xxxx)^4
nbytes=4;
if((c>>1)==0x7e) // 1111 110x (10xx xxxx)^5
nbytes=5;
if(c==0xfe) // 1111 1110 (10xx xxxx)^6
nbytes=6;
return nbytes;
}
@ -153,7 +146,7 @@ std::string chrhex(const char c)
return {"0123456789abcdef"[(c&0xf0)>>4],"0123456789abcdef"[c&0x0f]};
}
std::string rawstr(const std::string& str)
std::string rawstr(const std::string& str,const size_t maxlen=0)
{
std::string ret("");
for(auto i:str)
@ -163,8 +156,7 @@ std::string rawstr(const std::string& str)
// if 'chcp65001' is not enabled, we output the hex
if(i<=0)
{
ret+="\\x";
ret+=chrhex(i);
ret+="\\x"+chrhex(i);
continue;
}
#endif
@ -185,6 +177,8 @@ std::string rawstr(const std::string& str)
default: ret+=i; break;
}
}
if(maxlen && ret.length()>maxlen)
ret=ret.substr(0,maxlen)+"...";
return ret;
}
#include "nasal_err.h"

View File

@ -341,7 +341,8 @@ nasal_ref builtin_split(nasal_ref* local,nasal_gc& gc)
size_t pos=s.find(deli,last);
while(pos!=std::string::npos)
{
vec.push_back(gc.newstr(s.substr(last,pos-last)));
if(pos>last)
vec.push_back(gc.newstr(s.substr(last,pos-last)));
last=pos+deli.length();
pos=s.find(deli,last);
}
@ -1209,7 +1210,7 @@ std::string tohex(uint32_t num)
}
return str;
}
std::string md5(std::string& source)
std::string md5(const std::string& source)
{
std::vector<uint32_t> buff;
uint32_t num=((source.length()+8)>>6)+1;
@ -1367,9 +1368,8 @@ nasal_ref builtin_corun(nasal_ref* local,nasal_gc& gc)
}
nasal_ref builtin_millisec(nasal_ref* local,nasal_gc& gc)
{
timeb now;
ftime(&now);
return {vm_num,(double)(now.time*1000+now.millitm)};
double res=std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
return {vm_num,res};
}
nasal_ref builtin_sysargv(nasal_ref* local,nasal_gc& gc)
{

View File

@ -1280,10 +1280,8 @@ void nasal_codegen::print_op(uint32_t index)
std::cout<<num_res[c.num&0x7fffffff]<<") sp-"<<(c.num>>31)<<"\n";
break;
case op_lnkeqc:
{
std::string tmp=rawstr(str_res[c.num&0x7fffffff]);
printf("0x%x (\"%.16s%s\") sp-%u\n",c.num&0x7fffffff,tmp.c_str(),tmp.length()>16?"...":"",c.num>>31);
}break;
printf("0x%x (\"%s\") sp-%u\n",c.num&0x7fffffff,rawstr(str_res[c.num&0x7fffffff],16).c_str(),c.num>>31);
break;
case op_addc: case op_subc: case op_mulc: case op_divc:
case op_lessc: case op_leqc: case op_grtc: case op_geqc:
case op_pnum:
@ -1302,10 +1300,7 @@ void nasal_codegen::print_op(uint32_t index)
case op_lnkc:
case op_callh: case op_mcallh:
case op_para: case op_defpara:case op_dynpara:
{
std::string tmp=rawstr(str_res[c.num]);
printf("0x%x (\"%.16s%s\")\n",c.num,tmp.c_str(),tmp.length()>16?"...":"");
}break;
printf("0x%x (\"%s\")\n",c.num,rawstr(str_res[c.num],16).c_str());break;
default:printf("\n");break;
}
}

View File

@ -7,6 +7,7 @@ private:
bool lib_loaded;
nasal_err& nerr;
std::vector<std::string> files;
std::vector<std::string> envpath;
bool imptchk(const nasal_ast&);
bool exist(const std::string&);
void linker(nasal_ast&,nasal_ast&&);
@ -15,11 +16,32 @@ private:
nasal_ast libimpt();
nasal_ast load(nasal_ast&,uint16_t);
public:
nasal_import(nasal_err& e):lib_loaded(false),nerr(e){}
nasal_import(nasal_err&);
void link(nasal_parse&,const std::string&);
const std::vector<std::string>& get_file() const {return files;}
};
nasal_import::nasal_import(nasal_err& e):lib_loaded(false),nerr(e){
#ifdef _WIN32
char sep=';';
#else
char sep=':';
#endif
std::string PATH=getenv("PATH");
size_t last=0;
size_t pos=PATH.find(sep,last);
while(pos!=std::string::npos)
{
std::string dirpath=PATH.substr(last,pos-last);
if(dirpath.length())
envpath.push_back(dirpath);
last=pos+1;
pos=PATH.find(sep,last);
}
if(last!=PATH.length())
envpath.push_back(PATH.substr(last,pos-last));
}
std::string nasal_import::path(const nasal_ast& node)
{
if(node[1].type()==ast_callf)
@ -31,8 +53,7 @@ std::string nasal_import::path(const nasal_ast& node)
#else
fpath+="\\"+node[i].str();
#endif
fpath+=".nas";
return fpath;
return fpath+".nas";
}
bool nasal_import::imptchk(const nasal_ast& node)
@ -44,7 +65,7 @@ bool nasal_import::imptchk(const nasal_ast& node)
|_callh:stl
|_callh:file
*/
if(node.type()==ast_call && node.size()>=2 && node[0].str()=="import" && node[1].type()==ast_callh)
if(node.type()==ast_call && node[0].str()=="import" && node.size()>=2 && node[1].type()==ast_callh)
{
for(size_t i=1;i<node.size();++i)
if(node[i].type()!=ast_callh)
@ -59,8 +80,8 @@ bool nasal_import::imptchk(const nasal_ast& node)
*/
return (
node.type()==ast_call &&
node.size()==2 &&
node[0].str()=="import" &&
node.size()==2 &&
node[1].type()==ast_callf &&
node[1].size()==1 &&
node[1][0].type()==ast_str
@ -111,19 +132,26 @@ nasal_ast nasal_import::fimpt(nasal_ast& node)
nasal_ast nasal_import::libimpt()
{
#ifdef _WIN32
#define nalib ".\\lib.nas"
#define nastllib ".\\stl\\lib.nas"
#define path_nalib "\\lib.nas"
#define path_stllib "\\stl\\lib.nas"
#else
#define nalib "./lib.nas"
#define nastllib "./stl/lib.nas"
#define path_nalib "/lib.nas"
#define path_stllib "/stl/lib.nas"
#endif
std::vector<std::string> libpath={nalib,nastllib};
for(auto& p:envpath)
{
libpath.push_back(p+path_nalib);
libpath.push_back(p+path_stllib);
}
nasal_lexer lex(nerr);
nasal_parse par(nerr);
const std::vector<std::string> libpath=
{
#ifdef __WIN32
".\\lib.nas",
".\\stl\\lib.nas"
#else
"./lib.nas",
"./stl/lib.nas"
#endif
};
std::string filename="";
for(auto& i:libpath)
if(access(i.c_str(),F_OK)!=-1)

View File

@ -401,7 +401,7 @@ void nasal_lexer::scan(const std::string& file)
void nasal_lexer::print()
{
for(auto& tok:tokens)
std::cout<<"("<<tok.line<<" | "<<rawstr(tok.str)<<")\n";
std::cout<<"("<<tok.line<<" | "<<rawstr(tok.str,128)<<")\n";
}
#endif

View File

@ -148,10 +148,8 @@ void nasal_vm::init(
/* set canary and program counter */
pc=0;
localr=nullptr;
memr=nullptr;
funcr=nil;
upvalr=nil;
localr=memr=nullptr;
funcr=upvalr=nil;
canary=stack+STACK_DEPTH-1; // stack[STACK_DEPTH-1]
top=stack;
}
@ -167,11 +165,7 @@ void nasal_vm::valinfo(nasal_ref& val)
case vm_cnt: printf("| cnt | " PRTINT64 "\n",val.cnt());break;
case vm_nil: printf("| nil |\n");break;
case vm_num: printf("| num | ");std::cout<<val.num()<<'\n';break;
case vm_str:
{
std::string tmp=rawstr(val.str());
printf("| str | <0x" PRTHEX64 "> %.16s%s\n",(uint64_t)p,tmp.c_str(),tmp.length()>16?"...":"");
}break;
case vm_str: printf("| str | <0x" PRTHEX64 "> %s\n",(uint64_t)p,rawstr(val.str(),16).c_str());break;
case vm_func: printf("| func | <0x" PRTHEX64 "> entry:0x%x\n",(uint64_t)p,val.func().entry);break;
case vm_upval:printf("| upval| <0x" PRTHEX64 "> [%u val]\n",(uint64_t)p,val.upval().size);break;
case vm_vec: printf("| vec | <0x" PRTHEX64 "> [%zu val]\n",(uint64_t)p,val.vec().size());break;
@ -204,10 +198,8 @@ void nasal_vm::bytecodeinfo(const char* header,const uint32_t p)
std::cout<<num_table[c.num&0x7fffffff]<<") sp-"<<(c.num>>31);
break;
case op_lnkeqc:
{
std::string tmp=rawstr(str_table[c.num&0x7fffffff]);
printf("0x%x (\"%.16s%s\") sp-%u",c.num&0x7fffffff,tmp.c_str(),tmp.length()>16?"...":"",c.num>>31);
}break;
printf("0x%x (\"%s\") sp-%u",c.num&0x7fffffff,rawstr(str_table[c.num&0x7fffffff],16).c_str(),c.num>>31);
break;
case op_addc: case op_subc: case op_mulc: case op_divc:
case op_lessc: case op_leqc: case op_grtc: case op_geqc:
case op_pnum:
@ -226,10 +218,8 @@ void nasal_vm::bytecodeinfo(const char* header,const uint32_t p)
case op_lnkc:
case op_callh: case op_mcallh:
case op_para: case op_defpara:case op_dynpara:
{
std::string tmp=rawstr(str_table[c.num]);
printf("0x%x (\"%.16s%s\")",c.num,tmp.c_str(),tmp.length()>16?"...":"");
}break;
printf("0x%x (\"%s\")",c.num,rawstr(str_table[c.num],16).c_str());
break;
default:printf("0x%x",c.num);break;
}
printf(" (%s:%u)\n",files[c.fidx].c_str(),c.line);

View File

@ -31,4 +31,4 @@ var find_all_files=func(path){
append(res,n);
unix.closedir(dd);
return res;
}
}

View File

@ -412,7 +412,8 @@ var unix=
chdir: func(path){return __builtin_chdir(path);},
environ: func(){return __builtin_environ();},
getcwd: func(){return __builtin_getcwd();},
getenv: func(envvar){return __builtin_getenv(envvar);}
getenv: func(envvar){return __builtin_getenv(envvar);},
getpath: func(){return split(os.platform()=="windows"?";":":",unix.getenv("PATH"));}
};
# dylib is the core hashmap for developers to load their own library.