update
This commit is contained in:
parent
7f6a521ad7
commit
789300e5f6
7
main.cpp
7
main.cpp
|
@ -3,9 +3,10 @@
|
||||||
nasal_lexer lexer;
|
nasal_lexer lexer;
|
||||||
nasal_parse parse;
|
nasal_parse parse;
|
||||||
nasal_import import;
|
nasal_import import;
|
||||||
nasal_codegen code_generator;
|
|
||||||
std::string inputfile="null";
|
std::string inputfile="null";
|
||||||
nasal_runtime runtime;
|
nasal_runtime runtime;
|
||||||
|
nasal_codegen code_generator;
|
||||||
|
nasal_bytecode_vm bytevm;
|
||||||
|
|
||||||
void help()
|
void help()
|
||||||
{
|
{
|
||||||
|
@ -131,6 +132,10 @@ void execute()
|
||||||
}
|
}
|
||||||
code_generator.main_progress(import.get_root());
|
code_generator.main_progress(import.get_root());
|
||||||
code_generator.print_byte_code();
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
1
nasal.h
1
nasal.h
|
@ -27,5 +27,6 @@
|
||||||
#include "nasal_builtin.h"
|
#include "nasal_builtin.h"
|
||||||
#include "nasal_runtime.h"
|
#include "nasal_runtime.h"
|
||||||
#include "nasal_codegen.h"
|
#include "nasal_codegen.h"
|
||||||
|
#include "nasal_bytecode_vm.h"
|
||||||
|
|
||||||
#endif
|
#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_jmp,
|
||||||
op_jmptrue,
|
op_jmptrue,
|
||||||
op_jmpfalse,
|
op_jmpfalse,
|
||||||
op_jp,
|
|
||||||
op_jtp,
|
|
||||||
op_jfp,
|
|
||||||
op_forindex, // index counter on the top of forindex_stack plus 1
|
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_foreach, // index counter on the top of forindex_stack plus 1 and get the value in vector
|
||||||
op_call, // call identifier
|
op_call, // call identifier
|
||||||
|
@ -87,9 +84,6 @@ struct
|
||||||
{op_jmp, "jmp "},
|
{op_jmp, "jmp "},
|
||||||
{op_jmptrue, "jt "},
|
{op_jmptrue, "jt "},
|
||||||
{op_jmpfalse, "jf "},
|
{op_jmpfalse, "jf "},
|
||||||
{op_jp, "jp "},
|
|
||||||
{op_jtp, "jtp "},
|
|
||||||
{op_jfp, "jfp "},
|
|
||||||
{op_forindex, "findx "},
|
{op_forindex, "findx "},
|
||||||
{op_foreach, "feach "},
|
{op_foreach, "feach "},
|
||||||
{op_call, "call "},
|
{op_call, "call "},
|
||||||
|
@ -119,6 +113,12 @@ struct opcode
|
||||||
index=0;
|
index=0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
opcode& operator=(opcode& tmp)
|
||||||
|
{
|
||||||
|
op=tmp.op;
|
||||||
|
index=tmp.index;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// unfinished
|
// unfinished
|
||||||
|
@ -175,6 +175,9 @@ public:
|
||||||
void main_progress(nasal_ast&);
|
void main_progress(nasal_ast&);
|
||||||
void print_op(int);
|
void print_op(int);
|
||||||
void print_byte_code();
|
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()
|
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)
|
if(tmp.get_type()==ast_if || tmp.get_type()==ast_elsif)
|
||||||
{
|
{
|
||||||
calculation_gen(tmp.get_children()[0]);
|
calculation_gen(tmp.get_children()[0]);
|
||||||
op.op=op_jfp;
|
op.op=op_jmpfalse;
|
||||||
int ptr=exec_code.size();
|
int ptr=exec_code.size();
|
||||||
exec_code.push_back(op);
|
exec_code.push_back(op);
|
||||||
|
|
||||||
pop_gen();
|
pop_gen();
|
||||||
block_gen(tmp.get_children()[1]);
|
block_gen(tmp.get_children()[1]);
|
||||||
|
|
||||||
op.op=op_jmp;
|
op.op=op_jmp;
|
||||||
jmp_label.push_back(exec_code.size());
|
jmp_label.push_back(exec_code.size());
|
||||||
exec_code.push_back(op);
|
exec_code.push_back(op);
|
||||||
exec_code[ptr].index=exec_code.size();
|
exec_code[ptr].index=exec_code.size();
|
||||||
|
pop_gen();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -677,7 +683,7 @@ void nasal_codegen::loop_gen(nasal_ast& ast)
|
||||||
void nasal_codegen::load_continue_break()
|
void nasal_codegen::load_continue_break()
|
||||||
{
|
{
|
||||||
for(int i=0;i<continue_ptr.size();++i)
|
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();
|
continue_ptr.clear();
|
||||||
for(int i=0;i<break_ptr.size();++i)
|
for(int i=0;i<break_ptr.size();++i)
|
||||||
exec_code[break_ptr[i]].index=exec_code.size();
|
exec_code[break_ptr[i]].index=exec_code.size();
|
||||||
|
@ -690,7 +696,7 @@ void nasal_codegen::while_gen(nasal_ast& ast)
|
||||||
opcode op;
|
opcode op;
|
||||||
int loop_ptr=exec_code.size();
|
int loop_ptr=exec_code.size();
|
||||||
calculation_gen(ast.get_children()[0]);
|
calculation_gen(ast.get_children()[0]);
|
||||||
op.op=op_jfp;
|
op.op=op_jmpfalse;
|
||||||
int condition_ptr=exec_code.size();
|
int condition_ptr=exec_code.size();
|
||||||
exec_code.push_back(op);
|
exec_code.push_back(op);
|
||||||
pop_gen();
|
pop_gen();
|
||||||
|
@ -699,6 +705,7 @@ void nasal_codegen::while_gen(nasal_ast& ast)
|
||||||
op.index=loop_ptr;
|
op.index=loop_ptr;
|
||||||
exec_code.push_back(op);
|
exec_code.push_back(op);
|
||||||
exec_code[condition_ptr].index=exec_code.size();
|
exec_code[condition_ptr].index=exec_code.size();
|
||||||
|
pop_gen();
|
||||||
load_continue_break();
|
load_continue_break();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -729,7 +736,7 @@ void nasal_codegen::for_gen(nasal_ast& ast)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
calculation_gen(ast.get_children()[1]);
|
calculation_gen(ast.get_children()[1]);
|
||||||
op.op=op_jfp;
|
op.op=op_jmpfalse;
|
||||||
int label_exit=exec_code.size();
|
int label_exit=exec_code.size();
|
||||||
exec_code.push_back(op);
|
exec_code.push_back(op);
|
||||||
pop_gen();
|
pop_gen();
|
||||||
|
@ -752,6 +759,7 @@ void nasal_codegen::for_gen(nasal_ast& ast)
|
||||||
op.index=jmp_place;
|
op.index=jmp_place;
|
||||||
exec_code.push_back(op);
|
exec_code.push_back(op);
|
||||||
exec_code[label_exit].index=exec_code.size();
|
exec_code[label_exit].index=exec_code.size();
|
||||||
|
pop_gen();
|
||||||
load_continue_break();
|
load_continue_break();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1239,4 +1247,19 @@ void nasal_codegen::print_byte_code()
|
||||||
return;
|
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
|
#endif
|
Loading…
Reference in New Issue