Mercurial > hg > Members > nobuyasu > SampleSource
view boost-spirit/Compiler-boost-spirit/compiler.h @ 0:db40c85cad7a default tip
upload sample source
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 09 May 2011 03:11:59 +0900 |
parents | |
children |
line wrap: on
line source
#ifndef __COMPILER_H__ #define __COMPILER_H__ #include "vm.h" #include "node.h" // 仮想マシンコード生成用 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) { } unsigned char *Get(unsigned char *p) const { if (op_ != VM_MAXCOMMAND) { // ラベルのダミーコマンド *p++ = op_; if (size_ > 1) { *(int *)p = arg1_; p += 4; } } return p; } public: unsigned char size_; unsigned char op_; int arg1_; } ; // ラベル class CLabel { public: CLabel(int index) : index_(index), pos_(0) { } ~CLabel() { } public: int index_; int pos_; } ; // 変数テーブル class CValueTag { public: CValueTag(): addr_(-1), type_(TYPE_INTEGER), size_(1), global_(false) { } CValueTag(int addr, int type, int size, bool global) : addr_(addr), type_(type), size_(size), global_(global) { } public: int addr_; int type_; int size_; bool global_; } ; 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), global_(false) { } void set_global() { global_ = true; } bool add(int type, const std::string &name, int size=1) { std::pair<iter, bool> result = variables_.insert(make_pair(name, CValueTag(addr_, type, size, global_))); 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(int type, const std::string &name, int addr) { std::pair<iter, bool> result = variables_.insert(make_pair(name, CValueTag(addr, type, 1, false))); 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_ << ", type = " << it.second.type_ << ", size = " << it.second.size_ << ", global = " << it.second.global_ << std::endl; } } ; void dump() const { std::cout << "-------- value --------" << std::endl; std::for_each(variables_.begin(), variables_.end(), dump_action()); } #endif private: std::map<std::string, CValueTag> variables_; int addr_; bool global_; } ; // 関数定義用 class CFunctionTag { private: enum { flag_declaration = 1 << 0, flag_definition = 1 << 1, flag_system = 1 << 2, } ; public: CFunctionTag() { } CFunctionTag(int type) : type_(type), flags_(0), index_(0) { } void SetArg(int type) { args_.push_back((unsigned char)type); } void SetArgs(const std::vector<cargdef> &args) { size_t size = args.size(); for (size_t i=0; i < size; i++) { args_.push_back((unsigned char)args[i].type()); } } void SetArgs(const std::vector<int> &args) { size_t size = args.size(); for (size_t i=0; i < size; i++) { args_.push_back((unsigned char)args[i]); } } bool SetArgs(const char *args) { if (args) { for (int i=0; args[i] != 0; i++) { switch (args[i]) { case 'I': case 'i': args_.push_back(TYPE_INTEGER); break; case 'S': case 's': args_.push_back(TYPE_STRING); break; default: return false; } } } return true; } bool ChkArgList(const std::vector<cargdef> &args) const { // 引数が無い場合 if (args.empty()) return args_.empty(); // 引数の個数が異なる if (args.size() != args_.size()) return false; // 全引数の型をチェック size_t size = args_.size(); for (size_t i=0; i < size; i++) { if (args[i].type() != (int)args_[i]) return false; } return true; } bool ChkArgList(const std::vector<int> &args) const { // 引数が無い場合 if (args.empty()) return args_.empty(); // 引数の個数が異なる if (args.size() != args_.size()) return false; // 全引数の型をチェック size_t size = args_.size(); for (size_t i=0; i < size; i++) { if (args[i] != (int)args_[i]) return false; } return true; } // 指定の引数の型を得る int GetArg(int index) const { return args_[index]; } int ArgSize() const { return (int)args_.size(); } void SetIndex(int index) { index_ = index; } void SetDeclaration() { flags_ |= flag_declaration; } // 宣言 void SetDefinition() { flags_ |= flag_definition; } // 定義 void SetSystem() { flags_ |= flag_system; } int GetIndex() const { return index_; } bool IsDeclaration() const { return (flags_ & flag_declaration) != 0; } bool IsDefinition() const { return (flags_ & flag_definition) != 0; } bool IsSystem() const { return (flags_ & flag_system) != 0; } public: int type_; int flags_; int index_; std::vector<unsigned char> args_; } ; class CFunctionTable { private: typedef std::map<std::string, CFunctionTag>::iterator iter; typedef std::map<std::string, CFunctionTag>::const_iterator const_iter; public: CFunctionTable() { } CFunctionTag *add(const std::string &name, const CFunctionTag &tag) { std::pair<iter, bool> result = functions_.insert(make_pair(name, tag)); if (result.second) return &result.first->second; return NULL; } const CFunctionTag *find(const std::string &name) const { const_iter it = functions_.find(name); if (it != functions_.end()) return &it->second; return NULL; } CFunctionTag *find(const std::string &name) { iter it = functions_.find(name); if (it != functions_.end()) return &it->second; return NULL; } void clear() { functions_.clear(); } private: std::map<std::string, CFunctionTag> functions_; } ; // コンパイラ class compiler { public: compiler(); virtual ~compiler(); bool compile(const std::string &file, vm::data &data); #ifdef _DEBUG void debug_dump(); #endif bool add_function(int index, int type, const char *name, const char *args); void DefineValue(int type, const std::vector<cnode_t> &node); void DefineFunction(int type, const std::string &name, const std::vector<int> &args); void AddFunction(int type, const std::string &name, const std::vector<cargdef> &args, cblock_t block); // 変数の検索、内側のブロックから検索する。 const CValueTag *GetValueTag(const std::string &name) const { int size = (int)variables.size(); for (int i=size-1; i>=0; i--) { const CValueTag *tag = variables[i].find(name); if (tag) return tag; } return NULL; } // 関数の検索 const CFunctionTag *GetFunctionTag(const std::string &name) const { return functions.find(name); } // for code generator. #define VM_CREATE #include "vm_code.h" #undef VM_CREATE void BlockIn(); void BlockOut(); void AllocStack(); int LabelSetting(); int SetBreakLabel(int label) { int old_index = break_index; break_index = label; return old_index; } bool JmpBreakLabel(); int MakeLabel(); void AddValue(int type, const std::string &name, cnode_t node); void SetLabel(int label); void PushString(const std::string &name); int GetFunctionType() const { return current_function_type; } bool CraeteData(vm::data &data, int code_size); // Error handling. void error(const std::string& m); private: CFunctionTable functions; std::vector<CValueTable> variables; std::vector<CVMCode> statement; std::vector<CLabel> labels; std::vector<char> text_table; int break_index; int error_count; std::string current_function_name; int current_function_type; } ; #endif