finish new codegen

This commit is contained in:
ValKmjolnir 2023-07-01 16:38:37 +08:00
parent 90ad1a53d7
commit b6886cc957
10 changed files with 1773 additions and 97 deletions

View File

@ -1,8 +1,8 @@
#include "nasal_new_codegen.h"
bool codegen::check_memory_reachable(call_expr* node) {
if (node->get_first()->get_type()==expr_type::ast_call) {
const auto tmp=node->get_calls().back();
bool codegen::check_memory_reachable(expr* node) {
if (node->get_type()==expr_type::ast_call) {
const auto tmp=((call_expr*)node)->get_calls().back();
if (tmp->get_type()==expr_type::ast_callf) {
die("bad left-value with function call", node->get_location());
return false;
@ -13,7 +13,7 @@ bool codegen::check_memory_reachable(call_expr* node) {
die("bad left-value with subvec", node->get_location());
return false;
}
} else if (node->get_first()->get_type()!=expr_type::ast_id) {
} else if (node->get_type()!=expr_type::ast_id) {
die("bad left-value", node->get_location());
return false;
}
@ -441,40 +441,127 @@ void codegen::assignment_gen(assignment_expr* node) {
gen(op_meq, 0, node->get_location().begin_line);
break;
case assignment_expr::assign_type::add_equal:
if (node->get_right()->get_type()!=expr_type::ast_num) {
calc_gen(node->get_right());
}
mcall((call_expr*)node->get_left());
if (node->get_right()->get_type()!=expr_type::ast_num) {
gen(op_addeq, 0, node->get_location().begin_line);
} else {
auto num = ((number_literal*)node->get_right())->get_number();
regist_num(num);
gen(op_addeqc, num_table[num], node->get_location().begin_line);
}
break;
case assignment_expr::assign_type::sub_equal:
if (node->get_right()->get_type()!=expr_type::ast_num) {
calc_gen(node->get_right());
}
mcall((call_expr*)node->get_left());
if (node->get_right()->get_type()!=expr_type::ast_num) {
gen(op_subeq, 0, node->get_location().begin_line);
} else {
auto num = ((number_literal*)node->get_right())->get_number();
regist_num(num);
gen(op_subeqc, num_table[num], node->get_location().begin_line);
}
break;
case assignment_expr::assign_type::mult_equal:
if (node->get_right()->get_type()!=expr_type::ast_num) {
calc_gen(node->get_right());
}
mcall((call_expr*)node->get_left());
if (node->get_right()->get_type()!=expr_type::ast_num) {
gen(op_muleq, 0, node->get_location().begin_line);
} else {
auto num = ((number_literal*)node->get_right())->get_number();
regist_num(num);
gen(op_muleqc, num_table[num], node->get_location().begin_line);
}
break;
case assignment_expr::assign_type::div_equal:
if (node->get_right()->get_type()!=expr_type::ast_num) {
calc_gen(node->get_right());
}
mcall((call_expr*)node->get_left());
if (node->get_right()->get_type()!=expr_type::ast_num) {
gen(node->get_type()-ast_addeq+op_addeq, 0, node->get_location().begin_line);
gen(op_diveq, 0, node->get_location().begin_line);
} else {
auto num = ((number_literal*)node->get_right())->get_number();
regist_num(num);
gen(node->get_type()-ast_addeq+op_addeqc, num_table[num], node->get_location().begin_line);
gen(op_diveqc, num_table[num], node->get_location().begin_line);
}
break;
case assignment_expr::assign_type::concat_equal:
if (node[1]->get_type()!=ast_str) {
calc_gen(node[1]);
} else {
regist_str(node[1].str());
if (node->get_right()->get_type()!=expr_type::ast_str) {
calc_gen(node->get_right());
}
mcall(node[0]);
if (node[1]->get_type()!=ast_str) {
mcall((call_expr*)node->get_left());
if (node->get_right()->get_type()!=expr_type::ast_str) {
gen(op_lnkeq, 0, node->get_location().begin_line);
} else {
gen(op_lnkeqc, str_table[node[1].str()], node->get_location().begin_line);
const auto& str = ((string_literal*)node->get_right())->get_content();
regist_str(str);
gen(op_lnkeqc, str_table[str], node->get_location().begin_line);
}
break;
case assignment_expr::assign_type::bitwise_and_equal:
calc_gen(node->get_right());
mcall((call_expr*)node->get_left());
gen(op_btandeq, 0, node->get_location().begin_line);
break;
case assignment_expr::assign_type::bitwise_or_equal:
calc_gen(node->get_right());
mcall((call_expr*)node->get_left());
gen(op_btoreq, 0, node->get_location().begin_line);
break;
case assignment_expr::assign_type::bitwise_xor_equal:
calc_gen(node->get_right());
mcall((call_expr*)node->get_left());
gen(node->get_type()-ast_btandeq+op_btandeq, 0, node->get_location().begin_line);
gen(op_btxoreq, 0, node->get_location().begin_line);
break;
}
}
void codegen::assign_statement(assignment_expr* node) {
switch(node->get_assignment_type()) {
case assignment_expr::assign_type::equal:
if (node->get_left()->get_type()==expr_type::ast_id) {
calc_gen(node->get_right());
mcall_id((identifier*)node->get_left());
// only the first mcall_id can use load
if (code.back().op==op_mcalll) {
code.back().op=op_loadl;
} else if (code.back().op==op_mupval) {
code.back().op=op_loadu;
} else {
code.back().op=op_loadg;
}
} else {
calc_gen(node);
if (code.back().op==op_meq) {
code.back().num=1;
} else {
gen(op_pop, 0, node->get_location().begin_line);
}
}
break;
case assignment_expr::assign_type::add_equal:
case assignment_expr::assign_type::sub_equal:
case assignment_expr::assign_type::mult_equal:
case assignment_expr::assign_type::div_equal:
case assignment_expr::assign_type::concat_equal:
case assignment_expr::assign_type::bitwise_and_equal:
case assignment_expr::assign_type::bitwise_or_equal:
case assignment_expr::assign_type::bitwise_xor_equal:
calc_gen(node);
if (op_addeq<=code.back().op && code.back().op<=op_btxoreq) {
code.back().num=1;
} else if (op_addeqc<=code.back().op && code.back().op<=op_lnkeqc) {
code.back().op=code.back().op-op_addeqc+op_addecp;
} else {
gen(op_pop, 0, node->get_location().begin_line);
}
break;
}
}
@ -624,50 +711,21 @@ void codegen::expr_gen(expr* node) {
switch(node->get_type()) {
case expr_type::ast_null:break;
case expr_type::ast_def:
def_gen((definition_expr*)node);break;
def_gen((definition_expr*)node); break;
case expr_type::ast_multi_assign:
multi_assign_gen((multi_assign*)node);break;
case expr_type::ast_nil:case expr_type::ast_num:case expr_type::ast_str:case expr_type::ast_bool:break;
case expr_type::ast_vec:case expr_type::ast_hash:case expr_type::ast_func:case expr_type::ast_call:
multi_assign_gen((multi_assign*)node); break;
case expr_type::ast_nil:case expr_type::ast_num:
case expr_type::ast_str:case expr_type::ast_bool:break;
case expr_type::ast_vec:case expr_type::ast_hash:
case expr_type::ast_func:case expr_type::ast_call:
case expr_type::ast_unary:
case expr_type::ast_binary:
case expr_type::ast_ternary:
calc_gen(node);
gen(op_pop, 0, node->get_location().begin_line);
break;
case expr_type::ast_equal:
if (node[0]->get_type()==expr_type::ast_id) {
calc_gen(node[1]);
mcall_id(node[0]);
// only the first mcall_id can use load
if (code.back().op==op_mcalll) {
code.back().op=op_loadl;
} else if (code.back().op==op_mupval) {
code.back().op=op_loadu;
} else {
code.back().op=op_loadg;
}
} else {
calc_gen(node);
if (code.back().op==op_meq) {
code.back().num=1;
} else {
gen(op_pop, 0, node->get_location().begin_line);
}
}
break;
case expr_type::ast_addeq:case expr_type::ast_subeq:
case expr_type::ast_multeq:case expr_type::ast_diveq:case expr_type::ast_lnkeq:
case expr_type::ast_btandeq:case expr_type::ast_btoreq:case expr_type::ast_btxoreq:
calc_gen(node);
if (op_addeq<=code.back().op && code.back().op<=op_btxoreq) {
code.back().num=1;
} else if (op_addeqc<=code.back().op && code.back().op<=op_lnkeqc) {
code.back().op=code.back().op-op_addeqc+op_addecp;
} else {
gen(op_pop, 0, node->get_location().begin_line);
}
break;
case expr_type::ast_assign:
assign_statement((assignment_expr*)node); break;
}
}

View File

@ -40,7 +40,7 @@ private:
// but in fact local scope also has less than STACK_DEPTH value
std::list<std::unordered_map<std::string,i32>> local;
bool check_memory_reachable(call_expr*);
bool check_memory_reachable(expr*);
void check_id_exist(identifier*);
void die(const std::string& info, const span& loc) {

235
ast/nasal_new_dbg.cpp Normal file
View File

@ -0,0 +1,235 @@
#include "nasal_new_dbg.h"
std::vector<std::string> dbg::parse(const std::string& cmd) {
std::vector<std::string> res;
usize last=0;
usize pos=cmd.find(" ", 0);
while(pos!=std::string::npos) {
if (pos>last) {
res.push_back(cmd.substr(last, pos-last));
}
last=pos+1;
pos=cmd.find(" ", last);
}
if (last<cmd.length()) {
res.push_back(cmd.substr(last));
}
return res;
}
u16 dbg::file_index(const std::string& filename) const {
for(u16 i=0;i<fsize;++i) {
if (filename==files[i]) {
return i;
}
}
return 65535;
}
void dbg::err() {
std::cerr
<<"incorrect command\n"
<<"input \'h\' to get help\n";
}
void dbg::help() {
std::clog
<<"<option>\n"
<<" h, help | get help\n"
<<" bt, backtrace | get function call trace\n"
<<" c, continue | run program until break point or exit\n"
<<" f, file | see all the compiled files\n"
<<" g, global | see global values\n"
<<" l, local | see local values\n"
<<" u, upval | see upvalue\n"
<<" r, register | show vm register detail\n"
<<" a, all | show global,local and upvalue\n"
<<" n, next | execute next bytecode\n"
<<" q, exit | exit debugger\n"
<<"<option> <filename> <line>\n"
<<" bk, break | set break point\n";
}
void dbg::list_file() const {
for(usize i=0; i<fsize; ++i) {
std::clog<<"["<<i<<"] "<<files[i]<<"\n";
}
}
void dbg::call_sort(const u64* arr) const {
typedef std::pair<u32,u64> op;
std::vector<op> opcall;
u64 total=0;
for(u32 i=0;i<op_ret+1;++i) {
total+=arr[i];
opcall.push_back({i, arr[i]});
}
std::sort(opcall.begin(), opcall.end(),
[](const op& a, const op& b) {return a.second>b.second;}
);
std::clog<<"\noperands call info (<1% ignored)\n";
for(auto& i:opcall) {
u64 rate=i.second*100/total;
if (!rate) {
break;
}
std::clog<<" "<<opname[i.first]<<" : "<<i.second<<" ("<<rate<<"%)\n";
}
std::clog<<" total : "<<total<<'\n';
}
void dbg::step_info() {
u32 line=bytecode[ctx.pc].line==0?0:bytecode[ctx.pc].line-1;
u32 begin=(line>>3)==0?0:((line>>3)<<3);
u32 end=(1+(line>>3))<<3;
src.load(files[bytecode[ctx.pc].fidx]);
std::clog<<"\nsource code:\n";
for(u32 i=begin;i<end && i<src.size();++i) {
std::clog<<(i==line?back_white:reset)<<(i==line?"--> ":" ")<<src[i]<<reset<<"\n";
}
begin=(ctx.pc>>3)==0?0:((ctx.pc>>3)<<3);
end=(1+(ctx.pc>>3))<<3;
codestream::set(cnum, cstr, files);
std::clog<<"next bytecode:\n";
for(u32 i=begin;i<end && bytecode[i].op!=op_exit;++i) {
std::clog
<<(i==ctx.pc?back_white:reset)
<<(i==ctx.pc?"--> ":" ")
<<codestream(bytecode[i], i)
<<reset<<"\n";
}
stackinfo(10);
}
void dbg::interact() {
// special operand, end execution
if (bytecode[ctx.pc].op==op_exit) {
return;
}
if ((bytecode[ctx.pc].fidx!=bk_fidx ||
bytecode[ctx.pc].line!=bk_line) && // break point
!next) {// next step
return;
}
next=false;
std::string cmd;
step_info();
while(true) {
std::clog<<">> ";
std::getline(std::cin, cmd);
auto res=parse(cmd);
if (res.size()==0) {
step_info();
} else if (res.size()==1) {
switch(get_cmd_type(res[0])) {
case dbg_cmd::cmd_help: help(); break;
case dbg_cmd::cmd_backtrace: traceback(); break;
case dbg_cmd::cmd_continue: return;
case dbg_cmd::cmd_list_file: list_file(); break;
case dbg_cmd::cmd_global: gstate(); break;
case dbg_cmd::cmd_local: lstate(); break;
case dbg_cmd::cmd_upval: ustate(); break;
case dbg_cmd::cmd_register: reginfo(); break;
case dbg_cmd::cmd_show_all: detail(); break;
case dbg_cmd::cmd_next: next=true; return;
case dbg_cmd::cmd_exit: std::exit(0);
default: err(); break;
}
} else if (res.size()==3 &&
get_cmd_type(res[0])==dbg_cmd::cmd_break_point) {
bk_fidx=file_index(res[1]);
if (bk_fidx==65535) {
std::clog<<"cannot find file named `"<<res[1]<<"`\n";
continue;
}
i32 tmp=atoi(res[2].c_str());
if (tmp<=0) {
std::clog<<"incorrect line number `"<<res[2]<<"`\n";
} else {
bk_line=tmp;
}
} else {
err();
}
}
}
void dbg::run(
const codegen& gen,
const linker& linker,
const std::vector<std::string>& argv) {
verbose=true;
fsize=linker.filelist().size();
init(gen.strs(), gen.nums(), gen.codes(), linker.filelist(), argv);
u64 count[op_ret+1]={0};
typedef void (dbg::*nafunc)();
const nafunc oprs[]={
nullptr, &dbg::o_intg,
&dbg::o_intl, &dbg::o_loadg,
&dbg::o_loadl, &dbg::o_loadu,
&dbg::o_pnum, &dbg::o_pnil,
&dbg::o_pstr, &dbg::o_newv,
&dbg::o_newh, &dbg::o_newf,
&dbg::o_happ, &dbg::o_para,
&dbg::o_deft, &dbg::o_dyn,
&dbg::o_lnot, &dbg::o_usub,
&dbg::o_bnot, &dbg::o_btor,
&dbg::o_btxor, &dbg::o_btand,
&dbg::o_add, &dbg::o_sub,
&dbg::o_mul, &dbg::o_div,
&dbg::o_lnk, &dbg::o_addc,
&dbg::o_subc, &dbg::o_mulc,
&dbg::o_divc, &dbg::o_lnkc,
&dbg::o_addeq, &dbg::o_subeq,
&dbg::o_muleq, &dbg::o_diveq,
&dbg::o_lnkeq, &dbg::o_bandeq,
&dbg::o_boreq, &dbg::o_bxoreq,
&dbg::o_addeqc, &dbg::o_subeqc,
&dbg::o_muleqc, &dbg::o_diveqc,
&dbg::o_lnkeqc, &dbg::o_addecp,
&dbg::o_subecp, &dbg::o_mulecp,
&dbg::o_divecp, &dbg::o_lnkecp,
&dbg::o_meq, &dbg::o_eq,
&dbg::o_neq, &dbg::o_less,
&dbg::o_leq, &dbg::o_grt,
&dbg::o_geq, &dbg::o_lessc,
&dbg::o_leqc, &dbg::o_grtc,
&dbg::o_geqc, &dbg::o_pop,
&dbg::o_jmp, &dbg::o_jt,
&dbg::o_jf, &dbg::o_cnt,
&dbg::o_findex, &dbg::o_feach,
&dbg::o_callg, &dbg::o_calll,
&dbg::o_upval, &dbg::o_callv,
&dbg::o_callvi, &dbg::o_callh,
&dbg::o_callfv, &dbg::o_callfh,
&dbg::o_callb, &dbg::o_slcbeg,
&dbg::o_slcend, &dbg::o_slc,
&dbg::o_slc2, &dbg::o_mcallg,
&dbg::o_mcalll, &dbg::o_mupval,
&dbg::o_mcallv, &dbg::o_mcallh,
&dbg::o_ret
};
std::vector<u32> code;
for(auto& i:gen.codes()) {
code.push_back(i.op);
imm.push_back(i.num);
}
while(oprs[code[ctx.pc]]) {
interact();
++count[code[ctx.pc]];
(this->*oprs[code[ctx.pc]])();
if (ctx.top>=ctx.canary) {
die("stack overflow");
}
++ctx.pc;
}
call_sort(count);
ngc.info();
ngc.clear();
imm.clear();
return;
}

87
ast/nasal_new_dbg.h Normal file
View File

@ -0,0 +1,87 @@
#pragma once
#include "nasal_new_import.h"
#include "nasal_new_err.h"
#include "nasal_new_opcode.h"
#include "nasal_new_vm.h"
#include <cstring>
#include <algorithm>
#include <unordered_map>
class dbg:public vm {
private:
enum class dbg_cmd {
cmd_error,
cmd_help,
cmd_backtrace,
cmd_continue,
cmd_list_file,
cmd_global,
cmd_local,
cmd_upval,
cmd_register,
cmd_show_all,
cmd_next,
cmd_break_point,
cmd_exit
};
private:
const std::unordered_map<std::string, dbg_cmd> command_table = {
{"h", dbg_cmd::cmd_help},
{"help", dbg_cmd::cmd_help},
{"bt", dbg_cmd::cmd_backtrace},
{"backtrace", dbg_cmd::cmd_backtrace},
{"c", dbg_cmd::cmd_continue},
{"continue", dbg_cmd::cmd_continue},
{"f", dbg_cmd::cmd_list_file},
{"file", dbg_cmd::cmd_list_file},
{"g", dbg_cmd::cmd_global},
{"global", dbg_cmd::cmd_global},
{"l", dbg_cmd::cmd_local},
{"local", dbg_cmd::cmd_local},
{"u", dbg_cmd::cmd_upval},
{"upval", dbg_cmd::cmd_upval},
{"r", dbg_cmd::cmd_register},
{"register", dbg_cmd::cmd_register},
{"a", dbg_cmd::cmd_show_all},
{"all", dbg_cmd::cmd_show_all},
{"n", dbg_cmd::cmd_next},
{"next", dbg_cmd::cmd_next},
{"bk", dbg_cmd::cmd_break_point},
{"break", dbg_cmd::cmd_break_point},
{"q", dbg_cmd::cmd_exit},
{"exit", dbg_cmd::cmd_exit}
};
dbg_cmd get_cmd_type(const std::string& cmd) const {
return command_table.count(cmd)?
command_table.at(cmd):dbg_cmd::cmd_error;
}
private:
bool next;
usize fsize;
u16 bk_fidx;
u32 bk_line;
error& src;
std::vector<std::string> parse(const std::string&);
u16 file_index(const std::string&) const;
void err();
void help();
void list_file() const;
void call_sort(const u64*) const;
void step_info();
void interact();
public:
dbg(error& err):
next(false), fsize(0),
bk_fidx(0), bk_line(0),
src(err) {}
void run(
const codegen&,
const linker&,
const std::vector<std::string>&
);
};

View File

@ -8,6 +8,9 @@
#include "ast_dumper.h"
#include "symbol_finder.h"
#include "optimizer.h"
#include "nasal_new_codegen.h"
#include "nasal_new_vm.h"
#include "nasal_new_dbg.h"
#include <unordered_map>
#include <thread>
@ -73,8 +76,8 @@ void err() {
void execute(
const std::string& file,
const std::vector<std::string>& argv,
const u32 cmd
) {
const u32 cmd) {
using clk=std::chrono::high_resolution_clock;
const auto den=clk::duration::period::den;
@ -82,8 +85,8 @@ void execute(
lexer lex(err);
parse parse(err);
linker ld(err);
// codegen gen(err);
// vm ctx;
codegen gen(err);
vm ctx;
// lexer scans file to get tokens
lex.scan(file).chkerr();
@ -103,24 +106,19 @@ void execute(
opt->do_optimization(parse.tree());
delete opt;
auto finder = new symbol_finder;
for(const auto& symbol : finder->do_find(parse.tree())) {
std::cout << symbol << std::endl;
}
// code generator gets parser's ast and import file list to generate code
// gen.compile(parse, ld).chkerr();
// if (cmd&VM_CODE) {
// gen.print();
// }
gen.compile(parse, ld).chkerr();
if (cmd&VM_CODE) {
gen.print();
}
// run
auto start=clk::now();
// if (cmd&VM_DEBUG) {
// dbg(err).run(gen, ld, argv);
// } else if (cmd&VM_TIME || cmd&VM_EXEC) {
// ctx.run(gen, ld, argv, cmd&VM_DETAIL);
// }
if (cmd&VM_DEBUG) {
dbg(err).run(gen, ld, argv);
} else if (cmd&VM_TIME || cmd&VM_EXEC) {
ctx.run(gen, ld, argv, cmd&VM_DETAIL);
}
// get running time
if (cmd&VM_TIME) {

View File

@ -1,5 +1,30 @@
#include "nasal_new_opcode.h"
const char* opname[]={
"exit ","intg ","intl ","loadg ",
"loadl ","loadu ","pnum ","pnil ",
"pstr ","newv ","newh ","newf ",
"happ ","para ","def ","dyn ",
"lnot ","usub ","bnot ","btor ",
"btxor ","btand ","add ","sub ",
"mult ","div ","lnk ","addc ",
"subc ","multc ","divc ","lnkc ",
"addeq ","subeq ","muleq ","diveq ",
"lnkeq ","bandeq","boreq ","bxoreq",
"addeqc","subeqc","muleqc","diveqc",
"lnkeqc","addecp","subecp","mulecp",
"divecp","lnkecp","meq ","eq ",
"neq ","less ","leq ","grt ",
"geq ","lessc ","leqc ","grtc ",
"geqc ","pop ","jmp ","jt ",
"jf ","cnt ","findx ","feach ",
"callg ","calll ","upval ","callv ",
"callvi","callh ","callfv","callfh",
"callb ","slcbeg","slcend","slc ",
"slc2 ","mcallg","mcalll","mupval",
"mcallv","mcallh","ret "
};
void codestream::set(
const f64* numbuff,
const std::string* strbuff,

View File

@ -95,31 +95,6 @@ enum op_code_type:u8 {
op_ret // return
};
const char* opname[]={
"exit ","intg ","intl ","loadg ",
"loadl ","loadu ","pnum ","pnil ",
"pstr ","newv ","newh ","newf ",
"happ ","para ","def ","dyn ",
"lnot ","usub ","bnot ","btor ",
"btxor ","btand ","add ","sub ",
"mult ","div ","lnk ","addc ",
"subc ","multc ","divc ","lnkc ",
"addeq ","subeq ","muleq ","diveq ",
"lnkeq ","bandeq","boreq ","bxoreq",
"addeqc","subeqc","muleqc","diveqc",
"lnkeqc","addecp","subecp","mulecp",
"divecp","lnkecp","meq ","eq ",
"neq ","less ","leq ","grt ",
"geq ","lessc ","leqc ","grtc ",
"geqc ","pop ","jmp ","jt ",
"jf ","cnt ","findx ","feach ",
"callg ","calll ","upval ","callv ",
"callvi","callh ","callfv","callfh",
"callb ","slcbeg","slcend","slc ",
"slc2 ","mcallg","mcalll","mupval",
"mcallv","mcallh","ret "
};
struct opcode {
u8 op; // opcode
u16 fidx; // source code file index
@ -143,4 +118,6 @@ public:
void dump(std::ostream&) const;
};
std::ostream& operator<<(std::ostream&, const codestream&);
std::ostream& operator<<(std::ostream&, const codestream&);
extern const char* opname[];

1129
ast/nasal_new_vm.cpp Normal file

File diff suppressed because it is too large Load Diff

159
ast/nasal_new_vm.h Normal file
View File

@ -0,0 +1,159 @@
#pragma once
#include <iomanip>
#include <stack>
#include "nasal_new_import.h"
#include "nasal_new_gc.h"
#include "nasal_new_codegen.h"
#ifdef _MSC_VER
#pragma warning (disable:4244)
#pragma warning (disable:4267)
#pragma warning (disable:4102)
#endif
class vm {
protected:
/* registers and constants of vm */
context ctx;
/* constants */
const f64* cnum=nullptr; // constant numbers
const std::string* cstr=nullptr; // constant symbols and strings
std::vector<u32> imm; // immediate number table
/* garbage collector */
gc ngc;
/* main stack */
var stack[STACK_DEPTH];
/* values used for debugger */
const std::string* files=nullptr; // file name list
const opcode* bytecode=nullptr; // bytecode buffer address
/* vm initializing function */
void init(
const std::vector<std::string>&,
const std::vector<f64>&,
const std::vector<opcode>&,
const std::vector<std::string>&,
const std::vector<std::string>&);
/* debug functions */
bool verbose;
void valinfo(var&);
void traceback();
void stackinfo(const u32);
void reginfo();
void gstate();
void lstate();
void ustate();
void detail();
void die(const std::string&);
/* vm calculation functions*/
bool cond(var&);
/* vm operands */
void o_intg();
void o_intl();
void o_loadg();
void o_loadl();
void o_loadu();
void o_pnum();
void o_pnil();
void o_pstr();
void o_newv();
void o_newh();
void o_newf();
void o_happ();
void o_para();
void o_deft();
void o_dyn();
void o_lnot();
void o_usub();
void o_bnot();
void o_btor();
void o_btxor();
void o_btand();
void o_add();
void o_sub();
void o_mul();
void o_div();
void o_lnk();
void o_addc();
void o_subc();
void o_mulc();
void o_divc();
void o_lnkc();
void o_addeq();
void o_subeq();
void o_muleq();
void o_diveq();
void o_lnkeq();
void o_bandeq();
void o_boreq();
void o_bxoreq();
void o_addeqc();
void o_subeqc();
void o_muleqc();
void o_diveqc();
void o_lnkeqc();
void o_addecp();
void o_subecp();
void o_mulecp();
void o_divecp();
void o_lnkecp();
void o_meq();
void o_eq();
void o_neq();
void o_less();
void o_leq();
void o_grt();
void o_geq();
void o_lessc();
void o_leqc();
void o_grtc();
void o_geqc();
void o_pop();
void o_jmp();
void o_jt();
void o_jf();
void o_cnt();
void o_findex();
void o_feach();
void o_callg();
void o_calll();
void o_upval();
void o_callv();
void o_callvi();
void o_callh();
void o_callfv();
void o_callfh();
void o_callb();
void o_slcbeg();
void o_slcend();
void o_slc();
void o_slc2();
void o_mcallg();
void o_mcalll();
void o_mupval();
void o_mcallv();
void o_mcallh();
void o_ret();
public:
/* constructor of vm instance */
vm(): ngc(&ctx), verbose(false) {}
/* execution entry */
void run(
const codegen&,
const linker&,
const std::vector<std::string>&,
const bool
);
};

View File

@ -84,6 +84,8 @@ NASAL_NEW_AST=\
nasal_new_codegen.o\
nasal_new_opcode.o\
nasal_new_parse.o\
nasal_new_vm.o\
nasal_new_dbg.o\
optimizer.o\
symbol_finder.o\
ast_visitor.o\
@ -120,7 +122,7 @@ nasal_new_builtin.o: ast/nasal_new_builtin.h ast/nasal_new_builtin.cpp
$(CXX) -std=$(STD) -c -O3 ast/nasal_new_builtin.cpp -fno-exceptions -fPIC -o nasal_new_builtin.o -I .
nasal_new_codegen.o: ast/nasal_new_codegen.h ast/nasal_new_codegen.cpp
# $(CXX) -std=$(STD) -c -O3 ast/nasal_new_codegen.cpp -fno-exceptions -fPIC -o nasal_new_codegen.o -I .
$(CXX) -std=$(STD) -c -O3 ast/nasal_new_codegen.cpp -fno-exceptions -fPIC -o nasal_new_codegen.o -I .
nasal_new_opcode.o: ast/nasal_new_opcode.h ast/nasal_new_opcode.cpp
$(CXX) -std=$(STD) -c -O3 ast/nasal_new_opcode.cpp -fno-exceptions -fPIC -o nasal_new_opcode.o -I .
@ -140,6 +142,12 @@ ast_visitor.o: ast/nasal_new_ast.h ast/ast_visitor.h ast/ast_visitor.cpp
ast_dumper.o: ast/nasal_new_ast.h ast/ast_visitor.h ast/ast_dumper.h ast/ast_dumper.cpp
$(CXX) -std=$(STD) -c -O3 ast/ast_dumper.cpp -fno-exceptions -fPIC -o ast_dumper.o -I .
nasal_new_vm.o: ast/nasal_new_vm.h ast/nasal_new_vm.cpp
$(CXX) -std=$(STD) -c -O3 ast/nasal_new_vm.cpp -fno-exceptions -fPIC -o nasal_new_vm.o -I .
nasal_new_dbg.o: ast/nasal_new_dbg.h ast/nasal_new_dbg.cpp
$(CXX) -std=$(STD) -c -O3 ast/nasal_new_dbg.cpp -fno-exceptions -fPIC -o nasal_new_dbg.o -I .
.PHONY: nasal_new_clean
nasal_new_clean:
rm $(NASAL_NEW_AST)