diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/all.h | 2 | ||||
-rw-r--r-- | src/emit.c | 15 | ||||
-rw-r--r-- | src/parse.c | 40 |
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); |