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