change function name and cli format

This commit is contained in:
ValKmjolnir 2021-10-14 23:22:28 +08:00
parent 58ea303202
commit 577546763f
12 changed files with 203 additions and 213 deletions

View File

@ -904,7 +904,7 @@ nasal_ref builtin_print(std::vector<nasal_ref>& local,nasal_gc& gc)
``` ```
After that, register the built-in function's name(in nasal) and the function's pointer in this table: After that, register the built-in function's name(in nasal) and the function's pointer in this table:
```C++ ```C++
struct FUNC_TABLE struct func
{ {
const char* name; const char* name;
nasal_ref (*func)(std::vector<nasal_ref>&,nasal_gc&); nasal_ref (*func)(std::vector<nasal_ref>&,nasal_gc&);

132
main.cpp
View File

@ -1,24 +1,28 @@
#include "nasal.h" #include "nasal.h"
#define VM_LEXINFO 1
#define VM_ASTINFO 2
#define VM_CODEINFO 4
#define VM_EXECTIME 8
#define VM_OPCALLNUM 16
#define VM_EXEC 32
void help_cmd() void help_cmd()
{ {
std::cout std::cout
#ifdef _WIN32 #ifdef _WIN32
<<"use command \'chcp 65001\' if want to use unicode.\n" <<"use command \'chcp 65001\' if want to use unicode.\n"
#endif #endif
<<"nasal [option]\n" <<"nasal <option>\n"
<<"option:\n" <<"option:\n"
<<" -h, --help | get help.\n" <<" -h, --help | get help.\n"
<<" -v, --version | get version of nasal interpreter.\n\n" <<" -v, --version | get version of nasal interpreter.\n\n"
<<"nasal [file]\n" <<"nasal <file>\n"
<<"file:\n" <<"file:\n"
<<" input file name to execute script file.\n\n" <<" input file name to execute script file.\n\n"
<<"nasal [option] [file]\n" <<"nasal [options] <file>\n"
<<"option:\n" <<"option:\n"
<<" -l, --lex | view token info.\n" <<" -l, --lex | view token info.\n"
<<" -a, --ast | view abstract syntax tree.\n" <<" -a, --ast | view abstract syntax tree.\n"
<<" -c, --code | view bytecode.\n" <<" -c, --code | view bytecode.\n"
<<" -e, --exec | execute script file.\n"
<<" -t, --time | execute and get the running time.\n" <<" -t, --time | execute and get the running time.\n"
<<" -o, --opcnt | count operands while running.\n" <<" -o, --opcnt | count operands while running.\n"
<<"file:\n" <<"file:\n"
@ -47,98 +51,94 @@ void die(const char* stage,const std::string& filename)
{ {
std::cout<<"["<<stage<<"] in <"<<filename<<">: error(s) occurred,stop.\n"; std::cout<<"["<<stage<<"] in <"<<filename<<">: error(s) occurred,stop.\n";
std::exit(1); std::exit(1);
return;
} }
void execute(const std::string& file,const std::string& command) void cmderr()
{
std::cout
<<"invalid argument(s).\n"
<<"use nasal -h to get help.\n";
std::exit(1);
}
void execute(const std::string& file,const uint16_t cmd)
{ {
nasal_lexer lexer; nasal_lexer lexer;
nasal_parse parse; nasal_parse parse;
nasal_import import; nasal_import import;
nasal_codegen codegen; nasal_codegen codegen;
nasal_vm vm; nasal_vm vm;
lexer.openfile(file); lexer.open(file);
lexer.scanner(); lexer.scan();
if(lexer.get_error()) if(lexer.err())
die("lexer",file); die("lexer",file);
if(command=="--lex" || command=="-l") if(cmd&VM_LEXINFO)
{ lexer.print();
lexer.print_token(); parse.compile(lexer.get_tokens());
return; if(parse.err())
}
parse.main_process(lexer.get_token_list());
if(parse.get_error())
die("parse",file); die("parse",file);
if(command=="--ast" || command=="-a") if(cmd&VM_ASTINFO)
{ parse.get_root().print(0);
parse.get_root().print_ast(0);
return;
}
// first used file is itself // first used file is itself
import.link(parse.get_root(),file); import.link(parse.get_root(),file);
if(import.get_error()) if(import.err())
die("import",file); die("import",file);
codegen.main_progress(import.get_root(),import.get_file()); codegen.compile(import.get_root(),import.get_file());
if(codegen.get_error()) if(codegen.err())
die("code",file); die("code",file);
if(command=="--code" || command=="-c") if(cmd&VM_CODEINFO)
{ codegen.print();
codegen.print_byte_code();
return;
}
vm.init( vm.init(
codegen.get_str_table(), codegen.get_strs(),
codegen.get_num_table(), codegen.get_nums(),
import.get_file() import.get_file()
); );
if(command=="--exec" || command=="-e" || command=="--opcnt" || command=="-o") if(cmd&VM_EXECTIME)
vm.run(codegen.get_exec_code(),command=="--opcnt" || command=="-o");
else if(command=="--time" || command=="-t")
{ {
clock_t begin=clock(); clock_t t=clock();
vm.run(codegen.get_exec_code(),false); vm.run(codegen.get_code(),cmd&VM_OPCALLNUM);
std::cout<<"process exited after "<<((double)(clock()-begin))/CLOCKS_PER_SEC<<"s.\n"; std::cout<<"process exited after "<<((double)(clock()-t))/CLOCKS_PER_SEC<<"s.\n";
} }
else if(cmd&VM_EXEC)
vm.run(codegen.get_code(),cmd&VM_OPCALLNUM);
vm.clear(); vm.clear();
return; return;
} }
int main(int argc,const char* argv[]) int main(int argc,const char* argv[])
{ {
std::string command,file; std::string filename;
uint16_t cmd=0;
if(argc==2 && (!strcmp(argv[1],"-v") || !strcmp(argv[1],"--version"))) if(argc==2 && (!strcmp(argv[1],"-v") || !strcmp(argv[1],"--version")))
logo(); logo();
else if(argc==2 && (!strcmp(argv[1],"-h") || !strcmp(argv[1],"--help"))) else if(argc==2 && (!strcmp(argv[1],"-h") || !strcmp(argv[1],"--help")))
help_cmd(); help_cmd();
else if(argc==2 && argv[1][0]!='-') else if(argc==2 && argv[1][0]!='-')
cmd|=VM_EXEC;
else if(argc>=3)
{ {
file=argv[1]; for(int i=1;i<argc-1;++i)
command="-e"; {
execute(file,command); std::string s(argv[i]);
} if(s=="--lex" || s=="-l")
else if(argc==3 && cmd|=VM_LEXINFO;
(!strcmp(argv[1],"--lex") || else if(s=="--ast" || s=="-a")
!strcmp(argv[1],"-l") || cmd|=VM_ASTINFO;
!strcmp(argv[1],"--ast") || else if(s=="--code" || s=="-c")
!strcmp(argv[1],"-a") || cmd|=VM_CODEINFO;
!strcmp(argv[1],"--code") || else if(s=="--opcnt" || s=="-o")
!strcmp(argv[1],"-c") || cmd|=VM_OPCALLNUM|VM_EXEC;
!strcmp(argv[1],"--exec") || else if(s=="--time" || s=="-t")
!strcmp(argv[1],"-e") || cmd|=VM_EXECTIME;
!strcmp(argv[1],"--opcnt")|| else
!strcmp(argv[1],"-o") || cmderr();
!strcmp(argv[1],"--time") || }
!strcmp(argv[1],"-t")))
{
file=argv[2];
command=argv[1];
execute(file,command);
} }
else else
{ cmderr();
std::cout if(argv[argc-1][0]=='-')
<<"invalid argument(s).\n" cmderr();
<<"use nasal -h to get help.\n"; if(cmd)
std::exit(1); execute(argv[argc-1],cmd);
}
return 0; return 0;
} }

24
nasal.h
View File

@ -1,6 +1,5 @@
#ifndef __NASAL_H__ #ifndef __NASAL_H__
#define __NASAL_H__ #define __NASAL_H__
#pragma GCC optimize(2) #pragma GCC optimize(2)
#include <stdint.h> #include <stdint.h>
@ -108,22 +107,23 @@ double str2num(const char* str)
/* /*
show raw string show raw string
*/ */
void raw_string(const std::string& str) std::string raw_string(const std::string& str)
{ {
std::string ret("");
for(auto i:str) for(auto i:str)
switch(i) switch(i)
{ {
case '\a': std::cout<<"\\a";break; case '\a': ret+="\\a";break;
case '\b': std::cout<<"\\b";break; case '\b': ret+="\\b";break;
case '\f': std::cout<<"\\f";break; case '\f': ret+="\\f";break;
case '\n': std::cout<<"\\n";break; case '\n': ret+="\\n";break;
case '\r': std::cout<<"\\r";break; case '\r': ret+="\\r";break;
case '\t': std::cout<<"\\t";break; case '\t': ret+="\\t";break;
case '\v': std::cout<<"\\v";break; case '\v': ret+="\\v";break;
case '\0': std::cout<<"\\0";break; case '\0': ret+="\\0";break;
default: std::cout<<i; break; default: ret+=i; break;
} }
return; return ret;
} }
#include "nasal_lexer.h" #include "nasal_lexer.h"
#include "nasal_ast.h" #include "nasal_ast.h"

View File

@ -50,36 +50,37 @@ const char* ast_name[]=
class nasal_ast class nasal_ast
{ {
private: private:
int line; uint32_t line;
int type; uint32_t type;
double num; double num;
std::string str; std::string str;
std::vector<nasal_ast> children; std::vector<nasal_ast> children;
public: public:
nasal_ast(){line=0;type=ast_null;} nasal_ast(){line=0;type=ast_null;}
nasal_ast(const int l,const int t){line=l;type=t;} nasal_ast(const uint32_t l,const uint32_t t){line=l;type=t;}
nasal_ast(const nasal_ast&); nasal_ast(const nasal_ast&);
nasal_ast(nasal_ast&&); nasal_ast(nasal_ast&&);
nasal_ast& operator=(const nasal_ast&); nasal_ast& operator=(const nasal_ast&);
nasal_ast& operator=(nasal_ast&&); nasal_ast& operator=(nasal_ast&&);
void print_ast(const int); void print(const int);
void clear(); void clear();
void add_child(nasal_ast&& ast){children.push_back(std::move(ast));} void add_child(nasal_ast&& ast){children.push_back(std::move(ast));}
void add_child(const nasal_ast& ast){children.push_back(ast);} void add_child(const nasal_ast& ast){children.push_back(ast);}
void set_line(const int l){line=l;} void set_line(const uint32_t l){line=l;}
void set_type(const int t){type=t;} void set_type(const uint32_t t){type=t;}
void set_str(const std::string& s){str=s;} void set_str(const std::string& s){str=s;}
void set_num(const double n){num=n;} void set_num(const double n){num=n;}
int get_line(){return line;}
int get_type(){return type;} uint32_t get_line(){return line;}
double get_num() {return num;} uint32_t get_type(){return type;}
std::string& get_str(){return str;} double get_num() {return num;}
std::string& get_str() {return str;}
std::vector<nasal_ast>& get_children(){return children;} std::vector<nasal_ast>& get_children(){return children;}
int get_line() const {return line;} uint32_t get_line() const {return line;}
int get_type() const {return type;} uint32_t get_type() const {return type;}
double get_num() const {return num;} double get_num() const {return num;}
const std::string& get_str() const {return str;} const std::string& get_str() const {return str;}
const std::vector<nasal_ast>& get_children() const {return children;} const std::vector<nasal_ast>& get_children() const {return children;}
}; };
@ -133,21 +134,18 @@ void nasal_ast::clear()
return; return;
} }
void nasal_ast::print_ast(const int depth) void nasal_ast::print(const int depth)
{ {
for(int i=0;i<depth;++i) for(int i=0;i<depth;++i)
std::cout<<"| "; std::cout<<"| ";
std::cout<<ast_name[type]; std::cout<<ast_name[type];
if(type==ast_str || type==ast_id || type==ast_default_arg || type==ast_dynamic_id || type==ast_callh) if(type==ast_str || type==ast_id || type==ast_default_arg || type==ast_dynamic_id || type==ast_callh)
{ std::cout<<":"<<raw_string(str);
std::cout<<":";
raw_string(str);
}
else if(type==ast_num || type==ast_file) else if(type==ast_num || type==ast_file)
std::cout<<":"<<num; std::cout<<":"<<num;
std::cout<<'\n'; std::cout<<'\n';
for(auto& i:children) for(auto& i:children)
i.print_ast(depth+1); i.print(depth+1);
return; return;
} }

View File

@ -62,8 +62,8 @@ nasal_ref builtin_err(const char* func_name,std::string info)
} }
// register builtin function's name and it's address here in this table below // register builtin function's name and it's address here in this table below
// this table must end with {"",nullptr} // this table must end with {nullptr,nullptr}
struct FUNC_TABLE struct func
{ {
const char* name; const char* name;
nasal_ref (*func)(std::vector<nasal_ref>&,nasal_gc&); nasal_ref (*func)(std::vector<nasal_ref>&,nasal_gc&);
@ -123,7 +123,7 @@ nasal_ref builtin_print(std::vector<nasal_ref>& local,nasal_gc& gc)
for(auto i:vec.vec()->elems) for(auto i:vec.vec()->elems)
switch(i.type) switch(i.type)
{ {
case vm_none: std::cout<<"undefined"; break; case vm_none: std::cout<<"null"; break;
case vm_nil: std::cout<<"nil"; break; case vm_nil: std::cout<<"nil"; break;
case vm_num: std::cout<<i.num(); break; case vm_num: std::cout<<i.num(); break;
case vm_str: std::cout<<*i.str(); break; case vm_str: std::cout<<*i.str(); break;

View File

@ -255,13 +255,13 @@ private:
void block_gen(const nasal_ast&); void block_gen(const nasal_ast&);
void ret_gen(const nasal_ast&); void ret_gen(const nasal_ast&);
public: public:
uint32_t get_error(){return error;} uint32_t err(){return error;}
void main_progress(const nasal_ast&,const std::vector<std::string>&); void compile(const nasal_ast&,const std::vector<std::string>&);
void print_op(uint32_t); void print_op(uint32_t);
void print_byte_code(); void print();
std::vector<std::string>& get_str_table(){return str_res_table;} std::vector<std::string>& get_strs(){return str_res_table;}
std::vector<double>& get_num_table(){return num_res_table;} std::vector<double>& get_nums(){return num_res_table;}
std::vector<opcode>& get_exec_code(){return exec_code;} std::vector<opcode>& get_code(){return exec_code;}
}; };
void nasal_codegen::die(const std::string info,const int line) void nasal_codegen::die(const std::string info,const int line)
@ -631,7 +631,7 @@ void nasal_codegen::mcall(const nasal_ast& ast)
void nasal_codegen::mcall_id(const nasal_ast& ast) void nasal_codegen::mcall_id(const nasal_ast& ast)
{ {
const std::string& str=ast.get_str(); const std::string& str=ast.get_str();
for(int i=0;builtin_func[i].name;++i) for(uint32_t i=0;builtin_func[i].name;++i)
if(builtin_func[i].name==str) if(builtin_func[i].name==str)
{ {
die("cannot change builtin function.",ast.get_line()); die("cannot change builtin function.",ast.get_line());
@ -1213,7 +1213,7 @@ void nasal_codegen::ret_gen(const nasal_ast& ast)
return; return;
} }
void nasal_codegen::main_progress(const nasal_ast& ast,const std::vector<std::string>& files) void nasal_codegen::compile(const nasal_ast& ast,const std::vector<std::string>& files)
{ {
error=0; error=0;
in_foreach=0; in_foreach=0;
@ -1326,25 +1326,19 @@ void nasal_codegen::print_op(uint32_t index)
case op_lnkc:case op_lnkeqc: case op_lnkc:case op_lnkeqc:
case op_callh:case op_mcallh: case op_callh:case op_mcallh:
case op_para:case op_defpara:case op_dynpara: case op_para:case op_defpara:case op_dynpara:
printf("0x%x (\"",code.num); printf("0x%x (\"%s\")\n",code.num,raw_string(str_res_table[code.num]).c_str());
raw_string(str_res_table[code.num]);
printf("\")\n");
break; break;
default:printf("\n");break; default:printf("\n");break;
} }
return; return;
} }
void nasal_codegen::print_byte_code() void nasal_codegen::print()
{ {
for(auto num:num_res_table) for(auto num:num_res_table)
std::cout<<".number "<<num<<'\n'; std::cout<<".number "<<num<<'\n';
for(auto& str:str_res_table) for(auto& str:str_res_table)
{ std::cout<<".symbol \""<<raw_string(str)<<"\"\n";
std::cout<<".symbol \"";
raw_string(str);
std::cout<<"\"\n";
}
for(uint32_t i=0;i<exec_code.size();++i) for(uint32_t i=0;i<exec_code.size();++i)
print_op(i); print_op(i);
return; return;

View File

@ -3,11 +3,11 @@
enum nasal_type enum nasal_type
{ {
// none-gc object /* none-gc object */
vm_none=0, vm_none=0,
vm_nil, vm_nil,
vm_num, vm_num,
// gc object /* gc object */
vm_str, vm_str,
vm_func, vm_func,
vm_vec, vm_vec,
@ -17,19 +17,19 @@ enum nasal_type
}; };
// change parameters here to make your own efficient gc // change parameters here to make your own efficient gc
// better set bigger number on vm_num and vm_vec // better set bigger number on vm_vec
const uint32_t increment[vm_type_size]= const uint32_t increment[vm_type_size]=
{ {
// none-gc object /* none-gc object */
0, // vm_none, error type 0, // vm_none, error type
0, // vm_nil 0, // vm_nil
0, // vm_num 0, // vm_num
// gc object /* gc object */
2048, // vm_str 2048, // vm_str
1024, // vm_func 1024, // vm_func
8192, // vm_vec 8192, // vm_vec
512, // vm_hash 512, // vm_hash
0 // vm_obj 128 // vm_obj
}; };
// declaration of nasal value type // declaration of nasal value type
@ -83,7 +83,7 @@ struct nasal_ref// 16 bytes
inline nasal_vec* vec (); inline nasal_vec* vec ();
inline nasal_hash* hash(); inline nasal_hash* hash();
inline nasal_func* func(); inline nasal_func* func();
inline void* obj (); inline void*& obj ();
}; };
struct nasal_vec// 24 bytes struct nasal_vec// 24 bytes
@ -282,6 +282,7 @@ nasal_val::nasal_val(uint8_t val_type)
case vm_vec: ptr.vec=new nasal_vec; break; case vm_vec: ptr.vec=new nasal_vec; break;
case vm_hash: ptr.hash=new nasal_hash; break; case vm_hash: ptr.hash=new nasal_hash; break;
case vm_func: ptr.func=new nasal_func; break; case vm_func: ptr.func=new nasal_func; break;
case vm_obj: ptr.obj=nullptr; break;
} }
return; return;
} }
@ -293,7 +294,12 @@ nasal_val::~nasal_val()
case vm_vec: delete ptr.vec; break; case vm_vec: delete ptr.vec; break;
case vm_hash: delete ptr.hash; break; case vm_hash: delete ptr.hash; break;
case vm_func: delete ptr.func; break; case vm_func: delete ptr.func; break;
case vm_obj:
if(ptr.obj)
free(ptr.obj);
break;
} }
ptr.obj=nullptr;
type=vm_nil; type=vm_nil;
return; return;
} }
@ -313,12 +319,12 @@ std::string nasal_ref::to_string()
return std::to_string(num()); return std::to_string(num());
return ""; return "";
} }
inline double& nasal_ref::num (){return value.num;} inline double& nasal_ref::num (){return value.num; }
inline std::string* nasal_ref::str (){return value.gcobj->ptr.str;} inline std::string* nasal_ref::str (){return value.gcobj->ptr.str; }
inline nasal_vec* nasal_ref::vec (){return value.gcobj->ptr.vec;} inline nasal_vec* nasal_ref::vec (){return value.gcobj->ptr.vec; }
inline nasal_hash* nasal_ref::hash(){return value.gcobj->ptr.hash;} inline nasal_hash* nasal_ref::hash(){return value.gcobj->ptr.hash;}
inline nasal_func* nasal_ref::func(){return value.gcobj->ptr.func;} inline nasal_func* nasal_ref::func(){return value.gcobj->ptr.func;}
inline void* nasal_ref::obj (){return value.gcobj->ptr.obj;} inline void*& nasal_ref::obj (){return value.gcobj->ptr.obj; }
struct nasal_gc struct nasal_gc
{ {
@ -326,7 +332,7 @@ struct nasal_gc
nasal_ref zero; // reserved address of nasal_val,type vm_num, 0 nasal_ref zero; // reserved address of nasal_val,type vm_num, 0
nasal_ref one; // reserved address of nasal_val,type vm_num, 1 nasal_ref one; // reserved address of nasal_val,type vm_num, 1
nasal_ref nil; // reserved address of nasal_val,type vm_nil nasal_ref nil; // reserved address of nasal_val,type vm_nil
nasal_ref val_stack[STACK_MAX_DEPTH+1];// 1 reserved to avoid stack overflow, stack grows 1 each time nasal_ref val_stack[STACK_MAX_DEPTH+1];// 1 reserved to avoid stack overflow
nasal_ref* stack_top; // stack top nasal_ref* stack_top; // stack top
std::vector<nasal_ref> str_addrs; // reserved address for const vm_str std::vector<nasal_ref> str_addrs; // reserved address for const vm_str
std::vector<nasal_val*> memory; // gc memory std::vector<nasal_val*> memory; // gc memory
@ -386,6 +392,11 @@ void nasal_gc::sweep()
case vm_vec: i->ptr.vec->elems.clear(); break; case vm_vec: i->ptr.vec->elems.clear(); break;
case vm_hash:i->ptr.hash->elems.clear();break; case vm_hash:i->ptr.hash->elems.clear();break;
case vm_func:i->ptr.func->clear(); break; case vm_func:i->ptr.func->clear(); break;
case vm_obj:
if(i->ptr.obj)
free(i->ptr.obj);
i->ptr.obj=nullptr;
break;
} }
free_list[i->type].push(i); free_list[i->type].push(i);
i->mark=GC_COLLECTED; i->mark=GC_COLLECTED;
@ -429,7 +440,6 @@ void nasal_gc::gc_clear()
while(!free_list[i].empty()) while(!free_list[i].empty())
free_list[i].pop(); free_list[i].pop();
local.clear(); local.clear();
for(auto& i:str_addrs) for(auto& i:str_addrs)
delete i.value.gcobj; delete i.value.gcobj;
str_addrs.clear(); str_addrs.clear();

