cc500.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  1. /*
  2. * Copyright (C) 2006 Edmund GRIMLEY EVANS <edmundo@rano.org>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. */
  18. /*
  19. * A self-compiling compiler for a small subset of C.
  20. */
  21. /* Our library functions. */
  22. void exit(int);
  23. int getchar(void);
  24. void *malloc(int);
  25. int putchar(int);
  26. /* The first thing defined must be main(). */
  27. int main1();
  28. int main()
  29. {
  30. int a = 10;
  31. int b = a;
  32. return main1();
  33. }
  34. char *my_realloc(char *old, int oldlen, int newlen)
  35. {
  36. char *new = malloc(newlen);
  37. int i = 0;
  38. while (i <= oldlen - 1) {
  39. new[i] = old[i];
  40. i = i + 1;
  41. }
  42. return new;
  43. }
  44. int nextc;
  45. char *token;
  46. int token_size;
  47. void error()
  48. {
  49. exit(1);
  50. }
  51. int i;
  52. void takechar()
  53. {
  54. if (token_size <= i + 1) {
  55. int x = (i + 10) << 1;
  56. token = my_realloc(token, token_size, x);
  57. token_size = x;
  58. }
  59. token[i] = nextc;
  60. i = i + 1;
  61. nextc = getchar();
  62. }
  63. void get_token()
  64. {
  65. int w = 1;
  66. while (w) {
  67. w = 0;
  68. while ((nextc == ' ') | (nextc == 9) | (nextc == 10))
  69. nextc = getchar();
  70. i = 0;
  71. while ((('a' <= nextc) & (nextc <= 'z')) |
  72. (('0' <= nextc) & (nextc <= '9')) | (nextc == '_'))
  73. takechar();
  74. if (i == 0)
  75. while ((nextc == '<') | (nextc == '=') | (nextc == '>') |
  76. (nextc == '|') | (nextc == '&') | (nextc == '!'))
  77. takechar();
  78. if (i == 0) {
  79. if (nextc == 39) {
  80. takechar();
  81. while (nextc != 39)
  82. takechar();
  83. takechar();
  84. }
  85. else if (nextc == '"') {
  86. takechar();
  87. while (nextc != '"')
  88. takechar();
  89. takechar();
  90. }
  91. else if (nextc == '/') {
  92. takechar();
  93. if (nextc == '*') {
  94. nextc = getchar();
  95. while (nextc != '/') {
  96. while (nextc != '*')
  97. nextc = getchar();
  98. nextc = getchar();
  99. }
  100. nextc = getchar();
  101. w = 1;
  102. }
  103. }
  104. else if (nextc != 0-1)
  105. takechar();
  106. }
  107. token[i] = 0;
  108. }
  109. }
  110. int peek(char *s)
  111. {
  112. int i = 0;
  113. while ((s[i] == token[i]) & (s[i] != 0))
  114. i = i + 1;
  115. return s[i] == token[i];
  116. }
  117. int accept(char *s)
  118. {
  119. if (peek(s)) {
  120. get_token();
  121. return 1;
  122. }
  123. else
  124. return 0;
  125. }
  126. void expect(char *s)
  127. {
  128. if (accept(s) == 0)
  129. error();
  130. }
  131. char *code;
  132. int code_size;
  133. int codepos;
  134. int code_offset;
  135. void save_int(char *p, int n)
  136. {
  137. p[0] = n;
  138. p[1] = n >> 8;
  139. p[2] = n >> 16;
  140. p[3] = n >> 24;
  141. }
  142. int load_int(char *p)
  143. {
  144. return ((p[0] & 255) + ((p[1] & 255) << 8) +
  145. ((p[2] & 255) << 16) + ((p[3] & 255) << 24));
  146. }
  147. void emit(int n, char *s)
  148. {
  149. i = 0;
  150. if (code_size <= codepos + n) {
  151. int x = (codepos + n) << 1;
  152. code = my_realloc(code, code_size, x);
  153. code_size = x;
  154. }
  155. while (i <= n - 1) {
  156. code[codepos] = s[i];
  157. codepos = codepos + 1;
  158. i = i + 1;
  159. }
  160. }
  161. void be_push()
  162. {
  163. emit(1, "\x50"); /* push %eax */
  164. }
  165. void be_pop(int n)
  166. {
  167. emit(6, "\x81\xc4...."); /* add $(n * 4),%esp */
  168. save_int(code + codepos - 4, n << 2);
  169. }
  170. char *table;
  171. int table_size;
  172. int table_pos;
  173. int stack_pos;
  174. int sym_lookup(char *s)
  175. {
  176. int t = 0;
  177. int current_symbol = 0;
  178. while (t <= table_pos - 1) {
  179. i = 0;
  180. while ((s[i] == table[t]) & (s[i] != 0)) {
  181. i = i + 1;
  182. t = t + 1;
  183. }
  184. if (s[i] == table[t])
  185. current_symbol = t;
  186. while (table[t] != 0)
  187. t = t + 1;
  188. t = t + 6;
  189. }
  190. return current_symbol;
  191. }
  192. void sym_declare(char *s, int type, int value)
  193. {
  194. int t = table_pos;
  195. i = 0;
  196. int x;
  197. while (s[i] != 0) {
  198. if (table_size <= t + 10) {
  199. x = (t + 10) << 1;
  200. table = my_realloc(table, table_size, x);
  201. table_size = x;
  202. }
  203. table[t] = s[i];
  204. i = i + 1;
  205. t = t + 1;
  206. }
  207. table[t] = 0;
  208. table[t + 1] = type;
  209. save_int(table + t + 2, value);
  210. table_pos = t + 6;
  211. }
  212. int sym_declare_global(char *s)
  213. {
  214. int current_symbol = sym_lookup(s);
  215. if (current_symbol == 0) {
  216. sym_declare(s, 'U', code_offset);
  217. current_symbol = table_pos - 6;
  218. }
  219. return current_symbol;
  220. }
  221. void sym_define_global(int current_symbol)
  222. {
  223. int i;
  224. int j;
  225. int t = current_symbol;
  226. int v = codepos + code_offset;
  227. if (table[t + 1] != 'U')
  228. error(); /* symbol redefined */
  229. i = load_int(table + t + 2) - code_offset;
  230. while (i) {
  231. j = load_int(code + i) - code_offset;
  232. save_int(code + i, v);
  233. i = j;
  234. }
  235. table[t + 1] = 'D';
  236. save_int(table + t + 2, v);
  237. }
  238. int number_of_args;
  239. void sym_get_value(char *s)
  240. {
  241. int t;
  242. if ((t = sym_lookup(s)) == 0)
  243. error();
  244. emit(5, "\xb8...."); /* mov $n,%eax */
  245. save_int(code + codepos - 4, load_int(table + t + 2));
  246. if (table[t + 1] == 'D') { /* defined global */
  247. }
  248. else if (table[t + 1] == 'U') /* undefined global */
  249. save_int(table + t + 2, codepos + code_offset - 4);
  250. else if (table[t + 1] == 'L') { /* local variable */
  251. int k = (stack_pos - table[t + 2] - 1) << 2;
  252. emit(7, "\x8d\x84\x24...."); /* lea (n * 4)(%esp),%eax */
  253. save_int(code + codepos - 4, k);
  254. }
  255. else if (table[t + 1] == 'A') { /* argument */
  256. int k = (stack_pos + number_of_args - table[t + 2] + 1) << 2;
  257. emit(7, "\x8d\x84\x24...."); /* lea (n * 4)(%esp),%eax */
  258. save_int(code + codepos - 4, k);
  259. }
  260. else
  261. error();
  262. }
  263. void be_start()
  264. {
  265. emit(16, "\x7f\x45\x4c\x46\x01\x01\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00");
  266. emit(16, "\x02\x00\x03\x00\x01\x00\x00\x00\x54\x80\x04\x08\x34\x00\x00\x00");
  267. emit(16, "\x00\x00\x00\x00\x00\x00\x00\x00\x34\x00\x20\x00\x01\x00\x00\x00");
  268. emit(16, "\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x80\x04\x08");
  269. emit(16, "\x00\x80\x04\x08\x10\x4b\x00\x00\x10\x4b\x00\x00\x07\x00\x00\x00");
  270. emit(16, "\x00\x10\x00\x00\xe8\x00\x00\x00\x00\x89\xc3\x31\xc0\x40\xcd\x80");
  271. sym_define_global(sym_declare_global("exit"));
  272. /* pop %ebx ; pop %ebx ; xor %eax,%eax ; inc %eax ; int $0x80 */
  273. emit(7, "\x5b\x5b\x31\xc0\x40\xcd\x80");
  274. sym_define_global(sym_declare_global("getchar"));
  275. /* mov $3,%eax ; xor %ebx,%ebx ; push %ebx ; mov %esp,%ecx */
  276. emit(10, "\xb8\x03\x00\x00\x00\x31\xdb\x53\x89\xe1");
  277. /* xor %edx,%edx ; inc %edx ; int $0x80 */
  278. /* test %eax,%eax ; pop %eax ; jne . + 7 */
  279. emit(10, "\x31\xd2\x42\xcd\x80\x85\xc0\x58\x75\x05");
  280. /* mov $-1,%eax ; ret */
  281. emit(6, "\xb8\xff\xff\xff\xff\xc3");
  282. sym_define_global(sym_declare_global("malloc"));
  283. /* mov 4(%esp),%eax */
  284. emit(4, "\x8b\x44\x24\x04");
  285. /* push %eax ; xor %ebx,%ebx ; mov $45,%eax ; int $0x80 */
  286. emit(10, "\x50\x31\xdb\xb8\x2d\x00\x00\x00\xcd\x80");
  287. /* pop %ebx ; add %eax,%ebx ; push %eax ; push %ebx ; mov $45,%eax */
  288. emit(10, "\x5b\x01\xc3\x50\x53\xb8\x2d\x00\x00\x00");
  289. /* int $0x80 ; pop %ebx ; cmp %eax,%ebx ; pop %eax ; jle . + 7 */
  290. emit(8, "\xcd\x80\x5b\x39\xc3\x58\x7e\x05");
  291. /* mov $-1,%eax ; ret */
  292. emit(6, "\xb8\xff\xff\xff\xff\xc3");
  293. sym_define_global(sym_declare_global("putchar"));
  294. /* mov $4,%eax ; xor %ebx,%ebx ; inc %ebx */
  295. emit(8, "\xb8\x04\x00\x00\x00\x31\xdb\x43");
  296. /* lea 4(%esp),%ecx ; mov %ebx,%edx ; int $0x80 ; ret */
  297. emit(9, "\x8d\x4c\x24\x04\x89\xda\xcd\x80\xc3");
  298. save_int(code + 85, codepos - 89); /* entry set to first thing in file */
  299. }
  300. void be_finish()
  301. {
  302. save_int(code + 68, codepos);
  303. save_int(code + 72, codepos);
  304. i = 0;
  305. while (i <= codepos - 1) {
  306. putchar(code[i]);
  307. i = i + 1;
  308. }
  309. }
  310. void promote(int type)
  311. {
  312. /* 1 = char lval, 2 = int lval, 3 = other */
  313. if (type == 1)
  314. emit(3, "\x0f\xbe\x00"); /* movsbl (%eax),%eax */
  315. else if (type == 2)
  316. emit(2, "\x8b\x00"); /* mov (%eax),%eax */
  317. }
  318. int expression();
  319. /*
  320. * primary-expr:
  321. * identifier
  322. * constant
  323. * ( expression )
  324. */
  325. int primary_expr()
  326. {
  327. int type;
  328. if (('0' <= token[0]) & (token[0] <= '9')) {
  329. int n = 0;
  330. i = 0;
  331. while (token[i]) {
  332. n = (n << 1) + (n << 3) + token[i] - '0';
  333. i = i + 1;
  334. }
  335. emit(5, "\xb8...."); /* mov $x,%eax */
  336. save_int(code + codepos - 4, n);
  337. type = 3;
  338. }
  339. else if (('a' <= token[0]) & (token[0] <= 'z')) {
  340. sym_get_value(token);
  341. type = 2;
  342. }
  343. else if (accept("(")) {
  344. type = expression();
  345. if (peek(")") == 0)
  346. error();
  347. }
  348. else if ((token[0] == 39) & (token[1] != 0) &
  349. (token[2] == 39) & (token[3] == 0)) {
  350. emit(5, "\xb8...."); /* mov $x,%eax */
  351. save_int(code + codepos - 4, token[1]);
  352. type = 3;
  353. }
  354. else if (token[0] == '"') {
  355. int i = 0;
  356. int j = 1;
  357. int k;
  358. while (token[j] != '"') {
  359. if ((token[j] == 92) & (token[j + 1] == 'x')) {
  360. if (token[j + 2] <= '9')
  361. k = token[j + 2] - '0';
  362. else
  363. k = token[j + 2] - 'a' + 10;
  364. k = k << 4;
  365. if (token[j + 3] <= '9')
  366. k = k + token[j + 3] - '0';
  367. else
  368. k = k + token[j + 3] - 'a' + 10;
  369. token[i] = k;
  370. j = j + 4;
  371. }
  372. else {
  373. token[i] = token[j];
  374. j = j + 1;
  375. }
  376. i = i + 1;
  377. }
  378. token[i] = 0;
  379. /* call ... ; the string ; pop %eax */
  380. emit(5, "\xe8....");
  381. save_int(code + codepos - 4, i + 1);
  382. emit(i + 1, token);
  383. emit(1, "\x58");
  384. type = 3;
  385. }
  386. else
  387. error();
  388. get_token();
  389. return type;
  390. }
  391. void binary1(int type)
  392. {
  393. promote(type);
  394. be_push();
  395. stack_pos = stack_pos + 1;
  396. }
  397. int binary2(int type, int n, char *s)
  398. {
  399. promote(type);
  400. emit(n, s);
  401. stack_pos = stack_pos - 1;
  402. return 3;
  403. }
  404. /*
  405. * postfix-expr:
  406. * primary-expr
  407. * postfix-expr [ expression ]
  408. * postfix-expr ( expression-list-opt )
  409. */
  410. int postfix_expr()
  411. {
  412. int type = primary_expr();
  413. if (accept("[")) {
  414. binary1(type); /* pop %ebx ; add %ebx,%eax */
  415. binary2(expression(), 3, "\x5b\x01\xd8");
  416. expect("]");
  417. type = 1;
  418. }
  419. else if (accept("(")) {
  420. int s = stack_pos;
  421. be_push();
  422. stack_pos = stack_pos + 1;
  423. if (accept(")") == 0) {
  424. promote(expression());
  425. be_push();
  426. stack_pos = stack_pos + 1;
  427. while (accept(",")) {
  428. promote(expression());
  429. be_push();
  430. stack_pos = stack_pos + 1;
  431. }
  432. expect(")");
  433. }
  434. emit(7, "\x8b\x84\x24...."); /* mov (n * 4)(%esp),%eax */
  435. save_int(code + codepos - 4, (stack_pos - s - 1) << 2);
  436. emit(2, "\xff\xd0"); /* call *%eax */
  437. be_pop(stack_pos - s);
  438. stack_pos = s;
  439. type = 3;
  440. }
  441. return type;
  442. }
  443. /*
  444. * additive-expr:
  445. * postfix-expr
  446. * additive-expr + postfix-expr
  447. * additive-expr - postfix-expr
  448. */
  449. int additive_expr()
  450. {
  451. int type = postfix_expr();
  452. while (1) {
  453. if (accept("+")) {
  454. binary1(type); /* pop %ebx ; add %ebx,%eax */
  455. type = binary2(postfix_expr(), 3, "\x5b\x01\xd8");
  456. }
  457. else if (accept("-")) {
  458. binary1(type); /* pop %ebx ; sub %eax,%ebx ; mov %ebx,%eax */
  459. type = binary2(postfix_expr(), 5, "\x5b\x29\xc3\x89\xd8");
  460. }
  461. else
  462. return type;
  463. }
  464. }
  465. /*
  466. * shift-expr:
  467. * additive-expr
  468. * shift-expr << additive-expr
  469. * shift-expr >> additive-expr
  470. */
  471. int shift_expr()
  472. {
  473. int type = additive_expr();
  474. while (1) {
  475. if (accept("<<")) {
  476. binary1(type); /* mov %eax,%ecx ; pop %eax ; shl %cl,%eax */
  477. type = binary2(additive_expr(), 5, "\x89\xc1\x58\xd3\xe0");
  478. }
  479. else if (accept(">>")) {
  480. binary1(type); /* mov %eax,%ecx ; pop %eax ; sar %cl,%eax */
  481. type = binary2(additive_expr(), 5, "\x89\xc1\x58\xd3\xf8");
  482. }
  483. else
  484. return type;
  485. }
  486. }
  487. /*
  488. * relational-expr:
  489. * shift-expr
  490. * relational-expr <= shift-expr
  491. */
  492. int relational_expr()
  493. {
  494. int type = shift_expr();
  495. while (accept("<=")) {
  496. binary1(type);
  497. /* pop %ebx ; cmp %eax,%ebx ; setle %al ; movzbl %al,%eax */
  498. type = binary2(shift_expr(),
  499. 9, "\x5b\x39\xc3\x0f\x9e\xc0\x0f\xb6\xc0");
  500. }
  501. return type;
  502. }
  503. /*
  504. * equality-expr:
  505. * relational-expr
  506. * equality-expr == relational-expr
  507. * equality-expr != relational-expr
  508. */
  509. int equality_expr()
  510. {
  511. int type = relational_expr();
  512. while (1) {
  513. if (accept("==")) {
  514. binary1(type);
  515. /* pop %ebx ; cmp %eax,%ebx ; sete %al ; movzbl %al,%eax */
  516. type = binary2(relational_expr(),
  517. 9, "\x5b\x39\xc3\x0f\x94\xc0\x0f\xb6\xc0");
  518. }
  519. else if (accept("!=")) {
  520. binary1(type);
  521. /* pop %ebx ; cmp %eax,%ebx ; setne %al ; movzbl %al,%eax */
  522. type = binary2(relational_expr(),
  523. 9, "\x5b\x39\xc3\x0f\x95\xc0\x0f\xb6\xc0");
  524. }
  525. else
  526. return type;
  527. }
  528. }
  529. /*
  530. * bitwise-and-expr:
  531. * equality-expr
  532. * bitwise-and-expr & equality-expr
  533. */
  534. int bitwise_and_expr()
  535. {
  536. int type = equality_expr();
  537. while (accept("&")) {
  538. binary1(type); /* pop %ebx ; and %ebx,%eax */
  539. type = binary2(equality_expr(), 3, "\x5b\x21\xd8");
  540. }
  541. return type;
  542. }
  543. /*
  544. * bitwise-or-expr:
  545. * bitwise-and-expr
  546. * bitwise-and-expr | bitwise-or-expr
  547. */
  548. int bitwise_or_expr()
  549. {
  550. int type = bitwise_and_expr();
  551. while (accept("|")) {
  552. binary1(type); /* pop %ebx ; or %ebx,%eax */
  553. type = binary2(bitwise_and_expr(), 3, "\x5b\x09\xd8");
  554. }
  555. return type;
  556. }
  557. /*
  558. * expression:
  559. * bitwise-or-expr
  560. * bitwise-or-expr = expression
  561. */
  562. int expression()
  563. {
  564. int type = bitwise_or_expr();
  565. if (accept("=")) {
  566. be_push();
  567. stack_pos = stack_pos + 1;
  568. promote(expression());
  569. if (type == 2)
  570. emit(3, "\x5b\x89\x03"); /* pop %ebx ; mov %eax,(%ebx) */
  571. else
  572. emit(3, "\x5b\x88\x03"); /* pop %ebx ; mov %al,(%ebx) */
  573. stack_pos = stack_pos - 1;
  574. type = 3;
  575. }
  576. return type;
  577. }
  578. /*
  579. * type-name:
  580. * char *
  581. * int
  582. */
  583. void type_name()
  584. {
  585. get_token();
  586. while (accept("*")) {
  587. }
  588. }
  589. /*
  590. * statement:
  591. * { statement-list-opt }
  592. * type-name identifier ;
  593. * type-name identifier = expression;
  594. * if ( expression ) statement
  595. * if ( expression ) statement else statement
  596. * while ( expression ) statement
  597. * return ;
  598. * expr ;
  599. */
  600. void statement()
  601. {
  602. int p1;
  603. int p2;
  604. if (accept("{")) {
  605. int n = table_pos;
  606. int s = stack_pos;
  607. while (accept("}") == 0)
  608. statement();
  609. table_pos = n;
  610. be_pop(stack_pos - s);
  611. stack_pos = s;
  612. }
  613. else if (peek("char") | peek("int")) {
  614. type_name();
  615. sym_declare(token, 'L', stack_pos);
  616. get_token();
  617. if (accept("="))
  618. promote(expression());
  619. expect(";");
  620. be_push();
  621. stack_pos = stack_pos + 1;
  622. }
  623. else if (accept("if")) {
  624. expect("(");
  625. promote(expression());
  626. emit(8, "\x85\xc0\x0f\x84...."); /* test %eax,%eax ; je ... */
  627. p1 = codepos;
  628. expect(")");
  629. statement();
  630. emit(5, "\xe9...."); /* jmp ... */
  631. p2 = codepos;
  632. save_int(code + p1 - 4, codepos - p1);
  633. if (accept("else"))
  634. statement();
  635. save_int(code + p2 - 4, codepos - p2);
  636. }
  637. else if (accept("while")) {
  638. expect("(");
  639. p1 = codepos;
  640. promote(expression());
  641. emit(8, "\x85\xc0\x0f\x84...."); /* test %eax,%eax ; je ... */
  642. p2 = codepos;
  643. expect(")");
  644. statement();
  645. emit(5, "\xe9...."); /* jmp ... */
  646. save_int(code + codepos - 4, p1 - codepos);
  647. save_int(code + p2 - 4, codepos - p2);
  648. }
  649. else if (accept("return")) {
  650. if (peek(";") == 0)
  651. promote(expression());
  652. expect(";");
  653. be_pop(stack_pos);
  654. emit(1, "\xc3"); /* ret */
  655. }
  656. else {
  657. expression();
  658. expect(";");
  659. }
  660. }
  661. /*
  662. * program:
  663. * declaration
  664. * declaration program
  665. *
  666. * declaration:
  667. * type-name identifier ;
  668. * type-name identifier ( parameter-list ) ;
  669. * type-name identifier ( parameter-list ) statement
  670. *
  671. * parameter-list:
  672. * parameter-declaration
  673. * parameter-list, parameter-declaration
  674. *
  675. * parameter-declaration:
  676. * type-name identifier-opt
  677. */
  678. void program()
  679. {
  680. int current_symbol;
  681. int n;
  682. while (token[0]) {
  683. type_name();
  684. current_symbol = sym_declare_global(token);
  685. get_token();
  686. if (accept(";")) {
  687. sym_define_global(current_symbol);
  688. emit(4, "\x00\x00\x00\x00");
  689. }
  690. else if (accept("(")) {
  691. n = table_pos;
  692. number_of_args = 0;
  693. while (accept(")") == 0) {
  694. number_of_args = number_of_args + 1;
  695. type_name();
  696. if (peek(")") == 0) {
  697. sym_declare(token, 'A', number_of_args);
  698. get_token();
  699. }
  700. accept(","); /* ignore trailing comma */
  701. }
  702. if (accept(";") == 0) {
  703. sym_define_global(current_symbol);
  704. statement();
  705. emit(1, "\xc3"); /* ret */
  706. }
  707. table_pos = n;
  708. }
  709. else
  710. error();
  711. }
  712. }
  713. int main1()
  714. {
  715. code_offset = 134512640; /* 0x08048000 */
  716. be_start();
  717. nextc = getchar();
  718. get_token();
  719. program();
  720. be_finish();
  721. return 0;
  722. }