summary refs log tree commit diff
path: root/lisc
diff options
context:
space:
mode:
Diffstat (limited to 'lisc')
-rw-r--r--lisc/emit.c36
-rw-r--r--lisc/lisc.h20
-rw-r--r--lisc/main.c8
-rw-r--r--lisc/parse.c62
4 files changed, 104 insertions, 22 deletions
diff --git a/lisc/emit.c b/lisc/emit.c
index ab7a72a..316c5f0 100644
--- 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
index d4c08ce..b3287f7 100644
--- 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
index c8edeb5..1591edb 100644
--- 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
index 70cdb55..8793d32 100644
--- 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: