diff --git a/asm.c b/asm.c index 5c07cac..1a493b7 100644 --- a/asm.c +++ b/asm.c @@ -21,6 +21,7 @@ char* instname[] = { [ILTW] = "lt", [ILEQW] = "leq", [IEQW] = "eq", + [INEQW] = "neq", }; void @@ -33,18 +34,17 @@ asminst(FILE *f, Inst *in) void asmexport(FILE *f, Sym *pkg, Decl **arr, int n) { - fprintf(f, "\tpackage\t"); + fprintf(f, "\n\tpackage\t"); fprintf(f, "%s\n", pkg->name); - fprintf(f, "\texported %d\n", n); + fprintf(f, "\tfn %d\n", n); for(int i = 0; i < n; ++i){ Decl *d = arr[i]; switch(d->store){ default: break; - // case Dfn: - // fprintf(f, "\tlink\t%u,%u,\"",d->desc->id, d->pc->pc); - // fprintf(f, "%s\"\n", d->sym->name); - // break; + case Dfn: + fprintf(f, "\tfn\t%s,%d,\n",d->sym->name, d->pc->pc); + break; } } } \ No newline at end of file diff --git a/assert.c b/assert.c index 75171b3..c1d533e 100644 --- a/assert.c +++ b/assert.c @@ -212,18 +212,16 @@ assertexpr(Node *n) break; case Oslice: t = usetype(l->ty); + assert(t->kind == Tarray || t->kind == Tslice); if(t->kind == Tslice) - t = typeofslice(t); - assert(t->kind == Tarray); - n->ty = mktype(Tslice, ArrHead, t, nil); + t = t->tof; + n->ty = mktype(Tslice, ArrHead, t->tof, nil); break; case Oindex: t = l->ty; - if(t->kind == Tslice) - t = typeofslice(t->tof); - assert(t->kind == Tarray); + assert(t->kind == Tarray || t->kind == Tslice); assertexpr(r); - if(r->op == Oconst) + if(r->op == Oconst && t->kind == Tarray) assert(r->val < t->len); n->ty = t->tof; break; @@ -280,16 +278,17 @@ assertstmt(Type *ret, Node *n) assert(l->ty == tnone); else assert(eqtype(ret, l->ty)); + n->ty = ret; return top; case Oif: n->l = l = assertstmt(ret, l); - assert(l->ty == tbool); + assert(l->ty->kind == Tbool); r->l = assertstmt(ret, r->l); n = r; break; case Ofor: assertexpr(l); - assert(l->ty == tbool); + assert(l->ty->kind == Tbool); pushloop(); r->r = assertstmt(ret, r->r); r->l = assertstmt(ret, r->l); diff --git a/com.c b/com.c index 3031c03..4fd4047 100644 --- a/com.c +++ b/com.c @@ -397,14 +397,6 @@ rewrite(Node *n) n->l->ty = tint; n->l = rewrite(n->l); return n; - case Oslice: - if(r->l == nil) - r->l = mkconst(0); - if(r->r == nil) - r->r = mkconst(n->ty->len); - n->l = rewrite(n->l); - n->r = rewrite(n->r); - break; case Oindex: t = n->ty; n->r = mkn(Omul, mkconst(IBY2WD), n->r); @@ -462,7 +454,7 @@ swaprelop(int op) case Ogt: return Olt; case Ogeq: return Oleq; case Oleq: return Ogeq; - default: assert(0); + default: return op; } } @@ -504,17 +496,13 @@ static Inst* brcom(Node *n, int ift, Inst *b) { Inst *bb = nil; - int op = n->op; Node nto={0}; - Node f = (Node){.op=Oconst,.val=!ift,.addable=Rconst,.ty=tbool}; + Node f = (Node){.op=Oconst,.addable=Rconst,.ty=tbool,.val=1}; - sumark(n); - if(op != Oconst){ - cmpcom(talloc(&nto, tbool, nil), n); - bb = genrawop(IBEQW, &nto, &f, nil); - }else{ - bb = genrawop(IBEQW, &f, n, nil); - } + if(ift) + f.val = 0; + ecom(talloc(&nto, tbool, nil), n); + bb = genrawop(IBEQW, &nto, &f, nil); bb->branch = b; tfree(&nto); return bb; @@ -668,6 +656,8 @@ scom(Node *n) case Oif: pushblock(); pushblock(); + n->l = simplifiy(n->l); + sumark(n->l); p = brcom(l, 1, nil); tfreenow(); popblock(); @@ -760,5 +750,4 @@ fncom(Decl *d) Decl *locs = concatdecl(d->locals, tdecls()); d->offset += idoffsets(locs, d->offset, IBY2WD); d->locals = locs; - printf("%d\n", d->offset); } diff --git a/dis.c b/dis.c index 74da130..a4b4be3 100644 --- a/dis.c +++ b/dis.c @@ -41,15 +41,15 @@ wr2(FILE *f, u16 v) fwrite(&v, 1, 2, f); } void -wr4(FILE *f, u32 v) +wr4(FILE *f, i32 v) { fwrite(&v, 1, 4, f); } void -disaddr(FILE* f, u32 m, Addr *a) +disaddr(FILE* f, i32 m, Addr *a) { - u32 val = 0; + i32 val = 0; switch(m){ case Anone: return; diff --git a/fib.yo b/fib.yo deleted file mode 100644 index e1f4480..0000000 --- a/fib.yo +++ /dev/null @@ -1,13 +0,0 @@ -package a - -fn main() int { - x := fib(10); - return x; -}; - -fn fib(n int) int{ - if n <= 1 { - return n; - }; - return fib(n-1) + fib(n-2); -}; diff --git a/file.c b/file.c index e8660fd..9ca3bcc 100644 --- a/file.c +++ b/file.c @@ -34,7 +34,7 @@ getfiles(char *path, char *sufix) int ll = strlen(path); int j = 1; s = new(sizeof(char*)); - d = opendir(path); + assert(d = opendir(path)); while((p=readdir(d)) != NULL){ if(issufix(p->d_name, sufix)){ s = realloc(s, (j+1)*sizeof(void*)); @@ -42,7 +42,7 @@ getfiles(char *path, char *sufix) char *n = new(l+ll+2); memcpy(n, path, ll); n[ll] = '/'; - memcpy(n+ll, p->d_name, l+1); + memcpy(n+ll+1, p->d_name, l+1); s[j-1] = n; s[j++] = nil; } @@ -50,4 +50,4 @@ getfiles(char *path, char *sufix) nsrc = j - 1; closedir(d); return s; -} \ No newline at end of file +} diff --git a/fn.h b/fn.h index b0d2de9..9321fae 100644 --- a/fn.h +++ b/fn.h @@ -83,8 +83,8 @@ int sharelocal(Decl *d); /* dis.c */ int disinst(FILE *out, Inst *in); void wr1(FILE *f, u8 v); -void wr4(FILE *f, u32 v); -void disaddr(FILE* f, u32 m, Addr *a); +void wr4(FILE *f, i32 v); +void disaddr(FILE* f, i32 m, Addr *a); /* gen.c */ void genstart(void); diff --git a/gen.c b/gen.c index c24b00d..0384a6f 100644 --- a/gen.c +++ b/gen.c @@ -238,6 +238,7 @@ genop(int op, Node *s, Node *m, Node *d) { [Olt] = {[Tint]=ILTW,[Tbool]=ILTW}, [Oeq] = {[Tint]=IEQW,[Tbool]=IEQW}, + [Oneq] = {[Tint]=INEQW,[Tbool]=INEQW}, [Oleq] ={[Tint]=ILEQW,[Tbool]=ILEQW}, [Oandand] = {[Tint]=IEQW,[Tbool]=IEQW}, [Ooror] = {[Tint]=IADDW,[Tbool]=IADDW}, @@ -273,25 +274,25 @@ addprint(FILE *f, int am, Addr *a) case Anone: return; case Afp: - fprintf(f, "%u(fp)", a->reg); + fprintf(f, "%d(fp)", a->reg); break; case Aimm: - fprintf(f, "$%u", a->offset); + fprintf(f, "$%d", a->offset); break; case Afpind: - fprintf(f, "%u(%u(fp))", a->offset, a->reg); + fprintf(f, "%d(%d(fp))", a->offset, a->reg); break; case Adesc: - fprintf(f, "$%u", a->offset+a->reg); + fprintf(f, "$%d", a->offset+a->reg); break; case Apc: - fprintf(f, "$%u", a->reg+a->offset); + fprintf(f, "$%d", a->reg+a->offset); break; case Amp: - fprintf(f, "%u(mp)",a->reg); + fprintf(f, "%d(mp)",a->reg); break; case Aldt: - fprintf(f, "$%u", a->reg); + fprintf(f, "$%d", a->reg); break; default: assert(0); diff --git a/isa.h b/isa.h index 5042bb6..fd9b687 100644 --- a/isa.h +++ b/isa.h @@ -32,6 +32,7 @@ enum IMOVM, ILTW, IEQW, + INEQW, ILEQW, IBEQW, IBNEQW, diff --git a/lex.c b/lex.c index 9b181c8..af976e6 100644 --- a/lex.c +++ b/lex.c @@ -330,4 +330,4 @@ importdef(Sym *file) assert(b != nil); assert(bstack + 1 < sizeof(bins)); bin = bins[++bstack] = b; -} \ No newline at end of file +} diff --git a/main.c b/main.c index 2bf495a..41d5acf 100644 --- a/main.c +++ b/main.c @@ -102,4 +102,5 @@ main(int argc, char **argv) genbin("obj"); asminst(stdout, firstinst); + asmexport(stdout, pkgname, fns, nfn); } diff --git a/makefile b/makefile index 9289ede..317de57 100644 --- a/makefile +++ b/makefile @@ -6,13 +6,12 @@ OBJS=$(SRCS:.c=.o) com: $(OBJS) $(CC) $(CFLAGS) -o $@ $^ make -C ./vm - cp ./vm/run . $(OBJS): yo.h isa.h fn.h dat.h tests: - ./com fib.yo - ./run obj + ./com ./test + ./vm/run obj clean: rm -f com $(OBJS) obj exported run diff --git a/parse.c b/parse.c index 301b0ed..0779bce 100644 --- a/parse.c +++ b/parse.c @@ -246,8 +246,8 @@ index(Node *id) assert(0); case ':': if(try((int[]){']',0}).kind) - return mkn(Oslice, id, mkn(Oseq, nil, nil)); - n = mkn(Oslice, id, mkn(Oseq, nil, expr())); + return mkn(Oslice, id, mkn(Oseq, mkconst(0), mkconst(-1))); + n = mkn(Oslice, id, mkn(Oseq, mkconst(0), expr())); break; default: l = expr(); @@ -257,7 +257,7 @@ index(Node *id) } want((int[]){':',0}); if(peek((int[]){']',0}).kind){ - n = mkn(Oslice, id, mkn(Oseq, l, nil)); + n = mkn(Oslice, id, mkn(Oseq, l, mkconst(-1))); break; } r = expr(); @@ -293,10 +293,10 @@ unrayexpr(void) switch(try((int[]){'+','-','*','/','&',0}).kind){ default: return primaryexprs(); case '+': - case '-': case '!': case '/': case '^': assert(0); + case '-': return mkn(Omul, mkconst(-1), unrayexpr()); case '*': return mkn(Oxref, unrayexpr(), nil); case '&': return mkn(Oref,unrayexpr(), nil); } @@ -587,12 +587,11 @@ paramdecl(void) static Decl* paramlist(void) { - Decl h={0}, *p = &h; - - p = p->next = paramdecl(); - for(;try((int[]){',',0}).kind==',';) - p = p->next = paramdecl(); - return h.next; + Decl *p = paramdecl(); + for(;try((int[]){',',0}).kind==',';){ + p =concatdecl(p, paramdecl()); + } + return p; } // "(" [parameterlist [ ',' ] ] ")" diff --git a/test/fib.yo b/test/fib.yo index 6f9658a..0a42718 100644 --- a/test/fib.yo +++ b/test/fib.yo @@ -1,13 +1,47 @@ -package a +package main + +type Any struct { + x,y int; + arr [8]int; +}; fn main() int { - x := fib(10); - return x; + arr := [8]int{}; + return nqueen(0, 0, arr[:]); }; fn fib(n int) int{ if n <= 1 { return n; }; - return fib(n-1) + return fib(n-2); + return fib(n-1) + fib(n-2); +}; + +fn nqueen(r,ans int, arr []int) int{ + if r == len(arr) { + return ans + 1; + }; + for c:=0; c < len(arr); c=c+1{ + arr[r] = c; + if canput(r, arr) { + ans = nqueen(r+1, ans, arr); + }; + }; + return ans; +}; + +fn canput(r int, arr []int) bool { + for i:=0; i < r; i=i+1 { + if arr[r] == arr[i] || abs(arr[r] - arr[i]) == abs(r - i) { + return false; + }; + }; + return true; +}; + +fn abs(x int) int { + if x < 0 { + return x * -1; + }; + return x; }; diff --git a/vm/dec.c b/vm/dec.c index 931a5d0..822be76 100644 --- a/vm/dec.c +++ b/vm/dec.c @@ -170,6 +170,18 @@ D91(void) R.m = R.FP+R.PC->reg; } static void +D92(void) +{ + R.s = (u8*)&R.PC->s.imm; + R.d = (u8*)&R.PC->d.imm; + R.m = R.FP+R.PC->reg; +} +static void +D93(void) +{ + R.s = (u8*)&R.PC->s.imm; +} +static void D95(void) { R.s = (u8*)&R.PC->s.imm; @@ -216,6 +228,8 @@ void (*dec[])(void) = [0x8A] = D8A, [0x8D] = D8D, [0x91] = D91, + [0x92] = D92, + [0x93] = D93, [0x95] = D95, [0xA9] = DA9, [0xAD] = DAD, diff --git a/vm/vm.c b/vm/vm.c index f4b9660..b196712 100644 --- a/vm/vm.c +++ b/vm/vm.c @@ -1,6 +1,6 @@ #include "vm.h" -static u8 end[1]; +static u8 end[1024]; u32 ninst; Inst *inst; REG R; @@ -47,10 +47,10 @@ rd2(FILE *f) assert(fread(&v, 1, 2, f) == 2); return v; } -u32 +WORD rd4(FILE *f) { - u32 v = 0; + i32 v = 0; assert(fread(&v, 1, 4, f) == 4); return v; } @@ -86,6 +86,7 @@ OP(bneqw) {if(W(s) != W(m)) JMP(d);} OP(ltw) {W(d) = (W(s) < W(m));} OP(leqw) {W(d) = (W(s) <= W(m));} OP(eqw) {W(d) = (W(s) == W(m));} +OP(neqw) {W(d) = (W(s) != W(m));} OP(frame){ Stack *s; Frame *f; @@ -116,6 +117,7 @@ OP(ret) { R.FP = f->fp; if(R.FP == NULL){ printf("result %ld\n", W(d)); + WORD *p = end; exit(0); } R.SP = (u8*)f; @@ -150,7 +152,8 @@ OP(slice){ if(s2 == -1) s2 = a->len; assert(s1 >= 0 && s1 < a->len); - assert(s2 >= 0 && s2 < a->len); + assert(s2 >= 0 && s2 <= a->len); + assert(s1 < s2); Array d = *a; d.len = s2 - s1; d.cap = s2 - s1; @@ -175,6 +178,7 @@ static void (*optab[])(void) = { [IBEQW] = beqw, [IBNEQW] = bneqw, [IEQW] = eqw, + [INEQW] = neqw, [ILEQW] = leqw, [ILTW] = ltw, }; diff --git a/vm/vm.h b/vm/vm.h index 498aed3..e3dd200 100644 --- a/vm/vm.h +++ b/vm/vm.h @@ -61,7 +61,7 @@ struct REG u8 *TS; u8 *EX; void *s, *d, *m; - int t, dt ,mt; + WORD t, dt ,mt; }; struct Array