View File

@ -4,7 +4,7 @@
class nasal_import class nasal_import
{ {
private: private:
int error; uint32_t error;
nasal_lexer import_lex; nasal_lexer import_lex;
nasal_parse import_par; nasal_parse import_par;
nasal_ast import_ast; nasal_ast import_ast;
@ -16,19 +16,16 @@ private:
nasal_ast file_import(nasal_ast&); nasal_ast file_import(nasal_ast&);
nasal_ast load(nasal_ast&,uint16_t); nasal_ast load(nasal_ast&,uint16_t);
public: public:
const int get_error(){return error;} uint32_t err(){return error;}
void link(nasal_ast&,const std::string&); void link(nasal_ast&,const std::string&);
const nasal_ast& const nasal_ast& get_root(){return import_ast;}
get_root(){return import_ast;} const std::vector<std::string>& get_file(){return filename_table;}
const std::vector<std::string>&
get_file(){return filename_table;}
}; };
void nasal_import::die(const std::string& filename,const char* error_stage) void nasal_import::die(const std::string& filename,const char* error_stage)
{ {
++error; ++error;
std::cout<<"[import] in <\""<<filename<<"\">: error(s) occurred in "<<error_stage<<".\n"; std::cout<<"[import] in <\""<<filename<<"\">: error(s) occurred in "<<error_stage<<".\n";
return;
} }
bool nasal_import::check_import(const nasal_ast& node) bool nasal_import::check_import(const nasal_ast& node)
@ -69,7 +66,6 @@ void nasal_import::linker(nasal_ast& root,nasal_ast&& add_root)
// add children of add_root to the back of root // add children of add_root to the back of root
for(auto& i:add_root.get_children()) for(auto& i:add_root.get_children())
root.add_child(std::move(i)); root.add_child(std::move(i));
return;
} }
nasal_ast nasal_import::file_import(nasal_ast& node) nasal_ast nasal_import::file_import(nasal_ast& node)
@ -86,15 +82,15 @@ nasal_ast nasal_import::file_import(nasal_ast& node)
return tmp; return tmp;
// start importing... // start importing...
import_lex.openfile(filename); import_lex.open(filename);
import_lex.scanner(); import_lex.scan();
if(import_lex.get_error()) if(import_lex.err())
{ {
die(filename,"lexer"); die(filename,"lexer");
return tmp; return tmp;
} }
import_par.main_process(import_lex.get_token_list()); import_par.compile(import_lex.get_tokens());
if(import_par.get_error()) if(import_par.err())
{ {
die(filename,"parser"); die(filename,"parser");
return tmp; return tmp;
@ -128,7 +124,6 @@ void nasal_import::link(nasal_ast& root,const std::string& self)
// scan root and import files,then generate a new ast and return to import_ast // scan root and import files,then generate a new ast and return to import_ast
// the main file's index is 0 // the main file's index is 0
import_ast=load(root,0); import_ast=load(root,0);
return;
} }
#endif #endif

