can run fibonacci sequence, nqueen
This commit is contained in:
parent
1bff7d30e7
commit
00f87d4e55
12
asm.c
12
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
17
assert.c
17
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);
|
||||
|
||||
27
com.c
27
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);
|
||||
}
|
||||
|
||||
6
dis.c
6
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;
|
||||
|
||||
13
fib.yo
13
fib.yo
@ -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);
|
||||
};
|
||||
4
file.c
4
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;
|
||||
}
|
||||
|
||||
4
fn.h
4
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);
|
||||
|
||||
15
gen.c
15
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);
|
||||
|
||||
1
main.c
1
main.c
@ -102,4 +102,5 @@ main(int argc, char **argv)
|
||||
genbin("obj");
|
||||
|
||||
asminst(stdout, firstinst);
|
||||
asmexport(stdout, pkgname, fns, nfn);
|
||||
}
|
||||
|
||||
5
makefile
5
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
|
||||
|
||||
19
parse.c
19
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 [ ',' ] ] ")"
|
||||
|
||||
42
test/fib.yo
42
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;
|
||||
};
|
||||
|
||||
14
vm/dec.c
14
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,
|
||||
|
||||
12
vm/vm.c
12
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,
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user