annotate Bison-Flex/BasicCompiler-MemoryBase/compiler.cpp @ 4:805d39d28230

add Compiler-stackbase
author nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
date Tue, 17 May 2011 08:00:38 +0900
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 #include <iostream>
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2 #include <iomanip>
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 #include "script-parser.hh"
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 #include "compiler.h"
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 #ifdef _MSC_VER
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 #pragma warning(disable: 4996)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 #endif
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 // コンストラクタ
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 compiler::compiler()
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 : error_count(0)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 // デストラクタ
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 compiler::~compiler()
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 // コンパイル
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
24
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 bool compiler::compile(const std::string &f, vm::data &data)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 // システムコールの設定
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
28
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
29 file = f;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
30 scan_begin(); // スキャナー初期化
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 yy::script_parser parser(*this); // パーサー構築
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 int result = parser.parse(); // 構文解析
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
33 scan_end(); // スキャナー終了
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
34
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
35 if (result != 0)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 return false; // パーサーエラー
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
37
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 // ステートスタックが空ではないならば、if, for, whileが
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 // 閉じていない
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
40 while (!state_stack.empty()) {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 CState state = state_stack.top();
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 switch (state.state_) {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
43 case STATE_IF:
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 error(state.l_, "ifに対応するendifが有りません");
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 break;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
46
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 case STATE_FOR:
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
48 error(state.l_, "forに対応するnextが有りません");
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
49 delete state.end_;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 delete state.step_;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
51 break;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
52
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 case STATE_WHILE:
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 error(state.l_, "whileに対応するwendが有りません");
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
55 break;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
56 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 state_stack.pop();
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
59
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
60 // 番兵用HALTコマンドを追加
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
61 const CVMCode &code = statement.back();
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 if (code.op_ != VM_HALT) // haltが無いならば
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
63 OpHalt(); // haltを追加
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
64
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
65 int code_size = LabelSetting(); // ラベルにアドレスを設定
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
66 CraeteData(data, code_size); // バイナリ生成
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
67
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
68 return error_count == 0;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
70
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
71 // エラーメッセージを出力
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
72
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
73 void compiler::error(const yy::location& l, const std::string& m)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
74 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
75 std::cerr << l << ": " << m << std::endl;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
76 error_count++;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
77 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
78
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
79 // エラーメッセージを出力
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
80
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
81 void compiler::error(const std::string& m)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
82 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
83 std::cerr << m << std::endl;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 error_count++;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
85 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
86
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
87 // 命令文の登録
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
88
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
89 // 代入文
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
90 void compiler::AssignStatement(const yy::location& l, CAssign *assign)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
91 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
92 assign->analyze(this);
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 delete assign;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
94 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
95
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 // if文
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
97 void compiler::IfStatement(const yy::location& l, CNode *expr)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
99 int label = MakeLabel();
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
100 MakeJmpNC(label, CNodeValue::MakeNodeValue(this, expr));
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
101
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
102 state_stack.push(CState(l, STATE_IF, label));
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
103
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
104 delete expr;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
105 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
106
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 void compiler::ElseStatement(const yy::location& l)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
109 if (state_stack.empty() || state_stack.top().state_ != STATE_IF) {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
110 error(l, "if文と対応していないelse文が有りました。");
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
111 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
112 else {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
113 CState &state = state_stack.top();
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
114 int label = MakeLabel();
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 OpJmp(label);
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
116 SetLabel(state.label1_); // 偽の時の飛び先をここにする
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
117 state.label1_ = label; // endifの飛び先を再設定
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
118 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
119 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
120
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
121 void compiler::EndifStatement(const yy::location& l)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
122 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
123 if (state_stack.empty() || state_stack.top().state_ != STATE_IF) {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
124 error(l, "if文と対応していないendif文が有りました。");
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
125 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
126 else {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
127 CState &state = state_stack.top();
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
128 SetLabel(state.label1_); // endifの飛び先をここにする
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
129 state_stack.pop(); // ステートスタックをpop
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
130 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
131 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
132
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 // FOR文
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
134 void compiler::ForStatement(const yy::location& l, CAssign *start, CNode *end, CNode *step)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
135 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
136 int label = MakeLabel();
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
137
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
138 CNodeValue counter = start->analyze(this);
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
139 SetLabel(label);
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
140
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
141 state_stack.push(CState(l, STATE_FOR, label, counter, end, step));
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
142 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
143
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
144 void compiler::NextStatement(const yy::location& l)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
145 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
146 if (state_stack.empty() || state_stack.top().state_ != STATE_FOR) {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
147 error(l, "for文と対応していないnext文が有りました。");
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
148 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
149 else {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
150 CState &state = state_stack.top();
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
151 int label = MakeLabel();
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
152 MakeJmpC(label, MakeOp(OP_EQ, -1, state.counter_, CNodeValue::MakeNodeValue(this, state.end_)));
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
153 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
154 CNodeValue step(CNodeValue::CONST, 1);
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
155 if (state.step_)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
156 step = CNodeValue::MakeNodeValue(this, state.step_);
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
157 MakeOp(OP_PLUS, state.counter_.value(), state.counter_, step);
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
158 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
159 OpJmp(state.label1_);
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
160 SetLabel(label);
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
161
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
162 // 後始末
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
163 delete state.end_;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
164 delete state.step_;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
165
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
166 state_stack.pop();
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
167 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
168 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
169
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
170 // while文
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
171 void compiler::WhileStatement(const yy::location& l, CNode *expr)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
172 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
173 int label1 = MakeLabel();
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
174 int label2 = MakeLabel();
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
175
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
176 SetLabel(label1);
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
177 MakeJmpNC(label2, CNodeValue::MakeNodeValue(this, expr));
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
178
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
179 state_stack.push(CState(l, STATE_WHILE, label1, label2));
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
180
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
181 delete expr;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
182 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
183
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
184 void compiler::WendStatement(const yy::location& l)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
185 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
186 if (state_stack.empty() || state_stack.top().state_ != STATE_WHILE) {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
187 error(l, "while文と対応していないwend文が有りました。");
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
188 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
189 else {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
190 CState &state = state_stack.top();
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
191 OpJmp(state.label1_);
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
192 SetLabel(state.label2_);
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
193 state_stack.pop();
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
194 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
195 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
196
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
197 // end文
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
198 //
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
199 // > halt
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
200 //
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
201 void compiler::EndStatement(const yy::location& l)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
202 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
203 OpHalt();
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
204 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
205
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
206 // print文
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
207 //
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
208 // print a, b, c
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
209 //
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
210 // > push c
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
211 // > push b
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
212 // > push a
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
213 // > print 3
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
214 //
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
215
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
216 struct print_action {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
217 compiler *comp_;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
218 print_action(compiler *comp): comp_(comp)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
219 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
220 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
221
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
222 void operator()(CNode *node) const
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
223 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
224 CNodeValue value = CNodeValue::MakeNodeValue(comp_, node);
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
225 comp_->MakePush(value);
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
226 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
227 } ;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
228
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
229 void compiler::PrintStatement(const yy::location& l, CArgs *args)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
230 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
231 int arg_count = 0;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
232 if (args) {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
233 args->for_each_rev(print_action(this));
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
234 arg_count = args->size();
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
235 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
236
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
237 OpPrint(arg_count);
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
238
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
239 delete args;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
240 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
241
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
242 // ラベル生成
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
243
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
244 int compiler::MakeLabel()
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
245 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
246 int index = (int)labels.size();
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
247 labels.push_back(CLabel(index));
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
248 return index;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
249 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
250
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
251 // ラベルのダミーコマンドをステートメントリストに登録する
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
252
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
253 void compiler::SetLabel(int label)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
254 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
255 statement.push_back(CVMCode(VM_MAXCOMMAND, label));
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
256 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
257
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
258 // ラベル解決
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
259 //
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
260 // 1.アドレスを生成する
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
261 // 2.ダミーのラベルコマンドが有ったアドレスを、ラベルテーブルに登録する
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
262 // 3.Jmpコマンドの飛び先をラベルテーブルに登録されたアドレスにする
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
263
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
264 // note:
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
265 // GCCでは、関数オブジェクトを関数内に書けないので、ここに記述する。
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
266 // VC++9.0(VS2008)では関数内に書くことで、スコープを封じ込める事が可能。
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
267
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
268 // アドレス計算関数オブジェクト
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
269 struct calc_addr {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
270 std::vector<CLabel> &labels_;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
271 int &pos_;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
272 calc_addr(std::vector<CLabel> &labels, int &pos): labels_(labels), pos_(pos)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
273 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
274 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
275 void operator()(const CVMCode &code)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
276 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
277 if (code.op_ == VM_MAXCOMMAND) { // ラベルのダミーコマンド
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
278 labels_[code.arg1_].pos_ = pos_;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
279 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
280 else {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
281 pos_ += code.size_;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
282 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
283 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
284 } ;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
285
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
286 // ジャンプアドレス設定関数オブジェクト
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
287 struct set_addr {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
288 std::vector<CLabel> &labels_;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
289 set_addr(std::vector<CLabel> &labels): labels_(labels)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
290 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
291 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
292 void operator()(CVMCode &code)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
293 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
294 switch (code.op_) {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
295 case VM_JMP:
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
296 case VM_JMPC:
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
297 case VM_JMPNC:
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
298 code.arg1_ = labels_[code.arg1_].pos_;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
299 break;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
300 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
301 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
302 } ;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
303
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
304 int compiler::LabelSetting()
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
305 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
306 // アドレス計算
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
307 int pos = 0;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
308 std::for_each(statement.begin(), statement.end(), calc_addr(labels, pos));
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
309
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
310 // ジャンプアドレス設定
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
311 std::for_each(statement.begin(), statement.end(), set_addr(labels));
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
312
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
313 return pos;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
314 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
315
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
316 // バイナリデータ生成
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
317
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
318 // 関数オブジェクト
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
319 struct copy_code {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
320 unsigned char *p;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
321 copy_code(unsigned char *code): p(code)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
322 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
323 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
324 void operator()(const CVMCode &code)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
325 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
326 p = code.Get(p);
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
327 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
328 } ;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
329
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
330 bool compiler::CraeteData(vm::data &data, int code_size)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
331 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
332 data.command_ = new unsigned char[code_size];
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
333 data.command_size_ = code_size;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
334 data.value_size_ = (int)variables.size();
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
335
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
336 std::for_each(statement.begin(), statement.end(), copy_code(data.command_));
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
337
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
338 return true;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
339 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
340
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
341 // 使用してよい一時変数を返す
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
342 int compiler::AllocTempValue()
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
343 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
344 // テーブルから空きを探してみる
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
345 size_t size = temp_value.size();
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
346
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
347 for (size_t i=0; i<size; i++) {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
348 if (temp_value[i].ref_ == 0) {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
349 temp_value[i].ref_ = 1;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
350 return (int)i;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
351 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
352 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
353
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
354 // 空きがなければ追加
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
355 char str[24];
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
356 sprintf(str, "#%d", size);
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
357 const CValueTag *tag = AddValue(str);
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
358 temp_value.push_back(CTempValue(1, tag->addr_));
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
359
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
360 return (int)size;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
361 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
362
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
363 // 一時変数使用
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
364 void compiler::UseTempValue(int value)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
365 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
366 temp_value[value].ref_++;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
367 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
368
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
369 // 一時変数返却
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
370 void compiler::ReleaseTempValue(int value)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
371 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
372 temp_value[value].ref_--;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
373 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
374
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
375 // 単項マイナスの生成
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
376 CNodeValue compiler::MakeNeg(int ret, const CNodeValue &value)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
377 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
378 CNodeValue v = CNodeValue::MakeTempValue(this, ret);
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
379
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
380 if (value.type() == CNodeValue::CONST)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
381 OpNegC(v.value(), value.value());
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
382 else
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
383 OpNegV(v.value(), value.value());
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
384
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
385 return v;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
386 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
387
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
388 // RAND関数の生成
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
389 CNodeValue compiler::MakeRand(int ret, const CNodeValue &value)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
390 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
391 CNodeValue v = CNodeValue::MakeTempValue(this, ret);
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
392
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
393 if (value.type() == CNodeValue::CONST)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
394 OpRandC(v.value(), value.value());
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
395 else
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
396 OpRandV(v.value(), value.value());
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
397
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
398 return v;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
399 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
400
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
401 // 代入の生成(定数)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
402 CNodeValue compiler::MakeMoveC(int ret, int value)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
403 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
404 CNodeValue v = CNodeValue::MakeTempValue(this, ret);
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
405
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
406 OpMovC(v.value(), value);
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
407
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
408 return v;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
409 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
410
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
411 // 代入の生成(変数)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
412 CNodeValue compiler::MakeMoveV(int ret, const CNodeValue &value)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
413 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
414 CNodeValue v = CNodeValue::MakeTempValue(this, ret);
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
415
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
416 OpMovV(v.value(), value.value());
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
417
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
418 return v;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
419 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
420
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
421 // 二項演算子の生成
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
422 CNodeValue compiler::MakeOp(int op, int ret, const CNodeValue &left, const CNodeValue &right)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
423 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
424 CNodeValue v = CNodeValue::MakeTempValue(this, ret);
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
425
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
426 int code = 0;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
427 switch (op) {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
428 case OP_EQ: code = VM_EQ_CC; break;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
429 case OP_NE: code = VM_NE_CC; break;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
430 case OP_GT: code = VM_GT_CC; break;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
431 case OP_GE: code = VM_GE_CC; break;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
432 case OP_LT: code = VM_LT_CC; break;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
433 case OP_LE: code = VM_LE_CC; break;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
434 case OP_MINUS: code = VM_SUB_CC; break;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
435 case OP_PLUS: code = VM_ADD_CC; break;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
436 case OP_TIMES: code = VM_MUL_CC; break;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
437 case OP_DIVIDE: code = VM_DIV_CC; break;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
438 case OP_MOD: code = VM_MOD_CC; break;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
439 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
440
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
441 if (left.type() != CNodeValue::CONST)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
442 code++;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
443 if (right.type() != CNodeValue::CONST)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
444 code += 2;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
445
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
446 statement.push_back(CVMCode(code, v.value(), left.value(), right.value()));
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
447 return v;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
448 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
449
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
450 // 条件ジャンプの生成(真)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
451 void compiler::MakeJmpC(int label, const CNodeValue &value)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
452 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
453 OpJmpC(label, value.value());
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
454 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
455
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
456 // 条件ジャンプの生成(偽)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
457 void compiler::MakeJmpNC(int label, const CNodeValue &value)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
458 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
459 OpJmpNC(label, value.value());
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
460 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
461
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
462 // pushの生成
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
463 void compiler::MakePush(const CNodeValue &value)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
464 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
465 if (value.type() == CNodeValue::CONST)
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
466 PushConst(value.value());
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
467 else
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
468 PushValue(value.value());
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
469 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
470
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
471 // デバッグダンプ
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
472 #ifdef _DEBUG
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
473 void compiler::debug_dump()
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
474 {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
475 std::cout << "---variables---" << std::endl;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
476 variables.dump();
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
477
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
478 static const char *op_name[] = {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
479 #define VM_NAMETABLE
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
480 #include "vm_code.h"
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
481 #undef VM_NAMETABLE
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
482 "LABEL",
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
483 } ;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
484 std::cout << "---code---" << std::endl;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
485
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
486 int pos = 0;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
487 size_t size = statement.size();
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
488 for (size_t i=0; i < size; i++) {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
489 std::cout << std::setw(6) << pos << ": " << op_name[statement[i].op_];
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
490 if (statement[i].size_ > 1) {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
491 std::cout << ", " << statement[i].arg1_;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
492 if (statement[i].size_ > 5) {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
493 std::cout << ", " << statement[i].arg2_;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
494 if (statement[i].size_ > 9) {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
495 std::cout << ", " << statement[i].arg3_;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
496 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
497 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
498 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
499 std::cout << std::endl;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
500
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
501 if (statement[i].op_ != VM_MAXCOMMAND) {
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
502 pos += statement[i].size_;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
503 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
504 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
505 std::cout << "---" << std::endl;
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
506 }
805d39d28230 add Compiler-stackbase
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
507 #endif