View File

@ -87,36 +87,36 @@ struct
struct token struct token
{ {
int line; uint32_t line;
int type; uint32_t type;
std::string str; std::string str;
token(int l=0,int t=tok_null,std::string s=""){line=l;type=t;str=s;} token(uint32_t l=0,uint32_t t=tok_null,std::string s=""){line=l;type=t;str=s;}
}; };
class nasal_lexer class nasal_lexer
{ {
private: private:
int error; uint32_t error;
int res_size; uint32_t line;
int line; uint32_t ptr;
int ptr; size_t res_size;
std::string line_code; std::string line_code;
std::string res; std::string res;
std::vector<token> token_list; std::vector<token> token_list;
int get_tok_type(const std::string&); uint32_t get_type(const std::string&);
void die(const char*); void die(const char*);
std::string id_gen(); std::string id_gen();
std::string num_gen(); std::string num_gen();
std::string str_gen(); std::string str_gen();
public: public:
void openfile(const std::string&); void open(const std::string&);
void scanner(); void scan();
void print_token(); void print();
int get_error(){return error;} uint32_t err(){return error;}
std::vector<token>& get_token_list(){return token_list;} const std::vector<token>& get_tokens(){return token_list;}
}; };
void nasal_lexer::openfile(const std::string& filename) void nasal_lexer::open(const std::string& filename)
{ {
error=0; error=0;
res.clear(); res.clear();
@ -137,7 +137,7 @@ void nasal_lexer::openfile(const std::string& filename)
return; return;
} }
int nasal_lexer::get_tok_type(const std::string& tk_str) uint32_t nasal_lexer::get_type(const std::string& tk_str)
{ {
for(int i=0;token_table[i].str;++i) for(int i=0;token_table[i].str;++i)
if(tk_str==token_table[i].str) if(tk_str==token_table[i].str)
@ -272,7 +272,7 @@ std::string nasal_lexer::str_gen()
return token_str; return token_str;
} }
void nasal_lexer::scanner() void nasal_lexer::scan()
{ {
token_list.clear(); token_list.clear();
line=1; line=1;
@ -297,7 +297,7 @@ void nasal_lexer::scanner()
if(IS_IDENTIFIER(res[ptr])) if(IS_IDENTIFIER(res[ptr]))
{ {
token_str=id_gen(); token_str=id_gen();
token_list.push_back({line,get_tok_type(token_str),token_str}); token_list.push_back({line,get_type(token_str),token_str});
if(!token_list.back().type) if(!token_list.back().type)
token_list.back().type=tok_id; token_list.back().type=tok_id;
} }
@ -309,7 +309,7 @@ void nasal_lexer::scanner()
{ {
token_str=res[ptr]; token_str=res[ptr];
line_code+=res[ptr]; line_code+=res[ptr];
int type=get_tok_type(token_str); uint32_t type=get_type(token_str);
if(!type) if(!type)
die("incorrect operator."); die("incorrect operator.");
token_list.push_back({line,type,token_str}); token_list.push_back({line,type,token_str});
@ -328,7 +328,7 @@ void nasal_lexer::scanner()
++ptr; ++ptr;
} }
line_code+=token_str; line_code+=token_str;
token_list.push_back({line,get_tok_type(token_str),token_str}); token_list.push_back({line,get_type(token_str),token_str});
} }
else if(IS_CALC_OPERATOR(res[ptr])) else if(IS_CALC_OPERATOR(res[ptr]))
{ {
@ -337,7 +337,7 @@ void nasal_lexer::scanner()
if(ptr<res_size && res[ptr]=='=') if(ptr<res_size && res[ptr]=='=')
token_str+=res[ptr++]; token_str+=res[ptr++];
line_code+=token_str; line_code+=token_str;
token_list.push_back({line,get_tok_type(token_str),token_str}); token_list.push_back({line,get_type(token_str),token_str});
} }
else if(IS_NOTE(res[ptr]))// avoid note, after this process ptr will point to a '\n', so next loop line counter+1 else if(IS_NOTE(res[ptr]))// avoid note, after this process ptr will point to a '\n', so next loop line counter+1
while(++ptr<res_size && res[ptr]!='\n'); while(++ptr<res_size && res[ptr]!='\n');
@ -352,7 +352,7 @@ void nasal_lexer::scanner()
return; return;
} }
void nasal_lexer::print_token() void nasal_lexer::print()
{ {
for(auto& tok:token_list) for(auto& tok:token_list)
std::cout<<"("<<tok.line<<" | "<<tok.str<<")\n"; std::cout<<"("<<tok.line<<" | "<<tok.str<<")\n";

View File

@ -42,7 +42,7 @@ class nasal_parse
#define is_call(type) ((type)==tok_lcurve || (type)==tok_lbracket || (type)==tok_dot) #define is_call(type) ((type)==tok_lcurve || (type)==tok_lbracket || (type)==tok_dot)
private: private:
int ptr; int ptr;
int error; uint32_t error;
nasal_ast root; nasal_ast root;
std::vector<token> tok_list; std::vector<token> tok_list;
std::vector<token> error_token; std::vector<token> error_token;
@ -99,11 +99,11 @@ private:
nasal_ast break_expr(); nasal_ast break_expr();
nasal_ast ret_expr(); nasal_ast ret_expr();
public: public:
int get_error(){return error;} uint32_t err(){return error;}
void main_process(std::vector<token>&); void compile(const std::vector<token>&);
nasal_ast& get_root(){return root;} nasal_ast& get_root(){return root;}
}; };
void nasal_parse::main_process(std::vector<token>& toks) void nasal_parse::compile(const std::vector<token>& toks)
{ {
tok_list=toks; tok_list=toks;
ptr=in_function=in_loop=error=0; ptr=in_function=in_loop=error=0;

View File

@ -193,20 +193,17 @@ void nasal_vm::stackinfo(const uint32_t limit)
} }
last_ptr=stack_top[0]; last_ptr=stack_top[0];
const nasal_val* ptr=stack_top[0].value.gcobj; const nasal_val* ptr=stack_top[0].value.gcobj;
putchar('\t');
switch(stack_top[0].type) switch(stack_top[0].type)
{ {
case vm_none: printf("null |");break; case vm_none: printf("\tnull |\n");break;
case vm_nil: printf("nil |");break; case vm_nil: printf("\tnil |\n");break;
case vm_num: printf("num | %lf",stack_top[0].num());break; case vm_num: printf("\tnum | %lf\n",stack_top[0].num());break;
case vm_str: printf("str | <%p> ",ptr);raw_string(*stack_top[0].str());break; case vm_str: printf("\tstr | <%p> %s\n",ptr,raw_string(*stack_top[0].str()).c_str());break;
case vm_func: printf("func | <%p> func{entry=0x%x}",ptr,stack_top[0].func()->entry);break; case vm_func: printf("\tfunc | <%p> func{entry=0x%x}\n",ptr,stack_top[0].func()->entry);break;
case vm_vec: printf("vec | <%p> [%lu val]",ptr,stack_top[0].vec()->elems.size());break; case vm_vec: printf("\tvec | <%p> [%lu val]\n",ptr,stack_top[0].vec()->elems.size());break;
case vm_hash: printf("hash | <%p> {%lu member}",ptr,stack_top[0].hash()->elems.size());break; case vm_hash: printf("\thash | <%p> {%lu member}\n",ptr,stack_top[0].hash()->elems.size());break;
case vm_obj: printf("obj | <%p>",ptr);break; case vm_obj: printf("\tobj | <%p>\n",ptr);break;
default: printf("unknown");break;
} }
putchar('\n');
} }
if(same_cnt) if(same_cnt)
printf("\t... | %d same value(s)\n",same_cnt); printf("\t... | %d same value(s)\n",same_cnt);
@ -839,7 +836,9 @@ inline void nasal_vm::opr_ret()
pc=ret.top();ret.pop(); // fetch pc pc=ret.top();ret.pop(); // fetch pc
return; return;
} }
void nasal_vm::run(const std::vector<opcode>& exec,const bool op_cnt) void nasal_vm::run(
const std::vector<opcode>& exec,
const bool op_cnt)
{ {
uint64_t count[op_exit+1]={0}; uint64_t count[op_exit+1]={0};
const void* opr_table[]= const void* opr_table[]=
@ -865,7 +864,6 @@ void nasal_vm::run(const std::vector<opcode>& exec,const bool op_cnt)
&&mcallg, &&mcalll, &&mupval, &&mcallv, &&mcallg, &&mcalll, &&mupval, &&mcallv,
&&mcallh, &&ret, &&vmexit &&mcallh, &&ret, &&vmexit
}; };
bytecode=exec; bytecode=exec;
std::vector<const void*> code; std::vector<const void*> code;
for(auto& i:exec) for(auto& i:exec)

