From 789300e5f6528cfaa3d888d5cc5f6a1d6dc504d0 Mon Sep 17 00:00:00 2001 From: Valk Richard Li <48872266+ValKmjolnir@users.noreply.github.com> Date: Thu, 10 Dec 2020 00:01:25 +0800 Subject: [PATCH] update --- main.cpp | 7 +- nasal.h | 1 + nasal_bytecode_vm.h | 181 ++++++++++++++++++++++++++++++++++++++++++++ nasal_codegen.h | 43 ++++++++--- 4 files changed, 221 insertions(+), 11 deletions(-) create mode 100644 nasal_bytecode_vm.h diff --git a/main.cpp b/main.cpp index acd5da3..1a586bf 100644 --- a/main.cpp +++ b/main.cpp @@ -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; } diff --git a/nasal.h b/nasal.h index d26aab3..e278d97 100644 --- a/nasal.h +++ b/nasal.h @@ -27,5 +27,6 @@ #include "nasal_builtin.h" #include "nasal_runtime.h" #include "nasal_codegen.h" +#include "nasal_bytecode_vm.h" #endif diff --git a/nasal_bytecode_vm.h b/nasal_bytecode_vm.h new file mode 100644 index 0000000..b606355 --- /dev/null +++ b/nasal_bytecode_vm.h @@ -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 exec_code; + std::stack value_stack; + std::vector string_table; + std::vector number_table; + std::map 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&); + void set_number_table(std::vector&); + void set_exec_code(std::vector&); + 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& table) +{ + string_table=table; + return; +} +void nasal_bytecode_vm::set_number_table(std::vector& table) +{ + number_table=table; + return; +} +void nasal_bytecode_vm::set_exec_code(std::vector& exec) +{ + int size=exec.size(); + for(int i=0;i*opr_table[exec_code[ptr].op])(); + vm.del_reference(global_scope_addr); + return; +} +#endif \ No newline at end of file diff --git a/nasal_codegen.h b/nasal_codegen.h index a321149..0833bf8 100644 --- a/nasal_codegen.h +++ b/nasal_codegen.h @@ -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& get_string_table(); + std::vector& get_number_table(); + std::vector& 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& nasal_codegen::get_string_table() +{ + return string_result_table; +} + +std::vector& nasal_codegen::get_number_table() +{ + return number_result_table; +} + +std::vector& nasal_codegen::get_exec_code() +{ + return exec_code; +} + #endif \ No newline at end of file