aboutsummaryrefslogtreecommitdiff
path: root/minic
diff options
context:
space:
mode:
authorQuentin Carbonneaux <[email protected]>2015-10-08 23:52:44 -0400
committerQuentin Carbonneaux <[email protected]>2015-10-08 23:52:44 -0400
commit5d2609b1674bc1d55872392693bf7281f6a83acc (patch)
tree67a41d535a78f0fd336bae2dbf6357fcc380c7a6 /minic
parenta72dfedc1f969ad41d9b5d3aee7f7939e7703dd8 (diff)
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')
-rw-r--r--minic/minic.y47
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)) {