Mercurial > hg > Members > nobuyasu > myCompiler
view Bison-Flex/BasicCompiler-MemoryBase/compiler.h @ 7:23b18b61c35f draft default tip
analyser
author | Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 05 Feb 2013 07:36:02 +0900 |
parents | 805d39d28230 |
children |
line wrap: on
line source
#ifndef __COMPILER_H__ #define __COMPILER_H__ #include <stack> #include "script-parser.hh" #include "vm.h" #include "node.h" // Forward declarations. class compiler; // flexの関数宣言 #define YY_DECL \ yy::script_parser::token_type \ yylex(yy::script_parser::semantic_type* yylval, \ yy::script_parser::location_type* yylloc, \ compiler& driver) YY_DECL; // 仮想マシンコード生成用 class CVMCode { public: CVMCode(unsigned char op) : size_(1), op_(op), arg1_(0) { } CVMCode(unsigned char op, int arg1) : size_(5), op_(op), arg1_(arg1) { } CVMCode(unsigned char op, int arg1, int arg2) : size_(9), op_(op), arg1_(arg1), arg2_(arg2) { } CVMCode(unsigned char op, int arg1, int arg2, int arg3) : size_(13), op_(op), arg1_(arg1), arg2_(arg2), arg3_(arg3) { } unsigned char *Get(unsigned char *p) const { if (op_ != VM_MAXCOMMAND) { // ラベルのダミーコマンド *p++ = op_; if (size_ > 1) { *(int *)p = arg1_; p += 4; } if (size_ > 5) { *(int *)p = arg2_; p += 4; } if (size_ > 9) { *(int *)p = arg3_; p += 4; } } return p; } public: unsigned char size_; unsigned char op_; int arg1_; int arg2_; int arg3_; } ; // ラベル class CLabel { public: CLabel(int index) : index_(index), pos_(0) { } ~CLabel() { } public: int index_; int pos_; } ; // 変数テーブル class CValueTag { public: CValueTag(): addr_(-1), size_(1) { } CValueTag(int addr, int size) : addr_(addr), size_(size) { } public: int addr_; int size_; } ; class CValueTable { private: typedef std::map<std::string, CValueTag>::iterator iter; typedef std::map<std::string, CValueTag>::const_iterator const_iter; public: CValueTable(int start_addr=0): addr_(start_addr) { } bool add(const std::string &name, int size=1) { std::pair<iter, bool> result = variables_.insert(make_pair(name, CValueTag(addr_, size))); if (result.second) { addr_ += size; return true; } return false; } const CValueTag *find(const std::string &name) const { const_iter it = variables_.find(name); if (it != variables_.end()) return &it->second; return NULL; } bool add_arg(const std::string &name, int addr) { std::pair<iter, bool> result = variables_.insert(make_pair(name, CValueTag(addr, 1))); return result.second; } int size() const { return addr_; } void clear() { variables_.clear(); addr_ = 0; } #ifdef _DEBUG struct dump_action { void operator()(const std::pair<std::string, CValueTag> &it) { std::cout << it.first << ", addr = " << it.second.addr_ << ", size = " << it.second.size_ << std::endl; } } ; void dump() const { std::for_each(variables_.begin(), variables_.end(), dump_action()); } #endif private: std::map<std::string, CValueTag> variables_; int addr_; } ; // 一時変数 class CTempValue { public: CTempValue(int ref, int addr) : ref_(ref), addr_(addr) { } public: int ref_; int addr_; } ; // コンパイラ class compiler { private: enum STACK_STATE { STATE_IF, STATE_FOR, STATE_WHILE, } ; class CState { public: CState(const yy::location& l, int state, int label) : l_(l), state_(state), label1_(label), label2_(0), end_(0), step_(0) { } CState(const yy::location& l, int state, int label1, int label2) : l_(l), state_(state), label1_(label1), label2_(label2), end_(0), step_(0) { } CState(const yy::location& l, int state, int label, CNodeValue &counter, CNode *end, CNode *step) : l_(l), state_(state), label1_(label), label2_(0), counter_(counter), end_(end), step_(step) { } public: yy::location l_; int state_; int label1_; int label2_; CNodeValue counter_; CNode *end_; CNode *step_; } ; public: compiler(); virtual ~compiler(); std::string &get_filename() { return file; } bool compile(const std::string &f, vm::data &data); #ifdef _DEBUG void debug_dump(); #endif // 文 // 代入文 void AssignStatement(const yy::location& l, CAssign *assign); // if文 void IfStatement(const yy::location& l, CNode *expr); void ElseStatement(const yy::location& l); void EndifStatement(const yy::location& l); // for文 void ForStatement(const yy::location& l, CAssign *start, CNode *end, CNode *step); void NextStatement(const yy::location& l); // while文 void WhileStatement(const yy::location& l, CNode *expr); void WendStatement(const yy::location& l); // end文 void EndStatement(const yy::location& l); // print文 void PrintStatement(const yy::location& l, CArgs *args); const CValueTag *GetValueTag(const std::string &name) const { return variables.find(name); } const CValueTag *AddValue(const std::string &name) { if (variables.add(name, 1)) { return variables.find(name); } return NULL; } // for code generator. #define VM_CREATE #include "vm_code.h" #undef VM_CREATE int LabelSetting(); int MakeLabel(); void SetLabel(int label); bool CraeteData(vm::data &data, int code_size); int AllocTempValue(); void UseTempValue(int value); void ReleaseTempValue(int value); int GetTempAddr(int value) const { return temp_value[value].addr_; } CNodeValue MakeNeg(int ret, const CNodeValue &value); CNodeValue MakeRand(int ret, const CNodeValue &value); CNodeValue MakeMoveC(int ret, int value); CNodeValue MakeMoveV(int ret, const CNodeValue &value); CNodeValue MakeOp(int op, int ret, const CNodeValue &left, const CNodeValue &right); void MakeJmpC(int label, const CNodeValue &value); void MakeJmpNC(int label, const CNodeValue &value); void MakePush(const CNodeValue &value); // Error handling. void error(const yy::location& l, const std::string& m); void error(const std::string& m); private: void scan_begin(); void scan_end(); private: CValueTable variables; std::vector<CVMCode> statement; std::vector<CLabel> labels; std::stack<CState> state_stack; std::vector<CTempValue> temp_value; int error_count; std::string file; } ; #endif