diff --git a/assert.c b/assert.c index c1d533e..ff10759 100644 --- a/assert.c +++ b/assert.c @@ -232,10 +232,10 @@ assertexpr(Node *n) case Ocall: assertexpr(r); t = l->ty; + n->ty = t->tof; if(l->op==Opkg) return; usetype(t); - n->ty = t->tof; break; default: assert(0); diff --git a/exports.c b/exports.c index 4d22976..4d75609 100644 --- a/exports.c +++ b/exports.c @@ -93,13 +93,15 @@ void genbin(char *name) { f = fopen(name, "w+"); - // fprintf(f, "%s\n", pkgname->name); - // fprintf(f, "%d\n", nimport); - // for(int i = 0; i < nimport; ++i){ - // fprintf(f, "%d %s %s\n", i, imports[i].path->name, imports[i].sym->name); - // } - - wr4(f, ninst); + wr4(f, nimport); + for(int i = 0; i < nimport; ++i){ + char buf[1024]; + sprintf(buf, "%s/obj", imports[i].path->name); + int len = strlen(buf); + wr4(f, len); + fwrite(buf, 1, len, f); + } + wr4(f, ninst); disinst(f, firstinst); fclose(f); } \ No newline at end of file diff --git a/parse.c b/parse.c index 0779bce..c60f6e5 100644 --- a/parse.c +++ b/parse.c @@ -827,7 +827,6 @@ imret(int n) if(n == 0) return tnone; if(n == 1){ - want((int[]){Lconst,0}); want((int[]){Lconst,0}); return imtype(); } diff --git a/test/fib/exported b/test/fib/exported new file mode 100644 index 0000000..2d96508 --- /dev/null +++ b/test/fib/exported @@ -0,0 +1,7 @@ +fib +fn .fib 160 0 1 1 + 0 + int 1 8 56 + 8 + int 1 8 0 + diff --git a/test/fib/fib.yo b/test/fib/fib.yo new file mode 100644 index 0000000..7f08d56 --- /dev/null +++ b/test/fib/fib.yo @@ -0,0 +1,8 @@ +package fib + +export fn fib(n int) int { + if n <= 1 { + return n; + }; + return fib(n-1) + fib(n-2); +}; diff --git a/test/fib/obj b/test/fib/obj new file mode 100644 index 0000000..45725b4 Binary files /dev/null and b/test/fib/obj differ diff --git a/test/main.yo b/test/main.yo new file mode 100644 index 0000000..af90e74 --- /dev/null +++ b/test/main.yo @@ -0,0 +1,10 @@ +package main + +import "./test/fib" +import "./test/nqueen" + +fn main() int { + f := fib.fib(10); + n := nqueen.solve(8); + return f + n; +}; diff --git a/test/nqueen/exported b/test/nqueen/exported new file mode 100644 index 0000000..81681b8 --- /dev/null +++ b/test/nqueen/exported @@ -0,0 +1,7 @@ +nqueen +fn .solve 296 0 1 1 + 0 + int 1 8 56 + 8 + int 1 8 0 + diff --git a/test/fib.yo b/test/nqueen/nqueen.yo similarity index 57% rename from test/fib.yo rename to test/nqueen/nqueen.yo index 0a42718..33e6e7c 100644 --- a/test/fib.yo +++ b/test/nqueen/nqueen.yo @@ -1,27 +1,15 @@ -package main +package nqueen -type Any struct { - x,y int; - arr [8]int; +export fn solve(n int) int { + arr := [16]int{}; + return nqueen(0, 0, arr[:n]); }; -fn main() int { - arr := [8]int{}; - return nqueen(0, 0, arr[:]); -}; - -fn fib(n int) int{ - if n <= 1 { - return n; - }; - return fib(n-1) + fib(n-2); -}; - -fn nqueen(r,ans int, arr []int) int{ +fn nqueen(r,ans int, arr []int) int { if r == len(arr) { return ans + 1; }; - for c:=0; c < len(arr); c=c+1{ + for c:=0; c < len(arr); c=c+1 { arr[r] = c; if canput(r, arr) { ans = nqueen(r+1, ans, arr); diff --git a/test/nqueen/obj b/test/nqueen/obj new file mode 100644 index 0000000..f0cd5ef Binary files /dev/null and b/test/nqueen/obj differ diff --git a/vm/run b/vm/run new file mode 100755 index 0000000..c3f2e32 Binary files /dev/null and b/vm/run differ diff --git a/vm/vm.c b/vm/vm.c index b196712..a7d21a0 100644 --- a/vm/vm.c +++ b/vm/vm.c @@ -5,6 +5,10 @@ u32 ninst; Inst *inst; REG R; +Inst **modules; +u32 *modsizes; +int nmodules; + #define OP(fn) void fn(void) #define B(r) *((i8*)(R.r)) #define F(r) ((WORD*)(R.r)) @@ -112,6 +116,18 @@ OP(call){ R.FP = (u8*)f; JMP(d); } +OP(pcall){ + Frame *f; + int mod, pc; + + f = T(s); + f->lr = R.PC; + f->fp = R.FP; + R.FP = (u8*)f; + mod = W(m); + pc = W(d); + R.PC = &modules[mod][pc]; +} OP(ret) { Frame *f = (Frame*)R.FP; R.FP = f->fp; @@ -165,6 +181,7 @@ static void (*optab[])(void) = { [ILEA] = lea, [IFRAME] = frame, [ICALL] = call, + [PCALL] = pcall, [IJMP] = jmp, [IRET] = ret, [ILEN] = len, @@ -204,15 +221,15 @@ xec(void) } void -bpatch(Inst *i) +bpatch(Inst *i, Inst *base, u32 n) { static int tab[IEND] = { [ICALL]=1,[IBEQW]=1,[IBNEQW]=1,[IJMP]=1, }; if(tab[i->op] == 0) return; - assert(i->d.imm >= 0 && i->d.imm < ninst); - i->d.imm = (WORD)&inst[i->d.imm]; + assert(i->d.imm >= 0 && i->d.imm < n); + i->d.imm = (WORD)&base[i->d.imm]; return; } @@ -243,12 +260,11 @@ rdinst(FILE *f, Inst *in) } switch(UXDST(in->add)) { case DST(AFP): - case DST(AMP): + case DST(AMP): in->d.ind = rd4(f); break; case DST(AIMM): in->d.ind = rd4(f); - bpatch(in); break; case DST(AIND|AFP): case DST(AIND|AMP): @@ -258,18 +274,53 @@ rdinst(FILE *f, Inst *in) } } +Inst* +loadmod(char *fname, u32 *outn) +{ + FILE *f = fopen(fname, "r"); + assert(f != 0); + u32 nim = rd4(f); + for(u32 i = 0; i < nim; i++){ + u32 len = rd4(f); + fseek(f, len, SEEK_CUR); + } + u32 n = rd4(f); + Inst *ins = calloc(sizeof(Inst), n); + for(u32 i = 0; i < n; i++) + rdinst(f, ins+i); + for(u32 i = 0; i < n; i++) + bpatch(ins+i, ins, n); + fclose(f); + *outn = n; + return ins; +} + void load(char *fname) { FILE *f = fopen(fname, "r"); - assert(f != 0); + assert(f != 0); initprog(1024); + + nmodules = rd4(f); + if(nmodules > 0){ + modules = calloc(sizeof(Inst*), nmodules); + modsizes = calloc(sizeof(u32), nmodules); + for(int i = 0; i < nmodules; i++){ + u32 len = rd4(f); + char *path = calloc(1, len+1); + fread(path, 1, len, f); + modules[i] = loadmod(path, &modsizes[i]); + free(path); + } + } + ninst = rd4(f); inst = calloc(sizeof(Inst), ninst); - - for(u32 i = 0; i < ninst; ++i){ - rdinst(f, inst+i); - } + for(u32 i = 0; i < ninst; i++) + rdinst(f, inst+i); + for(u32 i = 0; i < ninst; i++) + bpatch(inst+i, inst, ninst); R.PC = inst; fclose(f); }