summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/all.h2
-rw-r--r--src/emit.c15
-rw-r--r--src/parse.c40
3 files changed, 38 insertions, 19 deletions
diff --git a/src/all.h b/src/all.h
index 03661ad..40c80f6 100644
--- a/src/all.h
+++ b/src/all.h
@@ -426,6 +426,7 @@ struct Fn {
 	Blk **rpo;
 	bits reg;
 	int slot;
+	char export;
 	char name[NString];
 };
 
@@ -466,6 +467,7 @@ struct Dat {
 	} u;
 	char isref;
 	char isstr;
+	char export;
 };
 
 
diff --git a/src/emit.c b/src/emit.c
index df96afd..9b2975d 100644
--- a/src/emit.c
+++ b/src/emit.c
@@ -497,13 +497,14 @@ emitfn(Fn *fn, FILE *f)
 	Ins *i, itmp;
 	int *r, c, fs;
 
+	fprintf(f, ".text\n");
+	if (fn->export)
+		fprintf(f, ".globl %s%s\n", symprefix, fn->name);
 	fprintf(f,
-		".text\n"
-		".globl %s%s\n"
 		"%s%s:\n"
 		"\tpush %%rbp\n"
 		"\tmov %%rsp, %%rbp\n",
-		symprefix, fn->name, symprefix, fn->name
+		symprefix, fn->name
 	);
 	fs = framesz(fn);
 	if (fs)
@@ -575,11 +576,9 @@ emitdat(Dat *d, FILE *f)
 	case DName:
 		if (!align)
 			fprintf(f, ".align 8\n");
-		fprintf(f,
-			".globl %s%s\n"
-			"%s%s:\n",
-			symprefix, d->u.str, symprefix, d->u.str
-		);
+		if (d->export)
+			fprintf(f, ".globl %s%s\n", symprefix, d->u.str);
+		fprintf(f, "%s%s:\n", symprefix, d->u.str);
 		break;
 	case DZ:
 		fprintf(f, "\t.fill %"PRId64",1,0\n", d->u.num);
diff --git a/src/parse.c b/src/parse.c
index 903e909..2590971 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -97,6 +97,7 @@ enum {
 	TJmp,
 	TJnz,
 	TRet,
+	TExport,
 	TFunc,
 	TType,
 	TData,
@@ -184,6 +185,7 @@ lex()
 		{ "jmp", TJmp },
 		{ "jnz", TJnz },
 		{ "ret", TRet },
+		{ "export", TExport },
 		{ "function", TFunc },
 		{ "type", TType },
 		{ "data", TData },
@@ -648,7 +650,7 @@ DoOp:
 }
 
 static Fn *
-parsefn()
+parsefn(int export)
 {
 	PState ps;
 	Fn *fn;
@@ -663,6 +665,7 @@ parsefn()
 	bmap = vnew(nblk, sizeof bmap[0]);
 	con[0].type = CBits;
 	fn = alloc(sizeof *fn);
+	fn->export = export;
 	blink = &fn->start;
 	fn->retty = -1;
 	if (peek() != TGlo)
@@ -809,7 +812,7 @@ parsedatstr(Dat *d)
 }
 
 static void
-parsedat(void cb(Dat *))
+parsedat(void cb(Dat *), int export)
 {
 	char s[NString];
 	int t;
@@ -818,6 +821,7 @@ parsedat(void cb(Dat *))
 	d.type = DStart;
 	d.isstr = 0;
 	d.isref = 0;
+	d.export = export;
 	cb(&d);
 	if (nextnl() != TGlo || nextnl() != TEq)
 		err("data name, then = expected");
@@ -882,28 +886,40 @@ Done:
 void
 parse(FILE *f, char *path, void data(Dat *), void func(Fn *))
 {
+	int t, export;
+
 	inf = f;
 	inpath = path;
 	lnum = 1;
 	thead = TXXX;
 	ntyp = 0;
-	for (;;)
+	for (;;) {
+		export = 0;
 		switch (nextnl()) {
+		default:
+			err("top-level definition expected");
+		case TExport:
+			export = 1;
+			t = nextnl();
+			if (t == TFunc) {
 		case TFunc:
-			func(parsefn());
-			break;
+				func(parsefn(export));
+				break;
+			}
+			else if (t == TData) {
+		case TData:
+				parsedat(data, export);
+				break;
+			}
+			else
+				err("export can only qualify data and function");
 		case TType:
 			parsetyp();
 			break;
-		case TData:
-			parsedat(data);
-			break;
 		case TEOF:
 			return;
-		default:
-			err("top-level definition expected");
-			break;
 		}
+	}
 }
 
 static void
@@ -1009,6 +1025,8 @@ printfn(Fn *fn, FILE *f)
 	Ins *i;
 	uint n;
 
+	if (fn->export)
+		fprintf(f, "export ");
 	fprintf(f, "function $%s() {\n", fn->name);
 	for (b=fn->start; b; b=b->link) {
 		fprintf(f, "@%s\n", b->name);