aboutsummaryrefslogtreecommitdiff
path: root/minic/minic.y
diff options
context:
space:
mode:
authorQuentin Carbonneaux <[email protected]>2015-10-12 14:00:20 -0400
committerQuentin Carbonneaux <[email protected]>2015-10-12 14:00:20 -0400
commit31b19a21b8ac2a8ce67864794af88241df7674a6 (patch)
treee9976e0a3f5e75d4e6293360dec3260b4515554e /minic/minic.y
parentf4dc0f98a5fc6b6c78400798d545b4f119bef665 (diff)
finish rough implementation of calls
Diffstat (limited to 'minic/minic.y')
-rw-r--r--minic/minic.y86
1 files changed, 68 insertions, 18 deletions
diff --git a/minic/minic.y b/minic/minic.y
index 2acd5a2..86846ee 100644
--- a/minic/minic.y
+++ b/minic/minic.y
@@ -15,9 +15,11 @@ enum { /* minic types */
INT = 0,
LNG = 1,
PTR = 2,
+ FUN = 3,
};
#define IDIR(x) (((x) << 2) + PTR)
+#define FUNC(x) (((x) << 2) + FUN)
#define DREF(x) ((x) >> 2)
#define KIND(x) ((x) & 3)
#define SIZE(x) (KIND(x) == INT ? 4 : 8)
@@ -26,15 +28,6 @@ typedef struct Node Node;
typedef struct Symb Symb;
typedef struct Stmt Stmt;
-struct Node {
- char op;
- union {
- int n;
- char v[NString];
- } u;
- Node *l, *r;
-};
-
struct Symb {
enum {
Con,
@@ -49,6 +42,16 @@ struct Symb {
unsigned long ctyp;
};
+struct Node {
+ char op;
+ union {
+ int n;
+ char v[NString];
+ Symb s;
+ } u;
+ Node *l, *r;
+};
+
struct Stmt {
enum {
If,
@@ -68,6 +71,7 @@ char *str[NStr];
struct {
char v[NString];
unsigned ctyp;
+ char glob;
} varh[NVar];
void
@@ -105,11 +109,12 @@ varclr()
unsigned h;
for (h=0; h<NVar; h++)
- varh[h].v[0] = 0;
+ if (!varh[h].glob)
+ varh[h].v[0] = 0;
}
void
-varadd(char *v, unsigned ctyp)
+varadd(char *v, int glob, unsigned ctyp)
{
unsigned h0, h;
@@ -118,6 +123,7 @@ varadd(char *v, unsigned ctyp)
do {
if (varh[h].v[0] == 0) {
strcpy(varh[h].v, v);
+ varh[h].glob = glob;
varh[h].ctyp = ctyp;
return;
}
@@ -128,7 +134,7 @@ varadd(char *v, unsigned ctyp)
}
unsigned
-varctyp(char *v)
+varctyp(char *v, unsigned d)
{
unsigned h0, h;
@@ -138,8 +144,10 @@ varctyp(char *v)
if (strcmp(varh[h].v, v) == 0)
return varh[h].ctyp;
} while (++h != h0 && varh[h].v[0] != 0);
+ if (d != -1u)
+ return d;
die("undeclared variable");
- return -1;
+ return INT;
}
char
@@ -250,6 +258,38 @@ load(Symb d, Symb s)
fprintf(of, "\n");
}
+void
+call(Node *n, Symb *sr)
+{
+ Node *a;
+ char *f;
+ unsigned ft;
+
+ f = n->l->u.v;
+ ft = varctyp(f, FUNC(INT));
+ if (KIND(ft) != FUN)
+ die("called variable is not a function");
+ 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);
+ a = n->r;
+ if (a)
+ for (;;) {
+ fprintf(of, "%c ", irtyp(a->u.s.ctyp));
+ psymb(a->u.s);
+ a = a->r;
+ if (a)
+ fprintf(of, ", ");
+ else {
+ fprintf(of, ")\n");
+ break;
+ }
+ }
+}
+
Symb
expr(Node *n)
{
@@ -272,6 +312,9 @@ expr(Node *n)
switch (n->op) {
+ case 0:
+ abort();
+
case 'V':
s0 = lval(n);
sr.ctyp = s0.ctyp;
@@ -291,7 +334,7 @@ expr(Node *n)
break;
case 'C':
- die("call not implemented");
+ call(n, &sr);
break;
case '@':
@@ -380,7 +423,7 @@ lval(Node *n)
die("invalid lvalue");
case 'V':
sr.t = Var;
- sr.ctyp = varctyp(n->u.v);
+ sr.ctyp = varctyp(n->u.v, -1u);
strcpy(sr.u.v, n->u.v);
break;
case '@':
@@ -520,7 +563,14 @@ mkstmt(int t, void *p1, void *p2, void *p3)
%%
-prog: prot '{' dcls stmts '}'
+prog: func prog | fdcl prog | ;
+
+fdcl: type IDENT '(' ')'
+{
+ varadd($2->u.v, 1, FUNC($1));
+};
+
+func: prot '{' dcls stmts '}'
{
int i;
@@ -547,7 +597,7 @@ dcls: | dcls type IDENT ';'
v = $3->u.v;
s = SIZE($2);
- varadd(v, $2);
+ varadd(v, 0, $2);
fprintf(of, "\t%%%s =l alloc%d %d\n", v, s, s);
};
@@ -604,7 +654,7 @@ arg0: arg1
| { $$ = 0; }
;
arg1: expr { $$ = mknode(0, $1, 0); }
- | arg1 ',' expr { $$ = mknode(0, $1, $3); }
+ | expr ',' arg1 { $$ = mknode(0, $1, $3); }
;
%%