blob: 052c3510a004d83ab46b60a6132e618abb3f44e3 [file] [log] [blame]
Jack Palevichae54f1f2009-05-08 14:54:15 -07001/*
2 **
3 ** Copyright 2009, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
Jack Palevich88311482009-05-08 13:57:37 -070017
Jack Palevichae54f1f2009-05-08 14:54:15 -070018/* Based upon the freeware version of the Obfuscated Tiny C Compiler
Jack Palevichd1605302009-05-08 15:26:24 -070019 * by Francis Bellard. <francis@bellard.org>.
Jack Palevichae54f1f2009-05-08 14:54:15 -070020 */
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25
Jack Palevichf0cbc922009-05-08 16:35:13 -070026#define TOKEN_OPERATOR 1
27#define TOKEN_NUMBER 2
Jack Palevich7448a2e2009-05-08 18:33:45 -070028
29#define TOKEN_SYMBOL_BASE 256
30#define TOKEN_INT 256
31#define TOKEN_IF 288
32#define TOKEN_ELSE 312
33#define TOKEN_WHILE 352
34#define TOKEN_BREAK 400
35#define TOKEN_RETURN 448
36#define TOKEN_FOR 504
37#define TOKEN_DEFINE 536
Jack Palevichf0cbc922009-05-08 16:35:13 -070038
39static int currentToken;
40static int currentTokenData;
41static int C;
42static int currentChar;
43static int K;
44static int q;
45static int G;
46static int savedChar;
47static char* pInProgressMacro;
Jack Palevich50791f52009-05-08 15:44:22 -070048static char* P;
49static char* ac;
50static char* v;
Jack Palevichf0cbc922009-05-08 16:35:13 -070051static char* pSymbolTable;
Jack Palevich50791f52009-05-08 15:44:22 -070052static char* M;
53static char* R;
Jack Palevichf0cbc922009-05-08 16:35:13 -070054static FILE* pInput;
Jack Palevichae54f1f2009-05-08 14:54:15 -070055
Jack Palevich7448a2e2009-05-08 18:33:45 -070056static void parseDeclarations (int isLocal);
57static void parseExpression();
Jack Palevichae54f1f2009-05-08 14:54:15 -070058
Jack Palevich50791f52009-05-08 15:44:22 -070059static void addToSymbolTable(char e) {
Jack Palevichf0cbc922009-05-08 16:35:13 -070060 *pSymbolTable++ = e;
Jack Palevich88311482009-05-08 13:57:37 -070061}
Jack Palevichae54f1f2009-05-08 14:54:15 -070062
Jack Palevichf0cbc922009-05-08 16:35:13 -070063static void nextChar() {
64 if (pInProgressMacro) {
65 currentChar = *(char*) pInProgressMacro++;
66 if (currentChar == 2) {
67 pInProgressMacro = NULL;
68 currentChar = savedChar;
Jack Palevichae54f1f2009-05-08 14:54:15 -070069 }
70 } else
Jack Palevichf0cbc922009-05-08 16:35:13 -070071 currentChar = fgetc(pInput);
Jack Palevich88311482009-05-08 13:57:37 -070072}
Jack Palevichae54f1f2009-05-08 14:54:15 -070073
Jack Palevichf0cbc922009-05-08 16:35:13 -070074static int isSymbolChar() {
75 return isalnum(currentChar) || currentChar == '_';
Jack Palevich88311482009-05-08 13:57:37 -070076}
Jack Palevichae54f1f2009-05-08 14:54:15 -070077
Jack Palevichf0cbc922009-05-08 16:35:13 -070078static void unescapeCurrentChar() {
79 if (currentChar == '\\') {
80 nextChar();
81 if (currentChar == 'n')
82 currentChar = '\n';
Jack Palevichae54f1f2009-05-08 14:54:15 -070083 }
Jack Palevich88311482009-05-08 13:57:37 -070084}
Jack Palevichae54f1f2009-05-08 14:54:15 -070085
Jack Palevichf0cbc922009-05-08 16:35:13 -070086static void nextToken() {
Jack Palevichae54f1f2009-05-08 14:54:15 -070087 int j, m;
Jack Palevichf0cbc922009-05-08 16:35:13 -070088 while (isspace(currentChar) || currentChar == '#') {
89 if (currentChar == '#') {
90 nextChar();
91 nextToken();
92 if (currentToken == TOKEN_DEFINE) {
93 nextToken();
94 addToSymbolTable(' ');
95 *(int*) currentToken = 1;
96 *(int*) (currentToken + 4) = (int) pSymbolTable;
Jack Palevichae54f1f2009-05-08 14:54:15 -070097 }
Jack Palevichf0cbc922009-05-08 16:35:13 -070098 while (currentChar != '\n') {
99 addToSymbolTable(currentChar);
100 nextChar();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700101 }
Jack Palevichf0cbc922009-05-08 16:35:13 -0700102 addToSymbolTable(currentChar);
Jack Palevich50791f52009-05-08 15:44:22 -0700103 addToSymbolTable(2);
Jack Palevichae54f1f2009-05-08 14:54:15 -0700104 }
Jack Palevichf0cbc922009-05-08 16:35:13 -0700105 nextChar();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700106 }
107 C = 0;
Jack Palevichf0cbc922009-05-08 16:35:13 -0700108 currentToken = currentChar;
109 if (isSymbolChar()) {
110 addToSymbolTable(' ');
111 M = pSymbolTable;
112 while (isSymbolChar()) {
113 addToSymbolTable(currentChar);
114 nextChar();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700115 }
Jack Palevichf0cbc922009-05-08 16:35:13 -0700116 if (isdigit(currentToken)) {
117 currentTokenData = strtol(M, 0, 0);
118 currentToken = TOKEN_NUMBER;
Jack Palevichae54f1f2009-05-08 14:54:15 -0700119 } else {
Jack Palevichf0cbc922009-05-08 16:35:13 -0700120 *(char*) pSymbolTable = ' ';
121 currentToken = strstr(R, M - 1) - R;
122 *(char*) pSymbolTable = 0;
Jack Palevich7448a2e2009-05-08 18:33:45 -0700123 currentToken = currentToken * 8 + TOKEN_SYMBOL_BASE;
Jack Palevichf0cbc922009-05-08 16:35:13 -0700124 if (currentToken > TOKEN_DEFINE) {
125 currentToken = ((int) P) + currentToken;
126 if (*(int*) currentToken == 1) {
127 pInProgressMacro = (char*) (*(int*) (currentToken + 4));
128 savedChar = currentChar;
129 nextChar();
130 nextToken();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700131 }
132 }
133 }
134 } else {
Jack Palevichf0cbc922009-05-08 16:35:13 -0700135 nextChar();
136 if (currentToken == '\'') {
137 currentToken = TOKEN_NUMBER;
138 unescapeCurrentChar();
139 currentTokenData = currentChar;
140 nextChar();
141 nextChar();
142 } else if (currentToken == '/' & currentChar == '*') {
143 nextChar();
144 while (currentChar) {
145 while (currentChar != '*')
146 nextChar();
147 nextChar();
148 if (currentChar == '/')
149 currentChar = 0;
Jack Palevichae54f1f2009-05-08 14:54:15 -0700150 }
Jack Palevichf0cbc922009-05-08 16:35:13 -0700151 nextChar();
152 nextToken();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700153 } else {
154 char* e = "++#m--%am*@R<^1c/@%[_[H3c%@%[_[H3c+@.B#d-@%:_^BKd<<Z/03e>>`/03e<=0f>=/f<@.f>@1f==&g!='g&&k||#l&@.BCh^@.BSi|@.B+j~@/%Yd!@&d*@b";
155 while (j = *(char*) e++) {
156 m = *(char*) e++;
Jack Palevichf0cbc922009-05-08 16:35:13 -0700157 currentTokenData = 0;
Jack Palevichae54f1f2009-05-08 14:54:15 -0700158 while ((C = *(char*) e++ - 98) < 0)
Jack Palevichf0cbc922009-05-08 16:35:13 -0700159 currentTokenData = currentTokenData * 64 + C + 64;
160 if (j == currentToken && (m == currentChar || m == 64)) {
161 if (m == currentChar) {
162 nextChar();
163 currentToken = TOKEN_OPERATOR;
Jack Palevichae54f1f2009-05-08 14:54:15 -0700164 }
165 break;
166 }
167 }
168 }
169 }
Jack Palevich88311482009-05-08 13:57:37 -0700170}
Jack Palevichae54f1f2009-05-08 14:54:15 -0700171
Jack Palevich7448a2e2009-05-08 18:33:45 -0700172/*
173 * Emit 1 to 4 bytes of code. Little-endian, doesn't emit high bytes that
174 * are 0x0 or 0xff
175 */
176static void emitCode(int g) {
Jack Palevichf0cbc922009-05-08 16:35:13 -0700177 while( g && g != -1) {
Jack Palevichae54f1f2009-05-08 14:54:15 -0700178 *(char*) q++=g;
179 g=g>>8;
180 }
Jack Palevich88311482009-05-08 13:57:37 -0700181}
Jack Palevichae54f1f2009-05-08 14:54:15 -0700182
Jack Palevich7448a2e2009-05-08 18:33:45 -0700183static void fixupAddress(e) {
Jack Palevichae54f1f2009-05-08 14:54:15 -0700184 int g;
185 while( e) {
186 g=*(int*) e;
187 *(int*) e=q-e-4;
188 e=g;
189 }
Jack Palevich88311482009-05-08 13:57:37 -0700190}
Jack Palevichae54f1f2009-05-08 14:54:15 -0700191
Jack Palevich7448a2e2009-05-08 18:33:45 -0700192static int emitCodeWithImmediate( g, e) {
193 emitCode(g);
Jack Palevichae54f1f2009-05-08 14:54:15 -0700194 *(int*) q = e;
195 e = q;
196 q = q + 4;
197 return e;
Jack Palevich88311482009-05-08 13:57:37 -0700198}
Jack Palevichae54f1f2009-05-08 14:54:15 -0700199
Jack Palevich7448a2e2009-05-08 18:33:45 -0700200static int emitLoadAccumulatorImmediate(e) {
201 emitCodeWithImmediate(0xb8,e); /* Move immediate a, e */
Jack Palevich88311482009-05-08 13:57:37 -0700202}
Jack Palevichae54f1f2009-05-08 14:54:15 -0700203
Jack Palevich7448a2e2009-05-08 18:33:45 -0700204static int emitBranch(e) {
205 return emitCodeWithImmediate(0xe9,e); /* Jump relative */
Jack Palevich88311482009-05-08 13:57:37 -0700206}
Jack Palevichae54f1f2009-05-08 14:54:15 -0700207
Jack Palevich50791f52009-05-08 15:44:22 -0700208static int S( j, e) {
Jack Palevich7448a2e2009-05-08 18:33:45 -0700209 emitCode(0x0FC085); /* XADD 85 r/m8, r8 exchange and add */
210 return emitCodeWithImmediate(0x84 + j, e); /* TEST */
Jack Palevich88311482009-05-08 13:57:37 -0700211}
Jack Palevichae54f1f2009-05-08 14:54:15 -0700212
Jack Palevich50791f52009-05-08 15:44:22 -0700213static void Z(e) {
Jack Palevich7448a2e2009-05-08 18:33:45 -0700214 emitCode( 0xC139);
215 emitLoadAccumulatorImmediate(0);
216 emitCode( 0x0F);
217 emitCode( e+0x90);
218 emitCode( 0xC0);
Jack Palevich88311482009-05-08 13:57:37 -0700219}
Jack Palevichae54f1f2009-05-08 14:54:15 -0700220
Jack Palevich50791f52009-05-08 15:44:22 -0700221static void N( j, e) {
Jack Palevich7448a2e2009-05-08 18:33:45 -0700222 emitCode(j + 0x83);
223 emitCodeWithImmediate((e < 512) << 7 | 5, e);
Jack Palevich88311482009-05-08 13:57:37 -0700224}
Jack Palevichae54f1f2009-05-08 14:54:15 -0700225
Jack Palevich7448a2e2009-05-08 18:33:45 -0700226static void T (int j) {
Jack Palevichae54f1f2009-05-08 14:54:15 -0700227 int g,e,m,aa;
228 g=1;
Jack Palevich7448a2e2009-05-08 18:33:45 -0700229 if( currentToken == '"') {
230 emitLoadAccumulatorImmediate(v);
231 while( currentChar != '"') {
Jack Palevichf0cbc922009-05-08 16:35:13 -0700232 unescapeCurrentChar ();
233 *(char*) v++=currentChar;
234 nextChar ();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700235 }
236 *(char*) v=0;
237 v= (char*) (((int)v) +4&-4);
Jack Palevich7448a2e2009-05-08 18:33:45 -0700238 nextChar();
Jack Palevichf0cbc922009-05-08 16:35:13 -0700239 nextToken();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700240 }
241 else {
242 aa=C;
Jack Palevichf0cbc922009-05-08 16:35:13 -0700243 m= currentTokenData;
244 e=currentToken;
245 nextToken();
Jack Palevich7448a2e2009-05-08 18:33:45 -0700246 if( e == TOKEN_NUMBER) {
247 emitLoadAccumulatorImmediate(m);
Jack Palevichae54f1f2009-05-08 14:54:15 -0700248 }
249 else if( aa == 2) {
250 T(0);
Jack Palevich7448a2e2009-05-08 18:33:45 -0700251 emitCodeWithImmediate(0xB9,0);
252 if( e == '!')Z(m);
253 else emitCode( m);
Jack Palevichae54f1f2009-05-08 14:54:15 -0700254 }
Jack Palevich7448a2e2009-05-08 18:33:45 -0700255 else if( e == '(') {
256 parseExpression ();
Jack Palevichf0cbc922009-05-08 16:35:13 -0700257 nextToken();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700258 }
Jack Palevich7448a2e2009-05-08 18:33:45 -0700259 else if( e == '*') {
Jack Palevichf0cbc922009-05-08 16:35:13 -0700260 nextToken();
261 e=currentToken;
262 nextToken();
263 nextToken();
Jack Palevich7448a2e2009-05-08 18:33:45 -0700264 if( currentToken == '*') {
Jack Palevichf0cbc922009-05-08 16:35:13 -0700265 nextToken();
266 nextToken();
267 nextToken();
268 nextToken();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700269 e=0;
270 }
Jack Palevichf0cbc922009-05-08 16:35:13 -0700271 nextToken();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700272 T(0);
Jack Palevich7448a2e2009-05-08 18:33:45 -0700273 if( currentToken == '=') {
Jack Palevichf0cbc922009-05-08 16:35:13 -0700274 nextToken();
Jack Palevich7448a2e2009-05-08 18:33:45 -0700275 emitCode( 0x50);
276 parseExpression ();
277 emitCode( 0x59);
278 emitCode( 0x188 + (e == TOKEN_INT));
Jack Palevichae54f1f2009-05-08 14:54:15 -0700279 }
280 else if( e) {
Jack Palevich7448a2e2009-05-08 18:33:45 -0700281 if( e == TOKEN_INT)emitCode( 0x8B);
282 else emitCode( 0xBE0F);
Jack Palevichae54f1f2009-05-08 14:54:15 -0700283 q++;
284 }
285 }
Jack Palevich7448a2e2009-05-08 18:33:45 -0700286 else if( e == '&') {
Jack Palevichf0cbc922009-05-08 16:35:13 -0700287 N(10,*(int*) currentToken);
288 nextToken();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700289 }
290 else {
291 g=*(int*) e;
292 if(!g)g=dlsym(0,M);
Jack Palevich7448a2e2009-05-08 18:33:45 -0700293 if( currentToken == '=' & j) {
Jack Palevichf0cbc922009-05-08 16:35:13 -0700294 nextToken();
Jack Palevich7448a2e2009-05-08 18:33:45 -0700295 parseExpression ();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700296 N(6,g);
297 }
Jack Palevich7448a2e2009-05-08 18:33:45 -0700298 else if( currentToken!= '(') {
Jack Palevichae54f1f2009-05-08 14:54:15 -0700299 N(8,g);
300 if( C == 11) {
301 N(0,g);
Jack Palevich7448a2e2009-05-08 18:33:45 -0700302 emitCode( currentTokenData);
Jack Palevichf0cbc922009-05-08 16:35:13 -0700303 nextToken();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700304 }
305 }
306 }
307 }
Jack Palevich7448a2e2009-05-08 18:33:45 -0700308 if( currentToken == '(') {
309 if( g == 1)emitCode( 0x50);
310 m= emitCodeWithImmediate(0xEC81,0);
Jack Palevichf0cbc922009-05-08 16:35:13 -0700311 nextToken();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700312 j=0;
Jack Palevich7448a2e2009-05-08 18:33:45 -0700313 while( currentToken!= ')') {
314 parseExpression ();
315 emitCodeWithImmediate(0x248489,j);
316 if( currentToken == ',')nextToken();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700317 j=j +4;
318 }
319 *(int*) m= j;
Jack Palevichf0cbc922009-05-08 16:35:13 -0700320 nextToken();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700321 if(!g) {
322 e=e +4;
Jack Palevich7448a2e2009-05-08 18:33:45 -0700323 *(int*) e=emitCodeWithImmediate(0xE8,*(int*) e);
Jack Palevichae54f1f2009-05-08 14:54:15 -0700324 }
325 else if( g == 1) {
Jack Palevich7448a2e2009-05-08 18:33:45 -0700326 emitCodeWithImmediate(0x2494FF,j);
Jack Palevichae54f1f2009-05-08 14:54:15 -0700327 j=j +4;
328 }
329 else {
Jack Palevich7448a2e2009-05-08 18:33:45 -0700330 emitCodeWithImmediate(0xE8,g-q-5);
Jack Palevichae54f1f2009-05-08 14:54:15 -0700331 }
Jack Palevich7448a2e2009-05-08 18:33:45 -0700332 if( j)emitCodeWithImmediate(0xC481,j);
Jack Palevichae54f1f2009-05-08 14:54:15 -0700333 }
Jack Palevich88311482009-05-08 13:57:37 -0700334}
Jack Palevichae54f1f2009-05-08 14:54:15 -0700335
Jack Palevich7448a2e2009-05-08 18:33:45 -0700336static void parseBinaryOp (int level) {
Jack Palevichae54f1f2009-05-08 14:54:15 -0700337 int e,g,m;
Jack Palevich7448a2e2009-05-08 18:33:45 -0700338 if( level--== 1)T(1);
Jack Palevichae54f1f2009-05-08 14:54:15 -0700339 else {
Jack Palevich7448a2e2009-05-08 18:33:45 -0700340 parseBinaryOp (level);
Jack Palevichae54f1f2009-05-08 14:54:15 -0700341 m= 0;
Jack Palevich7448a2e2009-05-08 18:33:45 -0700342 while( level == C) {
Jack Palevichf0cbc922009-05-08 16:35:13 -0700343 g=currentToken;
344 e=currentTokenData;
345 nextToken();
Jack Palevich7448a2e2009-05-08 18:33:45 -0700346 if( level>8) {
Jack Palevichae54f1f2009-05-08 14:54:15 -0700347 m= S(e,m);
Jack Palevich7448a2e2009-05-08 18:33:45 -0700348 parseBinaryOp (level);
Jack Palevichae54f1f2009-05-08 14:54:15 -0700349 }
350 else {
Jack Palevich7448a2e2009-05-08 18:33:45 -0700351 emitCode( 0x50);
352 parseBinaryOp (level);
353 emitCode( 0x59);
354 if( level == 4 | level == 5) {
Jack Palevichae54f1f2009-05-08 14:54:15 -0700355 Z(e);
356 }
357 else {
Jack Palevich7448a2e2009-05-08 18:33:45 -0700358 emitCode( e);
359 if( g == '%')emitCode( 0x92);
Jack Palevichae54f1f2009-05-08 14:54:15 -0700360 }
361 }
362 }
Jack Palevich7448a2e2009-05-08 18:33:45 -0700363 if( m&&level>8) {
Jack Palevichae54f1f2009-05-08 14:54:15 -0700364 m= S(e,m);
Jack Palevich7448a2e2009-05-08 18:33:45 -0700365 emitLoadAccumulatorImmediate(e^1);
366 emitBranch(5);
367 fixupAddress(m);
368 emitLoadAccumulatorImmediate(e);
Jack Palevichae54f1f2009-05-08 14:54:15 -0700369 }
370 }
Jack Palevich88311482009-05-08 13:57:37 -0700371}
Jack Palevichae54f1f2009-05-08 14:54:15 -0700372
Jack Palevich7448a2e2009-05-08 18:33:45 -0700373static void parseExpression() {
374 parseBinaryOp(11);
Jack Palevich88311482009-05-08 13:57:37 -0700375}
Jack Palevichae54f1f2009-05-08 14:54:15 -0700376
Jack Palevich50791f52009-05-08 15:44:22 -0700377static int U() {
Jack Palevich7448a2e2009-05-08 18:33:45 -0700378 parseExpression();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700379 return S(0, 0);
Jack Palevich88311482009-05-08 13:57:37 -0700380}
Jack Palevichae54f1f2009-05-08 14:54:15 -0700381
Jack Palevich7448a2e2009-05-08 18:33:45 -0700382static void parseStatement (int* pBreakTarget) {
Jack Palevichae54f1f2009-05-08 14:54:15 -0700383 int m,g,e;
Jack Palevich7448a2e2009-05-08 18:33:45 -0700384 if( currentToken == TOKEN_IF) {
Jack Palevichf0cbc922009-05-08 16:35:13 -0700385 nextToken();
386 nextToken();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700387 m= U ();
Jack Palevichf0cbc922009-05-08 16:35:13 -0700388 nextToken();
Jack Palevich7448a2e2009-05-08 18:33:45 -0700389 parseStatement (pBreakTarget);
390 if( currentToken == TOKEN_ELSE) {
Jack Palevichf0cbc922009-05-08 16:35:13 -0700391 nextToken();
Jack Palevich7448a2e2009-05-08 18:33:45 -0700392 g=emitBranch(0);
393 fixupAddress(m);
394 parseStatement (pBreakTarget);
395 fixupAddress(g);
Jack Palevichae54f1f2009-05-08 14:54:15 -0700396 }
397 else {
Jack Palevich7448a2e2009-05-08 18:33:45 -0700398 fixupAddress(m);
Jack Palevichae54f1f2009-05-08 14:54:15 -0700399 }
400 }
Jack Palevich7448a2e2009-05-08 18:33:45 -0700401 else if ( currentToken == TOKEN_WHILE || currentToken == TOKEN_FOR) {
402 e = currentToken;
Jack Palevichf0cbc922009-05-08 16:35:13 -0700403 nextToken();
404 nextToken();
Jack Palevich7448a2e2009-05-08 18:33:45 -0700405 if( e == TOKEN_WHILE) {
Jack Palevichae54f1f2009-05-08 14:54:15 -0700406 g=q;
407 m= U ();
408 }
409 else {
Jack Palevich7448a2e2009-05-08 18:33:45 -0700410 if( currentToken != ';')parseExpression ();
Jack Palevichf0cbc922009-05-08 16:35:13 -0700411 nextToken();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700412 g=q;
413 m= 0;
Jack Palevich7448a2e2009-05-08 18:33:45 -0700414 if( currentToken != ';')m= U ();
Jack Palevichf0cbc922009-05-08 16:35:13 -0700415 nextToken();
Jack Palevich7448a2e2009-05-08 18:33:45 -0700416 if( currentToken!= ')') {
417 e=emitBranch(0);
418 parseExpression ();
419 emitBranch(g-q-5);
420 fixupAddress(e);
Jack Palevichae54f1f2009-05-08 14:54:15 -0700421 g=e +4;
422 }
423 }
Jack Palevichf0cbc922009-05-08 16:35:13 -0700424 nextToken();
Jack Palevich7448a2e2009-05-08 18:33:45 -0700425 parseStatement(&m);
426 emitBranch(g-q-5);
427 fixupAddress(m);
Jack Palevichae54f1f2009-05-08 14:54:15 -0700428 }
Jack Palevich7448a2e2009-05-08 18:33:45 -0700429 else if( currentToken == '{') {
Jack Palevichf0cbc922009-05-08 16:35:13 -0700430 nextToken();
Jack Palevich7448a2e2009-05-08 18:33:45 -0700431 parseDeclarations(1);
432 while( currentToken != '}') parseStatement(pBreakTarget);
Jack Palevichf0cbc922009-05-08 16:35:13 -0700433 nextToken();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700434 }
435 else {
Jack Palevich7448a2e2009-05-08 18:33:45 -0700436 if( currentToken == TOKEN_RETURN) {
Jack Palevichf0cbc922009-05-08 16:35:13 -0700437 nextToken();
Jack Palevich7448a2e2009-05-08 18:33:45 -0700438 if( currentToken != ';') parseExpression();
439 K=emitBranch(K);
Jack Palevichae54f1f2009-05-08 14:54:15 -0700440 }
Jack Palevich7448a2e2009-05-08 18:33:45 -0700441 else if( currentToken == TOKEN_BREAK) {
Jack Palevichf0cbc922009-05-08 16:35:13 -0700442 nextToken();
Jack Palevich7448a2e2009-05-08 18:33:45 -0700443 *pBreakTarget = emitBranch(*pBreakTarget);
Jack Palevichae54f1f2009-05-08 14:54:15 -0700444 }
Jack Palevich7448a2e2009-05-08 18:33:45 -0700445 else if( currentToken != ';') parseExpression();
Jack Palevichf0cbc922009-05-08 16:35:13 -0700446 nextToken();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700447 }
Jack Palevich88311482009-05-08 13:57:37 -0700448}
Jack Palevichae54f1f2009-05-08 14:54:15 -0700449
Jack Palevich7448a2e2009-05-08 18:33:45 -0700450static void parseDeclarations (int isLocal) {
Jack Palevichae54f1f2009-05-08 14:54:15 -0700451 int m;
Jack Palevich7448a2e2009-05-08 18:33:45 -0700452 while( currentToken == TOKEN_INT | currentToken != -1 & !isLocal ) {
453 if( currentToken == TOKEN_INT) {
Jack Palevichf0cbc922009-05-08 16:35:13 -0700454 nextToken();
Jack Palevich7448a2e2009-05-08 18:33:45 -0700455 while( currentToken != ';') {
456 if( isLocal ) {
Jack Palevichae54f1f2009-05-08 14:54:15 -0700457 G=G +4;
Jack Palevichf0cbc922009-05-08 16:35:13 -0700458 *(int*) currentToken=-G;
Jack Palevichae54f1f2009-05-08 14:54:15 -0700459 }
460 else {
Jack Palevichf0cbc922009-05-08 16:35:13 -0700461 *(char**) currentToken = v;
Jack Palevichae54f1f2009-05-08 14:54:15 -0700462 v=v +4;
463 }
Jack Palevichf0cbc922009-05-08 16:35:13 -0700464 nextToken();
Jack Palevich7448a2e2009-05-08 18:33:45 -0700465 if( currentToken == ',')nextToken();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700466 }
Jack Palevichf0cbc922009-05-08 16:35:13 -0700467 nextToken();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700468 }
469 else {
Jack Palevich7448a2e2009-05-08 18:33:45 -0700470 fixupAddress(*(int*)(currentToken + 4));
Jack Palevichf0cbc922009-05-08 16:35:13 -0700471 *(int*) currentToken=q;
472 nextToken();
473 nextToken();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700474 m= 8;
Jack Palevich7448a2e2009-05-08 18:33:45 -0700475 while( currentToken != ')') {
Jack Palevichf0cbc922009-05-08 16:35:13 -0700476 *(int*) currentToken=m;
Jack Palevichae54f1f2009-05-08 14:54:15 -0700477 m= m +4;
Jack Palevichf0cbc922009-05-08 16:35:13 -0700478 nextToken();
Jack Palevich7448a2e2009-05-08 18:33:45 -0700479 if( currentToken == ',')nextToken();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700480 }
Jack Palevichf0cbc922009-05-08 16:35:13 -0700481 nextToken();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700482 K=G=0;
Jack Palevich7448a2e2009-05-08 18:33:45 -0700483 emitCode( 0xE58955);
484 m= emitCodeWithImmediate(0xEC81,0);
485 parseStatement(0);
486 fixupAddress(K);
487 emitCode( 0xC3C9);
Jack Palevichae54f1f2009-05-08 14:54:15 -0700488 *(int*) m= G;
489 }
490 }
Jack Palevich88311482009-05-08 13:57:37 -0700491}
Jack Palevichae54f1f2009-05-08 14:54:15 -0700492
493int main( int argc, char** argv) {
Jack Palevichf0cbc922009-05-08 16:35:13 -0700494 pInput = stdin;
Jack Palevichae54f1f2009-05-08 14:54:15 -0700495 if (argc-- > 1) {
496 char* file = argv[1];
497 argv += 1;
Jack Palevichf0cbc922009-05-08 16:35:13 -0700498 pInput = fopen(file, "r");
499 if (pInput == NULL) {
Jack Palevichae54f1f2009-05-08 14:54:15 -0700500 fprintf(stderr, "Could not open file \"%s\"\n", file);
501 return -1;
502 }
503 }
Jack Palevichf0cbc922009-05-08 16:35:13 -0700504 pSymbolTable = strcpy(R = calloc(1, 99999),
Jack Palevichae54f1f2009-05-08 14:54:15 -0700505 " int if else while break return for define main ") + 48;
506 v = calloc(1, 99999);
Jack Palevichd1605302009-05-08 15:26:24 -0700507 ac = calloc(1, 99999);
508 q = (int) ac;
Jack Palevichae54f1f2009-05-08 14:54:15 -0700509 P = calloc(1, 99999);
Jack Palevichf0cbc922009-05-08 16:35:13 -0700510 nextChar();
511 nextToken();
Jack Palevich7448a2e2009-05-08 18:33:45 -0700512 parseDeclarations(0);
Jack Palevichae54f1f2009-05-08 14:54:15 -0700513#if 1
514 fwrite(R, 1, 99999, stdout);
515 fwrite(ac, 1, 99999, stdout);
516 fwrite(P, 1, 99999, stdout);
517 return 0;
518#else
519 return (*(int(*)()) *(int*) (P + 592))(argc, argv);
520#endif
Jack Palevich88311482009-05-08 13:57:37 -0700521}
522