diff options
author | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2015-10-08 23:52:44 -0400 |
---|---|---|
committer | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2015-10-08 23:52:44 -0400 |
commit | 5d2609b1674bc1d55872392693bf7281f6a83acc (patch) | |
tree | 67a41d535a78f0fd336bae2dbf6357fcc380c7a6 /minic/minic.y | |
parent | a72dfedc1f969ad41d9b5d3aee7f7939e7703dd8 (diff) | |
download | roux-5d2609b1674bc1d55872392693bf7281f6a83acc.tar.gz |
add clumsy support for string literals
It's currently clumsy because they are given the type 'int *' instead of 'char *', the reason is that the char base type is not supported now. I don't think it would be hard to add proper support for char, though.
Diffstat (limited to 'minic/minic.y')
-rw-r--r-- | minic/minic.y | 47 |
1 files changed, 44 insertions, 3 deletions
diff --git a/minic/minic.y b/minic/minic.y index 3465ca5..5222869 100644 --- a/minic/minic.y +++ b/minic/minic.y @@ -8,9 +8,9 @@ enum { NString = 16, NVar = 256, + NStr = 256, }; - enum { /* minic types */ INT = 0, LNG = 1, @@ -40,6 +40,7 @@ struct Symb { Con, Tmp, Var, + Glo, } t; union { int n; @@ -62,7 +63,8 @@ int yylex(void), yyerror(char *); Symb expr(Node *), lval(Node *); FILE *of; -int lbl, tmp; +int lbl, tmp, str; +char *slit[NStr]; struct { char v[NString]; unsigned ctyp; @@ -167,6 +169,9 @@ psymb(Symb s) case Con: fprintf(of, "%d", s.u.n); break; + case Glo: + fprintf(of, "$%s", s.u.v); + break; } } @@ -275,6 +280,12 @@ expr(Node *n) sr.ctyp = INT; break; + case 'S': + sr.t = Glo; + sprintf(sr.u.v, "str%d", n->u.n); + sr.ctyp = IDIR(INT); + break; + case '@': s0 = expr(n->l); if (KIND(s0.ctyp) != PTR) @@ -480,6 +491,7 @@ mkstmt(int t, void *p1, void *p2, void *p3) } %token <n> NUM +%token <n> STR %token <n> IDENT %token PP MM LE GE @@ -502,9 +514,13 @@ mkstmt(int t, void *p1, void *p2, void *p3) prog: prot '{' dcls stmts '}' { + int i; + stmt($4); fprintf(of, "\tret\n"); fprintf(of, "}\n\n"); + for (i = 0; i < str; i++) + fprintf(of, "data $str%d = \"%s\"\n", i, slit[i]); }; prot: IDENT '(' ')' @@ -512,7 +528,7 @@ prot: IDENT '(' ')' varclr(); lbl = 0; tmp = 0; - fprintf(of, "function %s() {\n", $1->u.v); + fprintf(of, "function $%s() {\n", $1->u.v); fprintf(of, "@l%d\n", lbl++); }; @@ -566,6 +582,7 @@ pref: post ; post: NUM + | STR | IDENT | '(' expr ')' { $$ = $2; } | post '[' expr ']' { $$ = mkidx($1, $3); } @@ -630,6 +647,30 @@ yylex() return IDENT; } + if (c == '"') { + if (str == NStr) + die("too many string literals"); + i = 0; + n = 32; + p = alloc(n); + for (i=0;; i++) { + c = getchar(); + if (c == EOF) + die("unclosed string literal"); + if (c == '"' && (!i || p[i-1]!='\\')) + break; + if (i >= n) { + p = memcpy(alloc(n*2), p, n); + n *= 2; + } + p[i] = c; + } + slit[str] = p; + yylval.n = mknode('S', 0, 0); + yylval.n->u.n = str++; + return STR; + } + c1 = getchar(); #define DI(a, b) a + b*256 switch (DI(c,c1)) { |