View File

@ -16,8 +16,7 @@ foreach(var i;hex_num)
append(hex,i~j); append(hex,i~j);
# read file # read file
var s=func() var s=func(){
{
var filename=[ var filename=[
"nasal.h", "nasal.h",
"main.cpp", "main.cpp",
@ -43,49 +42,45 @@ var cnt=0;
var hex_index=[0,0,0,0]; var hex_index=[0,0,0,0];
# print binary in text format # print binary in text format
var textprint=func(index) var textprint=func(index){
{ var info='';
print(' |');
for(var i=index-cnt;i<index;i+=1) for(var i=index-cnt;i<index;i+=1)
print((0<=s[i] and s[i]<32)?'.':chr(s[i])); info~=(0<=s[i] and s[i]<32)?'.':chr(s[i]);
for(var i=cnt;i<16;i+=1) for(var i=cnt;i<16;i+=1)
print('.'); info~='.';
print('|\n'); return ' |'~info~'|\n';
} }
# print index # print index
var indexprint=func(index) var indexprint=func(index){
{ forindex(var i;hex_index){
forindex(var i;hex_index)
{
hex_index[i]=index-int(index/256)*256; hex_index[i]=index-int(index/256)*256;
index=int(index/256); index=int(index/256);
} }
var info='';
for(var i=3;i>=0;i-=1) for(var i=3;i>=0;i-=1)
print(hex[hex_index[i]]); info~=hex[hex_index[i]];
print(' '); return info~' ';
return;
} }
# main # main
func() func(){
{ var info=indexprint(0);
indexprint(0); for(var i=0;i<size(s);i+=1){
for(var i=0;i<size(s);i+=1)
{
if(cnt==16){ if(cnt==16){
textprint(i); info~=textprint(i);
print(info);
cnt=0; cnt=0;
indexprint(i); info=indexprint(i);
}elsif(cnt==8){ }elsif(cnt==8)
print(' '); info~=' ';
}
cnt+=1; cnt+=1;
print(hex[s[i]],' '); info~=hex[s[i]]~' ';
} }
for(var l=cnt;l<16;l+=1) for(var l=cnt;l<16;l+=1)
print(' '); info~=' ';
if(cnt<=8) if(cnt<=8)
print(' '); info~=' ';
textprint(i); info~=textprint(i);
print(info);
}(); }();