prepare for byte code interpreter
This commit is contained in:
parent
939a7a62b7
commit
50694f467b
|
@ -4,6 +4,7 @@ nasal_resource resource;
|
||||||
nasal_lexer lexer;
|
nasal_lexer lexer;
|
||||||
nasal_parse parse;
|
nasal_parse parse;
|
||||||
nasal_import preprocessor;
|
nasal_import preprocessor;
|
||||||
|
nasal_codegen code_generator;
|
||||||
std::string command;
|
std::string command;
|
||||||
std::string inputfile="null";
|
std::string inputfile="null";
|
||||||
nasal_runtime runtime;
|
nasal_runtime runtime;
|
||||||
|
@ -17,6 +18,7 @@ void help()
|
||||||
std::cout<<">> [lex ] use lexer to turn code into tokens."<<std::endl;
|
std::cout<<">> [lex ] use lexer to turn code into tokens."<<std::endl;
|
||||||
std::cout<<">> [ast ] do parsing and check the abstract syntax tree."<<std::endl;
|
std::cout<<">> [ast ] do parsing and check the abstract syntax tree."<<std::endl;
|
||||||
std::cout<<">> [run ] run code."<<std::endl;
|
std::cout<<">> [run ] run code."<<std::endl;
|
||||||
|
std::cout<<">> [exec ] generate byte code."<<std::endl;
|
||||||
std::cout<<">> [logo ] print logo of nasal ."<<std::endl;
|
std::cout<<">> [logo ] print logo of nasal ."<<std::endl;
|
||||||
std::cout<<">> [exit ] quit nasal interpreter."<<std::endl;
|
std::cout<<">> [exit ] quit nasal interpreter."<<std::endl;
|
||||||
return;
|
return;
|
||||||
|
@ -104,6 +106,32 @@ void runtime_start()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void codegen_start()
|
||||||
|
{
|
||||||
|
lexer.scanner(resource.get_file());
|
||||||
|
if(lexer.get_error())
|
||||||
|
{
|
||||||
|
die("lexer",inputfile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
parse.set_toklist(lexer.get_token_list());
|
||||||
|
parse.main_process();
|
||||||
|
if(parse.get_error())
|
||||||
|
{
|
||||||
|
die("parse",inputfile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
preprocessor.preprocessing(parse.get_root());
|
||||||
|
if(preprocessor.get_error())
|
||||||
|
{
|
||||||
|
die("import",inputfile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
runtime.set_root(preprocessor.get_root());
|
||||||
|
code_generator.main_progress(inputfile+".naexec",preprocessor.get_root());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -154,6 +182,8 @@ int main()
|
||||||
ast_print();
|
ast_print();
|
||||||
else if(command=="run")
|
else if(command=="run")
|
||||||
runtime_start();
|
runtime_start();
|
||||||
|
else if(command=="exec")
|
||||||
|
codegen_start();
|
||||||
else if(command=="logo")
|
else if(command=="logo")
|
||||||
logo();
|
logo();
|
||||||
else if(command=="exit")
|
else if(command=="exit")
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "nasal_ast.h"
|
#include "nasal_ast.h"
|
||||||
#include "nasal_parse.h"
|
#include "nasal_parse.h"
|
||||||
#include "nasal_import.h"
|
#include "nasal_import.h"
|
||||||
|
#include "nasal_codegen.h"
|
||||||
#include "nasal_gc.h"
|
#include "nasal_gc.h"
|
||||||
#include "nasal_runtime.h"
|
#include "nasal_runtime.h"
|
||||||
#include "nasal_builtin.h"
|
#include "nasal_builtin.h"
|
||||||
|
|
|
@ -0,0 +1,158 @@
|
||||||
|
#ifndef __NASAL_CODEGEN_H__
|
||||||
|
#define __NASAL_CODEGEN_H__
|
||||||
|
|
||||||
|
// unfinished
|
||||||
|
|
||||||
|
enum bytecode
|
||||||
|
{
|
||||||
|
code_nop=0,
|
||||||
|
|
||||||
|
code_number_list,
|
||||||
|
code_string_list,
|
||||||
|
code_symbol_list,
|
||||||
|
};
|
||||||
|
|
||||||
|
class nasal_codegen
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::vector<std::string> number_list;
|
||||||
|
std::vector<std::string> string_list;
|
||||||
|
std::vector<std::string> symbol_list;
|
||||||
|
int error;
|
||||||
|
void die(std::string);
|
||||||
|
void init();
|
||||||
|
void output_int(unsigned int,std::ofstream&);
|
||||||
|
void generate_root(nasal_ast&,std::ofstream&);
|
||||||
|
void generate_number_list(std::ofstream&);
|
||||||
|
void generate_string_list(std::ofstream&);
|
||||||
|
void generate_symbol_list(std::ofstream&);
|
||||||
|
public:
|
||||||
|
nasal_codegen();
|
||||||
|
void main_progress(std::string,nasal_ast&);
|
||||||
|
};
|
||||||
|
|
||||||
|
class nasal_bytecode_runtime
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
public:
|
||||||
|
};
|
||||||
|
|
||||||
|
nasal_codegen::nasal_codegen()
|
||||||
|
{
|
||||||
|
error=0;
|
||||||
|
number_list.clear();
|
||||||
|
string_list.clear();
|
||||||
|
symbol_list.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nasal_codegen::die(std::string info)
|
||||||
|
{
|
||||||
|
++error;
|
||||||
|
std::cout<<">> [code] "<<info<<std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nasal_codegen::init()
|
||||||
|
{
|
||||||
|
error=0;
|
||||||
|
number_list.clear();
|
||||||
|
string_list.clear();
|
||||||
|
symbol_list.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nasal_codegen::output_int(unsigned int num,std::ofstream& fout)
|
||||||
|
{
|
||||||
|
unsigned int get_byte=0xff000000;
|
||||||
|
int offset=24;
|
||||||
|
for(int i=0;i<4;++i)
|
||||||
|
{
|
||||||
|
fout<<(unsigned char)((get_byte&num)>>offset);
|
||||||
|
get_byte>>=8;
|
||||||
|
offset-=8;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nasal_codegen::generate_root(nasal_ast& root,std::ofstream& fout)
|
||||||
|
{
|
||||||
|
std::vector<nasal_ast>& ref_vec=root.get_children();
|
||||||
|
int root_children_size=ref_vec.size();
|
||||||
|
for(int i=0;i<root_children_size;++i)
|
||||||
|
{
|
||||||
|
switch(ref_vec[i].get_type())
|
||||||
|
{
|
||||||
|
case ast_definition:break;
|
||||||
|
case ast_multi_assign:break;
|
||||||
|
case ast_conditional:break;
|
||||||
|
case ast_while:case ast_for:case ast_forindex:case ast_foreach:
|
||||||
|
break;
|
||||||
|
case ast_nil:case ast_number:case ast_string:case ast_function:break;
|
||||||
|
case ast_identifier:
|
||||||
|
case ast_vector:case ast_hash:
|
||||||
|
case ast_call:
|
||||||
|
case ast_equal:case ast_add_equal:case ast_sub_equal:case ast_mult_equal:case ast_div_equal:case ast_link_equal:
|
||||||
|
case ast_unary_sub:case ast_unary_not:
|
||||||
|
case ast_add:case ast_sub:case ast_mult:case ast_div:case ast_link:
|
||||||
|
case ast_trinocular:break;
|
||||||
|
case ast_break:die("break in main.");break;
|
||||||
|
case ast_continue:die("continue in main.");break;
|
||||||
|
case ast_return:die("return in main.");break;
|
||||||
|
}
|
||||||
|
if(error)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
output_int(code_nop,fout);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void nasal_codegen::generate_number_list(std::ofstream& fout)
|
||||||
|
{
|
||||||
|
output_int(code_number_list,fout);
|
||||||
|
int size=number_list.size();
|
||||||
|
output_int(size,fout);
|
||||||
|
for(int i=0;i<size;++i)
|
||||||
|
fout<<number_list[i]<<"\0";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void nasal_codegen::generate_string_list(std::ofstream& fout)
|
||||||
|
{
|
||||||
|
output_int(code_string_list,fout);
|
||||||
|
int size=string_list.size();
|
||||||
|
output_int(size,fout);
|
||||||
|
for(int i=0;i<size;++i)
|
||||||
|
fout<<string_list[i]<<"\0";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void nasal_codegen::generate_symbol_list(std::ofstream& fout)
|
||||||
|
{
|
||||||
|
output_int(code_symbol_list,fout);
|
||||||
|
int size=symbol_list.size();
|
||||||
|
output_int(size,fout);
|
||||||
|
for(int i=0;i<size;++i)
|
||||||
|
fout<<symbol_list[i]<<"\0";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nasal_codegen::main_progress(std::string filename,nasal_ast& root)
|
||||||
|
{
|
||||||
|
this->init();
|
||||||
|
std::ofstream fout(filename,std::ios::binary);
|
||||||
|
if(fout.fail())
|
||||||
|
{
|
||||||
|
std::cout<<">> [code] cannot generate file \""<<filename<<"\"."<<std::endl;
|
||||||
|
fout.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unsigned char header[4]={0x40,0x56,0x4b,0x21};
|
||||||
|
for(int i=0;i<4;++i)
|
||||||
|
fout<<header[i];
|
||||||
|
generate_root(root,fout);
|
||||||
|
generate_number_list(fout);
|
||||||
|
generate_string_list(fout);
|
||||||
|
generate_symbol_list(fout);
|
||||||
|
fout.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -107,20 +107,20 @@ nasal_ast nasal_import::file_import(nasal_ast& node)
|
||||||
// start importing...
|
// start importing...
|
||||||
if(!import_src.input_file(filename))
|
if(!import_src.input_file(filename))
|
||||||
{
|
{
|
||||||
die(filename,"resource");
|
this->die(filename,"resource");
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
import_lex.scanner(import_src.get_file());
|
import_lex.scanner(import_src.get_file());
|
||||||
if(import_lex.get_error())
|
if(import_lex.get_error())
|
||||||
{
|
{
|
||||||
die(filename,"lexer");
|
this->die(filename,"lexer");
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
import_par.set_toklist(import_lex.get_token_list());
|
import_par.set_toklist(import_lex.get_token_list());
|
||||||
import_par.main_process();
|
import_par.main_process();
|
||||||
if(import_par.get_error())
|
if(import_par.get_error())
|
||||||
{
|
{
|
||||||
die(filename,"parser");
|
this->die(filename,"parser");
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
tmp=import_par.get_root();
|
tmp=import_par.get_root();
|
||||||
|
|
Loading…
Reference in New Issue