N88BASICが簡単に動くインタープリタを目指します。
@@ -10,12 +10,8 @@ | ||
10 | 10 | { |
11 | 11 | static void Main(string[] args) |
12 | 12 | { |
13 | - var tg = new TokenGetter(); | |
14 | - var token = tg.NextToken(); | |
15 | - while (!token.isEof()) { | |
16 | - Console.WriteLine(token.ToString()); | |
17 | - token = tg.NextToken(); | |
18 | - } | |
13 | + var c = new compile(); | |
14 | + c.DoComple(); | |
19 | 15 | } |
20 | 16 | } |
21 | 17 | } |
@@ -19,14 +19,15 @@ | ||
19 | 19 | DoubleQuote,//" |
20 | 20 | Lss, Gtr,// < > |
21 | 21 | Letter, Digit, Colon, Others, |
22 | - EndOfFile | |
22 | + EndOfLine, EndOfFile | |
23 | 23 | } |
24 | 24 | class Token |
25 | 25 | { |
26 | - TokenType tokenType; | |
27 | - int src_line; | |
28 | - int src_col; | |
29 | - string src_str; | |
26 | + public TokenType TokenType { get; } | |
27 | + | |
28 | + public int src_line { get; } | |
29 | + public int src_col { get; } | |
30 | + public string src_str { get; } | |
30 | 31 | public bool isEof() |
31 | 32 | { |
32 | 33 | return src_str == ";";//"とりあえずセミコロンで終わる。 |
@@ -36,11 +37,11 @@ | ||
36 | 37 | this.src_col = src_col; |
37 | 38 | this.src_line = src_line; |
38 | 39 | this.src_str = src_str; |
39 | - this.tokenType = t; | |
40 | + this.TokenType = t; | |
40 | 41 | } |
41 | 42 | public override string ToString() |
42 | 43 | { |
43 | - return $"{tokenType}:line={src_line}:col={src_col}:{src_str}"; | |
44 | + return $"{TokenType}:line={src_line}:col={src_col}:{src_str}"; | |
44 | 45 | } |
45 | 46 | } |
46 | 47 | } |
@@ -64,8 +64,9 @@ | ||
64 | 64 | case '>': return Gtr; |
65 | 65 | case ',': return Comma; |
66 | 66 | case '.': return Period; |
67 | - case '"': return DoubleQuote; | |
67 | + case '"': return DoubleQuote; | |
68 | 68 | case ';': return EndOfFile;//test用 Semicolon; |
69 | + case '\n': return EndOfLine; | |
69 | 70 | case ':': return Colon; |
70 | 71 | default: |
71 | 72 | break; |
@@ -96,7 +97,7 @@ | ||
96 | 97 | |
97 | 98 | public TokenType NextTokenType() |
98 | 99 | { |
99 | - while (curChar == ' ' || curChar == '\t') | |
100 | + while (curChar == ' ' || curChar == '\t' || curChar == '\r') | |
100 | 101 | { |
101 | 102 | NextChar(); |
102 | 103 | } |
@@ -105,10 +106,6 @@ | ||
105 | 106 | { |
106 | 107 | src_str = "\\n"; |
107 | 108 | } |
108 | - if (curChar == '\r') | |
109 | - { | |
110 | - src_str = "\\r"; | |
111 | - } | |
112 | 109 | var t = getCurCharType(); |
113 | 110 | NextChar(); |
114 | 111 | switch (t) |
@@ -0,0 +1,257 @@ | ||
1 | +using System; | |
2 | +using System.Collections.Generic; | |
3 | +using System.Linq; | |
4 | +using System.Text; | |
5 | +using System.Threading.Tasks; | |
6 | + | |
7 | +namespace getToken | |
8 | +{ | |
9 | + class compile | |
10 | + { | |
11 | + TokenGetter tg = new TokenGetter(); | |
12 | + Token nextToken; | |
13 | + private void next() | |
14 | + { | |
15 | + nextToken = tg.NextToken(); | |
16 | + } | |
17 | + /// <summary> | |
18 | + /// コンパイルする | |
19 | + /// </summary> | |
20 | + /// <returns>true:コンパイル成功</returns> | |
21 | + public bool DoComple(){ | |
22 | + Console.WriteLine("start compile"); | |
23 | + next(); | |
24 | + while (! nextToken.isEof() ) | |
25 | + { | |
26 | + statement(); | |
27 | + } | |
28 | + return true; | |
29 | + } | |
30 | + | |
31 | + public void statement() | |
32 | + { | |
33 | + switch (nextToken.TokenType) | |
34 | + { | |
35 | + case TokenType.abn88_line: | |
36 | + next(); | |
37 | + s_abn88_Line(); | |
38 | + break; | |
39 | + case TokenType.abn88_print: | |
40 | + next(); | |
41 | + s_abn88_Print(); | |
42 | + break; | |
43 | + } | |
44 | + } | |
45 | + | |
46 | + public void s_abn88_Line() | |
47 | + { | |
48 | + Console.Write("n88.Line("); | |
49 | + if (nextToken.TokenType == TokenType.Lparen) | |
50 | + { | |
51 | + next(); | |
52 | + } | |
53 | + else | |
54 | + { | |
55 | + syntaxError(); | |
56 | + return; | |
57 | + } | |
58 | + expression();//pt_start_x | |
59 | + if (nextToken.TokenType == TokenType.Comma) | |
60 | + { | |
61 | + Console.Write(","); | |
62 | + next(); | |
63 | + } | |
64 | + else | |
65 | + { | |
66 | + syntaxError(); | |
67 | + return; | |
68 | + } | |
69 | + expression();//pt_start_y | |
70 | + if(nextToken.TokenType == TokenType.Rparen) | |
71 | + { | |
72 | + Console.Write(","); | |
73 | + next(); | |
74 | + } | |
75 | + else | |
76 | + { | |
77 | + syntaxError(); | |
78 | + return; | |
79 | + } | |
80 | + if (nextToken.TokenType == TokenType.Minus) | |
81 | + { | |
82 | + next(); | |
83 | + } | |
84 | + else | |
85 | + { | |
86 | + syntaxError(); | |
87 | + return; | |
88 | + } | |
89 | + if (nextToken.TokenType == TokenType.Lparen) | |
90 | + { | |
91 | + next(); | |
92 | + } | |
93 | + else | |
94 | + { | |
95 | + syntaxError(); | |
96 | + return; | |
97 | + } | |
98 | + expression();//pt_end_x | |
99 | + if(nextToken.TokenType == TokenType.Comma) | |
100 | + { | |
101 | + Console.Write(","); | |
102 | + next(); | |
103 | + } | |
104 | + else | |
105 | + { | |
106 | + syntaxError(); | |
107 | + return; | |
108 | + } | |
109 | + expression();//pt_end_y | |
110 | + if (nextToken.TokenType == TokenType.Rparen) | |
111 | + { | |
112 | + next(); | |
113 | + } | |
114 | + else | |
115 | + { | |
116 | + syntaxError(); | |
117 | + return; | |
118 | + } | |
119 | + if (nextToken.TokenType == TokenType.Comma) | |
120 | + { | |
121 | + next(); | |
122 | + Console.Write(","); | |
123 | + expression();//color | |
124 | + } | |
125 | + else | |
126 | + { | |
127 | + next(); | |
128 | + Console.WriteLine(")"); | |
129 | + return; | |
130 | + } | |
131 | + if (nextToken.TokenType == TokenType.Comma) | |
132 | + { | |
133 | + next(); | |
134 | + Console.Write(","); | |
135 | + } | |
136 | + else | |
137 | + { | |
138 | + next(); | |
139 | + Console.WriteLine(")"); | |
140 | + return; | |
141 | + } | |
142 | + if (nextToken.TokenType == TokenType.identifier | |
143 | + && (nextToken.src_str == "B" || nextToken.src_str == "BF")) | |
144 | + { | |
145 | + Console.Write(","); | |
146 | + Console.Write($"LineBF.{nextToken.src_str}"); | |
147 | + next(); | |
148 | + } | |
149 | + if (nextToken.TokenType == TokenType.Comma) | |
150 | + { | |
151 | + Console.Write(","); | |
152 | + expression();//color2 | |
153 | + } | |
154 | + Console.WriteLine(")"); | |
155 | + next(); | |
156 | + } | |
157 | + void expression() | |
158 | + { | |
159 | + TokenType t = nextToken.TokenType; | |
160 | + if (t == TokenType.Plus || t == TokenType.Minus) | |
161 | + { | |
162 | + next(); | |
163 | + term(); | |
164 | + if (t == TokenType.Minus) | |
165 | + { | |
166 | + //gencode neg | |
167 | + Console.Write("-"); | |
168 | + } | |
169 | + } | |
170 | + else | |
171 | + { | |
172 | + term(); | |
173 | + } | |
174 | + t = nextToken.TokenType; | |
175 | + while(t == TokenType.Plus || t == TokenType.Minus) | |
176 | + { | |
177 | + if (t == TokenType.Minus) | |
178 | + { | |
179 | + //gencode sub | |
180 | + Console.Write("-"); | |
181 | + } | |
182 | + else | |
183 | + { | |
184 | + //gencode add | |
185 | + Console.Write("+"); | |
186 | + } | |
187 | + next(); | |
188 | + term(); | |
189 | + t = nextToken.TokenType; | |
190 | + } | |
191 | + } | |
192 | + void term() { | |
193 | + | |
194 | + factor(); | |
195 | + var t = nextToken.TokenType; | |
196 | + while(t == TokenType.Mult || t == TokenType.Div) | |
197 | + { | |
198 | + if (t == TokenType.Mult) | |
199 | + { | |
200 | + //gencode mul | |
201 | + Console.Write("*"); | |
202 | + } | |
203 | + else | |
204 | + { | |
205 | + //gencode div | |
206 | + Console.Write("/"); | |
207 | + } | |
208 | + next(); | |
209 | + factor(); | |
210 | + | |
211 | + } | |
212 | + } | |
213 | + void factor() | |
214 | + { | |
215 | + if (nextToken.TokenType == TokenType.identifier) | |
216 | + { | |
217 | + Console.Write(nextToken.src_str); | |
218 | + next(); | |
219 | + } | |
220 | + if (nextToken.TokenType == TokenType.int_value) | |
221 | + { | |
222 | + Console.Write(nextToken.src_str); | |
223 | + next(); | |
224 | + } | |
225 | + if (nextToken.TokenType == TokenType.double_value) | |
226 | + { | |
227 | + Console.Write(nextToken.src_str); | |
228 | + next(); | |
229 | + } | |
230 | + if(nextToken.TokenType == TokenType.Lparen) | |
231 | + { | |
232 | + next(); | |
233 | + expression(); | |
234 | + if(nextToken.TokenType == TokenType.Rparen) | |
235 | + { | |
236 | + next(); | |
237 | + return; | |
238 | + } | |
239 | + else | |
240 | + { | |
241 | + syntaxError(); | |
242 | + } | |
243 | + } | |
244 | + } | |
245 | + | |
246 | + | |
247 | + public void s_abn88_Print() | |
248 | + { | |
249 | + | |
250 | + } | |
251 | + | |
252 | + void syntaxError() | |
253 | + { | |
254 | + Console.WriteLine($"syntax error:line {nextToken.src_line}, col {nextToken.src_col}, {nextToken.src_str}"); | |
255 | + } | |
256 | + } | |
257 | +} |