commit 7e86fc39fcee98595a723daac39aa8a4ee3dfc96
parent 9210e17c784c54efa840c4237d9dc15e6da2227f
Author: Quentin Carbonneaux <quentin.carbonneaux@yale.edu>
Date: Wed, 9 Sep 2015 18:33:00 -0400
add parsing code for function calls
Diffstat:
| M | lisc/lisc.h | | | 9 | ++++++++- |
| M | lisc/parse.c | | | 147 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------- |
2 files changed, 115 insertions(+), 41 deletions(-)
diff --git a/lisc/lisc.h b/lisc/lisc.h
@@ -75,6 +75,7 @@ enum {
RTmp,
RCon,
RSlot,
+ RTyp,
NRef = (1<<14) - 1
};
@@ -83,6 +84,7 @@ enum {
#define CON(x) (Ref){RCon, x}
#define CON_Z CON(0) /* reserved zero constant */
#define SLOT(x) (Ref){RSlot, x}
+#define TYP(x) (Ref){RTyp, x}
static inline int req(Ref a, Ref b)
{ return a.type == b.type && a.val == b.val; }
@@ -132,8 +134,13 @@ enum Op {
OCopy,
NPubOp,
+ /* function instructions */
+ OArg = NPubOp,
+ OArgc,
+ OCall,
+
/* reserved instructions */
- ONop = NPubOp,
+ ONop,
OAddr,
OSwap,
OSign,
diff --git a/lisc/parse.c b/lisc/parse.c
@@ -37,6 +37,9 @@ OpDesc opdesc[NOp] = {
[OXCmp] = { "xcmp", 2, 1 },
[OXTest] = { "xtest", 2, 1 },
[OAddr] = { "addr", 1, 0 },
+ [OArg] = { "arg", 1, 0 },
+ [OArgc] = { "argc", 1, 0 },
+ [OCall] = { "call", 1, 0 },
[OAlloc] = { "alloc4", 1, 1 },
[OAlloc+1] = { "alloc8", 1, 1 },
[OAlloc+2] = { "alloc16", 1, 1 },
@@ -58,6 +61,7 @@ typedef enum {
enum {
TXXX = NPubOp,
+ TCall,
TPhi,
TJmp,
TJnz,
@@ -146,6 +150,7 @@ lex()
char *str;
int tok;
} tmap[] = {
+ { "call", TCall },
{ "phi", TPhi },
{ "jmp", TJmp },
{ "jnz", TJnz },
@@ -278,6 +283,29 @@ nextnl()
return t;
}
+static void
+expect(int t)
+{
+ static char *names[] = {
+ [TLbl] = "label",
+ [TComma] = ",",
+ [TEq] = "=",
+ [TNL] = "newline",
+ [TEOF] = 0,
+ };
+ char buf[128], *s1, *s2;
+ int t1;
+
+ t1 = next();
+ if (t == t1)
+ return;
+ s1 = names[t] ? names[t] : "??";
+ s2 = names[t1] ? names[t1] : "??";
+ snprintf(buf, sizeof buf,
+ "%s expected (got %s instead)", s1, s2);
+ err(buf);
+}
+
Blk *
blocka()
{
@@ -338,6 +366,54 @@ parseref()
}
}
+static int
+parsecls(char *ty)
+{
+ switch (next()) {
+ default:
+ err("invalid class specifier");
+ case TW:
+ return 0;
+ case TL:
+ return 1;
+ case TTyp:
+ strcpy(ty, tokval.str);
+ return 2;
+ }
+}
+
+static void
+parseargl()
+{
+ char ty[NString];
+ int w, t;
+ Ref r;
+
+ expect(TLParen);
+ if (peek() == TRParen) {
+ next();
+ return;
+ }
+ for (;;) {
+ if (curi - insb >= NIns)
+ err("too many instructions (1)");
+ w = parsecls(ty);
+ r = parseref();
+ if (req(r, R))
+ err("invalid reference argument");
+ if (w == 2)
+ *curi = (Ins){OArgc, 0, R, {TYP(0), r}};
+ else
+ *curi = (Ins){OArg, w, R, {r, R}};
+ curi++;
+ t = next();
+ if (t == TRParen)
+ break;
+ if (t != TComma)
+ err(", or ) expected");
+ }
+}
+
static Blk *
findblk(char *name)
{
@@ -357,29 +433,6 @@ findblk(char *name)
}
static void
-expect(int t)
-{
- static char *names[] = {
- [TLbl] = "label",
- [TComma] = "comma",
- [TEq] = "=",
- [TNL] = "newline",
- [TEOF] = 0,
- };
- char buf[128], *s1, *s2;
- int t1;
-
- t1 = next();
- if (t == t1)
- return;
- s1 = names[t] ? names[t] : "??";
- s2 = names[t1] ? names[t1] : "??";
- snprintf(buf, sizeof buf,
- "%s expected (got %s instead)", s1, s2);
- err(buf);
-}
-
-static void
closeblk()
{
curb->nins = curi - insb;
@@ -398,6 +451,7 @@ parseline(PState ps)
Ref r;
Blk *b;
int t, op, i, w;
+ char ty[NString];
t = nextnl();
if (ps == PLbl && t != TLbl && t != TRBrace)
@@ -407,6 +461,7 @@ parseline(PState ps)
if (OStorel <= t && t <= OStoreb) {
/* operations without result */
r = R;
+ w = 0;
op = t;
goto DoOp;
}
@@ -457,16 +512,7 @@ parseline(PState ps)
}
r = tmpref(tokval.str, 0);
expect(TEq);
- switch (next()) {
- case TW:
- w = 0;
- break;
- case TL:
- w = 1;
- break;
- default:
- err("class expected after =");
- }
+ w = parsecls(ty);
op = next();
DoOp:
if (op == TPhi) {
@@ -474,6 +520,21 @@ DoOp:
err("unexpected phi instruction");
op = -1;
}
+ if (op == TCall) {
+ /* do eet! */
+ arg[0] = parseref();
+ parseargl();
+ expect(TNL);
+ op = OCall;
+ if (w == 2) {
+ w = 0;
+ arg[1] = TYP(0);
+ } else
+ arg[1] = R;
+ goto Ins;
+ }
+ if (w == 2)
+ err("size class must be w or l");
if (op >= NPubOp)
err("invalid instruction");
i = 0;
@@ -493,15 +554,16 @@ DoOp:
if (t == TNL)
break;
if (t != TComma)
- err("comma or end of line expected");
+ err(", or end of line expected");
next();
}
next();
if (op != -1 && i != opdesc[op].arity)
err("invalid arity");
if (op != -1) {
+ Ins:
if (curi - insb >= NIns)
- err("too many instructions in block");
+ err("too many instructions (2)");
curi->op = op;
curi->wide = w;
curi->to = r;
@@ -708,6 +770,9 @@ printref(Ref r, Fn *fn, FILE *f)
case RSlot:
fprintf(f, "S%d", r.val);
break;
+ case RTyp:
+ fprintf(f, ":%d", r.val);
+ break;
}
}
@@ -748,17 +813,19 @@ printfn(Fn *fn, FILE *f)
if (!req(i->to, R)) {
printref(i->to, fn, f);
fprintf(f, " =");
+ fprintf(f, i->wide ? "l " : "w ");
}
assert(opdesc[i->op].name);
- if (OStorel > i->op || i->op > OStoreb)
- fprintf(f, i->wide ? "l " : "w ");
fprintf(f, "%s", opdesc[i->op].name);
- n = opdesc[i->op].arity;
- if (n > 0) {
+ if (req(i->to, R))
+ if (i->op < OStorel || i->op > OStoreb)
+ if (i->op != OArgc)
+ fprintf(f, i->wide ? "l" : "w");
+ if (!req(i->arg[0], R)) {
fprintf(f, " ");
printref(i->arg[0], fn, f);
}
- if (n > 1) {
+ if (!req(i->arg[1], R)) {
fprintf(f, ", ");
printref(i->arg[1], fn, f);
}