change code structure

This commit is contained in:
ValKmjolnir 2021-11-02 22:44:42 +08:00
parent f8e2918561
commit cd08b2d1bb
9 changed files with 172 additions and 134 deletions

View File

@ -63,7 +63,6 @@ void err()
void execute(const std::string& file,const uint32_t cmd) void execute(const std::string& file,const uint32_t cmd)
{ {
// 33kb space on stack
nasal_lexer lexer; nasal_lexer lexer;
nasal_parse parse; nasal_parse parse;
nasal_import linker; nasal_import linker;

View File

@ -13,6 +13,7 @@ test:nasal
./nasal test/class.nas ./nasal test/class.nas
# ./nasal test/exception.nas # ./nasal test/exception.nas
./nasal -t test/fib.nas ./nasal -t test/fib.nas
./nasal test/filesystem.nas
./nasal test/hexdump.nas ./nasal test/hexdump.nas
./nasal test/json.nas ./nasal test/json.nas
./nasal test/leetcode1319.nas ./nasal test/leetcode1319.nas

View File

@ -4,32 +4,63 @@
enum ast_node enum ast_node
{ {
ast_null=0, ast_null=0,
ast_root, ast_root, // mark the root node of ast
ast_block, ast_block, // expression block
ast_file, // ast_file is only used to store which file the subtree is on,codegen will generate nothing ast_file, // used to store which file the sub-tree is on
ast_nil,ast_num,ast_str,ast_id,ast_func,ast_hash,ast_vec, ast_nil, // nil keyword
ast_hashmember, ast_num, // number, basic value type
ast_call,ast_callh,ast_callv,ast_callf, ast_str, // string, basic value type
ast_subvec, ast_id, // identifier
ast_args,ast_default,ast_dynamic, ast_func, // func keyword
ast_and,ast_or, ast_hash, // hash, basic value type
ast_equal, ast_vec, // vector, basic value type
ast_addeq,ast_subeq, ast_hashmember,// elements in hashmap
ast_multeq,ast_diveq, ast_call, // mark a sub-tree of calling an identifier
ast_lnkeq, ast_callh, // id.name
ast_cmpeq,ast_neq, ast_callv, // id[index]
ast_less,ast_leq, ast_callf, // id()
ast_grt,ast_geq, ast_subvec, // id[index:index]
ast_add,ast_sub, ast_args, // mark a sub-tree of function parameters
ast_mult,ast_div, ast_default, // default parameter
ast_link, ast_dynamic, // dynamic parameter
ast_neg,ast_not, ast_and, // and keyword
ast_trino, ast_or, // or keyword
ast_for,ast_forindex,ast_foreach,ast_while,ast_new_iter, ast_equal, // =
ast_conditional,ast_if,ast_elsif,ast_else, ast_addeq, // +=
ast_multi_id,ast_multi_scalar, ast_subeq, // -=
ast_def,ast_multi_assign, ast_multeq, // *=
ast_continue,ast_break,ast_ret ast_diveq, // /=
ast_lnkeq, // ~=
ast_cmpeq, // ==
ast_neq, // !=
ast_less, // <
ast_leq, // <=
ast_grt, // >
ast_geq, // >=
ast_add, // +
ast_sub, // -
ast_mult, // *
ast_div, // /
ast_link, // ~
ast_neg, // -
ast_not, // ~
ast_trino, // ?:
ast_for, // for keyword
ast_forindex,// forindex keyword
ast_foreach, // foreach keyword
ast_while, // while
ast_new_iter,// iterator, used in forindex/foreach
ast_conditional,// mark a sub-tree of conditional expression
ast_if, // if keyword
ast_elsif, // elsif keyword
ast_else, // else keyword
ast_multi_id,// multi identifiers sub-tree
ast_multi_scalar,// multi value sub-tree
ast_def, // definition
ast_multi_assign,// multi assignment sub-tree
ast_continue,// continue keyword
ast_break, // break keyword
ast_ret // return keyword
}; };
const char* ast_name[]= const char* ast_name[]=
@ -38,29 +69,61 @@ const char* ast_name[]=
"root", "root",
"block", "block",
"file", "file",
"nil","num","str","id","func","hash","vec", "nil",
"num",
"str",
"id",
"func",
"hash",
"vec",
"hashmember", "hashmember",
"call","callh","callv","callf", "call",
"callh",
"callv",
"callf",
"subvec", "subvec",
"args","default","dynamic", "args",
"and","or", "default",
"dynamic",
"and",
"or",
"=", "=",
"+=","-=", "+=",
"*=","/=", "-=",
"*=",
"/=",
"~=", "~=",
"==","!=", "==",
"<","<=", "!=",
">",">=", "<",
"+","-", "<=",
"*","/", ">",
">=",
"+",
"-",
"*",
"/",
"~", "~",
"unary-","unary!", "unary-",
"unary!",
"trino", "trino",
"for","forindex","foreach","while","iter", "for",
"conditional","if","elsif","else", "forindex",
"multi_id","multi_scalar", "foreach",
"def","multi_assign", "while",
"continue","break","return" "iter",
"conditional",
"if",
"elsif",
"else",
"multi_id",
"multi_scalar",
"def",
"multi_assign",
"continue",
"break",
"return",
nullptr
}; };
class nasal_ast class nasal_ast

