Xv6 with picoc & Linkage editor
v1.0
The project delineate mutual cohesion between c library, linkage editor ( linker), interpreter and operating system by porting the same on xv6 kernel
|
00001 /* 00002 * Copyright (C) 2006 Edmund GRIMLEY EVANS <edmundo@rano.org> 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software 00016 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 */ 00018 00019 /* 00020 * A self-compiling compiler for a small subset of C. 00021 */ 00022 00023 /* Our library functions. */ 00024 void exit(int); 00025 int getchar(void); 00026 void *malloc(int); 00027 int putchar(int); 00028 00029 /* The first thing defined must be main(). */ 00030 int main1(); 00031 int main() 00032 { 00033 return main1(); 00034 } 00035 00036 char *my_realloc(char *old, int oldlen, int newlen) 00037 { 00038 char *new = malloc(newlen); 00039 int i = 0; 00040 while (i <= oldlen - 1) { 00041 new[i] = old[i]; 00042 i = i + 1; 00043 } 00044 return new; 00045 } 00046 00047 int nextc; 00048 char *token; 00049 int token_size; 00050 00051 void error() 00052 { 00053 exit(1); 00054 } 00055 00056 int i; 00057 00058 void takechar() 00059 { 00060 if (token_size <= i + 1) { 00061 int x = (i + 10) << 1; 00062 token = my_realloc(token, token_size, x); 00063 token_size = x; 00064 } 00065 token[i] = nextc; 00066 i = i + 1; 00067 nextc = getchar(); 00068 } 00069 00070 void get_token() 00071 { 00072 int w = 1; 00073 while (w) { 00074 w = 0; 00075 while ((nextc == ' ') | (nextc == 9) | (nextc == 10)) 00076 nextc = getchar(); 00077 i = 0; 00078 while ((('a' <= nextc) & (nextc <= 'z')) | 00079 (('0' <= nextc) & (nextc <= '9')) | (nextc == '_')) 00080 takechar(); 00081 if (i == 0) 00082 while ((nextc == '<') | (nextc == '=') | (nextc == '>') | 00083 (nextc == '|') | (nextc == '&') | (nextc == '!')) 00084 takechar(); 00085 if (i == 0) { 00086 if (nextc == 39) { 00087 takechar(); 00088 while (nextc != 39) 00089 takechar(); 00090 takechar(); 00091 } 00092 else if (nextc == '"') { 00093 takechar(); 00094 while (nextc != '"') 00095 takechar(); 00096 takechar(); 00097 } 00098 else if (nextc == '/') { 00099 takechar(); 00100 if (nextc == '*') { 00101 nextc = getchar(); 00102 while (nextc != '/') { 00103 while (nextc != '*') 00104 nextc = getchar(); 00105 nextc = getchar(); 00106 } 00107 nextc = getchar(); 00108 w = 1; 00109 } 00110 } 00111 else if (nextc != 0-1) 00112 takechar(); 00113 } 00114 token[i] = 0; 00115 } 00116 } 00117 00118 int peek(char *s) 00119 { 00120 int i = 0; 00121 while ((s[i] == token[i]) & (s[i] != 0)) 00122 i = i + 1; 00123 return s[i] == token[i]; 00124 } 00125 00126 int accept(char *s) 00127 { 00128 if (peek(s)) { 00129 get_token(); 00130 return 1; 00131 } 00132 else 00133 return 0; 00134 } 00135 00136 void expect(char *s) 00137 { 00138 if (accept(s) == 0) 00139 error(); 00140 } 00141 00142 char *code; 00143 int code_size; 00144 int codepos; 00145 int code_offset; 00146 00147 void save_int(char *p, int n) 00148 { 00149 p[0] = n; 00150 p[1] = n >> 8; 00151 p[2] = n >> 16; 00152 p[3] = n >> 24; 00153 } 00154 00155 int load_int(char *p) 00156 { 00157 return ((p[0] & 255) + ((p[1] & 255) << 8) + 00158 ((p[2] & 255) << 16) + ((p[3] & 255) << 24)); 00159 } 00160 00161 void emit(int n, char *s) 00162 { 00163 i = 0; 00164 if (code_size <= codepos + n) { 00165 int x = (codepos + n) << 1; 00166 code = my_realloc(code, code_size, x); 00167 code_size = x; 00168 } 00169 while (i <= n - 1) { 00170 code[codepos] = s[i]; 00171 codepos = codepos + 1; 00172 i = i + 1; 00173 } 00174 } 00175 00176 void be_push() 00177 { 00178 emit(1, "\x50"); /* push %eax */ 00179 } 00180 00181 void be_pop(int n) 00182 { 00183 emit(6, "\x81\xc4...."); /* add $(n * 4),%esp */ 00184 save_int(code + codepos - 4, n << 2); 00185 } 00186 00187 char *table; 00188 int table_size; 00189 int table_pos; 00190 int stack_pos; 00191 00192 int sym_lookup(char *s) 00193 { 00194 int t = 0; 00195 int current_symbol = 0; 00196 while (t <= table_pos - 1) { 00197 i = 0; 00198 while ((s[i] == table[t]) & (s[i] != 0)) { 00199 i = i + 1; 00200 t = t + 1; 00201 } 00202 if (s[i] == table[t]) 00203 current_symbol = t; 00204 while (table[t] != 0) 00205 t = t + 1; 00206 t = t + 6; 00207 } 00208 return current_symbol; 00209 } 00210 00211 void sym_declare(char *s, int type, int value) 00212 { 00213 int t = table_pos; 00214 i = 0; 00215 while (s[i] != 0) { 00216 if (table_size <= t + 10) { 00217 int x = (t + 10) << 1; 00218 table = my_realloc(table, table_size, x); 00219 table_size = x; 00220 } 00221 table[t] = s[i]; 00222 i = i + 1; 00223 t = t + 1; 00224 } 00225 table[t] = 0; 00226 table[t + 1] = type; 00227 save_int(table + t + 2, value); 00228 table_pos = t + 6; 00229 } 00230 00231 int sym_declare_global(char *s) 00232 { 00233 int current_symbol = sym_lookup(s); 00234 if (current_symbol == 0) { 00235 sym_declare(s, 'U', code_offset); 00236 current_symbol = table_pos - 6; 00237 } 00238 return current_symbol; 00239 } 00240 00241 void sym_define_global(int current_symbol) 00242 { 00243 int i; 00244 int j; 00245 int t = current_symbol; 00246 int v = codepos + code_offset; 00247 if (table[t + 1] != 'U') 00248 error(); /* symbol redefined */ 00249 i = load_int(table + t + 2) - code_offset; 00250 while (i) { 00251 j = load_int(code + i) - code_offset; 00252 save_int(code + i, v); 00253 i = j; 00254 } 00255 table[t + 1] = 'D'; 00256 save_int(table + t + 2, v); 00257 } 00258 00259 int number_of_args; 00260 00261 void sym_get_value(char *s) 00262 { 00263 int t; 00264 if ((t = sym_lookup(s)) == 0) 00265 error(); 00266 emit(5, "\xb8...."); /* mov $n,%eax */ 00267 save_int(code + codepos - 4, load_int(table + t + 2)); 00268 if (table[t + 1] == 'D') { /* defined global */ 00269 } 00270 else if (table[t + 1] == 'U') /* undefined global */ 00271 save_int(table + t + 2, codepos + code_offset - 4); 00272 else if (table[t + 1] == 'L') { /* local variable */ 00273 int k = (stack_pos - table[t + 2] - 1) << 2; 00274 emit(7, "\x8d\x84\x24...."); /* lea (n * 4)(%esp),%eax */ 00275 save_int(code + codepos - 4, k); 00276 } 00277 else if (table[t + 1] == 'A') { /* argument */ 00278 int k = (stack_pos + number_of_args - table[t + 2] + 1) << 2; 00279 emit(7, "\x8d\x84\x24...."); /* lea (n * 4)(%esp),%eax */ 00280 save_int(code + codepos - 4, k); 00281 } 00282 else 00283 error(); 00284 } 00285 00286 void be_start() 00287 { 00288 emit(16, "\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00"); 00289 emit(16, "\x02\x00\x03\x00\x01\x00\x00\x00\x54\x80\x04\x08\x34\x00\x00\x00"); 00290 emit(16, "\x00\x00\x00\x00\x00\x00\x00\x00\x34\x00\x20\x00\x01\x00\x00\x00"); 00291 emit(16, "\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x80\x04\x08"); 00292 emit(16, "\x00\x80\x04\x08\x10\x4b\x00\x00\x10\x4b\x00\x00\x07\x00\x00\x00"); 00293 emit(16, "\x00\x10\x00\x00\xe8\x00\x00\x00\x00\x89\xc3\x31\xc0\x40\xcd\x80"); 00294 00295 sym_define_global(sym_declare_global("exit")); 00296 /* pop %ebx ; pop %ebx ; xor %eax,%eax ; inc %eax ; int $0x80 */ 00297 emit(7, "\x5b\x5b\x31\xc0\x40\xcd\x80"); 00298 00299 sym_define_global(sym_declare_global("getchar")); 00300 /* mov $3,%eax ; xor %ebx,%ebx ; push %ebx ; mov %esp,%ecx */ 00301 emit(10, "\xb8\x03\x00\x00\x00\x31\xdb\x53\x89\xe1"); 00302 /* xor %edx,%edx ; inc %edx ; int $0x80 */ 00303 /* test %eax,%eax ; pop %eax ; jne . + 7 */ 00304 emit(10, "\x31\xd2\x42\xcd\x80\x85\xc0\x58\x75\x05"); 00305 /* mov $-1,%eax ; ret */ 00306 emit(6, "\xb8\xff\xff\xff\xff\xc3"); 00307 00308 sym_define_global(sym_declare_global("malloc")); 00309 /* mov 4(%esp),%eax */ 00310 emit(4, "\x8b\x44\x24\x04"); 00311 /* push %eax ; xor %ebx,%ebx ; mov $45,%eax ; int $0x80 */ 00312 emit(10, "\x50\x31\xdb\xb8\x2d\x00\x00\x00\xcd\x80"); 00313 /* pop %ebx ; add %eax,%ebx ; push %eax ; push %ebx ; mov $45,%eax */ 00314 emit(10, "\x5b\x01\xc3\x50\x53\xb8\x2d\x00\x00\x00"); 00315 /* int $0x80 ; pop %ebx ; cmp %eax,%ebx ; pop %eax ; je . + 7 */ 00316 emit(8, "\xcd\x80\x5b\x39\xc3\x58\x74\x05"); 00317 /* mov $-1,%eax ; ret */ 00318 emit(6, "\xb8\xff\xff\xff\xff\xc3"); 00319 00320 sym_define_global(sym_declare_global("putchar")); 00321 /* mov $4,%eax ; xor %ebx,%ebx ; inc %ebx */ 00322 emit(8, "\xb8\x04\x00\x00\x00\x31\xdb\x43"); 00323 /* lea 4(%esp),%ecx ; mov %ebx,%edx ; int $0x80 ; ret */ 00324 emit(9, "\x8d\x4c\x24\x04\x89\xda\xcd\x80\xc3"); 00325 00326 save_int(code + 85, codepos - 89); /* entry set to first thing in file */ 00327 } 00328 00329 void be_finish() 00330 { 00331 save_int(code + 68, codepos); 00332 save_int(code + 72, codepos); 00333 i = 0; 00334 while (i <= codepos - 1) { 00335 putchar(code[i]); 00336 i = i + 1; 00337 } 00338 } 00339 00340 void promote(int type) 00341 { 00342 /* 1 = char lval, 2 = int lval, 3 = other */ 00343 if (type == 1) 00344 emit(3, "\x0f\xbe\x00"); /* movsbl (%eax),%eax */ 00345 else if (type == 2) 00346 emit(2, "\x8b\x00"); /* mov (%eax),%eax */ 00347 } 00348 00349 int expression(); 00350 00351 /* 00352 * primary-expr: 00353 * identifier 00354 * constant 00355 * ( expression ) 00356 */ 00357 int primary_expr() 00358 { 00359 int type; 00360 if (('0' <= token[0]) & (token[0] <= '9')) { 00361 int n = 0; 00362 i = 0; 00363 while (token[i]) { 00364 n = (n << 1) + (n << 3) + token[i] - '0'; 00365 i = i + 1; 00366 } 00367 emit(5, "\xb8...."); /* mov $x,%eax */ 00368 save_int(code + codepos - 4, n); 00369 type = 3; 00370 } 00371 else if (('a' <= token[0]) & (token[0] <= 'z')) { 00372 sym_get_value(token); 00373 type = 2; 00374 } 00375 else if (accept("(")) { 00376 type = expression(); 00377 if (peek(")") == 0) 00378 error(); 00379 } 00380 else if ((token[0] == 39) & (token[1] != 0) & 00381 (token[2] == 39) & (token[3] == 0)) { 00382 emit(5, "\xb8...."); /* mov $x,%eax */ 00383 save_int(code + codepos - 4, token[1]); 00384 type = 3; 00385 } 00386 else if (token[0] == '"') { 00387 int i = 0; 00388 int j = 1; 00389 int k; 00390 while (token[j] != '"') { 00391 if ((token[j] == 92) & (token[j + 1] == 'x')) { 00392 if (token[j + 2] <= '9') 00393 k = token[j + 2] - '0'; 00394 else 00395 k = token[j + 2] - 'a' + 10; 00396 k = k << 4; 00397 if (token[j + 3] <= '9') 00398 k = k + token[j + 3] - '0'; 00399 else 00400 k = k + token[j + 3] - 'a' + 10; 00401 token[i] = k; 00402 j = j + 4; 00403 } 00404 else { 00405 token[i] = token[j]; 00406 j = j + 1; 00407 } 00408 i = i + 1; 00409 } 00410 token[i] = 0; 00411 /* call ... ; the string ; pop %eax */ 00412 emit(5, "\xe8...."); 00413 save_int(code + codepos - 4, i + 1); 00414 emit(i + 1, token); 00415 emit(1, "\x58"); 00416 type = 3; 00417 } 00418 else 00419 error(); 00420 get_token(); 00421 return type; 00422 } 00423 00424 void binary1(int type) 00425 { 00426 promote(type); 00427 be_push(); 00428 stack_pos = stack_pos + 1; 00429 } 00430 00431 int binary2(int type, int n, char *s) 00432 { 00433 promote(type); 00434 emit(n, s); 00435 stack_pos = stack_pos - 1; 00436 return 3; 00437 } 00438 00439 /* 00440 * postfix-expr: 00441 * primary-expr 00442 * postfix-expr [ expression ] 00443 * postfix-expr ( expression-list-opt ) 00444 */ 00445 int postfix_expr() 00446 { 00447 int type = primary_expr(); 00448 if (accept("[")) { 00449 binary1(type); /* pop %ebx ; add %ebx,%eax */ 00450 binary2(expression(), 3, "\x5b\x01\xd8"); 00451 expect("]"); 00452 type = 1; 00453 } 00454 else if (accept("(")) { 00455 int s = stack_pos; 00456 be_push(); 00457 stack_pos = stack_pos + 1; 00458 if (accept(")") == 0) { 00459 promote(expression()); 00460 be_push(); 00461 stack_pos = stack_pos + 1; 00462 while (accept(",")) { 00463 promote(expression()); 00464 be_push(); 00465 stack_pos = stack_pos + 1; 00466 } 00467 expect(")"); 00468 } 00469 emit(7, "\x8b\x84\x24...."); /* mov (n * 4)(%esp),%eax */ 00470 save_int(code + codepos - 4, (stack_pos - s - 1) << 2); 00471 emit(2, "\xff\xd0"); /* call *%eax */ 00472 be_pop(stack_pos - s); 00473 stack_pos = s; 00474 type = 3; 00475 } 00476 return type; 00477 } 00478 00479 /* 00480 * additive-expr: 00481 * postfix-expr 00482 * additive-expr + postfix-expr 00483 * additive-expr - postfix-expr 00484 */ 00485 int additive_expr() 00486 { 00487 int type = postfix_expr(); 00488 while (1) { 00489 if (accept("+")) { 00490 binary1(type); /* pop %ebx ; add %ebx,%eax */ 00491 type = binary2(postfix_expr(), 3, "\x5b\x01\xd8"); 00492 } 00493 else if (accept("-")) { 00494 binary1(type); /* pop %ebx ; sub %eax,%ebx ; mov %ebx,%eax */ 00495 type = binary2(postfix_expr(), 5, "\x5b\x29\xc3\x89\xd8"); 00496 } 00497 else 00498 return type; 00499 } 00500 } 00501 00502 /* 00503 * shift-expr: 00504 * additive-expr 00505 * shift-expr << additive-expr 00506 * shift-expr >> additive-expr 00507 */ 00508 int shift_expr() 00509 { 00510 int type = additive_expr(); 00511 while (1) { 00512 if (accept("<<")) { 00513 binary1(type); /* mov %eax,%ecx ; pop %eax ; shl %cl,%eax */ 00514 type = binary2(additive_expr(), 5, "\x89\xc1\x58\xd3\xe0"); 00515 } 00516 else if (accept(">>")) { 00517 binary1(type); /* mov %eax,%ecx ; pop %eax ; sar %cl,%eax */ 00518 type = binary2(additive_expr(), 5, "\x89\xc1\x58\xd3\xf8"); 00519 } 00520 else 00521 return type; 00522 } 00523 } 00524 00525 /* 00526 * relational-expr: 00527 * shift-expr 00528 * relational-expr <= shift-expr 00529 */ 00530 int relational_expr() 00531 { 00532 int type = shift_expr(); 00533 while (accept("<=")) { 00534 binary1(type); 00535 /* pop %ebx ; cmp %eax,%ebx ; setle %al ; movzbl %al,%eax */ 00536 type = binary2(shift_expr(), 00537 9, "\x5b\x39\xc3\x0f\x9e\xc0\x0f\xb6\xc0"); 00538 } 00539 return type; 00540 } 00541 00542 /* 00543 * equality-expr: 00544 * relational-expr 00545 * equality-expr == relational-expr 00546 * equality-expr != relational-expr 00547 */ 00548 int equality_expr() 00549 { 00550 int type = relational_expr(); 00551 while (1) { 00552 if (accept("==")) { 00553 binary1(type); 00554 /* pop %ebx ; cmp %eax,%ebx ; sete %al ; movzbl %al,%eax */ 00555 type = binary2(relational_expr(), 00556 9, "\x5b\x39\xc3\x0f\x94\xc0\x0f\xb6\xc0"); 00557 } 00558 else if (accept("!=")) { 00559 binary1(type); 00560 /* pop %ebx ; cmp %eax,%ebx ; setne %al ; movzbl %al,%eax */ 00561 type = binary2(relational_expr(), 00562 9, "\x5b\x39\xc3\x0f\x95\xc0\x0f\xb6\xc0"); 00563 } 00564 else 00565 return type; 00566 } 00567 } 00568 00569 /* 00570 * bitwise-and-expr: 00571 * equality-expr 00572 * bitwise-and-expr & equality-expr 00573 */ 00574 int bitwise_and_expr() 00575 { 00576 int type = equality_expr(); 00577 while (accept("&")) { 00578 binary1(type); /* pop %ebx ; and %ebx,%eax */ 00579 type = binary2(equality_expr(), 3, "\x5b\x21\xd8"); 00580 } 00581 return type; 00582 } 00583 00584 /* 00585 * bitwise-or-expr: 00586 * bitwise-and-expr 00587 * bitwise-and-expr | bitwise-or-expr 00588 */ 00589 int bitwise_or_expr() 00590 { 00591 int type = bitwise_and_expr(); 00592 while (accept("|")) { 00593 binary1(type); /* pop %ebx ; or %ebx,%eax */ 00594 type = binary2(bitwise_and_expr(), 3, "\x5b\x09\xd8"); 00595 } 00596 return type; 00597 } 00598 00599 /* 00600 * expression: 00601 * bitwise-or-expr 00602 * bitwise-or-expr = expression 00603 */ 00604 int expression() 00605 { 00606 int type = bitwise_or_expr(); 00607 if (accept("=")) { 00608 be_push(); 00609 stack_pos = stack_pos + 1; 00610 promote(expression()); 00611 if (type == 2) 00612 emit(3, "\x5b\x89\x03"); /* pop %ebx ; mov %eax,(%ebx) */ 00613 else 00614 emit(3, "\x5b\x88\x03"); /* pop %ebx ; mov %al,(%ebx) */ 00615 stack_pos = stack_pos - 1; 00616 type = 3; 00617 } 00618 return type; 00619 } 00620 00621 /* 00622 * type-name: 00623 * char * 00624 * int 00625 */ 00626 void type_name() 00627 { 00628 get_token(); 00629 while (accept("*")) { 00630 } 00631 } 00632 00633 /* 00634 * statement: 00635 * { statement-list-opt } 00636 * type-name identifier ; 00637 * type-name identifier = expression; 00638 * if ( expression ) statement 00639 * if ( expression ) statement else statement 00640 * while ( expression ) statement 00641 * return ; 00642 * expr ; 00643 */ 00644 void statement() 00645 { 00646 int p1; 00647 int p2; 00648 if (accept("{")) { 00649 int n = table_pos; 00650 int s = stack_pos; 00651 while (accept("}") == 0) 00652 statement(); 00653 table_pos = n; 00654 be_pop(stack_pos - s); 00655 stack_pos = s; 00656 } 00657 else if (peek("char") | peek("int")) { 00658 type_name(); 00659 sym_declare(token, 'L', stack_pos); 00660 get_token(); 00661 if (accept("=")) 00662 promote(expression()); 00663 expect(";"); 00664 be_push(); 00665 stack_pos = stack_pos + 1; 00666 } 00667 else if (accept("if")) { 00668 expect("("); 00669 promote(expression()); 00670 emit(8, "\x85\xc0\x0f\x84...."); /* test %eax,%eax ; je ... */ 00671 p1 = codepos; 00672 expect(")"); 00673 statement(); 00674 emit(5, "\xe9...."); /* jmp ... */ 00675 p2 = codepos; 00676 save_int(code + p1 - 4, codepos - p1); 00677 if (accept("else")) 00678 statement(); 00679 save_int(code + p2 - 4, codepos - p2); 00680 } 00681 else if (accept("while")) { 00682 expect("("); 00683 p1 = codepos; 00684 promote(expression()); 00685 emit(8, "\x85\xc0\x0f\x84...."); /* test %eax,%eax ; je ... */ 00686 p2 = codepos; 00687 expect(")"); 00688 statement(); 00689 emit(5, "\xe9...."); /* jmp ... */ 00690 save_int(code + codepos - 4, p1 - codepos); 00691 save_int(code + p2 - 4, codepos - p2); 00692 } 00693 else if (accept("return")) { 00694 if (peek(";") == 0) 00695 promote(expression()); 00696 expect(";"); 00697 be_pop(stack_pos); 00698 emit(1, "\xc3"); /* ret */ 00699 } 00700 else { 00701 expression(); 00702 expect(";"); 00703 } 00704 } 00705 00706 /* 00707 * program: 00708 * declaration 00709 * declaration program 00710 * 00711 * declaration: 00712 * type-name identifier ; 00713 * type-name identifier ( parameter-list ) ; 00714 * type-name identifier ( parameter-list ) statement 00715 * 00716 * parameter-list: 00717 * parameter-declaration 00718 * parameter-list, parameter-declaration 00719 * 00720 * parameter-declaration: 00721 * type-name identifier-opt 00722 */ 00723 void program() 00724 { 00725 int current_symbol; 00726 while (token[0]) { 00727 type_name(); 00728 current_symbol = sym_declare_global(token); 00729 get_token(); 00730 if (accept(";")) { 00731 sym_define_global(current_symbol); 00732 emit(4, "\x00\x00\x00\x00"); 00733 } 00734 else if (accept("(")) { 00735 int n = table_pos; 00736 number_of_args = 0; 00737 while (accept(")") == 0) { 00738 number_of_args = number_of_args + 1; 00739 type_name(); 00740 if (peek(")") == 0) { 00741 sym_declare(token, 'A', number_of_args); 00742 get_token(); 00743 } 00744 accept(","); /* ignore trailing comma */ 00745 } 00746 if (accept(";") == 0) { 00747 sym_define_global(current_symbol); 00748 statement(); 00749 emit(1, "\xc3"); /* ret */ 00750 } 00751 table_pos = n; 00752 } 00753 else 00754 error(); 00755 } 00756 } 00757 00758 int main1() 00759 { 00760 code_offset = 134512640; /* 0x08048000 */ 00761 be_start(); 00762 nextc = getchar(); 00763 get_token(); 00764 program(); 00765 be_finish(); 00766 return 0; 00767 }