summary refs log tree commit diff
path: root/lisc
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2016-02-28 20:36:01 -0800
committerOri Bernstein <ori@eigenstate.org>2016-02-28 20:36:01 -0800
commit8a9b0c551366d1b16ae6ddbe72c8480d9df0a736 (patch)
treea82d6872236b211f52f3b4b117060bc6cb7ca084 /lisc
parent50c5af4290aed32a7733768c1bee2e64c93a7f84 (diff)
downloadroux-8a9b0c551366d1b16ae6ddbe72c8480d9df0a736.tar.gz
Add strings as 'b "foo"'
Diffstat (limited to 'lisc')
-rw-r--r--lisc/emit.c9
-rw-r--r--lisc/lisc.h2
-rw-r--r--lisc/parse.c89
3 files changed, 55 insertions, 45 deletions
diff --git a/lisc/emit.c b/lisc/emit.c
index d0599a4..4bf2c63 100644
--- a/lisc/emit.c
+++ b/lisc/emit.c
@@ -549,9 +549,12 @@ emitdat(Dat *d, FILE *f)
 			d->u.str, d->u.str, d->u.str
 		);
 		break;
-	case DA:
-		fprintf(f, "\t.asciz \"%s\"\n", d->u.str);
-		break;
+	case DB:
+		if (d->isstr) {
+			fprintf(f, "\t.ascii \"%s\"\n", d->u.str);
+			break;
+		}
+		/* fallthrough */
 	default:
 		if (d->isref)
 			fprintf(f, "%s %s+%"PRId64"\n", dtoa[d->type], d->u.ref.nam, d->u.ref.off);
diff --git a/lisc/lisc.h b/lisc/lisc.h
index fd0a8ba..57ce9be 100644
--- a/lisc/lisc.h
+++ b/lisc/lisc.h
@@ -429,7 +429,6 @@ struct Dat {
 		DEnd,
 		DName,
 		DAlign,
-		DA,
 		DB,
 		DH,
 		DW,
@@ -446,6 +445,7 @@ struct Dat {
 		} ref;
 	} u;
 	char isref;
+	char isstr;
 };
 
 
diff --git a/lisc/parse.c b/lisc/parse.c
index 34c487f..99af770 100644
--- a/lisc/parse.c
+++ b/lisc/parse.c
@@ -769,10 +769,13 @@ parsetyp()
 static void
 parsedataref(Dat *d)
 {
+	int t;
+
 	d->isref = 1;
 	d->u.ref.nam = tokval.str;
 	d->u.ref.off = 0;
-	if (peek() == TPlus) {
+	t = peek();
+	if (t == TPlus) {
 		next();
 		if (next() != TInt)
 			err("invalid token after offset in ref");
@@ -781,6 +784,13 @@ parsedataref(Dat *d)
 }
 
 static void
+parsedatastr(Dat *d)
+{
+	d->isstr = 1;
+	d->u.str = tokval.str;
+}
+
+static void
 parsedat(void cb(Dat *))
 {
 	char s[NString];
@@ -804,47 +814,44 @@ parsedat(void cb(Dat *))
 	d.type = DName;
 	d.u.str = s;
 	cb(&d);
-	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 %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;
-			case TB: d.type = DB; break;
-			case TS: d.type = DW; break;
-			case TD: d.type = DL; break;
-			}
-			t = nextnl();
-			do {
-				d.isref = 0;
-				memset(&d.u, 0, sizeof d.u);
-				if (t == TFlts)
-					d.u.flts = tokval.flts;
-				else if (t == TFltd)
-					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);
-				t = nextnl();
-			} while (t == TInt || t == TFlts || t == TFltd);
-			if (t == TRBrace)
-				break;
-			if (t != TComma)
-				err(", or } expected");
+
+	if (t != TLBrace)
+		err("expected data contents in { .. }");
+	for (;;) {
+		switch (nextnl()) {
+		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;
+		case TB: d.type = DB; break;
+		case TS: d.type = DW; break;
+		case TD: d.type = DL; break;
 		}
+		t = nextnl();
+		do {
+			d.isref = 0;
+			d.isstr = 0;
+			memset(&d.u, 0, sizeof d.u);
+			if (t == TFlts)
+				d.u.flts = tokval.flts;
+			else if (t == TFltd)
+				d.u.fltd = tokval.fltd;
+			else if (t == TInt)
+				d.u.num = tokval.num;
+			else if (t == TGlo)
+				parsedataref(&d);
+			else if (t == TStr)
+				parsedatastr(&d);
+			else
+				err("constant literal expected");
+			cb(&d);
+			t = nextnl();
+		} while (t == TInt || t == TFlts || t == TFltd);
+		if (t == TRBrace)
+			break;
+		if (t != TComma)
+			err(", or } expected");
 	}
 Done:
 	d.type = DEnd;