blob: c2c38c49e976c98344d22a71fa57a30d16f0a120 [file] [log] [blame]
Jack Palevichae54f1f2009-05-08 14:54:15 -07001/*
Jack Paleviche27bf3e2009-05-10 14:09:03 -07002 Obfuscated Tiny C Compiler
Jack Palevich88311482009-05-08 13:57:37 -07003
Jack Paleviche27bf3e2009-05-10 14:09:03 -07004 Copyright (C) 2001-2003 Fabrice Bellard
Jack Palevichae54f1f2009-05-08 14:54:15 -07005
Jack Paleviche27bf3e2009-05-10 14:09:03 -07006 This software is provided 'as-is', without any express or implied
7 warranty. In no event will the authors be held liable for any damages
8 arising from the use of this software.
9
10 Permission is granted to anyone to use this software for any purpose,
11 including commercial applications, and to alter it and redistribute it
12 freely, subject to the following restrictions:
13
14 1. The origin of this software must not be misrepresented; you must not
15 claim that you wrote the original software. If you use this software
16 in a product, an acknowledgment in the product and its documentation
17 *is* required.
18 2. Altered source versions must be plainly marked as such, and must not be
19 misrepresented as being the original software.
20 3. This notice may not be removed or altered from any source distribution.
21*/
22
Jack Palevich77ae76e2009-05-10 19:59:24 -070023#include <ctype.h>
24#include <dlfcn.h>
Jack Paleviche27bf3e2009-05-10 14:09:03 -070025#include <stdarg.h>
Jack Palevichae54f1f2009-05-08 14:54:15 -070026#include <stdio.h>
Jack Palevichf6b5a532009-05-10 19:16:42 -070027#include <stdlib.h>
28#include <string.h>
Jack Palevichae54f1f2009-05-08 14:54:15 -070029
Jack Palevich77ae76e2009-05-10 19:59:24 -070030class compiler {
Jack Paleviche27bf3e2009-05-10 14:09:03 -070031/* vars: value of variables
32 loc : local variable index
33 glo : global variable index
34 ind : output code ptr
35 rsym: return symbol
36 prog: output code
37 dstk: define stack
38 dptr, dch: macro state
39*/
Jack Palevichf6b5a532009-05-10 19:16:42 -070040int tok, tokc, tokl, ch, vars, rsym, prog, ind, loc, glo, sym_stk, dstk, dptr, dch, last_id;
41FILE* file;
Jack Palevich7448a2e2009-05-08 18:33:45 -070042
Jack Paleviche27bf3e2009-05-10 14:09:03 -070043#define ALLOC_SIZE 99999
Jack Palevichf0cbc922009-05-08 16:35:13 -070044
Jack Paleviche27bf3e2009-05-10 14:09:03 -070045/* depends on the init string */
46#define TOK_STR_SIZE 48
47#define TOK_IDENT 0x100
48#define TOK_INT 0x100
49#define TOK_IF 0x120
50#define TOK_ELSE 0x138
51#define TOK_WHILE 0x160
52#define TOK_BREAK 0x190
53#define TOK_RETURN 0x1c0
54#define TOK_FOR 0x1f8
55#define TOK_DEFINE 0x218
56#define TOK_MAIN 0x250
Jack Palevichae54f1f2009-05-08 14:54:15 -070057
Jack Paleviche27bf3e2009-05-10 14:09:03 -070058#define TOK_DUMMY 1
59#define TOK_NUM 2
Jack Palevichae54f1f2009-05-08 14:54:15 -070060
Jack Paleviche27bf3e2009-05-10 14:09:03 -070061#define LOCAL 0x200
62
63#define SYM_FORWARD 0
64#define SYM_DEFINE 1
65
66/* tokens in string heap */
67#define TAG_TOK ' '
68#define TAG_MACRO 2
69
Jack Palevich77ae76e2009-05-10 19:59:24 -070070void pdef(int t)
Jack Paleviche27bf3e2009-05-10 14:09:03 -070071{
72 *(char *)dstk++ = t;
Jack Palevich88311482009-05-08 13:57:37 -070073}
Jack Palevichae54f1f2009-05-08 14:54:15 -070074
Jack Palevich77ae76e2009-05-10 19:59:24 -070075void inp()
Jack Paleviche27bf3e2009-05-10 14:09:03 -070076{
77 if (dptr) {
78 ch = *(char *)dptr++;
79 if (ch == TAG_MACRO) {
80 dptr = 0;
81 ch = dch;
Jack Palevichae54f1f2009-05-08 14:54:15 -070082 }
83 } else
Jack Paleviche27bf3e2009-05-10 14:09:03 -070084 ch = fgetc(file);
85 /* printf("ch=%c 0x%x\n", ch, ch); */
Jack Palevich88311482009-05-08 13:57:37 -070086}
Jack Palevichae54f1f2009-05-08 14:54:15 -070087
Jack Palevich77ae76e2009-05-10 19:59:24 -070088int isid()
Jack Paleviche27bf3e2009-05-10 14:09:03 -070089{
90 return isalnum(ch) | ch == '_';
Jack Palevich88311482009-05-08 13:57:37 -070091}
Jack Palevichae54f1f2009-05-08 14:54:15 -070092
Jack Paleviche27bf3e2009-05-10 14:09:03 -070093/* read a character constant */
Jack Palevich77ae76e2009-05-10 19:59:24 -070094void getq()
Jack Paleviche27bf3e2009-05-10 14:09:03 -070095{
96 if (ch == '\\') {
97 inp();
98 if (ch == 'n')
99 ch = '\n';
Jack Palevichae54f1f2009-05-08 14:54:15 -0700100 }
Jack Palevich88311482009-05-08 13:57:37 -0700101}
Jack Palevichae54f1f2009-05-08 14:54:15 -0700102
Jack Palevich77ae76e2009-05-10 19:59:24 -0700103void next()
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700104{
Jack Palevichf6b5a532009-05-10 19:16:42 -0700105 int l, a;
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700106
107 while (isspace(ch) | ch == '#') {
108 if (ch == '#') {
109 inp();
110 next();
111 if (tok == TOK_DEFINE) {
112 next();
113 pdef(TAG_TOK); /* fill last ident tag */
114 *(int *)tok = SYM_DEFINE;
115 *(int *)(tok + 4) = dstk; /* define stack */
Jack Palevichae54f1f2009-05-08 14:54:15 -0700116 }
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700117 /* well we always save the values ! */
118 while (ch != '\n') {
119 pdef(ch);
120 inp();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700121 }
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700122 pdef(ch);
123 pdef(TAG_MACRO);
Jack Palevichae54f1f2009-05-08 14:54:15 -0700124 }
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700125 inp();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700126 }
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700127 tokl = 0;
128 tok = ch;
129 /* encode identifiers & numbers */
130 if (isid()) {
131 pdef(TAG_TOK);
132 last_id = dstk;
133 while (isid()) {
134 pdef(ch);
135 inp();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700136 }
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700137 if (isdigit(tok)) {
Jack Palevichf6b5a532009-05-10 19:16:42 -0700138 tokc = strtol((char*) last_id, 0, 0);
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700139 tok = TOK_NUM;
Jack Palevichae54f1f2009-05-08 14:54:15 -0700140 } else {
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700141 *(char *)dstk = TAG_TOK; /* no need to mark end of string (we
142 suppose data is initied to zero */
Jack Palevichf6b5a532009-05-10 19:16:42 -0700143 tok = (int) (strstr((char*) sym_stk, (char*) (last_id - 1)) - sym_stk);
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700144 *(char *)dstk = 0; /* mark real end of ident for dlsym() */
145 tok = tok * 8 + TOK_IDENT;
146 if (tok > TOK_DEFINE) {
147 tok = vars + tok;
148 /* printf("tok=%s %x\n", last_id, tok); */
149 /* define handling */
150 if (*(int *)tok == SYM_DEFINE) {
151 dptr = *(int *)(tok + 4);
152 dch = ch;
153 inp();
154 next();
Jack Palevichae54f1f2009-05-08 14:54:15 -0700155 }
156 }
157 }
158 } else {
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700159 inp();
160 if (tok == '\'') {
161 tok = TOK_NUM;
162 getq();
163 tokc = ch;
164 inp();
165 inp();
166 } else if (tok == '/' & ch == '*') {
167 inp();
168 while (ch) {
169 while (ch != '*')
170 inp();
171 inp();
172 if (ch == '/')
173 ch = 0;
Jack Palevichae54f1f2009-05-08 14:54:15 -0700174 }
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700175 inp();
176 next();
177 } else
178 {
Jack Palevichf6b5a532009-05-10 19:16:42 -0700179 char* t = "++#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";
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700180 while (l = *(char *)t++) {
181 a = *(char *)t++;
182 tokc = 0;
183 while ((tokl = *(char *)t++ - 'b') < 0)
184 tokc = tokc * 64 + tokl + 64;
185 if (l == tok & (a == ch | a == '@')) {
186#if 0
187 printf("%c%c -> tokl=%d tokc=0x%x\n",
188 l, a, tokl, tokc);
189#endif
190 if (a == ch) {
191 inp();
192 tok = TOK_DUMMY; /* dummy token for double tokens */
Jack Palevichae54f1f2009-05-08 14:54:15 -0700193 }
194 break;
195 }
196 }
197 }
198 }
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700199#if 0
200 {
201 int p;
Jack Palevichae54f1f2009-05-08 14:54:15 -0700202
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700203 printf("tok=0x%x ", tok);
204 if (tok >= TOK_IDENT) {
205 printf("'");
206 if (tok > TOK_DEFINE)
207 p = sym_stk + 1 + (tok - vars - TOK_IDENT) / 8;
208 else
209 p = sym_stk + 1 + (tok - TOK_IDENT) / 8;
210 while (*(char *)p != TAG_TOK && *(char *)p)
211 printf("%c", *(char *)p++);
212 printf("'\n");
213 } else if (tok == TOK_NUM) {
214 printf("%d\n", tokc);
215 } else {
216 printf("'%c'\n", tok);
Jack Palevichae54f1f2009-05-08 14:54:15 -0700217 }
218 }
Jack Palevichae54f1f2009-05-08 14:54:15 -0700219#endif
Jack Palevich88311482009-05-08 13:57:37 -0700220}
221
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700222void error(char *fmt,...)
223{
224 va_list ap;
225
226 va_start(ap, fmt);
227 fprintf(stderr, "%d: ", ftell((FILE *)file));
228 vfprintf(stderr, fmt, ap);
229 fprintf(stderr, "\n");
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700230 va_end(ap);
Jack Palevich77ae76e2009-05-10 19:59:24 -0700231 exit(1);
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700232}
233
Jack Palevich77ae76e2009-05-10 19:59:24 -0700234void skip(int c)
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700235{
236 if (tok != c) {
237 error("'%c' expected", c);
238 }
239 next();
240}
241
Jack Palevich77ae76e2009-05-10 19:59:24 -0700242void o(int n)
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700243{
244 /* cannot use unsigned, so we must do a hack */
245 while (n && n != -1) {
246 *(char *)ind++ = n;
247 n = n >> 8;
248 }
249}
250
251/* output a symbol and patch all calls to it */
Jack Palevich77ae76e2009-05-10 19:59:24 -0700252void gsym(int t)
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700253{
254 int n;
255 while (t) {
256 n = *(int *)t; /* next value */
257 *(int *)t = ind - t - 4;
258 t = n;
259 }
260}
261
262/* psym is used to put an instruction with a data field which is a
263 reference to a symbol. It is in fact the same as oad ! */
264#define psym oad
265
266/* instruction + address */
Jack Palevich77ae76e2009-05-10 19:59:24 -0700267int oad(int n, int t)
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700268{
269 o(n);
270 *(int *)ind = t;
271 t = ind;
272 ind = ind + 4;
273 return t;
274}
275
276/* load immediate value */
Jack Palevich77ae76e2009-05-10 19:59:24 -0700277int li(int t)
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700278{
279 oad(0xb8, t); /* mov $xx, %eax */
280}
281
Jack Palevich77ae76e2009-05-10 19:59:24 -0700282int gjmp(int t)
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700283{
284 return psym(0xe9, t);
285}
286
287/* l = 0: je, l == 1: jne */
Jack Palevich77ae76e2009-05-10 19:59:24 -0700288int gtst(int l, int t)
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700289{
290 o(0x0fc085); /* test %eax, %eax, je/jne xxx */
291 return psym(0x84 + l, t);
292}
293
Jack Palevich77ae76e2009-05-10 19:59:24 -0700294int gcmp(int t)
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700295{
296 o(0xc139); /* cmp %eax,%ecx */
297 li(0);
298 o(0x0f); /* setxx %al */
299 o(t + 0x90);
300 o(0xc0);
301}
302
Jack Palevich77ae76e2009-05-10 19:59:24 -0700303int gmov(int l, int t)
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700304{
305 o(l + 0x83);
306 oad((t < LOCAL) << 7 | 5, t);
307}
308
309/* l is one if '=' parsing wanted (quick hack) */
Jack Palevich77ae76e2009-05-10 19:59:24 -0700310void unary(int l)
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700311{
312 int n, t, a, c;
313
314 n = 1; /* type of expression 0 = forward, 1 = value, other =
315 lvalue */
316 if (tok == '\"') {
317 li(glo);
318 while (ch != '\"') {
319 getq();
320 *(char *)glo++ = ch;
321 inp();
322 }
323 *(char *)glo = 0;
324 glo = glo + 4 & -4; /* align heap */
325 inp();
326 next();
327 } else {
328 c = tokl;
329 a = tokc;
330 t = tok;
331 next();
332 if (t == TOK_NUM) {
333 li(a);
334 } else if (c == 2) {
335 /* -, +, !, ~ */
336 unary(0);
337 oad(0xb9, 0); /* movl $0, %ecx */
338 if (t == '!')
339 gcmp(a);
340 else
341 o(a);
342 } else if (t == '(') {
343 expr();
344 skip(')');
345 } else if (t == '*') {
346 /* parse cast */
347 skip('(');
348 t = tok; /* get type */
349 next(); /* skip int/char/void */
350 next(); /* skip '*' or '(' */
351 if (tok == '*') {
352 /* function type */
353 skip('*');
354 skip(')');
355 skip('(');
356 skip(')');
357 t = 0;
358 }
359 skip(')');
360 unary(0);
361 if (tok == '=') {
362 next();
363 o(0x50); /* push %eax */
364 expr();
365 o(0x59); /* pop %ecx */
366 o(0x0188 + (t == TOK_INT)); /* movl %eax/%al, (%ecx) */
367 } else if (t) {
368 if (t == TOK_INT)
369 o(0x8b); /* mov (%eax), %eax */
370 else
371 o(0xbe0f); /* movsbl (%eax), %eax */
372 ind++; /* add zero in code */
373 }
374 } else if (t == '&') {
375 gmov(10, *(int *)tok); /* leal EA, %eax */
376 next();
377 } else {
378 n = *(int *)t;
379 /* forward reference: try dlsym */
380 if (!n)
Jack Palevich77ae76e2009-05-10 19:59:24 -0700381 n = (int) dlsym(0, (char*) last_id);
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700382 if (tok == '=' & l) {
383 /* assignment */
384 next();
385 expr();
386 gmov(6, n); /* mov %eax, EA */
387 } else if (tok != '(') {
388 /* variable */
389 gmov(8, n); /* mov EA, %eax */
390 if (tokl == 11) {
391 gmov(0, n);
392 o(tokc);
393 next();
394 }
395 }
396 }
397 }
398
399 /* function call */
400 if (tok == '(') {
401 if (n == 1)
402 o(0x50); /* push %eax */
403
404 /* push args and invert order */
405 a = oad(0xec81, 0); /* sub $xxx, %esp */
406 next();
407 l = 0;
408 while(tok != ')') {
409 expr();
410 oad(0x248489, l); /* movl %eax, xxx(%esp) */
411 if (tok == ',')
412 next();
413 l = l + 4;
414 }
415 *(int *)a = l;
416 next();
417 if (!n) {
418 /* forward reference */
419 t = t + 4;
420 *(int *)t = psym(0xe8, *(int *)t);
421 } else if (n == 1) {
422 oad(0x2494ff, l); /* call *xxx(%esp) */
423 l = l + 4;
424 } else {
425 oad(0xe8, n - ind - 5); /* call xxx */
426 }
427 if (l)
428 oad(0xc481, l); /* add $xxx, %esp */
429 }
430}
431
Jack Palevich77ae76e2009-05-10 19:59:24 -0700432void sum(int l)
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700433{
434 int t, n, a;
435
436 if (l-- == 1)
437 unary(1);
438 else {
439 sum(l);
440 a = 0;
441 while (l == tokl) {
442 n = tok;
443 t = tokc;
444 next();
445
446 if (l > 8) {
447 a = gtst(t, a); /* && and || output code generation */
448 sum(l);
449 } else {
450 o(0x50); /* push %eax */
451 sum(l);
452 o(0x59); /* pop %ecx */
453
454 if (l == 4 | l == 5) {
455 gcmp(t);
456 } else {
457 o(t);
458 if (n == '%')
459 o(0x92); /* xchg %edx, %eax */
460 }
461 }
462 }
463 /* && and || output code generation */
464 if (a && l > 8) {
465 a = gtst(t, a);
466 li(t ^ 1);
467 gjmp(5); /* jmp $ + 5 */
468 gsym(a);
469 li(t);
470 }
471 }
472}
473
Jack Palevich77ae76e2009-05-10 19:59:24 -0700474void expr()
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700475{
476 sum(11);
477}
478
479
Jack Palevich77ae76e2009-05-10 19:59:24 -0700480int test_expr()
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700481{
482 expr();
483 return gtst(0, 0);
484}
485
Jack Palevich77ae76e2009-05-10 19:59:24 -0700486
487void block(int l)
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700488{
489 int a, n, t;
490
491 if (tok == TOK_IF) {
492 next();
493 skip('(');
494 a = test_expr();
495 skip(')');
496 block(l);
497 if (tok == TOK_ELSE) {
498 next();
499 n = gjmp(0); /* jmp */
500 gsym(a);
501 block(l);
502 gsym(n); /* patch else jmp */
503 } else {
504 gsym(a); /* patch if test */
505 }
506 } else if (tok == TOK_WHILE | tok == TOK_FOR) {
507 t = tok;
508 next();
509 skip('(');
510 if (t == TOK_WHILE) {
511 n = ind;
512 a = test_expr();
513 } else {
514 if (tok != ';')
515 expr();
516 skip(';');
517 n = ind;
518 a = 0;
519 if (tok != ';')
520 a = test_expr();
521 skip(';');
522 if (tok != ')') {
523 t = gjmp(0);
524 expr();
525 gjmp(n - ind - 5);
526 gsym(t);
527 n = t + 4;
528 }
529 }
530 skip(')');
Jack Palevich77ae76e2009-05-10 19:59:24 -0700531 block((int) &a);
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700532 gjmp(n - ind - 5); /* jmp */
533 gsym(a);
534 } else if (tok == '{') {
535 next();
536 /* declarations */
537 decl(1);
538 while(tok != '}')
539 block(l);
540 next();
541 } else {
542 if (tok == TOK_RETURN) {
543 next();
544 if (tok != ';')
545 expr();
546 rsym = gjmp(rsym); /* jmp */
547 } else if (tok == TOK_BREAK) {
548 next();
549 *(int *)l = gjmp(*(int *)l);
550 } else if (tok != ';')
551 expr();
552 skip(';');
553 }
554}
555
556/* 'l' is true if local declarations */
Jack Palevich77ae76e2009-05-10 19:59:24 -0700557void decl(int l)
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700558{
559 int a;
560
561 while (tok == TOK_INT | tok != -1 & !l) {
562 if (tok == TOK_INT) {
563 next();
564 while (tok != ';') {
565 if (l) {
566 loc = loc + 4;
567 *(int *)tok = -loc;
568 } else {
569 *(int *)tok = glo;
570 glo = glo + 4;
571 }
572 next();
573 if (tok == ',')
574 next();
575 }
576 skip(';');
577 } else {
578 /* patch forward references (XXX: do not work for function
579 pointers) */
580 gsym(*(int *)(tok + 4));
581 /* put function address */
582 *(int *)tok = ind;
583 next();
584 skip('(');
585 a = 8;
586 while (tok != ')') {
587 /* read param name and compute offset */
588 *(int *)tok = a;
589 a = a + 4;
590 next();
591 if (tok == ',')
592 next();
593 }
594 next(); /* skip ')' */
595 rsym = loc = 0;
596 o(0xe58955); /* push %ebp, mov %esp, %ebp */
597 a = oad(0xec81, 0); /* sub $xxx, %esp */
598 block(0);
599 gsym(rsym);
600 o(0xc3c9); /* leave, ret */
601 *(int *)a = loc; /* save local variables */
602 }
603 }
604}
605
Jack Palevich77ae76e2009-05-10 19:59:24 -0700606public:
607compiler(){}
608
609int compile(int n, char** t)
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700610{
611 file = stdin;
612 if (n-- > 1) {
Jack Palevichf6b5a532009-05-10 19:16:42 -0700613 t = t + 1;
614 file = fopen(*t, "r");
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700615 }
Jack Palevichf6b5a532009-05-10 19:16:42 -0700616 sym_stk = (int) calloc(1, ALLOC_SIZE);
617 dstk = (int) strcpy((char*) sym_stk,
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700618 " int if else while break return for define main ") + TOK_STR_SIZE;
Jack Palevichf6b5a532009-05-10 19:16:42 -0700619 glo = (int) calloc(1, ALLOC_SIZE);
620 ind = prog = (int) calloc(1, ALLOC_SIZE);
621 vars = (int) calloc(1, ALLOC_SIZE);
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700622 inp();
623 next();
624 decl(0);
625#ifdef TEST
626 {
627 FILE *f;
Jack Palevichf6b5a532009-05-10 19:16:42 -0700628 f = fopen(t[1], "w");
Jack Paleviche27bf3e2009-05-10 14:09:03 -0700629 fwrite((void *)prog, 1, ind - prog, f);
630 fclose(f);
631 return 0;
632 }
633#else
634 return (*(int (*)())*(int *)(vars + TOK_MAIN)) (n, t);
635#endif
636}
Jack Palevich77ae76e2009-05-10 19:59:24 -0700637
638};
639
640int main(int argc, char** argv) {
641 compiler c;
642 return c.compile(argc, argv);
643}