commit fb423f749cc0f6f0cceea7d8b77be5a0d807e26d
parent b93b0d2902bae928edd960ae4d373f5e0033e39e
Author: Quentin Carbonneaux <quentin.carbonneaux@yale.edu>
Date: Wed, 7 Oct 2015 22:26:13 -0400
finish implementing data parsing
Diffstat:
4 files changed, 104 insertions(+), 22 deletions(-)
diff --git a/lisc/emit.c b/lisc/emit.c
@@ -315,6 +315,7 @@ emitfn(Fn *fn, FILE *f)
int *r, c, fs;
fprintf(f,
+ "\n"
".text\n"
".globl %s\n"
".type %s, @function\n"
@@ -366,3 +367,38 @@ emitfn(Fn *fn, FILE *f)
}
}
+
+void
+emitdat(Dat *d, FILE *f)
+{
+ switch (d->type) {
+ case DName:
+ fprintf(f,
+ "\n"
+ ".data\n"
+ ".globl %s\n"
+ ".type %s, @object\n"
+ "%s:\n",
+ d->u.str, d->u.str, d->u.str
+ );
+ break;
+ case DAlign:
+ fprintf(f, ".align %"PRId64"\n", d->u.num);
+ break;
+ case DA:
+ fprintf(f, "\t.string \"%s\"\n", d->u.str);
+ break;
+ case DB:
+ fprintf(f, "\t.byte %"PRId64"\n", d->u.num);
+ break;
+ case DH:
+ fprintf(f, "\t.value %"PRId64"\n", d->u.num);
+ break;
+ case DW:
+ fprintf(f, "\t.long %"PRId64"\n", d->u.num);
+ break;
+ case DL:
+ fprintf(f, "\t.quad %"PRId64"\n", d->u.num);
+ break;
+ }
+}
diff --git a/lisc/lisc.h b/lisc/lisc.h
@@ -17,6 +17,7 @@ typedef struct Tmp Tmp;
typedef struct Con Con;
typedef struct Fn Fn;
typedef struct Typ Typ;
+typedef struct Dat Dat;
enum Reg {
RXX,
@@ -263,6 +264,22 @@ struct Typ {
} seg[NSeg+1];
};
+struct Dat {
+ enum {
+ DName,
+ DAlign,
+ DA,
+ DB,
+ DH,
+ DW,
+ DL
+ } type;
+ union {
+ int64_t num;
+ char *str;
+ } u;
+};
+
/* main.c */
extern char debug['Z'+1];
@@ -288,7 +305,7 @@ Ref getcon(int64_t, Fn *);
/* parse.c */
extern OpDesc opdesc[NOp];
-Fn *parse(FILE *);
+Fn *parse(FILE *, void (Dat *));
void printfn(Fn *, FILE *);
/* ssa.c */
@@ -319,3 +336,4 @@ void rega(Fn *);
/* emit.c */
void emitfn(Fn *, FILE *);
+void emitdat(Dat *, FILE *);
diff --git a/lisc/main.c b/lisc/main.c
@@ -22,6 +22,12 @@ dumpts(Bits *b, Tmp *tmp, FILE *f)
fprintf(f, " ]\n");
}
+static void
+data(Dat *d)
+{
+ emitdat(d, stdout);
+}
+
int
main(int ac, char *av[])
{
@@ -60,7 +66,7 @@ main(int ac, char *av[])
}
}
- fn = parse(inf);
+ fn = parse(inf, data);
fclose(inf);
if (debug['P']) {
fprintf(stderr, "\n> After parsing:\n");
diff --git a/lisc/parse.c b/lisc/parse.c
@@ -70,6 +70,7 @@ enum {
TRet,
TFunc,
TType,
+ TData,
TAlign,
TL,
TW,
@@ -83,6 +84,7 @@ enum {
TLbl,
TGlo,
TTyp,
+ TStr,
TEq,
TComma,
TLParen,
@@ -138,6 +140,7 @@ lex()
{ "ret", TRet },
{ "function", TFunc },
{ "type", TType },
+ { "data", TData },
{ "align", TAlign },
{ "l", TL },
{ "w", TW },
@@ -207,6 +210,17 @@ lex()
tokval.num *= sgn;
return TNum;
}
+ if (c == '"') {
+ tokval.str = valloc(0, 1);
+ for (i=0;; i++) {
+ c = fgetc(inf);
+ if (c == '"')
+ if (!i || tokval.str[i-1] != '\\')
+ return TStr;
+ vgrow(&tokval.str, i+1);
+ tokval.str[i] = c;
+ }
+ }
t = TXXX;
if (0)
Alpha: c = fgetc(inf);
@@ -711,24 +725,6 @@ parsetyp()
err("expected closing }");
}
-typedef struct Dat Dat;
-
-struct Dat {
- enum {
- DName,
- DAlign,
- DA,
- DB,
- DH,
- DW,
- DL
- } type;
- union {
- long long num;
- char *str;
- } u;
-};
-
static void
parsedat(void cb(Dat *))
{
@@ -749,12 +745,35 @@ parsedat(void cb(Dat *))
cb(&d);
t = nextnl();
}
+ if (t == TStr) {
+ d.type = DA;
+ d.u.str = tokval.str;
+ cb(&d);
+ return;
+ }
if (t != TLBrace)
- err("data contents must start with {");
+ err("data contents must be { .. } or \" .. \"");
+ for (;;) {
+ switch (nextnl()) {
+ case TL: d.type = DL; break;
+ case TW: d.type = DW; break;
+ case TH: d.type = DH; break;
+ case TB: d.type = DB; break;
+ }
+ if (nextnl() != TNum)
+ err("number expected");
+ d.u.num = tokval.num;
+ cb(&d);
+ t = nextnl();
+ if (t == TRBrace)
+ break;
+ if (t != TComma)
+ err(", or } expected");
+ }
}
Fn *
-parse(FILE *f)
+parse(FILE *f, void data(Dat *))
{
Fn *fn;
@@ -776,6 +795,9 @@ parse(FILE *f)
case TType:
parsetyp();
break;
+ case TData:
+ parsedat(data);
+ break;
case TEOF:
return fn;
default: