This commit is contained in:
Valk Richard Li 2020-12-10 00:01:25 +08:00
parent 7f6a521ad7
commit 789300e5f6
4 changed files with 221 additions and 11 deletions

View File

@ -3,9 +3,10 @@
nasal_lexer lexer;
nasal_parse parse;
nasal_import import;
nasal_codegen code_generator;
std::string inputfile="null";
nasal_runtime runtime;
nasal_codegen code_generator;
nasal_bytecode_vm bytevm;
void help()
{
@ -131,6 +132,10 @@ void execute()
}
code_generator.main_progress(import.get_root());
code_generator.print_byte_code();
bytevm.set_string_table(code_generator.get_string_table());
bytevm.set_number_table(code_generator.get_number_table());
bytevm.set_exec_code(code_generator.get_exec_code());
//bytevm.run();
return;
}

View File

@ -27,5 +27,6 @@
#include "nasal_builtin.h"
#include "nasal_runtime.h"
#include "nasal_codegen.h"
#include "nasal_bytecode_vm.h"
#endif

181
nasal_bytecode_vm.h Normal file
View File

@ -0,0 +1,181 @@
#ifndef __NASAL_BYTECODE_VM_H__
#define __NASAL_BYTECODE_VM_H__
class nasal_bytecode_vm
{
private:
int ptr;
int global_scope_addr;
nasal_virtual_machine vm;
std::vector<opcode> exec_code;
std::stack<int> value_stack;
std::vector<std::string> string_table;
std::vector<double> number_table;
std::map<int,void (nasal_bytecode_vm::*)()> opr_table;
void opr_nop();
void opr_load();
void opr_pushnum();
void opr_pushone();
void opr_pushzero();
void opr_pushnil();
void opr_pushstr();
public:
nasal_bytecode_vm();
~nasal_bytecode_vm();
void set_string_table(std::vector<std::string>&);
void set_number_table(std::vector<double>&);
void set_exec_code(std::vector<opcode>&);
void run();
};
nasal_bytecode_vm::nasal_bytecode_vm()
{
struct
{
int op;
void (nasal_bytecode_vm::*ptr)();
}function_table[]=
{
{op_nop,nasal_bytecode_vm::opr_nop},
{op_load,nasal_bytecode_vm::opr_load},
{op_pushnum,nasal_bytecode_vm::opr_pushnum},
{op_pushone,nasal_bytecode_vm::opr_pushone},
{op_pushzero,nasal_bytecode_vm::opr_pushzero},
{op_pushnil,nasal_bytecode_vm::opr_pushnil},
{op_pushstr,nasal_bytecode_vm::opr_pushstr},
{op_newvec, NULL},
{op_newhash, NULL},
{op_newfunc, NULL},
{op_vecapp, NULL},
{op_hashapp, NULL},
{op_para, NULL},
{op_defpara, NULL},
{op_dynpara, NULL},
{op_entry, NULL},
{op_unot, NULL},
{op_usub, NULL},
{op_add, NULL},
{op_sub, NULL},
{op_mul, NULL},
{op_div, NULL},
{op_lnk, NULL},
{op_addeq, NULL},
{op_subeq, NULL},
{op_muleq, NULL},
{op_diveq, NULL},
{op_lnkeq, NULL},
{op_meq, NULL},
{op_eq, NULL},
{op_neq, NULL},
{op_less, NULL},
{op_leq, NULL},
{op_grt, NULL},
{op_geq, NULL},
{op_pop, NULL},
{op_jmp, NULL},
{op_jmptrue, NULL},
{op_jmpfalse, NULL},
{op_forindex, NULL},
{op_foreach, NULL},
{op_call, NULL},
{op_callv, NULL},
{op_callvi, NULL},
{op_callh, NULL},
{op_callf, NULL},
{op_builtincall, NULL},
{op_slicebegin, NULL},
{op_sliceend, NULL},
{op_slice, NULL},
{op_slice2, NULL},
{op_mcall, NULL},
{op_mcallv, NULL},
{op_mcallh, NULL},
{op_return, NULL},
{-1,NULL}
};
for(int i=0;function_table[i].ptr;++i)
opr_table[function_table[i].op]=function_table[i].ptr;
return;
}
nasal_bytecode_vm::~nasal_bytecode_vm()
{
opr_table.clear();
return;
}
void nasal_bytecode_vm::opr_nop()
{
return;
}
void nasal_bytecode_vm::opr_load()
{
int val_addr=value_stack.top();
value_stack.pop();
vm.gc_get(global_scope_addr).get_closure().add_new_value(string_table[exec_code[ptr].index],val_addr);
return;
}
void nasal_bytecode_vm::opr_pushnum()
{
int val_addr=vm.gc_alloc(vm_number);
vm.gc_get(val_addr).set_number(number_table[exec_code[ptr].index]);
value_stack.push(val_addr);
return;
}
void nasal_bytecode_vm::opr_pushone()
{
int val_addr=vm.gc_alloc(vm_number);
vm.gc_get(val_addr).set_number(1);
value_stack.push(val_addr);
return;
}
void nasal_bytecode_vm::opr_pushzero()
{
int val_addr=vm.gc_alloc(vm_number);
vm.gc_get(val_addr).set_number(0);
value_stack.push(val_addr);
return;
}
void nasal_bytecode_vm::opr_pushnil()
{
int val_addr=vm.gc_alloc(vm_nil);
value_stack.push(val_addr);
return;
}
void nasal_bytecode_vm::opr_pushstr()
{
int val_addr=vm.gc_alloc(vm_string);
vm.gc_get(val_addr).set_string(string_table[exec_code[ptr].index]);
value_stack.push(val_addr);
return;
}
void nasal_bytecode_vm::set_string_table(std::vector<std::string>& table)
{
string_table=table;
return;
}
void nasal_bytecode_vm::set_number_table(std::vector<double>& table)
{
number_table=table;
return;
}
void nasal_bytecode_vm::set_exec_code(std::vector<opcode>& exec)
{
int size=exec.size();
for(int i=0;i<size;++i)
{
opcode tmp;
tmp=exec[i];
exec_code.push_back(tmp);
}
return;
}
void nasal_bytecode_vm::run()
{
global_scope_addr=vm.gc_alloc(vm_closure);
int size=exec_code.size();
for(ptr=0;ptr<size;++ptr)
(this->*opr_table[exec_code[ptr].op])();
vm.del_reference(global_scope_addr);
return;
}
#endif

