Mercurial > hg > Members > nobuyasu > SampleSource
diff Bison-Flex/BasicCompiler-StackBase/EUC/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 diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Bison-Flex/BasicCompiler-StackBase/EUC/compiler.h Mon May 09 03:11:59 2011 +0900 @@ -0,0 +1,254 @@ +#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) + { + } + + 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), 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 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), start_(0), end_(0), step_(0) + { + } + CState(const yy::location& l, int state, int label1, int label2) + : l_(l), state_(state), label1_(label1), label2_(label2), start_(0), end_(0), step_(0) + { + } + CState(const yy::location& l, int state, int label, CAssign *start, CNode *end, CNode *step) + : l_(l), state_(state), label1_(label), label2_(0), start_(start), end_(end), step_(step) + { + } + + public: + yy::location l_; + int state_; + int label1_; + int label2_; + CAssign *start_; + 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); + + // 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; + + int error_count; + + std::string file; +} ; + +#endif