update
This commit is contained in:
parent
7f6a521ad7
commit
789300e5f6
7
main.cpp
7
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;
|
||||
}
|
||||
|
||||
|
|
1
nasal.h
1
nasal.h
|
@ -27,5 +27,6 @@
|
|||
#include "nasal_builtin.h"
|
||||
#include "nasal_runtime.h"
|
||||
#include "nasal_codegen.h"
|
||||
#include "nasal_bytecode_vm.h"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue