diff --git a/a.h b/a.h index 025fcfe..40f33b7 100644 --- a/a.h +++ b/a.h @@ -1,4 +1,3 @@ -#include #include #include #include @@ -25,7 +24,6 @@ typedef int16_t Hs; typedef uint32_t W; typedef int32_t Ws; typedef FILE*F; - NR V die(IM C*,...); V asrt(B,IM C*); V*mk(W); diff --git a/as.c b/as.c index ab250b3..d2a84bb 100644 --- a/as.c +++ b/as.c @@ -1,27 +1,39 @@ -#include"u.h" -#define BE(y,...)Q(seql(Sl(y),x),__VA_ARGS__)OR +#include"a.h" +#define Aget(T,a,i)*(T*)aget((a),i) +#define Afop(T,a,x,i,...)for(W i=0;i<(a)->l;++i){T*x=aget((a),i);__VA_ARGS__;} +#define Afor(T,a,x,i,...)for(W i=0;i<(a).l;++i){T x=Aget(T,&(a),i);__VA_ARGS__;} +#define Nt(T,p)((T*)(p)->v) +#define S0 (S){0,0} +#define Sl(s)(S){SZ(s)-1,(B*)(s)} +#define Sfor(s,x,i,...)W i;for(i=0;ip+(a->z*i);} +_ V*aput(A*a){Q(2*a->l>a->c,a->c*=2,a->p=remk(a->p,a->c*a->z))R aget(a,a->l++);} +_ C scmp(S a,S b){Q(a.l!=b.l,R b.l-a.l;)Sfor(a,c,i,Q(c!=b.p[i],R b.p[i]-a.p[i];))R 0;} +_ N*nnew(S k,W z){N*n;n=mk(z+SZ(N)),n->k=k;R n;} +_ N*nget(T n,S k ){ C c;WH(n,Q(0==(c=scmp(k,n->k)),R n);n=0l:n->r)R 0;} +_ N*nput(T*t,S k,W z){N*o=0,*n=*t;C c;WH(n,Q(0==(c=scmp(k,n->k)),R 0)o=n,n=0l:n->r)R*(!o?t:0l:&o->r)=nnew(k,z);} +_ S snxt(S s,B d){_ S x;_ W i;W b;Q(s.l,i=0,x=s);for(;i=MEMSZ||i>8),mb(i+1,h);} _ V mw(W i,W w){mh(i,w>>16),mh(i+2,w);} _ V mcpy(W dst,B*src,W l){for(W i=0;ia=mel,l->p=label,hini(&l->c,4,SZ(Label)),label=l;} -_ Label*lget(Label*l,S n){S x;Label*p=l;x=snxt(n,'/'); - WH(p,Q(l=hget(p->c,x),break)p=p->p)N(l,R l)WH((x=snxt(S0,'/')).l,Q(l,l=hget(l->c,x))OR R 0)R l;} +_ L*lget(N*p,S k){S x;N*l;x=snxt(k,'/');N(p,p=root)WH(p,Q(l=nget(p,x),break;);p=Nt(L,p)->p)WH(l&&(x=snxt(S0,'/')).l,l=nget(l,x))R(L*)(l?l->v:0);} _ B ops[OPSZ*2]="npexpbphpwprfbfhfwmbmhmwioiissdrswduovadsumudianorxrslsrsaeqltgtnojujccacc"; _ B op(B x[2]){W i=0;WH(i++='a'&&h<='f'?h-'a'+10:h>='A'&&h<='F'?h-'F'+10:h>='0'&&h<='9'?h-'0':16;} @@ -36,6 +48,7 @@ _ S next(S*t){B c,**p;W*l;l=&t->l,p=&t->p;*p+=*l,*l=0;WH(ws(**p),++*p);c=**p,++* Q('"'==c,WH('"'!=(*p)[(*l)++],))OR Q('{'==c,WH('}'!=(*p)[(*l)++],))OR WH(!ws((*p)[*l]),++*l); R*t;} +_ V finp(F); _ V builtin(S*t){FILE*f;S y,x=*t;++x.p,--x.l; BE("org",y=next(t),tasrt(y,'#'),mel=tton(*t);N(orq,orq=1,org=mel)) BE("res",y=next(t),tasrt(y,'#'),mel+=tton(*t)) @@ -46,18 +59,18 @@ _ V pass1(S*t){_ B o=0;S x=*t;B c;c=*x.p; Q('{'==c,/*discard*/)OR Q('"'==c,mcpy(mel,x.p+1,x.l-=2),mew=mel+=x.l)OR Q('#'==c,B bs[tz(x)];tto4b(x,bs),mcpy(mel,bs,SZ(bs)),mew=mel+=SZ(bs))OR - Q(':'==c,++x.p,--x.l,lini(hput(&label->c,x)))OR - Q('@'==c,++x.p,--x.l,rini(vput(&refs),0,x),mew=mel+=4)OR - Q('^'==c,++x.p,--x.l,rini(vput(&refs),1,x),mew=mel+=1)OR - Q('!'==c,Macro*m;++x.p,--x.l,m=hput(¯os,x);vini(&m->ws,8,SZ(S));WH(';'!=*next(t).p,*(S*)vput(&m->ws)=*t))OR - Q('`'==c,Macro*m;++x.p,--x.l;Q(m=hget(macros,x),Vfor(S,m->ws,y,i,pass1(&y)))OR tw(x),die(" unknown macro"))OR + Q(':'==c,N*l;++x.p,--x.l;N(l=nput(&root,x,SZ(L)),tw(x),die(" duplicate label"))*Nt(L,l)=(L){root,mel},root=l)OR + Q('!'==c,N*m;++x.p,--x.l;N(m=nput(¯os,x,SZ(A)),tw(x),die(" duplicate macro"))aini(Nt(A,m),8,SZ(S));WH(';'!=*next(t).p,*(S*)aput(Nt(A,m))=*t))OR + Q('@'==c,++x.p,--x.l,*(P*)aput(&refs)=(P){0,root,mel,x},mw(mel,0),mew=mel+=4)OR + Q('^'==c,++x.p,--x.l,*(P*)aput(&refs)=(P){1,root,mel,x},mb(mel,0),mew=mel+=1)OR + Q('`'==c,N*m;++x.p,--x.l;N(m=nget(macros,x),tw(x),die(" unknown macro"))Afor(S,*Nt(A,m),y,i,pass1(&y)))OR Q('-'==c,builtin(t))OR - Q(';'==c,N(label->p,die("; at top-level"))label=label->p)OR + Q(';'==c,N(root,die("; at top-level"))root=((L*)root->v)->p)OR Q('~'==c,++x.p,--x.l,o|=0x40,pass1(&x))OR Q('$'==c,++x.p,--x.l,o|=0x80,pass1(&x))OR Q(2!=x.l||OPSZ==(o|=op(x.p)),tw(x),die(" unknown inst"))OR mb(mel++,o),mew=mel,o=0;} -_ V pass2(V){Label*l;Ws a;Bs b;Vfor(Ref,refs,r,i,Q(l=lget(r.p,r.n), +_ V pass2(V){L*l;Ws a;Bs b;Afor(P,refs,r,i,Q(l=lget(r.p,r.n), Q(0==r.r,mw(r.a,l->a))OR Q(1==r.r,a=l->a-r.a;Q(a==(b=a),mb(r.a,b))OR tw(r.n),die(" too far (%d bytes) for ^ref",a)))OR tw(r.n),die(" unknown ref"))} @@ -67,8 +80,7 @@ _ V finp(F f){B*in;W l;S t={0}; _ V fout(F f){pass2();xw(f,meb,1,mew-org);} I main(I ac,C**av){FILE *f; Q(3!=ac,die("usage: as INPUT.ASM OUTPUT.ROM")) - label=&(Label){0,0,{0}}; - hini(&label->c,64,SZ(Label)),hini(¯os,64,SZ(Macro)),vini(&refs,64,SZ(Ref)); + aini(&refs,64,SZ(P)); WIF(f,av[1],"rb",finp(f)) WIF(f,av[2],"wb",fout(f)) printf("done: %d bytes wrote\n",mew-org); diff --git a/meson.build b/meson.build index f87c48a..d60a8f8 100644 --- a/meson.build +++ b/meson.build @@ -5,7 +5,6 @@ project('kip','c',version:'0.0.1', 'werror=true']) sdl2=dependency('sdl2') liba=library('a','a.c') -libu=library('u','u.c',link_with:liba) executable('kip', 'kip.c', 'kip-io-disk.c', @@ -17,6 +16,4 @@ executable('kip', link_with:liba) executable('as', 'as.c', - link_with:libu) - -test('libu',executable('u','t/u.c',link_with:libu)) + link_with:liba) diff --git a/u.c b/u.c deleted file mode 100644 index b87ce73..0000000 --- a/u.c +++ /dev/null @@ -1,13 +0,0 @@ -#include"u.h" -V vini(Vec*v,W c,W z){*v=(Vec){z,c,0,mk(c*z)};} -V vgrw(Vec*v,W c){v->p=remk(v->p,c*v->z),v->c=c;} -V*vput(Vec*v){Q(v->l>=v->c,vgrw(v,(v->c*3)/2))R vget(*v,v->l++);} -V*vget(Vec v,W i){R v.p+(v.z*i);} -B seql(S a,S b){Q(a.l!=b.l,R 0)Sfor(a,c,i,Q(c!=b.p[i],R 0))R 1;} -S snxt(S s,B d){_ S x;_ W i;W b;Q(s.l,i=0,x=s);for(;ik=mk(c*SZ(S)),h->v=mk(c*h->z),h->c=c;Hfor(j,k,v,i,memcpy(hput(h,k),v,h->z));del(j.k),del(j.v);} -W hind(Ht h,S k){W j,i=fnv1a(k);do j=i%h.c;while(i++,h.k[j].l&&!seql(k,h.k[j]));R j;} -V*hget(Ht h,S k){W i=hind(h,k);R h.k[i].l?h.v+i*h.z:0;} -V*hput(Ht*h,S k){W i;Q((++h->l)*3/2>=h->c,hgrw(h,h->c*3/2))i=hind(*h,k),h->k[i]=k;R h->v+i*h->z;} diff --git a/u.h b/u.h deleted file mode 100644 index a609bc4..0000000 --- a/u.h +++ /dev/null @@ -1,26 +0,0 @@ -#include"a.h" - -typedef struct{W z,c,l;B*p;}Vec; -#define Vget(T,v,i)*(T*)vget((v),i) -#define Vfor(T,v,x,i,...)for(W i=0;i<(v).l;++i){T x=Vget(T,v,i);__VA_ARGS__;} -V vini(Vec*,W,W); -V vgrw(Vec*,W); -V*vget(Vec,W); -V*vput(Vec*); - -typedef struct{W l;B*p;}S; -#define S0 (S){0,0} -#define Sl(s)(S){SZ(s)-1,(B*)(s)} -#define Sfor(s,x,i,...)W i;for(i=0;i<(s).l;++i){B x=s.p[i];__VA_ARGS__;} -B seql(S,S); -S snxt(S,B); -W fnv1a(S); - -typedef struct{W z,c,l;S*k;B*v;}Ht; -#define Hget(T,h,i)(T*)hget((h),(i)) -#define Hfor(h,n,v,i,...)for(W i=0;i<(h).c;++i){S n=(h).k[i];Q(k.l,B*v=(B*)((h).v+i*(h).z);__VA_ARGS__;)} -V hini(Ht*,W,W); -V hgrw(Ht*,W); -W hind(Ht,S); -V*hget(Ht,S); -V*hput(Ht*,S);