change function name and cli format
This commit is contained in:
parent
58ea303202
commit
577546763f
|
@ -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:
|
||||
```C++
|
||||
struct FUNC_TABLE
|
||||
struct func
|
||||
{
|
||||
const char* name;
|
||||
nasal_ref (*func)(std::vector<nasal_ref>&,nasal_gc&);
|
||||
|
|
130
main.cpp
130
main.cpp
|
@ -1,24 +1,28 @@
|
|||
#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()
|
||||
{
|
||||
std::cout
|
||||
#ifdef _WIN32
|
||||
<<"use command \'chcp 65001\' if want to use unicode.\n"
|
||||
#endif
|
||||
<<"nasal [option]\n"
|
||||
<<"nasal <option>\n"
|
||||
<<"option:\n"
|
||||
<<" -h, --help | get help.\n"
|
||||
<<" -v, --version | get version of nasal interpreter.\n\n"
|
||||
<<"nasal [file]\n"
|
||||
<<"nasal <file>\n"
|
||||
<<"file:\n"
|
||||
<<" input file name to execute script file.\n\n"
|
||||
<<"nasal [option] [file]\n"
|
||||
<<"nasal [options] <file>\n"
|
||||
<<"option:\n"
|
||||
<<" -l, --lex | view token info.\n"
|
||||
<<" -a, --ast | view abstract syntax tree.\n"
|
||||
<<" -c, --code | view bytecode.\n"
|
||||
<<" -e, --exec | execute script file.\n"
|
||||
<<" -t, --time | execute and get the running time.\n"
|
||||
<<" -o, --opcnt | count operands while running.\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::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_parse parse;
|
||||
nasal_import import;
|
||||
nasal_codegen codegen;
|
||||
nasal_vm vm;
|
||||
lexer.openfile(file);
|
||||
lexer.scanner();
|
||||
if(lexer.get_error())
|
||||
lexer.open(file);
|
||||
lexer.scan();
|
||||
if(lexer.err())
|
||||
die("lexer",file);
|
||||
if(command=="--lex" || command=="-l")
|
||||
{
|
||||
lexer.print_token();
|
||||
return;
|
||||
}
|
||||
parse.main_process(lexer.get_token_list());
|
||||
if(parse.get_error())
|
||||
if(cmd&VM_LEXINFO)
|
||||
lexer.print();
|
||||
parse.compile(lexer.get_tokens());
|
||||
if(parse.err())
|
||||
die("parse",file);
|
||||
if(command=="--ast" || command=="-a")
|
||||
{
|
||||
parse.get_root().print_ast(0);
|
||||
return;
|
||||
}
|
||||
if(cmd&VM_ASTINFO)
|
||||
parse.get_root().print(0);
|
||||
// first used file is itself
|
||||
import.link(parse.get_root(),file);
|
||||
if(import.get_error())
|
||||
if(import.err())
|
||||
die("import",file);
|
||||
codegen.main_progress(import.get_root(),import.get_file());
|
||||
if(codegen.get_error())
|
||||
codegen.compile(import.get_root(),import.get_file());
|
||||
if(codegen.err())
|
||||
die("code",file);
|
||||
if(command=="--code" || command=="-c")
|
||||
{
|
||||
codegen.print_byte_code();
|
||||
return;
|
||||
}
|
||||
if(cmd&VM_CODEINFO)
|
||||
codegen.print();
|
||||
vm.init(
|
||||
codegen.get_str_table(),
|
||||
codegen.get_num_table(),
|
||||
codegen.get_strs(),
|
||||
codegen.get_nums(),
|
||||
import.get_file()
|
||||
);
|
||||
if(command=="--exec" || command=="-e" || command=="--opcnt" || command=="-o")
|
||||
vm.run(codegen.get_exec_code(),command=="--opcnt" || command=="-o");
|
||||
else if(command=="--time" || command=="-t")
|
||||
if(cmd&VM_EXECTIME)
|
||||
{
|
||||
clock_t begin=clock();
|
||||
vm.run(codegen.get_exec_code(),false);
|
||||
std::cout<<"process exited after "<<((double)(clock()-begin))/CLOCKS_PER_SEC<<"s.\n";
|
||||
clock_t t=clock();
|
||||
vm.run(codegen.get_code(),cmd&VM_OPCALLNUM);
|
||||
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();
|
||||
return;
|
||||
}
|
||||
|
||||
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")))
|
||||
logo();
|
||||
else if(argc==2 && (!strcmp(argv[1],"-h") || !strcmp(argv[1],"--help")))
|
||||
help_cmd();
|
||||
else if(argc==2 && argv[1][0]!='-')
|
||||
cmd|=VM_EXEC;
|
||||
else if(argc>=3)
|
||||
{
|
||||
file=argv[1];
|
||||
command="-e";
|
||||
execute(file,command);
|
||||
for(int i=1;i<argc-1;++i)
|
||||
{
|
||||
std::string s(argv[i]);
|
||||
if(s=="--lex" || s=="-l")
|
||||
cmd|=VM_LEXINFO;
|
||||
else if(s=="--ast" || s=="-a")
|
||||
cmd|=VM_ASTINFO;
|
||||
else if(s=="--code" || s=="-c")
|
||||
cmd|=VM_CODEINFO;
|
||||
else if(s=="--opcnt" || s=="-o")
|
||||
cmd|=VM_OPCALLNUM|VM_EXEC;
|
||||
else if(s=="--time" || s=="-t")
|
||||
cmd|=VM_EXECTIME;
|
||||
else
|
||||
cmderr();
|
||||
}
|
||||
else if(argc==3 &&
|
||||
(!strcmp(argv[1],"--lex") ||
|
||||
!strcmp(argv[1],"-l") ||
|
||||
!strcmp(argv[1],"--ast") ||
|
||||
!strcmp(argv[1],"-a") ||
|
||||
!strcmp(argv[1],"--code") ||
|
||||
!strcmp(argv[1],"-c") ||
|
||||
!strcmp(argv[1],"--exec") ||
|
||||
!strcmp(argv[1],"-e") ||
|
||||
!strcmp(argv[1],"--opcnt")||
|
||||
!strcmp(argv[1],"-o") ||
|
||||
!strcmp(argv[1],"--time") ||
|
||||
!strcmp(argv[1],"-t")))
|
||||
{
|
||||
file=argv[2];
|
||||
command=argv[1];
|
||||
execute(file,command);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout
|
||||
<<"invalid argument(s).\n"
|
||||
<<"use nasal -h to get help.\n";
|
||||
std::exit(1);
|
||||
}
|
||||
cmderr();
|
||||
if(argv[argc-1][0]=='-')
|
||||
cmderr();
|
||||
if(cmd)
|
||||
execute(argv[argc-1],cmd);
|
||||
return 0;
|
||||
}
|
24
nasal.h
24
nasal.h
|
@ -1,6 +1,5 @@
|
|||
#ifndef __NASAL_H__
|
||||
#define __NASAL_H__
|
||||
|
||||
#pragma GCC optimize(2)
|
||||
|
||||
#include <stdint.h>
|
||||
|
@ -108,22 +107,23 @@ double str2num(const char* str)
|
|||
/*
|
||||
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)
|
||||
switch(i)
|
||||
{
|
||||
case '\a': std::cout<<"\\a";break;
|
||||
case '\b': std::cout<<"\\b";break;
|
||||
case '\f': std::cout<<"\\f";break;
|
||||
case '\n': std::cout<<"\\n";break;
|
||||
case '\r': std::cout<<"\\r";break;
|
||||
case '\t': std::cout<<"\\t";break;
|
||||
case '\v': std::cout<<"\\v";break;
|
||||
case '\0': std::cout<<"\\0";break;
|
||||
default: std::cout<<i; break;
|
||||
case '\a': ret+="\\a";break;
|
||||
case '\b': ret+="\\b";break;
|
||||
case '\f': ret+="\\f";break;
|
||||
case '\n': ret+="\\n";break;
|
||||
case '\r': ret+="\\r";break;
|
||||
case '\t': ret+="\\t";break;
|
||||
case '\v': ret+="\\v";break;
|
||||
case '\0': ret+="\\0";break;
|
||||
default: ret+=i; break;
|
||||
}
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
#include "nasal_lexer.h"
|
||||
#include "nasal_ast.h"
|
||||
|
|
32
nasal_ast.h
32
nasal_ast.h
|
@ -50,34 +50,35 @@ const char* ast_name[]=
|
|||
class nasal_ast
|
||||
{
|
||||
private:
|
||||
int line;
|
||||
int type;
|
||||
uint32_t line;
|
||||
uint32_t type;
|
||||
double num;
|
||||
std::string str;
|
||||
std::vector<nasal_ast> children;
|
||||
public:
|
||||
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(nasal_ast&&);
|
||||
nasal_ast& operator=(const nasal_ast&);
|
||||
nasal_ast& operator=(nasal_ast&&);
|
||||
void print_ast(const int);
|
||||
void print(const int);
|
||||
void clear();
|
||||
void add_child(nasal_ast&& ast){children.push_back(std::move(ast));}
|
||||
void add_child(const nasal_ast& ast){children.push_back(ast);}
|
||||
void set_line(const int l){line=l;}
|
||||
void set_type(const int t){type=t;}
|
||||
void set_line(const uint32_t l){line=l;}
|
||||
void set_type(const uint32_t t){type=t;}
|
||||
void set_str(const std::string& s){str=s;}
|
||||
void set_num(const double n){num=n;}
|
||||
int get_line(){return line;}
|
||||
int get_type(){return type;}
|
||||
|
||||
uint32_t get_line(){return line;}
|
||||
uint32_t get_type(){return type;}
|
||||
double get_num() {return num;}
|
||||
std::string& get_str(){return str;}
|
||||
std::string& get_str() {return str;}
|
||||
std::vector<nasal_ast>& get_children(){return children;}
|
||||
|
||||
int get_line() const {return line;}
|
||||
int get_type() const {return type;}
|
||||
uint32_t get_line() const {return line;}
|
||||
uint32_t get_type() const {return type;}
|
||||
double get_num() const {return num;}
|
||||
const std::string& get_str() const {return str;}
|
||||
const std::vector<nasal_ast>& get_children() const {return children;}
|
||||
|
@ -133,21 +134,18 @@ void nasal_ast::clear()
|
|||
return;
|
||||
}
|
||||
|
||||
void nasal_ast::print_ast(const int depth)
|
||||
void nasal_ast::print(const int depth)
|
||||
{
|
||||
for(int i=0;i<depth;++i)
|
||||
std::cout<<"| ";
|
||||
std::cout<<ast_name[type];
|
||||
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)
|
||||
std::cout<<":"<<num;
|
||||
std::cout<<'\n';
|
||||
for(auto& i:children)
|
||||
i.print_ast(depth+1);
|
||||
i.print(depth+1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
// this table must end with {"",nullptr}
|
||||
struct FUNC_TABLE
|
||||
// this table must end with {nullptr,nullptr}
|
||||
struct func
|
||||
{
|
||||
const char* name;
|
||||
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)
|
||||
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_num: std::cout<<i.num(); break;
|
||||
case vm_str: std::cout<<*i.str(); break;
|
||||
|
|
|
@ -255,13 +255,13 @@ private:
|
|||
void block_gen(const nasal_ast&);
|
||||
void ret_gen(const nasal_ast&);
|
||||
public:
|
||||
uint32_t get_error(){return error;}
|
||||
void main_progress(const nasal_ast&,const std::vector<std::string>&);
|
||||
uint32_t err(){return error;}
|
||||
void compile(const nasal_ast&,const std::vector<std::string>&);
|
||||
void print_op(uint32_t);
|
||||
void print_byte_code();
|
||||
std::vector<std::string>& get_str_table(){return str_res_table;}
|
||||
std::vector<double>& get_num_table(){return num_res_table;}
|
||||
std::vector<opcode>& get_exec_code(){return exec_code;}
|
||||
void print();
|
||||
std::vector<std::string>& get_strs(){return str_res_table;}
|
||||
std::vector<double>& get_nums(){return num_res_table;}
|
||||
std::vector<opcode>& get_code(){return exec_code;}
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
die("cannot change builtin function.",ast.get_line());
|
||||
|
@ -1213,7 +1213,7 @@ void nasal_codegen::ret_gen(const nasal_ast& ast)
|
|||
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;
|
||||
in_foreach=0;
|
||||
|
@ -1326,25 +1326,19 @@ void nasal_codegen::print_op(uint32_t index)
|
|||
case op_lnkc:case op_lnkeqc:
|
||||
case op_callh:case op_mcallh:
|
||||
case op_para:case op_defpara:case op_dynpara:
|
||||
printf("0x%x (\"",code.num);
|
||||
raw_string(str_res_table[code.num]);
|
||||
printf("\")\n");
|
||||
printf("0x%x (\"%s\")\n",code.num,raw_string(str_res_table[code.num]).c_str());
|
||||
break;
|
||||
default:printf("\n");break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void nasal_codegen::print_byte_code()
|
||||
void nasal_codegen::print()
|
||||
{
|
||||
for(auto num:num_res_table)
|
||||
std::cout<<".number "<<num<<'\n';
|
||||
for(auto& str:str_res_table)
|
||||
{
|
||||
std::cout<<".symbol \"";
|
||||
raw_string(str);
|
||||
std::cout<<"\"\n";
|
||||
}
|
||||
std::cout<<".symbol \""<<raw_string(str)<<"\"\n";
|
||||
for(uint32_t i=0;i<exec_code.size();++i)
|
||||
print_op(i);
|
||||
return;
|
||||
|
|
36
nasal_gc.h
36
nasal_gc.h
|
@ -3,11 +3,11 @@
|
|||
|
||||
enum nasal_type
|
||||
{
|
||||
// none-gc object
|
||||
/* none-gc object */
|
||||
vm_none=0,
|
||||
vm_nil,
|
||||
vm_num,
|
||||
// gc object
|
||||
/* gc object */
|
||||
vm_str,
|
||||
vm_func,
|
||||
vm_vec,
|
||||
|
@ -17,19 +17,19 @@ enum nasal_type
|
|||
};
|
||||
|
||||
// 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]=
|
||||
{
|
||||
// none-gc object
|
||||
/* none-gc object */
|
||||
0, // vm_none, error type
|
||||
0, // vm_nil
|
||||
0, // vm_num
|
||||
// gc object
|
||||
/* gc object */
|
||||
2048, // vm_str
|
||||
1024, // vm_func
|
||||
8192, // vm_vec
|
||||
512, // vm_hash
|
||||
0 // vm_obj
|
||||
128 // vm_obj
|
||||
};
|
||||
|
||||
// declaration of nasal value type
|
||||
|
@ -83,7 +83,7 @@ struct nasal_ref// 16 bytes
|
|||
inline nasal_vec* vec ();
|
||||
inline nasal_hash* hash();
|
||||
inline nasal_func* func();
|
||||
inline void* obj ();
|
||||
inline void*& obj ();
|
||||
};
|
||||
|
||||
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_hash: ptr.hash=new nasal_hash; break;
|
||||
case vm_func: ptr.func=new nasal_func; break;
|
||||
case vm_obj: ptr.obj=nullptr; break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -293,7 +294,12 @@ nasal_val::~nasal_val()
|
|||
case vm_vec: delete ptr.vec; break;
|
||||
case vm_hash: delete ptr.hash; break;
|
||||
case vm_func: delete ptr.func; break;
|
||||
case vm_obj:
|
||||
if(ptr.obj)
|
||||
free(ptr.obj);
|
||||
break;
|
||||
}
|
||||
ptr.obj=nullptr;
|
||||
type=vm_nil;
|
||||
return;
|
||||
}
|
||||
|
@ -313,12 +319,12 @@ std::string nasal_ref::to_string()
|
|||
return std::to_string(num());
|
||||
return "";
|
||||
}
|
||||
inline double& nasal_ref::num (){return value.num;}
|
||||
inline std::string* nasal_ref::str (){return value.gcobj->ptr.str;}
|
||||
inline nasal_vec* nasal_ref::vec (){return value.gcobj->ptr.vec;}
|
||||
inline double& nasal_ref::num (){return value.num; }
|
||||
inline std::string* nasal_ref::str (){return value.gcobj->ptr.str; }
|
||||
inline nasal_vec* nasal_ref::vec (){return value.gcobj->ptr.vec; }
|
||||
inline nasal_hash* nasal_ref::hash(){return value.gcobj->ptr.hash;}
|
||||
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
|
||||
{
|
||||
|
@ -326,7 +332,7 @@ struct nasal_gc
|
|||
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 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
|
||||
std::vector<nasal_ref> str_addrs; // reserved address for const vm_str
|
||||
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_hash:i->ptr.hash->elems.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);
|
||||
i->mark=GC_COLLECTED;
|
||||
|
@ -429,7 +440,6 @@ void nasal_gc::gc_clear()
|
|||
while(!free_list[i].empty())
|
||||
free_list[i].pop();
|
||||
local.clear();
|
||||
|
||||
for(auto& i:str_addrs)
|
||||
delete i.value.gcobj;
|
||||
str_addrs.clear();
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
class nasal_import
|
||||
{
|
||||
private:
|
||||
int error;
|
||||
uint32_t error;
|
||||
nasal_lexer import_lex;
|
||||
nasal_parse import_par;
|
||||
nasal_ast import_ast;
|
||||
|
@ -16,19 +16,16 @@ private:
|
|||
nasal_ast file_import(nasal_ast&);
|
||||
nasal_ast load(nasal_ast&,uint16_t);
|
||||
public:
|
||||
const int get_error(){return error;}
|
||||
uint32_t err(){return error;}
|
||||
void link(nasal_ast&,const std::string&);
|
||||
const nasal_ast&
|
||||
get_root(){return import_ast;}
|
||||
const std::vector<std::string>&
|
||||
get_file(){return filename_table;}
|
||||
const nasal_ast& get_root(){return import_ast;}
|
||||
const std::vector<std::string>& get_file(){return filename_table;}
|
||||
};
|
||||
|
||||
void nasal_import::die(const std::string& filename,const char* error_stage)
|
||||
{
|
||||
++error;
|
||||
std::cout<<"[import] in <\""<<filename<<"\">: error(s) occurred in "<<error_stage<<".\n";
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
for(auto& i:add_root.get_children())
|
||||
root.add_child(std::move(i));
|
||||
return;
|
||||
}
|
||||
|
||||
nasal_ast nasal_import::file_import(nasal_ast& node)
|
||||
|
@ -86,15 +82,15 @@ nasal_ast nasal_import::file_import(nasal_ast& node)
|
|||
return tmp;
|
||||
|
||||
// start importing...
|
||||
import_lex.openfile(filename);
|
||||
import_lex.scanner();
|
||||
if(import_lex.get_error())
|
||||
import_lex.open(filename);
|
||||
import_lex.scan();
|
||||
if(import_lex.err())
|
||||
{
|
||||
die(filename,"lexer");
|
||||
return tmp;
|
||||
}
|
||||
import_par.main_process(import_lex.get_token_list());
|
||||
if(import_par.get_error())
|
||||
import_par.compile(import_lex.get_tokens());
|
||||
if(import_par.err())
|
||||
{
|
||||
die(filename,"parser");
|
||||
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
|
||||
// the main file's index is 0
|
||||
import_ast=load(root,0);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -87,36 +87,36 @@ struct
|
|||
|
||||
struct token
|
||||
{
|
||||
int line;
|
||||
int type;
|
||||
uint32_t line;
|
||||
uint32_t type;
|
||||
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
|
||||
{
|
||||
private:
|
||||
int error;
|
||||
int res_size;
|
||||
int line;
|
||||
int ptr;
|
||||
uint32_t error;
|
||||
uint32_t line;
|
||||
uint32_t ptr;
|
||||
size_t res_size;
|
||||
std::string line_code;
|
||||
std::string res;
|
||||
std::vector<token> token_list;
|
||||
int get_tok_type(const std::string&);
|
||||
uint32_t get_type(const std::string&);
|
||||
void die(const char*);
|
||||
std::string id_gen();
|
||||
std::string num_gen();
|
||||
std::string str_gen();
|
||||
public:
|
||||
void openfile(const std::string&);
|
||||
void scanner();
|
||||
void print_token();
|
||||
int get_error(){return error;}
|
||||
std::vector<token>& get_token_list(){return token_list;}
|
||||
void open(const std::string&);
|
||||
void scan();
|
||||
void print();
|
||||
uint32_t err(){return error;}
|
||||
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;
|
||||
res.clear();
|
||||
|
@ -137,7 +137,7 @@ void nasal_lexer::openfile(const std::string& filename)
|
|||
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)
|
||||
if(tk_str==token_table[i].str)
|
||||
|
@ -272,7 +272,7 @@ std::string nasal_lexer::str_gen()
|
|||
return token_str;
|
||||
}
|
||||
|
||||
void nasal_lexer::scanner()
|
||||
void nasal_lexer::scan()
|
||||
{
|
||||
token_list.clear();
|
||||
line=1;
|
||||
|
@ -297,7 +297,7 @@ void nasal_lexer::scanner()
|
|||
if(IS_IDENTIFIER(res[ptr]))
|
||||
{
|
||||
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)
|
||||
token_list.back().type=tok_id;
|
||||
}
|
||||
|
@ -309,7 +309,7 @@ void nasal_lexer::scanner()
|
|||
{
|
||||
token_str=res[ptr];
|
||||
line_code+=res[ptr];
|
||||
int type=get_tok_type(token_str);
|
||||
uint32_t type=get_type(token_str);
|
||||
if(!type)
|
||||
die("incorrect operator.");
|
||||
token_list.push_back({line,type,token_str});
|
||||
|
@ -328,7 +328,7 @@ void nasal_lexer::scanner()
|
|||
++ptr;
|
||||
}
|
||||
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]))
|
||||
{
|
||||
|
@ -337,7 +337,7 @@ void nasal_lexer::scanner()
|
|||
if(ptr<res_size && res[ptr]=='=')
|
||||
token_str+=res[ptr++];
|
||||
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
|
||||
while(++ptr<res_size && res[ptr]!='\n');
|
||||
|
@ -352,7 +352,7 @@ void nasal_lexer::scanner()
|
|||
return;
|
||||
}
|
||||
|
||||
void nasal_lexer::print_token()
|
||||
void nasal_lexer::print()
|
||||
{
|
||||
for(auto& tok:token_list)
|
||||
std::cout<<"("<<tok.line<<" | "<<tok.str<<")\n";
|
||||
|
|
|
@ -42,7 +42,7 @@ class nasal_parse
|
|||
#define is_call(type) ((type)==tok_lcurve || (type)==tok_lbracket || (type)==tok_dot)
|
||||
private:
|
||||
int ptr;
|
||||
int error;
|
||||
uint32_t error;
|
||||
nasal_ast root;
|
||||
std::vector<token> tok_list;
|
||||
std::vector<token> error_token;
|
||||
|
@ -99,11 +99,11 @@ private:
|
|||
nasal_ast break_expr();
|
||||
nasal_ast ret_expr();
|
||||
public:
|
||||
int get_error(){return error;}
|
||||
void main_process(std::vector<token>&);
|
||||
uint32_t err(){return error;}
|
||||
void compile(const std::vector<token>&);
|
||||
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;
|
||||
ptr=in_function=in_loop=error=0;
|
||||
|
|
24
nasal_vm.h
24
nasal_vm.h
|
@ -193,20 +193,17 @@ void nasal_vm::stackinfo(const uint32_t limit)
|
|||
}
|
||||
last_ptr=stack_top[0];
|
||||
const nasal_val* ptr=stack_top[0].value.gcobj;
|
||||
putchar('\t');
|
||||
switch(stack_top[0].type)
|
||||
{
|
||||
case vm_none: printf("null |");break;
|
||||
case vm_nil: printf("nil |");break;
|
||||
case vm_num: printf("num | %lf",stack_top[0].num());break;
|
||||
case vm_str: printf("str | <%p> ",ptr);raw_string(*stack_top[0].str());break;
|
||||
case vm_func: printf("func | <%p> func{entry=0x%x}",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_hash: printf("hash | <%p> {%lu member}",ptr,stack_top[0].hash()->elems.size());break;
|
||||
case vm_obj: printf("obj | <%p>",ptr);break;
|
||||
default: printf("unknown");break;
|
||||
case vm_none: printf("\tnull |\n");break;
|
||||
case vm_nil: printf("\tnil |\n");break;
|
||||
case vm_num: printf("\tnum | %lf\n",stack_top[0].num());break;
|
||||
case vm_str: printf("\tstr | <%p> %s\n",ptr,raw_string(*stack_top[0].str()).c_str());break;
|
||||
case vm_func: printf("\tfunc | <%p> func{entry=0x%x}\n",ptr,stack_top[0].func()->entry);break;
|
||||
case vm_vec: printf("\tvec | <%p> [%lu val]\n",ptr,stack_top[0].vec()->elems.size());break;
|
||||
case vm_hash: printf("\thash | <%p> {%lu member}\n",ptr,stack_top[0].hash()->elems.size());break;
|
||||
case vm_obj: printf("\tobj | <%p>\n",ptr);break;
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
if(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
|
||||
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};
|
||||
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,
|
||||
&&mcallh, &&ret, &&vmexit
|
||||
};
|
||||
|
||||
bytecode=exec;
|
||||
std::vector<const void*> code;
|
||||
for(auto& i:exec)
|
||||
|
|
|
@ -16,8 +16,7 @@ foreach(var i;hex_num)
|
|||
append(hex,i~j);
|
||||
|
||||
# read file
|
||||
var s=func()
|
||||
{
|
||||
var s=func(){
|
||||
var filename=[
|
||||
"nasal.h",
|
||||
"main.cpp",
|
||||
|
@ -43,49 +42,45 @@ var cnt=0;
|
|||
var hex_index=[0,0,0,0];
|
||||
|
||||
# print binary in text format
|
||||
var textprint=func(index)
|
||||
{
|
||||
print(' |');
|
||||
var textprint=func(index){
|
||||
var info='';
|
||||
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)
|
||||
print('.');
|
||||
print('|\n');
|
||||
info~='.';
|
||||
return ' |'~info~'|\n';
|
||||
}
|
||||
|
||||
# print index
|
||||
var indexprint=func(index)
|
||||
{
|
||||
forindex(var i;hex_index)
|
||||
{
|
||||
var indexprint=func(index){
|
||||
forindex(var i;hex_index){
|
||||
hex_index[i]=index-int(index/256)*256;
|
||||
index=int(index/256);
|
||||
}
|
||||
var info='';
|
||||
for(var i=3;i>=0;i-=1)
|
||||
print(hex[hex_index[i]]);
|
||||
print(' ');
|
||||
return;
|
||||
info~=hex[hex_index[i]];
|
||||
return info~' ';
|
||||
}
|
||||
|
||||
# main
|
||||
func()
|
||||
{
|
||||
indexprint(0);
|
||||
for(var i=0;i<size(s);i+=1)
|
||||
{
|
||||
func(){
|
||||
var info=indexprint(0);
|
||||
for(var i=0;i<size(s);i+=1){
|
||||
if(cnt==16){
|
||||
textprint(i);
|
||||
info~=textprint(i);
|
||||
print(info);
|
||||
cnt=0;
|
||||
indexprint(i);
|
||||
}elsif(cnt==8){
|
||||
print(' ');
|
||||
}
|
||||
info=indexprint(i);
|
||||
}elsif(cnt==8)
|
||||
info~=' ';
|
||||
cnt+=1;
|
||||
print(hex[s[i]],' ');
|
||||
info~=hex[s[i]]~' ';
|
||||
}
|
||||
for(var l=cnt;l<16;l+=1)
|
||||
print(' ');
|
||||
info~=' ';
|
||||
if(cnt<=8)
|
||||
print(' ');
|
||||
textprint(i);
|
||||
info~=' ';
|
||||
info~=textprint(i);
|
||||
print(info);
|
||||
}();
|
Loading…
Reference in New Issue