minic.y 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951
  1. %{
  2. #include <ctype.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. enum {
  7. NString = 32,
  8. NGlo = 256,
  9. NVar = 512,
  10. NStr = 256,
  11. };
  12. enum { /* minic types */
  13. NIL,
  14. INT,
  15. LNG,
  16. PTR,
  17. FUN,
  18. };
  19. #define IDIR(x) (((x) << 3) + PTR)
  20. #define FUNC(x) (((x) << 3) + FUN)
  21. #define DREF(x) ((x) >> 3)
  22. #define KIND(x) ((x) & 7)
  23. #define SIZE(x) \
  24. (x == NIL ? (die("void has no size"), 0) : \
  25. x == INT ? 4 : 8)
  26. typedef struct Node Node;
  27. typedef struct Symb Symb;
  28. typedef struct Stmt Stmt;
  29. struct Symb {
  30. enum {
  31. Con,
  32. Tmp,
  33. Var,
  34. Glo,
  35. } t;
  36. union {
  37. int n;
  38. char v[NString];
  39. } u;
  40. unsigned long ctyp;
  41. };
  42. struct Node {
  43. char op;
  44. union {
  45. int n;
  46. char v[NString];
  47. Symb s;
  48. } u;
  49. Node *l, *r;
  50. };
  51. struct Stmt {
  52. enum {
  53. If,
  54. While,
  55. Seq,
  56. Expr,
  57. Break,
  58. Ret,
  59. } t;
  60. void *p1, *p2, *p3;
  61. };
  62. int yylex(void), yyerror(char *);
  63. Symb expr(Node *), lval(Node *);
  64. void branch(Node *, int, int);
  65. FILE *of;
  66. int line;
  67. int lbl, tmp, nglo;
  68. char *ini[NGlo];
  69. struct {
  70. char v[NString];
  71. unsigned ctyp;
  72. int glo;
  73. } varh[NVar];
  74. void
  75. die(char *s)
  76. {
  77. fprintf(stderr, "error:%d: %s\n", line, s);
  78. exit(1);
  79. }
  80. void *
  81. alloc(size_t s)
  82. {
  83. void *p;
  84. p = malloc(s);
  85. if (!p)
  86. die("out of memory");
  87. return p;
  88. }
  89. unsigned
  90. hash(char *s)
  91. {
  92. unsigned h;
  93. h = 42;
  94. while (*s)
  95. h += 11 * h + *s++;
  96. return h % NVar;
  97. }
  98. void
  99. varclr()
  100. {
  101. unsigned h;
  102. for (h=0; h<NVar; h++)
  103. if (!varh[h].glo)
  104. varh[h].v[0] = 0;
  105. }
  106. void
  107. varadd(char *v, int glo, unsigned ctyp)
  108. {
  109. unsigned h0, h;
  110. h0 = hash(v);
  111. h = h0;
  112. do {
  113. if (varh[h].v[0] == 0) {
  114. strcpy(varh[h].v, v);
  115. varh[h].glo = glo;
  116. varh[h].ctyp = ctyp;
  117. return;
  118. }
  119. if (strcmp(varh[h].v, v) == 0)
  120. die("double definition");
  121. h = (h+1) % NVar;
  122. } while(h != h0);
  123. die("too many variables");
  124. }
  125. Symb *
  126. varget(char *v)
  127. {
  128. static Symb s;
  129. unsigned h0, h;
  130. h0 = hash(v);
  131. h = h0;
  132. do {
  133. if (strcmp(varh[h].v, v) == 0) {
  134. if (!varh[h].glo) {
  135. s.t = Var;
  136. strcpy(s.u.v, v);
  137. } else {
  138. s.t = Glo;
  139. s.u.n = varh[h].glo;
  140. }
  141. s.ctyp = varh[h].ctyp;
  142. return &s;
  143. }
  144. h = (h+1) % NVar;
  145. } while (h != h0 && varh[h].v[0] != 0);
  146. return 0;
  147. }
  148. char
  149. irtyp(unsigned ctyp)
  150. {
  151. return SIZE(ctyp) == 8 ? 'l' : 'w';
  152. }
  153. void
  154. psymb(Symb s)
  155. {
  156. switch (s.t) {
  157. case Tmp:
  158. fprintf(of, "%%t%d", s.u.n);
  159. break;
  160. case Var:
  161. fprintf(of, "%%%s", s.u.v);
  162. break;
  163. case Glo:
  164. fprintf(of, "$glo%d", s.u.n);
  165. break;
  166. case Con:
  167. fprintf(of, "%d", s.u.n);
  168. break;
  169. }
  170. }
  171. void
  172. sext(Symb *s)
  173. {
  174. fprintf(of, "\t%%t%d =l extsw ", tmp);
  175. psymb(*s);
  176. fprintf(of, "\n");
  177. s->t = Tmp;
  178. s->ctyp = LNG;
  179. s->u.n = tmp++;
  180. }
  181. unsigned
  182. prom(int op, Symb *l, Symb *r)
  183. {
  184. Symb *t;
  185. int sz;
  186. if (l->ctyp == r->ctyp && KIND(l->ctyp) != PTR)
  187. return l->ctyp;
  188. if (l->ctyp == LNG && r->ctyp == INT) {
  189. sext(r);
  190. return LNG;
  191. }
  192. if (l->ctyp == INT && r->ctyp == LNG) {
  193. sext(l);
  194. return LNG;
  195. }
  196. if (op == '+') {
  197. if (KIND(r->ctyp) == PTR) {
  198. t = l;
  199. l = r;
  200. r = t;
  201. }
  202. if (KIND(r->ctyp) == PTR)
  203. die("pointers added");
  204. goto Scale;
  205. }
  206. if (op == '-') {
  207. if (KIND(l->ctyp) != PTR)
  208. die("pointer substracted from integer");
  209. if (KIND(r->ctyp) != PTR)
  210. goto Scale;
  211. if (l->ctyp != r->ctyp)
  212. die("non-homogeneous pointers in substraction");
  213. return LNG;
  214. }
  215. Scale:
  216. sz = SIZE(DREF(l->ctyp));
  217. if (r->t == Con)
  218. r->u.n *= sz;
  219. else {
  220. if (irtyp(r->ctyp) != 'l')
  221. sext(r);
  222. fprintf(of, "\t%%t%d =l mul %d, ", tmp, sz);
  223. psymb(*r);
  224. fprintf(of, "\n");
  225. r->u.n = tmp++;
  226. }
  227. return l->ctyp;
  228. }
  229. void
  230. load(Symb d, Symb s)
  231. {
  232. char t;
  233. fprintf(of, "\t");
  234. psymb(d);
  235. t = irtyp(d.ctyp);
  236. fprintf(of, " =%c load%c ", t, t);
  237. psymb(s);
  238. fprintf(of, "\n");
  239. }
  240. void
  241. call(Node *n, Symb *sr)
  242. {
  243. Node *a;
  244. char *f;
  245. unsigned ft;
  246. f = n->l->u.v;
  247. if (varget(f)) {
  248. ft = varget(f)->ctyp;
  249. if (KIND(ft) != FUN)
  250. die("invalid call");
  251. } else
  252. ft = FUNC(INT);
  253. sr->ctyp = DREF(ft);
  254. for (a=n->r; a; a=a->r)
  255. a->u.s = expr(a->l);
  256. fprintf(of, "\t");
  257. psymb(*sr);
  258. fprintf(of, " =%c call $%s(", irtyp(sr->ctyp), f);
  259. for (a=n->r; a; a=a->r) {
  260. fprintf(of, "%c ", irtyp(a->u.s.ctyp));
  261. psymb(a->u.s);
  262. fprintf(of, ", ");
  263. }
  264. fprintf(of, "...)\n");
  265. }
  266. Symb
  267. expr(Node *n)
  268. {
  269. static char *otoa[] = {
  270. ['+'] = "add",
  271. ['-'] = "sub",
  272. ['*'] = "mul",
  273. ['/'] = "div",
  274. ['%'] = "rem",
  275. ['&'] = "and",
  276. ['<'] = "cslt", /* meeeeh, wrong for pointers! */
  277. ['l'] = "csle",
  278. ['e'] = "ceq",
  279. ['n'] = "cne",
  280. };
  281. Symb sr, s0, s1, sl;
  282. int o, l;
  283. char ty[2];
  284. sr.t = Tmp;
  285. sr.u.n = tmp++;
  286. switch (n->op) {
  287. case 0:
  288. abort();
  289. case 'o':
  290. case 'a':
  291. l = lbl;
  292. lbl += 3;
  293. branch(n, l, l+1);
  294. fprintf(of, "@l%d\n", l);
  295. fprintf(of, "\tjmp @l%d\n", l+2);
  296. fprintf(of, "@l%d\n", l+1);
  297. fprintf(of, "\tjmp @l%d\n", l+2);
  298. fprintf(of, "@l%d\n", l+2);
  299. fprintf(of, "\t");
  300. sr.ctyp = INT;
  301. psymb(sr);
  302. fprintf(of, " =w phi @l%d 1, @l%d 0\n", l, l+1);
  303. break;
  304. case 'V':
  305. s0 = lval(n);
  306. sr.ctyp = s0.ctyp;
  307. load(sr, s0);
  308. break;
  309. case 'N':
  310. sr.t = Con;
  311. sr.u.n = n->u.n;
  312. sr.ctyp = INT;
  313. break;
  314. case 'S':
  315. sr.t = Glo;
  316. sr.u.n = n->u.n;
  317. sr.ctyp = IDIR(INT);
  318. break;
  319. case 'C':
  320. call(n, &sr);
  321. break;
  322. case '@':
  323. s0 = expr(n->l);
  324. if (KIND(s0.ctyp) != PTR)
  325. die("dereference of a non-pointer");
  326. sr.ctyp = DREF(s0.ctyp);
  327. load(sr, s0);
  328. break;
  329. case 'A':
  330. sr = lval(n->l);
  331. sr.ctyp = IDIR(sr.ctyp);
  332. break;
  333. case '=':
  334. s0 = expr(n->r);
  335. s1 = lval(n->l);
  336. sr = s0;
  337. if (s1.ctyp == LNG && s0.ctyp == INT)
  338. sext(&s0);
  339. if (s0.ctyp != IDIR(NIL) || KIND(s1.ctyp) != PTR)
  340. if (s1.ctyp != IDIR(NIL) || KIND(s0.ctyp) != PTR)
  341. if (s1.ctyp != s0.ctyp)
  342. die("invalid assignment");
  343. fprintf(of, "\tstore%c ", irtyp(s1.ctyp));
  344. goto Args;
  345. case 'P':
  346. case 'M':
  347. o = n->op == 'P' ? '+' : '-';
  348. sl = lval(n->l);
  349. s0.t = Tmp;
  350. s0.u.n = tmp++;
  351. s0.ctyp = sl.ctyp;
  352. load(s0, sl);
  353. s1.t = Con;
  354. s1.u.n = 1;
  355. s1.ctyp = INT;
  356. goto Binop;
  357. default:
  358. s0 = expr(n->l);
  359. s1 = expr(n->r);
  360. o = n->op;
  361. Binop:
  362. sr.ctyp = prom(o, &s0, &s1);
  363. if (strchr("ne<l", n->op)) {
  364. sprintf(ty, "%c", irtyp(sr.ctyp));
  365. sr.ctyp = INT;
  366. } else
  367. strcpy(ty, "");
  368. fprintf(of, "\t");
  369. psymb(sr);
  370. fprintf(of, " =%c", irtyp(sr.ctyp));
  371. fprintf(of, " %s%s ", otoa[o], ty);
  372. Args:
  373. psymb(s0);
  374. fprintf(of, ", ");
  375. psymb(s1);
  376. fprintf(of, "\n");
  377. break;
  378. }
  379. if (n->op == '-'
  380. && KIND(s0.ctyp) == PTR
  381. && KIND(s1.ctyp) == PTR) {
  382. fprintf(of, "\t%%t%d =l div ", tmp);
  383. psymb(sr);
  384. fprintf(of, ", %d\n", SIZE(DREF(s0.ctyp)));
  385. sr.u.n = tmp++;
  386. }
  387. if (n->op == 'P' || n->op == 'M') {
  388. fprintf(of, "\tstore%c ", irtyp(sl.ctyp));
  389. psymb(sr);
  390. fprintf(of, ", ");
  391. psymb(sl);
  392. fprintf(of, "\n");
  393. sr = s0;
  394. }
  395. return sr;
  396. }
  397. Symb
  398. lval(Node *n)
  399. {
  400. Symb sr;
  401. switch (n->op) {
  402. default:
  403. die("invalid lvalue");
  404. case 'V':
  405. if (!varget(n->u.v))
  406. die("undefined variable");
  407. sr = *varget(n->u.v);
  408. break;
  409. case '@':
  410. sr = expr(n->l);
  411. if (KIND(sr.ctyp) != PTR)
  412. die("dereference of a non-pointer");
  413. sr.ctyp = DREF(sr.ctyp);
  414. break;
  415. }
  416. return sr;
  417. }
  418. void
  419. branch(Node *n, int lt, int lf)
  420. {
  421. Symb s;
  422. int l;
  423. switch (n->op) {
  424. default:
  425. s = expr(n); /* TODO: insert comparison to 0 with proper type */
  426. fprintf(of, "\tjnz ");
  427. psymb(s);
  428. fprintf(of, ", @l%d, @l%d\n", lt, lf);
  429. break;
  430. case 'o':
  431. l = lbl;
  432. lbl += 1;
  433. branch(n->l, lt, l);
  434. fprintf(of, "@l%d\n", l);
  435. branch(n->r, lt, lf);
  436. break;
  437. case 'a':
  438. l = lbl;
  439. lbl += 1;
  440. branch(n->l, l, lf);
  441. fprintf(of, "@l%d\n", l);
  442. branch(n->r, lt, lf);
  443. break;
  444. }
  445. }
  446. int
  447. stmt(Stmt *s, int b)
  448. {
  449. int l, r;
  450. Symb x;
  451. if (!s)
  452. return 0;
  453. switch (s->t) {
  454. case Ret:
  455. x = expr(s->p1);
  456. fprintf(of, "\tret ");
  457. psymb(x);
  458. fprintf(of, "\n");
  459. return 1;
  460. case Break:
  461. if (b < 0)
  462. die("break not in loop");
  463. fprintf(of, "\tjmp @l%d\n", b);
  464. return 1;
  465. case Expr:
  466. expr(s->p1);
  467. return 0;
  468. case Seq:
  469. return stmt(s->p1, b) || stmt(s->p2, b);
  470. case If:
  471. l = lbl;
  472. lbl += 3;
  473. branch(s->p1, l, l+1);
  474. fprintf(of, "@l%d\n", l);
  475. if (!(r=stmt(s->p2, b)))
  476. if (s->p3)
  477. fprintf(of, "\tjmp @l%d\n", l+2);
  478. fprintf(of, "@l%d\n", l+1);
  479. if (s->p3)
  480. if (!(r &= stmt(s->p3, b)))
  481. fprintf(of, "@l%d\n", l+2);
  482. return s->p3 && r;
  483. case While:
  484. l = lbl;
  485. lbl += 3;
  486. fprintf(of, "@l%d\n", l);
  487. branch(s->p1, l+1, l+2);
  488. fprintf(of, "@l%d\n", l+1);
  489. if (!stmt(s->p2, l+2))
  490. fprintf(of, "\tjmp @l%d\n", l);
  491. fprintf(of, "@l%d\n", l+2);
  492. return 0;
  493. }
  494. }
  495. Node *
  496. mknode(char op, Node *l, Node *r)
  497. {
  498. Node *n;
  499. n = alloc(sizeof *n);
  500. n->op = op;
  501. n->l = l;
  502. n->r = r;
  503. return n;
  504. }
  505. Node *
  506. mkidx(Node *a, Node *i)
  507. {
  508. Node *n;
  509. n = mknode('+', a, i);
  510. n = mknode('@', n, 0);
  511. return n;
  512. }
  513. Node *
  514. mkneg(Node *n)
  515. {
  516. static Node *z;
  517. if (!z) {
  518. z = mknode('N', 0, 0);
  519. z->u.n = 0;
  520. }
  521. return mknode('-', z, n);
  522. }
  523. Stmt *
  524. mkstmt(int t, void *p1, void *p2, void *p3)
  525. {
  526. Stmt *s;
  527. s = alloc(sizeof *s);
  528. s->t = t;
  529. s->p1 = p1;
  530. s->p2 = p2;
  531. s->p3 = p3;
  532. return s;
  533. }
  534. Node *
  535. param(char *v, unsigned ctyp, Node *pl)
  536. {
  537. Node *n;
  538. if (ctyp == NIL)
  539. die("invalid void declaration");
  540. n = mknode(0, 0, pl);
  541. varadd(v, 0, ctyp);
  542. strcpy(n->u.v, v);
  543. return n;
  544. }
  545. Stmt *
  546. mkfor(Node *ini, Node *tst, Node *inc, Stmt *s)
  547. {
  548. Stmt *s1, *s2;
  549. if (ini)
  550. s1 = mkstmt(Expr, ini, 0, 0);
  551. else
  552. s1 = 0;
  553. if (inc) {
  554. s2 = mkstmt(Expr, inc, 0, 0);
  555. s2 = mkstmt(Seq, s, s2, 0);
  556. } else
  557. s2 = s;
  558. if (!tst) {
  559. tst = mknode('N', 0, 0);
  560. tst->u.n = 1;
  561. }
  562. s2 = mkstmt(While, tst, s2, 0);
  563. if (s1)
  564. return mkstmt(Seq, s1, s2, 0);
  565. else
  566. return s2;
  567. }
  568. %}
  569. %union {
  570. Node *n;
  571. Stmt *s;
  572. unsigned u;
  573. }
  574. %token <n> NUM
  575. %token <n> STR
  576. %token <n> IDENT
  577. %token PP MM LE GE SIZEOF
  578. %token TVOID TINT TLNG
  579. %token IF ELSE WHILE FOR BREAK RETURN
  580. %right '='
  581. %left OR
  582. %left AND
  583. %left '&'
  584. %left EQ NE
  585. %left '<' '>' LE GE
  586. %left '+' '-'
  587. %left '*' '/' '%'
  588. %type <u> type
  589. %type <s> stmt stmts
  590. %type <n> expr exp0 pref post arg0 arg1 par0 par1
  591. %%
  592. prog: func prog | fdcl prog | idcl prog | ;
  593. fdcl: type IDENT '(' ')' ';'
  594. {
  595. varadd($2->u.v, 1, FUNC($1));
  596. };
  597. idcl: type IDENT ';'
  598. {
  599. if ($1 == NIL)
  600. die("invalid void declaration");
  601. if (nglo == NGlo)
  602. die("too many string literals");
  603. ini[nglo] = alloc(sizeof "{ x 0 }");
  604. sprintf(ini[nglo], "{ %c 0 }", irtyp($1));
  605. varadd($2->u.v, nglo++, $1);
  606. };
  607. init:
  608. {
  609. varclr();
  610. tmp = 0;
  611. };
  612. func: init prot '{' dcls stmts '}'
  613. {
  614. if (!stmt($5, -1))
  615. fprintf(of, "\tret 0\n");
  616. fprintf(of, "}\n\n");
  617. };
  618. prot: IDENT '(' par0 ')'
  619. {
  620. Symb *s;
  621. Node *n;
  622. int t, m;
  623. varadd($1->u.v, 1, FUNC(INT));
  624. fprintf(of, "export function w $%s(", $1->u.v);
  625. n = $3;
  626. if (n)
  627. for (;;) {
  628. s = varget(n->u.v);
  629. fprintf(of, "%c ", irtyp(s->ctyp));
  630. fprintf(of, "%%t%d", tmp++);
  631. n = n->r;
  632. if (n)
  633. fprintf(of, ", ");
  634. else
  635. break;
  636. }
  637. fprintf(of, ") {\n");
  638. fprintf(of, "@l%d\n", lbl++);
  639. for (t=0, n=$3; n; t++, n=n->r) {
  640. s = varget(n->u.v);
  641. m = SIZE(s->ctyp);
  642. fprintf(of, "\t%%%s =l alloc%d %d\n", n->u.v, m, m);
  643. fprintf(of, "\tstore%c %%t%d", irtyp(s->ctyp), t);
  644. fprintf(of, ", %%%s\n", n->u.v);
  645. }
  646. };
  647. par0: par1
  648. | { $$ = 0; }
  649. ;
  650. par1: type IDENT ',' par1 { $$ = param($2->u.v, $1, $4); }
  651. | type IDENT { $$ = param($2->u.v, $1, 0); }
  652. ;
  653. dcls: | dcls type IDENT ';'
  654. {
  655. int s;
  656. char *v;
  657. if ($2 == NIL)
  658. die("invalid void declaration");
  659. v = $3->u.v;
  660. s = SIZE($2);
  661. varadd(v, 0, $2);
  662. fprintf(of, "\t%%%s =l alloc%d %d\n", v, s, s);
  663. };
  664. type: type '*' { $$ = IDIR($1); }
  665. | TINT { $$ = INT; }
  666. | TLNG { $$ = LNG; }
  667. | TVOID { $$ = NIL; }
  668. ;
  669. stmt: ';' { $$ = 0; }
  670. | '{' stmts '}' { $$ = $2; }
  671. | BREAK ';' { $$ = mkstmt(Break, 0, 0, 0); }
  672. | RETURN expr ';' { $$ = mkstmt(Ret, $2, 0, 0); }
  673. | expr ';' { $$ = mkstmt(Expr, $1, 0, 0); }
  674. | WHILE '(' expr ')' stmt { $$ = mkstmt(While, $3, $5, 0); }
  675. | IF '(' expr ')' stmt ELSE stmt { $$ = mkstmt(If, $3, $5, $7); }
  676. | IF '(' expr ')' stmt { $$ = mkstmt(If, $3, $5, 0); }
  677. | FOR '(' exp0 ';' exp0 ';' exp0 ')' stmt
  678. { $$ = mkfor($3, $5, $7, $9); }
  679. ;
  680. stmts: stmts stmt { $$ = mkstmt(Seq, $1, $2, 0); }
  681. | { $$ = 0; }
  682. ;
  683. expr: pref
  684. | expr '=' expr { $$ = mknode('=', $1, $3); }
  685. | expr '+' expr { $$ = mknode('+', $1, $3); }
  686. | expr '-' expr { $$ = mknode('-', $1, $3); }
  687. | expr '*' expr { $$ = mknode('*', $1, $3); }
  688. | expr '/' expr { $$ = mknode('/', $1, $3); }
  689. | expr '%' expr { $$ = mknode('%', $1, $3); }
  690. | expr '<' expr { $$ = mknode('<', $1, $3); }
  691. | expr '>' expr { $$ = mknode('<', $3, $1); }
  692. | expr LE expr { $$ = mknode('l', $1, $3); }
  693. | expr GE expr { $$ = mknode('l', $3, $1); }
  694. | expr EQ expr { $$ = mknode('e', $1, $3); }
  695. | expr NE expr { $$ = mknode('n', $1, $3); }
  696. | expr '&' expr { $$ = mknode('&', $1, $3); }
  697. | expr AND expr { $$ = mknode('a', $1, $3); }
  698. | expr OR expr { $$ = mknode('o', $1, $3); }
  699. ;
  700. exp0: expr
  701. | { $$ = 0; }
  702. ;
  703. pref: post
  704. | '-' pref { $$ = mkneg($2); }
  705. | '*' pref { $$ = mknode('@', $2, 0); }
  706. | '&' pref { $$ = mknode('A', $2, 0); }
  707. ;
  708. post: NUM
  709. | STR
  710. | IDENT
  711. | SIZEOF '(' type ')' { $$ = mknode('N', 0, 0); $$->u.n = SIZE($3); }
  712. | '(' expr ')' { $$ = $2; }
  713. | IDENT '(' arg0 ')' { $$ = mknode('C', $1, $3); }
  714. | post '[' expr ']' { $$ = mkidx($1, $3); }
  715. | post PP { $$ = mknode('P', $1, 0); }
  716. | post MM { $$ = mknode('M', $1, 0); }
  717. ;
  718. arg0: arg1
  719. | { $$ = 0; }
  720. ;
  721. arg1: expr { $$ = mknode(0, $1, 0); }
  722. | expr ',' arg1 { $$ = mknode(0, $1, $3); }
  723. ;
  724. %%
  725. int
  726. yylex()
  727. {
  728. struct {
  729. char *s;
  730. int t;
  731. } kwds[] = {
  732. { "void", TVOID },
  733. { "int", TINT },
  734. { "long", TLNG },
  735. { "if", IF },
  736. { "else", ELSE },
  737. { "for", FOR },
  738. { "while", WHILE },
  739. { "return", RETURN },
  740. { "break", BREAK },
  741. { "sizeof", SIZEOF },
  742. { 0, 0 }
  743. };
  744. int i, c, c1, n;
  745. char v[NString], *p;
  746. do {
  747. c = getchar();
  748. if (c == '#')
  749. while ((c = getchar()) != '\n')
  750. ;
  751. if (c == '\n')
  752. line++;
  753. } while (isspace(c));
  754. if (c == EOF)
  755. return 0;
  756. if (isdigit(c)) {
  757. n = 0;
  758. do {
  759. n *= 10;
  760. n += c-'0';
  761. c = getchar();
  762. } while (isdigit(c));
  763. ungetc(c, stdin);
  764. yylval.n = mknode('N', 0, 0);
  765. yylval.n->u.n = n;
  766. return NUM;
  767. }
  768. if (isalpha(c)) {
  769. p = v;
  770. do {
  771. if (p == &v[NString-1])
  772. die("ident too long");
  773. *p++ = c;
  774. c = getchar();
  775. } while (isalpha(c) || c == '_');
  776. *p = 0;
  777. ungetc(c, stdin);
  778. for (i=0; kwds[i].s; i++)
  779. if (strcmp(v, kwds[i].s) == 0)
  780. return kwds[i].t;
  781. yylval.n = mknode('V', 0, 0);
  782. strcpy(yylval.n->u.v, v);
  783. return IDENT;
  784. }
  785. if (c == '"') {
  786. i = 0;
  787. n = 32;
  788. p = alloc(n);
  789. strcpy(p, "{ b \"");
  790. for (i=5;; i++) {
  791. c = getchar();
  792. if (c == EOF)
  793. die("unclosed string literal");
  794. if (i+8 >= n) {
  795. p = memcpy(alloc(n*2), p, n);
  796. n *= 2;
  797. }
  798. p[i] = c;
  799. if (c == '"' && p[i-1]!='\\')
  800. break;
  801. }
  802. strcpy(&p[i], "\", b 0 }");
  803. if (nglo == NGlo)
  804. die("too many globals");
  805. ini[nglo] = p;
  806. yylval.n = mknode('S', 0, 0);
  807. yylval.n->u.n = nglo++;
  808. return STR;
  809. }
  810. c1 = getchar();
  811. #define DI(a, b) a + b*256
  812. switch (DI(c,c1)) {
  813. case DI('!','='): return NE;
  814. case DI('=','='): return EQ;
  815. case DI('<','='): return LE;
  816. case DI('>','='): return GE;
  817. case DI('+','+'): return PP;
  818. case DI('-','-'): return MM;
  819. case DI('&','&'): return AND;
  820. case DI('|','|'): return OR;
  821. }
  822. #undef DI
  823. ungetc(c1, stdin);
  824. return c;
  825. }
  826. int
  827. yyerror(char *err)
  828. {
  829. die("parse error");
  830. return 0;
  831. }
  832. int
  833. main()
  834. {
  835. int i;
  836. of = stdout;
  837. nglo = 1;
  838. if (yyparse() != 0)
  839. die("parse error");
  840. for (i=1; i<nglo; i++)
  841. fprintf(of, "data $glo%d = %s\n", i, ini[i]);
  842. return 0;
  843. }