diff options
author | Ori Bernstein <ori@eigenstate.org> | 2016-02-28 20:02:36 -0800 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2016-02-28 20:16:20 -0800 |
commit | 50c5af4290aed32a7733768c1bee2e64c93a7f84 (patch) | |
tree | ee2d1b70942006735e3d8af44ab38de43c94818a | |
parent | ec7c4e0d60e22c10b6f7817436bd3f4abf2d5356 (diff) | |
download | roux-50c5af4290aed32a7733768c1bee2e64c93a7f84.tar.gz |
Allow trailing and ',' and references in data.
This change adds support for two things: data $foo {l 123,} Which allows easier machine generation of data statements. It also adds the ability to parse and emit references in data declarations.
-rw-r--r-- | lisc/emit.c | 5 | ||||
-rw-r--r-- | lisc/lisc.h | 5 | ||||
-rw-r--r-- | lisc/parse.c | 31 |
3 files changed, 37 insertions, 4 deletions
diff --git a/lisc/emit.c b/lisc/emit.c index 876d9ef..d0599a4 100644 --- a/lisc/emit.c +++ b/lisc/emit.c @@ -553,7 +553,10 @@ emitdat(Dat *d, FILE *f) fprintf(f, "\t.asciz \"%s\"\n", d->u.str); break; default: - fprintf(f, "%s %"PRId64"\n", dtoa[d->type], d->u.num); + if (d->isref) + fprintf(f, "%s %s+%"PRId64"\n", dtoa[d->type], d->u.ref.nam, d->u.ref.off); + else + fprintf(f, "%s %"PRId64"\n", dtoa[d->type], d->u.num); break; } } diff --git a/lisc/lisc.h b/lisc/lisc.h index 18d435d..fd0a8ba 100644 --- a/lisc/lisc.h +++ b/lisc/lisc.h @@ -440,7 +440,12 @@ struct Dat { double fltd; float flts; char *str; + struct { + char *nam; + int64_t off; + } ref; } u; + char isref; }; diff --git a/lisc/parse.c b/lisc/parse.c index 1a39db6..34c487f 100644 --- a/lisc/parse.c +++ b/lisc/parse.c @@ -88,6 +88,8 @@ enum { TD, TS, + TPlus, + TInt, TFlts, TFltd, @@ -111,6 +113,7 @@ static FILE *inf; static char *inpath; static int thead; static struct { + char chr; double fltd; float flts; int64_t num; @@ -186,6 +189,7 @@ lex() c = fgetc(inf); while (isblank(c)); t = TXXX; + tokval.chr = c; switch (c) { case EOF: return TEOF; @@ -201,6 +205,8 @@ lex() return TRBrace; case '=': return TEq; + case '+': + return TPlus; case 's': if (fscanf(inf, "_%f", &tokval.flts) != 1) break; @@ -710,7 +716,7 @@ parsetyp() for (;;) { flt = 0; switch (t) { - default: err("invalid size specifier"); + default: err("invalid size specifier %c", tokval.chr); case TD: flt = 1; case TL: s = 8; a = 3; break; case TS: flt = 1; @@ -761,6 +767,20 @@ parsetyp() } static void +parsedataref(Dat *d) +{ + d->isref = 1; + d->u.ref.nam = tokval.str; + d->u.ref.off = 0; + if (peek() == TPlus) { + next(); + if (next() != TInt) + err("invalid token after offset in ref"); + d->u.ref.off = tokval.num; + } +} + +static void parsedat(void cb(Dat *)) { char s[NString]; @@ -787,13 +807,15 @@ parsedat(void cb(Dat *)) if (t == TStr) { d.type = DA; d.u.str = tokval.str; + d.isref = 0; cb(&d); } else { if (t != TLBrace) err("data contents must be { .. } or \" .. \""); for (;;) { switch (nextnl()) { - default: err("invalid size specifier in data"); + default: err("invalid size specifier %c in data", tokval.chr); + case TRBrace: goto Done; case TL: d.type = DL; break; case TW: d.type = DW; break; case TH: d.type = DH; break; @@ -803,7 +825,7 @@ parsedat(void cb(Dat *)) } t = nextnl(); do { - + d.isref = 0; memset(&d.u, 0, sizeof d.u); if (t == TFlts) d.u.flts = tokval.flts; @@ -811,6 +833,8 @@ parsedat(void cb(Dat *)) d.u.fltd = tokval.fltd; else if (t == TInt) d.u.num = tokval.num; + else if (t == TGlo) + parsedataref(&d); else err("constant literal expected"); cb(&d); @@ -822,6 +846,7 @@ parsedat(void cb(Dat *)) err(", or } expected"); } } +Done: d.type = DEnd; cb(&d); } |