View File

@ -197,11 +197,11 @@ private:
uint16_t fileindex; uint16_t fileindex;
uint32_t in_forindex; uint32_t in_forindex;
uint32_t in_foreach; uint32_t in_foreach;
const std::string* file;
std::unordered_map<double,int> num_table; std::unordered_map<double,int> num_table;
std::unordered_map<std::string,int> str_table; std::unordered_map<std::string,int> str_table;
std::vector<double> num_res; std::vector<double> num_res;
std::vector<std::string> str_res; std::vector<std::string> str_res;
std::vector<std::string> file;
std::vector<opcode> code; std::vector<opcode> code;
std::list<std::vector<int>> continue_ptr; std::list<std::vector<int>> continue_ptr;
std::list<std::vector<int>> break_ptr; std::list<std::vector<int>> break_ptr;
@ -1146,20 +1146,9 @@ void nasal_codegen::ret_gen(const nasal_ast& ast)
void nasal_codegen::compile(const nasal_parse& parse,const nasal_import& import) void nasal_codegen::compile(const nasal_parse& parse,const nasal_import& import)
{ {
error=0; error=in_foreach=in_forindex=0;
in_foreach=0;
in_forindex=0;
fileindex=0; fileindex=0;
file=import.get_file().data();
num_table.clear();
str_table.clear();
num_res.clear();
str_res.clear();
file=import.get_file();
code.clear();
global.clear();
local.clear();
// search symbols first // search symbols first
find_symbol(parse.ast()); find_symbol(parse.ast());
@ -1263,7 +1252,7 @@ void nasal_codegen::print_op(uint32_t index)
void nasal_codegen::print() void nasal_codegen::print()
{ {
for(auto num:num_res) for(auto& num:num_res)
std::cout<<".number "<<num<<'\n'; std::cout<<".number "<<num<<'\n';
for(auto& str:str_res) for(auto& str:str_res)
std::cout<<".symbol \""<<rawstr(str)<<"\"\n"; std::cout<<".symbol \""<<rawstr(str)<<"\"\n";

View File

@ -5,8 +5,6 @@ class nasal_import
{ {
private: private:
uint32_t error; uint32_t error;
nasal_lexer lex;
nasal_parse par;
std::vector<std::string> files; std::vector<std::string> files;
void die(const std::string&,const char*); void die(const std::string&,const char*);
bool check_import(const nasal_ast&); bool check_import(const nasal_ast&);
@ -67,6 +65,8 @@ void nasal_import::linker(nasal_ast& root,nasal_ast&& add_root)
nasal_ast nasal_import::file_import(nasal_ast& node) nasal_ast nasal_import::file_import(nasal_ast& node)
{ {
nasal_lexer lex;
nasal_parse par;
// get filename and set node to ast_null // get filename and set node to ast_null
std::string filename=node[1][0].str(); std::string filename=node[1][0].str();
node.clear(); node.clear();

View File

@ -101,10 +101,10 @@ private:
uint32_t error; uint32_t error;
uint32_t line; uint32_t line;
uint32_t ptr; uint32_t ptr;
size_t size;
std::string code; std::string code;
std::string res; std::string res;
std::vector<token> tokens; std::vector<token> tokens;
uint32_t get_type(const std::string&); uint32_t get_type(const std::string&);
void die(const char*); void die(const char*);
void open(const std::string&); void open(const std::string&);
@ -120,7 +120,6 @@ public:
void nasal_lexer::open(const std::string& file) void nasal_lexer::open(const std::string& file)
{ {
error=0;
std::ifstream fin(file,std::ios::binary); std::ifstream fin(file,std::ios::binary);
if(fin.fail()) if(fin.fail())
{ {
@ -152,7 +151,7 @@ void nasal_lexer::die(const char* info)
std::string nasal_lexer::id_gen() std::string nasal_lexer::id_gen()
{ {
std::string str=""; std::string str="";
while(ptr<size && (ID(res[ptr])||DIGIT(res[ptr]))) while(ptr<res.size() && (ID(res[ptr])||DIGIT(res[ptr])))
str+=res[ptr++]; str+=res[ptr++];
code+=str; code+=str;
return str; return str;
@ -161,11 +160,11 @@ std::string nasal_lexer::id_gen()
std::string nasal_lexer::num_gen() std::string nasal_lexer::num_gen()
{ {
// generate hex number // generate hex number
if(ptr+1<size && res[ptr]=='0' && res[ptr+1]=='x') if(ptr+1<res.size() && res[ptr]=='0' && res[ptr+1]=='x')
{ {
std::string str="0x"; std::string str="0x";
ptr+=2; ptr+=2;
while(ptr<size && HEX(res[ptr])) while(ptr<res.size() && HEX(res[ptr]))
str+=res[ptr++]; str+=res[ptr++];
code+=str; code+=str;
if(str.length()<3)// "0x" if(str.length()<3)// "0x"
@ -173,11 +172,11 @@ std::string nasal_lexer::num_gen()
return str; return str;
} }
// generate oct number // generate oct number
else if(ptr+1<size && res[ptr]=='0' && res[ptr+1]=='o') else if(ptr+1<res.size() && res[ptr]=='0' && res[ptr+1]=='o')
{ {
std::string str="0o"; std::string str="0o";
ptr+=2; ptr+=2;
while(ptr<size && OCT(res[ptr])) while(ptr<res.size() && OCT(res[ptr]))
str+=res[ptr++]; str+=res[ptr++];
code+=str; code+=str;
if(str.length()<3)// "0o" if(str.length()<3)// "0o"
@ -187,12 +186,12 @@ std::string nasal_lexer::num_gen()
// generate dec number // generate dec number
// dec number -> [0~9][0~9]*(.[0~9]*)(e|E(+|-)0|[1~9][0~9]*) // dec number -> [0~9][0~9]*(.[0~9]*)(e|E(+|-)0|[1~9][0~9]*)
std::string str=""; std::string str="";
while(ptr<size && DIGIT(res[ptr])) while(ptr<res.size() && DIGIT(res[ptr]))
str+=res[ptr++]; str+=res[ptr++];
if(ptr<size && res[ptr]=='.') if(ptr<res.size() && res[ptr]=='.')
{ {
str+=res[ptr++]; str+=res[ptr++];
while(ptr<size && DIGIT(res[ptr])) while(ptr<res.size() && DIGIT(res[ptr]))
str+=res[ptr++]; str+=res[ptr++];
// "xxxx." is not a correct number // "xxxx." is not a correct number
if(str.back()=='.') if(str.back()=='.')
@ -202,12 +201,12 @@ std::string nasal_lexer::num_gen()
return "0"; return "0";
} }
} }
if(ptr<size && (res[ptr]=='e' || res[ptr]=='E')) if(ptr<res.size() && (res[ptr]=='e' || res[ptr]=='E'))
{ {
str+=res[ptr++]; str+=res[ptr++];
if(ptr<size && (res[ptr]=='-' || res[ptr]=='+')) if(ptr<res.size() && (res[ptr]=='-' || res[ptr]=='+'))
str+=res[ptr++]; str+=res[ptr++];
while(ptr<size && DIGIT(res[ptr])) while(ptr<res.size() && DIGIT(res[ptr]))
str+=res[ptr++]; str+=res[ptr++];
// "xxxe(-|+)" is not a correct number // "xxxe(-|+)" is not a correct number
if(str.back()=='e' || str.back()=='E' || str.back()=='-' || str.back()=='+') if(str.back()=='e' || str.back()=='E' || str.back()=='-' || str.back()=='+')
@ -226,7 +225,7 @@ std::string nasal_lexer::str_gen()
std::string str=""; std::string str="";
char begin=res[ptr]; char begin=res[ptr];
code+=begin; code+=begin;
while(++ptr<size && res[ptr]!=begin) while(++ptr<res.size() && res[ptr]!=begin)
{ {
code+=res[ptr]; code+=res[ptr];
if(res[ptr]=='\n') if(res[ptr]=='\n')
@ -234,7 +233,7 @@ std::string nasal_lexer::str_gen()
code=""; code="";
++line; ++line;
} }
if(res[ptr]=='\\' && ptr+1<size) if(res[ptr]=='\\' && ptr+1<res.size())
{ {
code+=res[++ptr]; code+=res[++ptr];
switch(res[ptr]) switch(res[ptr])
@ -258,7 +257,7 @@ std::string nasal_lexer::str_gen()
str+=res[ptr]; str+=res[ptr];
} }
// check if this string ends with a " or ' // check if this string ends with a " or '
if(ptr++>=size) if(ptr++>=res.size())
{ {
die("get EOF when generating string."); die("get EOF when generating string.");
return str; return str;
@ -272,16 +271,13 @@ std::string nasal_lexer::str_gen()
void nasal_lexer::scan(const std::string& file) void nasal_lexer::scan(const std::string& file)
{ {
open(file); open(file);
tokens.clear();
line=1; line=1;
ptr=0; error=ptr=0;
code="";
size=res.size();
std::string str; std::string str;
while(ptr<size) while(ptr<res.size())
{ {
while(ptr<size && (res[ptr]==' ' || res[ptr]=='\n' || res[ptr]=='\t' || res[ptr]=='\r' || res[ptr]<0)) while(ptr<res.size() && (res[ptr]==' ' || res[ptr]=='\n' || res[ptr]=='\t' || res[ptr]=='\r' || res[ptr]<0))
{ {
// these characters will be ignored, and '\n' will cause ++line // these characters will be ignored, and '\n' will cause ++line
code+=res[ptr]; code+=res[ptr];
@ -291,7 +287,7 @@ void nasal_lexer::scan(const std::string& file)
code=""; code="";
} }
} }
if(ptr>=size) break; if(ptr>=res.size()) break;
if(ID(res[ptr])) if(ID(res[ptr]))
{ {
str=id_gen(); str=id_gen();
@ -315,7 +311,7 @@ void nasal_lexer::scan(const std::string& file)
else if(res[ptr]=='.') else if(res[ptr]=='.')
{ {
str="."; str=".";
if(ptr+2<size && res[ptr+1]=='.' && res[ptr+2]=='.') if(ptr+2<res.size() && res[ptr+1]=='.' && res[ptr+2]=='.')
str+=".."; str+="..";
ptr+=str.length(); ptr+=str.length();
code+=str; code+=str;
@ -325,13 +321,13 @@ void nasal_lexer::scan(const std::string& file)
{ {
// get calculation operator // get calculation operator
str=res[ptr++]; str=res[ptr++];
if(ptr<size && res[ptr]=='=') if(ptr<res.size() && res[ptr]=='=')
str+=res[ptr++]; str+=res[ptr++];
code+=str; code+=str;
tokens.push_back({line,get_type(str),str}); tokens.push_back({line,get_type(str),str});
} }
else if(NOTE(res[ptr]))// avoid note, after this process ptr will point to a '\n', so next loop line counter+1 else if(NOTE(res[ptr]))// avoid note, after this process ptr will point to a '\n', so next loop line counter+1
while(++ptr<size && res[ptr]!='\n'); while(++ptr<res.size() && res[ptr]!='\n');
else else
{ {
code+=res[ptr++]; code+=res[ptr++];
@ -339,7 +335,7 @@ void nasal_lexer::scan(const std::string& file)
} }
} }
tokens.push_back({line,tok_eof,"eof"}); tokens.push_back({line,tok_eof,"eof"});
res.clear(); code=res="";
} }
void nasal_lexer::print() void nasal_lexer::print()

View File

@ -43,12 +43,11 @@ class nasal_parse
private: private:
uint32_t ptr; uint32_t ptr;
uint32_t error; uint32_t error;
uint32_t in_func; // count when generating function block uint32_t in_func; // count function block
uint32_t in_loop; // count when generating loop block uint32_t in_loop; // count loop block
const token* tokens;// ref from nasal_lexer
nasal_ast root; nasal_ast root;
std::vector<token> tokens;
std::vector<token> error_token;
void die(uint32_t,const std::string&); void die(uint32_t,const std::string&);
void match(uint32_t type,const char* info=nullptr); void match(uint32_t type,const char* info=nullptr);
bool check_comma(const uint32_t*); bool check_comma(const uint32_t*);
@ -84,8 +83,8 @@ private:
nasal_ast callf(); nasal_ast callf();
nasal_ast subvec(); nasal_ast subvec();
nasal_ast definition(); nasal_ast definition();
nasal_ast var_incurve_def(); nasal_ast incurve_def();
nasal_ast var_outcurve_def(); nasal_ast outcurve_def();
nasal_ast multi_id(); nasal_ast multi_id();
nasal_ast multi_scalar(bool); nasal_ast multi_scalar(bool);
nasal_ast multi_assgin(); nasal_ast multi_assgin();
@ -107,38 +106,19 @@ public:
}; };
void nasal_parse::compile(const nasal_lexer& lexer) void nasal_parse::compile(const nasal_lexer& lexer)
{ {
tokens=lexer.get_tokens(); tokens=lexer.get_tokens().data();
ptr=in_func=in_loop=error=0; ptr=in_func=in_loop=error=0;
error_token.clear();
root={1,ast_root}; root={1,ast_root};
while(tokens[ptr].type!=tok_eof) while(tokens[ptr].type!=tok_eof)
{ {
uint32_t err_tok_size=error_token.size();
root.add(expr()); root.add(expr());
if(tokens[ptr].type==tok_semi) if(tokens[ptr].type==tok_semi)
match(tok_semi); match(tok_semi);
// if detect error token, avoid checking semicolon
else if(error_token.size()>err_tok_size)
continue;
// the last expression can be recognized without semi // the last expression can be recognized without semi
else if(need_semi_check(root.child().back()) && tokens[ptr].type!=tok_eof) else if(need_semi_check(root.child().back()) && tokens[ptr].type!=tok_eof)
die(error_line,"expected \";\""); die(error_line,"expected \";\"");
} }
if(!error_token.size())
return;
++error;
std::cout<<"[parse] line";
uint32_t err_line=0;
for(auto& tok:error_token)
if(err_line!=tok.line)
{
std::cout<<' '<<tok.line;
err_line=tok.line;
}
std::cout
<<" have fatal syntax errors."
<<"check \'(\',\'[\',\'{\',\')\',\']\',\'}\' match or not.\n";
} }
void nasal_parse::die(uint32_t line,const std::string& info) void nasal_parse::die(uint32_t line,const std::string& info)
{ {
@ -476,7 +456,10 @@ nasal_ast nasal_parse::expr()
case tok_break: return break_expr(); break; case tok_break: return break_expr(); break;
case tok_ret: return ret_expr(); break; case tok_ret: return ret_expr(); break;
case tok_semi: break; case tok_semi: break;
default:error_token.push_back(tokens[ptr]);++ptr;break; default:
die(error_line,"incorrect token <"+tokens[ptr].str+">");
++ptr;
break;
} }
return {tokens[ptr].line,ast_null}; return {tokens[ptr].line,ast_null};
} }
@ -493,13 +476,9 @@ nasal_ast nasal_parse::exprs()
match(tok_lbrace); match(tok_lbrace);
while(tokens[ptr].type!=tok_rbrace && tokens[ptr].type!=tok_eof) while(tokens[ptr].type!=tok_rbrace && tokens[ptr].type!=tok_eof)
{ {
uint32_t err_tok_size=error_token.size();
node.add(expr()); node.add(expr());
if(tokens[ptr].type==tok_semi) if(tokens[ptr].type==tok_semi)
match(tok_semi); match(tok_semi);
// if detect error token, avoid checking semicolon
else if(error_token.size()>err_tok_size)
continue;
// the last expression can be recognized without semi // the last expression can be recognized without semi
else if(need_semi_check(node.child().back()) && tokens[ptr].type!=tok_rbrace) else if(need_semi_check(node.child().back()) && tokens[ptr].type!=tok_rbrace)
die(error_line,"expected \";\""); die(error_line,"expected \";\"");
@ -766,12 +745,12 @@ nasal_ast nasal_parse::definition()
switch(tokens[ptr].type) switch(tokens[ptr].type)
{ {
case tok_id: node.add(id());match(tok_id);break; case tok_id: node.add(id());match(tok_id);break;
case tok_lcurve: node.add(var_outcurve_def());break; case tok_lcurve: node.add(outcurve_def());break;
default: die(error_line,"expected identifier");break; default: die(error_line,"expected identifier");break;
} }
} }
else if(tokens[ptr].type==tok_lcurve) else if(tokens[ptr].type==tok_lcurve)
node.add(var_incurve_def()); node.add(incurve_def());
match(tok_eq); match(tok_eq);
if(tokens[ptr].type==tok_lcurve) if(tokens[ptr].type==tok_lcurve)
node.add(check_multi_scalar()?multi_scalar(false):calc()); node.add(check_multi_scalar()?multi_scalar(false):calc());
@ -784,7 +763,7 @@ nasal_ast nasal_parse::definition()
die(node[0].line(),"too much or lack values in multi-definition"); die(node[0].line(),"too much or lack values in multi-definition");
return node; return node;
} }
nasal_ast nasal_parse::var_incurve_def() nasal_ast nasal_parse::incurve_def()
{ {
match(tok_lcurve); match(tok_lcurve);
match(tok_var); match(tok_var);
@ -792,7 +771,7 @@ nasal_ast nasal_parse::var_incurve_def()
match(tok_rcurve); match(tok_rcurve);
return node; return node;
} }
nasal_ast nasal_parse::var_outcurve_def() nasal_ast nasal_parse::outcurve_def()
{ {
match(tok_lcurve); match(tok_lcurve);
nasal_ast node=multi_id(); nasal_ast node=multi_id();

View File

@ -7,18 +7,18 @@ private:
/* values of nasal_vm */ /* values of nasal_vm */
uint32_t pc; // program counter uint32_t pc; // program counter
uint32_t offset; // used to load default parameters to a new function uint32_t offset; // used to load default parameters to a new function
const double* num_table;// const numbers, ref from nasal_codegen
const std::string* str_table;// const symbols, ref from nasal_codegen
std::stack<uint32_t> ret; // stack to store return pc std::stack<uint32_t> ret; // stack to store return pc
std::stack<nasal_func*> func_stk; // stack to store function, used to get upvalues std::stack<nasal_func*> func_stk; // stack to store function, used to get upvalues
std::stack<int> counter; // iterator stack for forindex/foreach std::stack<int> counter; // iterator stack for forindex/foreach
const double* num_table;// const numbers
std::vector<std::string> str_table;// const symbols
std::vector<uint32_t> imm; // immediate number std::vector<uint32_t> imm; // immediate number
nasal_ref* mem_addr; // used for mem_call nasal_ref* mem_addr; // used for mem_call
/* garbage collector */ /* garbage collector */
nasal_gc gc; nasal_gc gc;
/* values used for debug */ /* values used for debug */
std::vector<opcode> bytecode; const opcode* bytecode; // ref from nasal_codegen
std::vector<std::string> files; const std::string* files; // ref from nasal_import
void init( void init(
const std::vector<std::string>&, const std::vector<std::string>&,
@ -130,8 +130,8 @@ void nasal_vm::init(
{ {
gc.init(strs); gc.init(strs);
num_table=nums.data(); num_table=nums.data();
str_table=strs; str_table=strs.data();
files=filenames; files=filenames.data();
} }
void nasal_vm::clear() void nasal_vm::clear()
{ {
@ -140,7 +140,6 @@ void nasal_vm::clear()
ret.pop(); ret.pop();
while(!counter.empty()) while(!counter.empty())
counter.pop(); counter.pop();
str_table.clear();
imm.clear(); imm.clear();
} }
void nasal_vm::valinfo(nasal_ref& val) void nasal_vm::valinfo(nasal_ref& val)
@ -804,7 +803,7 @@ inline void nasal_vm::opr_mcallh()
if(hash.type!=vm_hash) if(hash.type!=vm_hash)
die("mcallh: must call a hash"); die("mcallh: must call a hash");
nasal_hash& ref=*hash.hash(); nasal_hash& ref=*hash.hash();
std::string& str=str_table[imm[pc]]; const std::string& str=str_table[imm[pc]];
mem_addr=ref.get_mem(str); mem_addr=ref.get_mem(str);
if(!mem_addr) // create a new key if(!mem_addr) // create a new key
{ {
@ -856,9 +855,9 @@ void nasal_vm::run(
&&mcallg, &&mcalll, &&mupval, &&mcallv, &&mcallg, &&mcalll, &&mupval, &&mcallv,
&&mcallh, &&ret, &&vmexit &&mcallh, &&ret, &&vmexit
}; };
bytecode=gen.get_code(); bytecode=gen.get_code().data();
std::vector<const void*> code; std::vector<const void*> code;
for(auto& i:bytecode) for(auto& i:gen.get_code())
{ {
code.push_back(opr_table[i.op]); code.push_back(opr_table[i.op]);
imm.push_back(i.num); imm.push_back(i.num);

12
test/filesystem.nas Normal file
View File

@ -0,0 +1,12 @@
import("lib.nas");
var fd=io.open("test/filesystem.nas");
while((var line=io.readln(fd))!=nil)
println(line);
io.close(fd);
println(io.stat("test/filesystem.nas"));
var dd=unix.opendir("test");
while((var name=unix.readdir(dd))!=nil)
println(name);
unix.closedir(dd);