View File

@ -21,9 +21,6 @@ enum op_code
op_jmp,
op_jmptrue,
op_jmpfalse,
op_jp,
op_jtp,
op_jfp,
op_forindex, // index counter on the top of forindex_stack plus 1
op_foreach, // index counter on the top of forindex_stack plus 1 and get the value in vector
op_call, // call identifier
@ -87,9 +84,6 @@ struct
{op_jmp, "jmp "},
{op_jmptrue, "jt "},
{op_jmpfalse, "jf "},
{op_jp, "jp "},
{op_jtp, "jtp "},
{op_jfp, "jfp "},
{op_forindex, "findx "},
{op_foreach, "feach "},
{op_call, "call "},
@ -119,6 +113,12 @@ struct opcode
index=0;
return;
}
opcode& operator=(opcode& tmp)
{
op=tmp.op;
index=tmp.index;
return *this;
}
};
// unfinished
@ -175,6 +175,9 @@ public:
void main_progress(nasal_ast&);
void print_op(int);
void print_byte_code();
std::vector<std::string>& get_string_table();
std::vector<double>& get_number_table();
std::vector<opcode>& get_exec_code();
};
nasal_codegen::nasal_codegen()
@ -641,15 +644,18 @@ void nasal_codegen::conditional_gen(nasal_ast& ast)
if(tmp.get_type()==ast_if || tmp.get_type()==ast_elsif)
{
calculation_gen(tmp.get_children()[0]);
op.op=op_jfp;
op.op=op_jmpfalse;
int ptr=exec_code.size();
exec_code.push_back(op);
pop_gen();
block_gen(tmp.get_children()[1]);
op.op=op_jmp;
jmp_label.push_back(exec_code.size());
exec_code.push_back(op);
exec_code[ptr].index=exec_code.size();
pop_gen();
}
else
{
@ -677,7 +683,7 @@ void nasal_codegen::loop_gen(nasal_ast& ast)
void nasal_codegen::load_continue_break()
{
for(int i=0;i<continue_ptr.size();++i)
exec_code[continue_ptr[i]].index=exec_code.size()-1;
exec_code[continue_ptr[i]].index=exec_code.size()-2;
continue_ptr.clear();
for(int i=0;i<break_ptr.size();++i)
exec_code[break_ptr[i]].index=exec_code.size();
@ -690,7 +696,7 @@ void nasal_codegen::while_gen(nasal_ast& ast)
opcode op;
int loop_ptr=exec_code.size();
calculation_gen(ast.get_children()[0]);
op.op=op_jfp;
op.op=op_jmpfalse;
int condition_ptr=exec_code.size();
exec_code.push_back(op);
pop_gen();
@ -699,6 +705,7 @@ void nasal_codegen::while_gen(nasal_ast& ast)
op.index=loop_ptr;
exec_code.push_back(op);
exec_code[condition_ptr].index=exec_code.size();
pop_gen();
load_continue_break();
return;
}
@ -729,7 +736,7 @@ void nasal_codegen::for_gen(nasal_ast& ast)
}
else
calculation_gen(ast.get_children()[1]);
op.op=op_jfp;
op.op=op_jmpfalse;
int label_exit=exec_code.size();
exec_code.push_back(op);
pop_gen();
@ -752,6 +759,7 @@ void nasal_codegen::for_gen(nasal_ast& ast)
op.index=jmp_place;
exec_code.push_back(op);
exec_code[label_exit].index=exec_code.size();
pop_gen();
load_continue_break();
return;
}
@ -1239,4 +1247,19 @@ void nasal_codegen::print_byte_code()
return;
}
std::vector<std::string>& nasal_codegen::get_string_table()
{
return string_result_table;
}
std::vector<double>& nasal_codegen::get_number_table()
{
return number_result_table;
}
std::vector<opcode>& nasal_codegen::get_exec_code()
{
return exec_code;
}
#endif