| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951 |
- %{
- #include <ctype.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- enum {
- NString = 32,
- NGlo = 256,
- NVar = 512,
- NStr = 256,
- };
- enum { /* minic types */
- NIL,
- INT,
- LNG,
- PTR,
- FUN,
- };
- #define IDIR(x) (((x) << 3) + PTR)
- #define FUNC(x) (((x) << 3) + FUN)
- #define DREF(x) ((x) >> 3)
- #define KIND(x) ((x) & 7)
- #define SIZE(x) \
- (x == NIL ? (die("void has no size"), 0) : \
- x == INT ? 4 : 8)
- typedef struct Node Node;
- typedef struct Symb Symb;
- typedef struct Stmt Stmt;
- struct Symb {
- enum {
- Con,
- Tmp,
- Var,
- Glo,
- } t;
- union {
- int n;
- char v[NString];
- } u;
- unsigned long ctyp;
- };
- struct Node {
- char op;
- union {
- int n;
- char v[NString];
- Symb s;
- } u;
- Node *l, *r;
- };
- struct Stmt {
- enum {
- If,
- While,
- Seq,
- Expr,
- Break,
- Ret,
- } t;
- void *p1, *p2, *p3;
- };
- int yylex(void), yyerror(char *);
- Symb expr(Node *), lval(Node *);
- void branch(Node *, int, int);
- FILE *of;
- int line;
- int lbl, tmp, nglo;
- char *ini[NGlo];
- struct {
- char v[NString];
- unsigned ctyp;
- int glo;
- } varh[NVar];
- void
- die(char *s)
- {
- fprintf(stderr, "error:%d: %s\n", line, s);
- exit(1);
- }
- void *
- alloc(size_t s)
- {
- void *p;
- p = malloc(s);
- if (!p)
- die("out of memory");
- return p;
- }
- unsigned
- hash(char *s)
- {
- unsigned h;
- h = 42;
- while (*s)
- h += 11 * h + *s++;
- return h % NVar;
- }
- void
- varclr()
- {
- unsigned h;
- for (h=0; h<NVar; h++)
- if (!varh[h].glo)
- varh[h].v[0] = 0;
- }
- void
- varadd(char *v, int glo, unsigned ctyp)
- {
- unsigned h0, h;
- h0 = hash(v);
- h = h0;
- do {
- if (varh[h].v[0] == 0) {
- strcpy(varh[h].v, v);
- varh[h].glo = glo;
- varh[h].ctyp = ctyp;
- return;
- }
- if (strcmp(varh[h].v, v) == 0)
- die("double definition");
- h = (h+1) % NVar;
- } while(h != h0);
- die("too many variables");
- }
- Symb *
- varget(char *v)
- {
- static Symb s;
- unsigned h0, h;
- h0 = hash(v);
- h = h0;
- do {
- if (strcmp(varh[h].v, v) == 0) {
- if (!varh[h].glo) {
- s.t = Var;
- strcpy(s.u.v, v);
- } else {
- s.t = Glo;
- s.u.n = varh[h].glo;
- }
- s.ctyp = varh[h].ctyp;
- return &s;
- }
- h = (h+1) % NVar;
- } while (h != h0 && varh[h].v[0] != 0);
- return 0;
- }
- char
- irtyp(unsigned ctyp)
- {
- return SIZE(ctyp) == 8 ? 'l' : 'w';
- }
- void
- psymb(Symb s)
- {
- switch (s.t) {
- case Tmp:
- fprintf(of, "%%t%d", s.u.n);
- break;
- case Var:
- fprintf(of, "%%%s", s.u.v);
- break;
- case Glo:
- fprintf(of, "$glo%d", s.u.n);
- break;
- case Con:
- fprintf(of, "%d", s.u.n);
- break;
- }
- }
- void
- sext(Symb *s)
- {
- fprintf(of, "\t%%t%d =l extsw ", tmp);
- psymb(*s);
- fprintf(of, "\n");
- s->t = Tmp;
- s->ctyp = LNG;
- s->u.n = tmp++;
- }
- unsigned
- prom(int op, Symb *l, Symb *r)
- {
- Symb *t;
- int sz;
- if (l->ctyp == r->ctyp && KIND(l->ctyp) != PTR)
- return l->ctyp;
- if (l->ctyp == LNG && r->ctyp == INT) {
- sext(r);
- return LNG;
- }
- if (l->ctyp == INT && r->ctyp == LNG) {
- sext(l);
- return LNG;
- }
- if (op == '+') {
- if (KIND(r->ctyp) == PTR) {
- t = l;
- l = r;
- r = t;
- }
- if (KIND(r->ctyp) == PTR)
- die("pointers added");
- goto Scale;
- }
- if (op == '-') {
- if (KIND(l->ctyp) != PTR)
- die("pointer substracted from integer");
- if (KIND(r->ctyp) != PTR)
- goto Scale;
- if (l->ctyp != r->ctyp)
- die("non-homogeneous pointers in substraction");
- return LNG;
- }
- Scale:
- sz = SIZE(DREF(l->ctyp));
- if (r->t == Con)
- r->u.n *= sz;
- else {
- if (irtyp(r->ctyp) != 'l')
- sext(r);
- fprintf(of, "\t%%t%d =l mul %d, ", tmp, sz);
- psymb(*r);
- fprintf(of, "\n");
- r->u.n = tmp++;
- }
- return l->ctyp;
- }
- void
- load(Symb d, Symb s)
- {
- char t;
- fprintf(of, "\t");
- psymb(d);
- t = irtyp(d.ctyp);
- fprintf(of, " =%c load%c ", t, t);
- psymb(s);
- fprintf(of, "\n");
- }
- void
- call(Node *n, Symb *sr)
- {
- Node *a;
- char *f;
- unsigned ft;
- f = n->l->u.v;
- if (varget(f)) {
- ft = varget(f)->ctyp;
- if (KIND(ft) != FUN)
- die("invalid call");
- } else
- ft = FUNC(INT);
- sr->ctyp = DREF(ft);
- for (a=n->r; a; a=a->r)
- a->u.s = expr(a->l);
- fprintf(of, "\t");
- psymb(*sr);
- fprintf(of, " =%c call $%s(", irtyp(sr->ctyp), f);
- for (a=n->r; a; a=a->r) {
- fprintf(of, "%c ", irtyp(a->u.s.ctyp));
- psymb(a->u.s);
- fprintf(of, ", ");
- }
- fprintf(of, "...)\n");
- }
- Symb
- expr(Node *n)
- {
- static char *otoa[] = {
- ['+'] = "add",
- ['-'] = "sub",
- ['*'] = "mul",
- ['/'] = "div",
- ['%'] = "rem",
- ['&'] = "and",
- ['<'] = "cslt", /* meeeeh, wrong for pointers! */
- ['l'] = "csle",
- ['e'] = "ceq",
- ['n'] = "cne",
- };
- Symb sr, s0, s1, sl;
- int o, l;
- char ty[2];
- sr.t = Tmp;
- sr.u.n = tmp++;
- switch (n->op) {
- case 0:
- abort();
- case 'o':
- case 'a':
- l = lbl;
- lbl += 3;
- branch(n, l, l+1);
- fprintf(of, "@l%d\n", l);
- fprintf(of, "\tjmp @l%d\n", l+2);
- fprintf(of, "@l%d\n", l+1);
- fprintf(of, "\tjmp @l%d\n", l+2);
- fprintf(of, "@l%d\n", l+2);
- fprintf(of, "\t");
- sr.ctyp = INT;
- psymb(sr);
- fprintf(of, " =w phi @l%d 1, @l%d 0\n", l, l+1);
- break;
- case 'V':
- s0 = lval(n);
- sr.ctyp = s0.ctyp;
- load(sr, s0);
- break;
- case 'N':
- sr.t = Con;
- sr.u.n = n->u.n;
- sr.ctyp = INT;
- break;
- case 'S':
- sr.t = Glo;
- sr.u.n = n->u.n;
- sr.ctyp = IDIR(INT);
- break;
- case 'C':
- call(n, &sr);
- break;
- case '@':
- s0 = expr(n->l);
- if (KIND(s0.ctyp) != PTR)
- die("dereference of a non-pointer");
- sr.ctyp = DREF(s0.ctyp);
- load(sr, s0);
- break;
- case 'A':
- sr = lval(n->l);
- sr.ctyp = IDIR(sr.ctyp);
- break;
- case '=':
- s0 = expr(n->r);
- s1 = lval(n->l);
- sr = s0;
- if (s1.ctyp == LNG && s0.ctyp == INT)
- sext(&s0);
- if (s0.ctyp != IDIR(NIL) || KIND(s1.ctyp) != PTR)
- if (s1.ctyp != IDIR(NIL) || KIND(s0.ctyp) != PTR)
- if (s1.ctyp != s0.ctyp)
- die("invalid assignment");
- fprintf(of, "\tstore%c ", irtyp(s1.ctyp));
- goto Args;
- case 'P':
- case 'M':
- o = n->op == 'P' ? '+' : '-';
- sl = lval(n->l);
- s0.t = Tmp;
- s0.u.n = tmp++;
- s0.ctyp = sl.ctyp;
- load(s0, sl);
- s1.t = Con;
- s1.u.n = 1;
- s1.ctyp = INT;
- goto Binop;
- default:
- s0 = expr(n->l);
- s1 = expr(n->r);
- o = n->op;
- Binop:
- sr.ctyp = prom(o, &s0, &s1);
- if (strchr("ne<l", n->op)) {
- sprintf(ty, "%c", irtyp(sr.ctyp));
- sr.ctyp = INT;
- } else
- strcpy(ty, "");
- fprintf(of, "\t");
- psymb(sr);
- fprintf(of, " =%c", irtyp(sr.ctyp));
- fprintf(of, " %s%s ", otoa[o], ty);
- Args:
- psymb(s0);
- fprintf(of, ", ");
- psymb(s1);
- fprintf(of, "\n");
- break;
- }
- if (n->op == '-'
- && KIND(s0.ctyp) == PTR
- && KIND(s1.ctyp) == PTR) {
- fprintf(of, "\t%%t%d =l div ", tmp);
- psymb(sr);
- fprintf(of, ", %d\n", SIZE(DREF(s0.ctyp)));
- sr.u.n = tmp++;
- }
- if (n->op == 'P' || n->op == 'M') {
- fprintf(of, "\tstore%c ", irtyp(sl.ctyp));
- psymb(sr);
- fprintf(of, ", ");
- psymb(sl);
- fprintf(of, "\n");
- sr = s0;
- }
- return sr;
- }
- Symb
- lval(Node *n)
- {
- Symb sr;
- switch (n->op) {
- default:
- die("invalid lvalue");
- case 'V':
- if (!varget(n->u.v))
- die("undefined variable");
- sr = *varget(n->u.v);
- break;
- case '@':
- sr = expr(n->l);
- if (KIND(sr.ctyp) != PTR)
- die("dereference of a non-pointer");
- sr.ctyp = DREF(sr.ctyp);
- break;
- }
- return sr;
- }
- void
- branch(Node *n, int lt, int lf)
- {
- Symb s;
- int l;
- switch (n->op) {
- default:
- s = expr(n); /* TODO: insert comparison to 0 with proper type */
- fprintf(of, "\tjnz ");
- psymb(s);
- fprintf(of, ", @l%d, @l%d\n", lt, lf);
- break;
- case 'o':
- l = lbl;
- lbl += 1;
- branch(n->l, lt, l);
- fprintf(of, "@l%d\n", l);
- branch(n->r, lt, lf);
- break;
- case 'a':
- l = lbl;
- lbl += 1;
- branch(n->l, l, lf);
- fprintf(of, "@l%d\n", l);
- branch(n->r, lt, lf);
- break;
- }
- }
- int
- stmt(Stmt *s, int b)
- {
- int l, r;
- Symb x;
- if (!s)
- return 0;
- switch (s->t) {
- case Ret:
- x = expr(s->p1);
- fprintf(of, "\tret ");
- psymb(x);
- fprintf(of, "\n");
- return 1;
- case Break:
- if (b < 0)
- die("break not in loop");
- fprintf(of, "\tjmp @l%d\n", b);
- return 1;
- case Expr:
- expr(s->p1);
- return 0;
- case Seq:
- return stmt(s->p1, b) || stmt(s->p2, b);
- case If:
- l = lbl;
- lbl += 3;
- branch(s->p1, l, l+1);
- fprintf(of, "@l%d\n", l);
- if (!(r=stmt(s->p2, b)))
- if (s->p3)
- fprintf(of, "\tjmp @l%d\n", l+2);
- fprintf(of, "@l%d\n", l+1);
- if (s->p3)
- if (!(r &= stmt(s->p3, b)))
- fprintf(of, "@l%d\n", l+2);
- return s->p3 && r;
- case While:
- l = lbl;
- lbl += 3;
- fprintf(of, "@l%d\n", l);
- branch(s->p1, l+1, l+2);
- fprintf(of, "@l%d\n", l+1);
- if (!stmt(s->p2, l+2))
- fprintf(of, "\tjmp @l%d\n", l);
- fprintf(of, "@l%d\n", l+2);
- return 0;
- }
- }
- Node *
- mknode(char op, Node *l, Node *r)
- {
- Node *n;
- n = alloc(sizeof *n);
- n->op = op;
- n->l = l;
- n->r = r;
- return n;
- }
- Node *
- mkidx(Node *a, Node *i)
- {
- Node *n;
- n = mknode('+', a, i);
- n = mknode('@', n, 0);
- return n;
- }
- Node *
- mkneg(Node *n)
- {
- static Node *z;
- if (!z) {
- z = mknode('N', 0, 0);
- z->u.n = 0;
- }
- return mknode('-', z, n);
- }
- Stmt *
- mkstmt(int t, void *p1, void *p2, void *p3)
- {
- Stmt *s;
- s = alloc(sizeof *s);
- s->t = t;
- s->p1 = p1;
- s->p2 = p2;
- s->p3 = p3;
- return s;
- }
- Node *
- param(char *v, unsigned ctyp, Node *pl)
- {
- Node *n;
- if (ctyp == NIL)
- die("invalid void declaration");
- n = mknode(0, 0, pl);
- varadd(v, 0, ctyp);
- strcpy(n->u.v, v);
- return n;
- }
- Stmt *
- mkfor(Node *ini, Node *tst, Node *inc, Stmt *s)
- {
- Stmt *s1, *s2;
- if (ini)
- s1 = mkstmt(Expr, ini, 0, 0);
- else
- s1 = 0;
- if (inc) {
- s2 = mkstmt(Expr, inc, 0, 0);
- s2 = mkstmt(Seq, s, s2, 0);
- } else
- s2 = s;
- if (!tst) {
- tst = mknode('N', 0, 0);
- tst->u.n = 1;
- }
- s2 = mkstmt(While, tst, s2, 0);
- if (s1)
- return mkstmt(Seq, s1, s2, 0);
- else
- return s2;
- }
- %}
- %union {
- Node *n;
- Stmt *s;
- unsigned u;
- }
- %token <n> NUM
- %token <n> STR
- %token <n> IDENT
- %token PP MM LE GE SIZEOF
- %token TVOID TINT TLNG
- %token IF ELSE WHILE FOR BREAK RETURN
- %right '='
- %left OR
- %left AND
- %left '&'
- %left EQ NE
- %left '<' '>' LE GE
- %left '+' '-'
- %left '*' '/' '%'
- %type <u> type
- %type <s> stmt stmts
- %type <n> expr exp0 pref post arg0 arg1 par0 par1
- %%
- prog: func prog | fdcl prog | idcl prog | ;
- fdcl: type IDENT '(' ')' ';'
- {
- varadd($2->u.v, 1, FUNC($1));
- };
- idcl: type IDENT ';'
- {
- if ($1 == NIL)
- die("invalid void declaration");
- if (nglo == NGlo)
- die("too many string literals");
- ini[nglo] = alloc(sizeof "{ x 0 }");
- sprintf(ini[nglo], "{ %c 0 }", irtyp($1));
- varadd($2->u.v, nglo++, $1);
- };
- init:
- {
- varclr();
- tmp = 0;
- };
- func: init prot '{' dcls stmts '}'
- {
- if (!stmt($5, -1))
- fprintf(of, "\tret 0\n");
- fprintf(of, "}\n\n");
- };
- prot: IDENT '(' par0 ')'
- {
- Symb *s;
- Node *n;
- int t, m;
- varadd($1->u.v, 1, FUNC(INT));
- fprintf(of, "export function w $%s(", $1->u.v);
- n = $3;
- if (n)
- for (;;) {
- s = varget(n->u.v);
- fprintf(of, "%c ", irtyp(s->ctyp));
- fprintf(of, "%%t%d", tmp++);
- n = n->r;
- if (n)
- fprintf(of, ", ");
- else
- break;
- }
- fprintf(of, ") {\n");
- fprintf(of, "@l%d\n", lbl++);
- for (t=0, n=$3; n; t++, n=n->r) {
- s = varget(n->u.v);
- m = SIZE(s->ctyp);
- fprintf(of, "\t%%%s =l alloc%d %d\n", n->u.v, m, m);
- fprintf(of, "\tstore%c %%t%d", irtyp(s->ctyp), t);
- fprintf(of, ", %%%s\n", n->u.v);
- }
- };
- par0: par1
- | { $$ = 0; }
- ;
- par1: type IDENT ',' par1 { $$ = param($2->u.v, $1, $4); }
- | type IDENT { $$ = param($2->u.v, $1, 0); }
- ;
- dcls: | dcls type IDENT ';'
- {
- int s;
- char *v;
- if ($2 == NIL)
- die("invalid void declaration");
- v = $3->u.v;
- s = SIZE($2);
- varadd(v, 0, $2);
- fprintf(of, "\t%%%s =l alloc%d %d\n", v, s, s);
- };
- type: type '*' { $$ = IDIR($1); }
- | TINT { $$ = INT; }
- | TLNG { $$ = LNG; }
- | TVOID { $$ = NIL; }
- ;
- stmt: ';' { $$ = 0; }
- | '{' stmts '}' { $$ = $2; }
- | BREAK ';' { $$ = mkstmt(Break, 0, 0, 0); }
- | RETURN expr ';' { $$ = mkstmt(Ret, $2, 0, 0); }
- | expr ';' { $$ = mkstmt(Expr, $1, 0, 0); }
- | WHILE '(' expr ')' stmt { $$ = mkstmt(While, $3, $5, 0); }
- | IF '(' expr ')' stmt ELSE stmt { $$ = mkstmt(If, $3, $5, $7); }
- | IF '(' expr ')' stmt { $$ = mkstmt(If, $3, $5, 0); }
- | FOR '(' exp0 ';' exp0 ';' exp0 ')' stmt
- { $$ = mkfor($3, $5, $7, $9); }
- ;
- stmts: stmts stmt { $$ = mkstmt(Seq, $1, $2, 0); }
- | { $$ = 0; }
- ;
- expr: pref
- | expr '=' expr { $$ = mknode('=', $1, $3); }
- | expr '+' expr { $$ = mknode('+', $1, $3); }
- | expr '-' expr { $$ = mknode('-', $1, $3); }
- | expr '*' expr { $$ = mknode('*', $1, $3); }
- | expr '/' expr { $$ = mknode('/', $1, $3); }
- | expr '%' expr { $$ = mknode('%', $1, $3); }
- | expr '<' expr { $$ = mknode('<', $1, $3); }
- | expr '>' expr { $$ = mknode('<', $3, $1); }
- | expr LE expr { $$ = mknode('l', $1, $3); }
- | expr GE expr { $$ = mknode('l', $3, $1); }
- | expr EQ expr { $$ = mknode('e', $1, $3); }
- | expr NE expr { $$ = mknode('n', $1, $3); }
- | expr '&' expr { $$ = mknode('&', $1, $3); }
- | expr AND expr { $$ = mknode('a', $1, $3); }
- | expr OR expr { $$ = mknode('o', $1, $3); }
- ;
- exp0: expr
- | { $$ = 0; }
- ;
- pref: post
- | '-' pref { $$ = mkneg($2); }
- | '*' pref { $$ = mknode('@', $2, 0); }
- | '&' pref { $$ = mknode('A', $2, 0); }
- ;
- post: NUM
- | STR
- | IDENT
- | SIZEOF '(' type ')' { $$ = mknode('N', 0, 0); $$->u.n = SIZE($3); }
- | '(' expr ')' { $$ = $2; }
- | IDENT '(' arg0 ')' { $$ = mknode('C', $1, $3); }
- | post '[' expr ']' { $$ = mkidx($1, $3); }
- | post PP { $$ = mknode('P', $1, 0); }
- | post MM { $$ = mknode('M', $1, 0); }
- ;
- arg0: arg1
- | { $$ = 0; }
- ;
- arg1: expr { $$ = mknode(0, $1, 0); }
- | expr ',' arg1 { $$ = mknode(0, $1, $3); }
- ;
- %%
- int
- yylex()
- {
- struct {
- char *s;
- int t;
- } kwds[] = {
- { "void", TVOID },
- { "int", TINT },
- { "long", TLNG },
- { "if", IF },
- { "else", ELSE },
- { "for", FOR },
- { "while", WHILE },
- { "return", RETURN },
- { "break", BREAK },
- { "sizeof", SIZEOF },
- { 0, 0 }
- };
- int i, c, c1, n;
- char v[NString], *p;
- do {
- c = getchar();
- if (c == '#')
- while ((c = getchar()) != '\n')
- ;
- if (c == '\n')
- line++;
- } while (isspace(c));
- if (c == EOF)
- return 0;
- if (isdigit(c)) {
- n = 0;
- do {
- n *= 10;
- n += c-'0';
- c = getchar();
- } while (isdigit(c));
- ungetc(c, stdin);
- yylval.n = mknode('N', 0, 0);
- yylval.n->u.n = n;
- return NUM;
- }
- if (isalpha(c)) {
- p = v;
- do {
- if (p == &v[NString-1])
- die("ident too long");
- *p++ = c;
- c = getchar();
- } while (isalpha(c) || c == '_');
- *p = 0;
- ungetc(c, stdin);
- for (i=0; kwds[i].s; i++)
- if (strcmp(v, kwds[i].s) == 0)
- return kwds[i].t;
- yylval.n = mknode('V', 0, 0);
- strcpy(yylval.n->u.v, v);
- return IDENT;
- }
- if (c == '"') {
- i = 0;
- n = 32;
- p = alloc(n);
- strcpy(p, "{ b \"");
- for (i=5;; i++) {
- c = getchar();
- if (c == EOF)
- die("unclosed string literal");
- if (i+8 >= n) {
- p = memcpy(alloc(n*2), p, n);
- n *= 2;
- }
- p[i] = c;
- if (c == '"' && p[i-1]!='\\')
- break;
- }
- strcpy(&p[i], "\", b 0 }");
- if (nglo == NGlo)
- die("too many globals");
- ini[nglo] = p;
- yylval.n = mknode('S', 0, 0);
- yylval.n->u.n = nglo++;
- return STR;
- }
- c1 = getchar();
- #define DI(a, b) a + b*256
- switch (DI(c,c1)) {
- case DI('!','='): return NE;
- case DI('=','='): return EQ;
- case DI('<','='): return LE;
- case DI('>','='): return GE;
- case DI('+','+'): return PP;
- case DI('-','-'): return MM;
- case DI('&','&'): return AND;
- case DI('|','|'): return OR;
- }
- #undef DI
- ungetc(c1, stdin);
- return c;
- }
- int
- yyerror(char *err)
- {
- die("parse error");
- return 0;
- }
- int
- main()
- {
- int i;
- of = stdout;
- nglo = 1;
- if (yyparse() != 0)
- die("parse error");
- for (i=1; i<nglo; i++)
- fprintf(of, "data $glo%d = %s\n", i, ini[i]);
- return 0;
- }
|