as:add namespaced labels

This commit is contained in:
Kitty-Cricket Piapiac 2023-03-23 02:33:33 -07:00
parent d13d7448a0
commit 69d31978ad
5 changed files with 44 additions and 26 deletions

22
as.c
View File

@ -26,12 +26,16 @@ _ 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 WH(!ws((*p)[*l]),++*l);
R*t;}
typedef struct{W a;}Label;
typedef struct l{W a;struct l*p;Ht c;}Label;
typedef struct{Vec ws;}Macro;
typedef struct{S n;W a;}Ref;
Ht labels;
typedef struct{S n;W a;Label*p;}Ref;
Label*label;
Ht macros;
Vec refs;
_ V lini(Label*l){l->a=mel,l->p=label,hini(&l->c,2,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;}
_ V rini(Ref*r,S n){*r=(Ref){n,mel,label};}
#define BE(y,...)Q(seql(Sl(y),x),__VA_ARGS__)OR
_ V frun(F);
@ -46,16 +50,17 @@ _ V pass1(S*t){S x=*t;B c,o;c=*x.p;
Q('{'==c,/*discard*/)OR
Q('"'==c,mcpy(mel,x.p+1,x.l-=2),mel+=x.l)OR
Q('#'==c,B bs[tz(x)];tto4b(x,bs),mcpy(mel,bs,SZ(bs)),mel+=SZ(bs))OR
Q(':'==c,++x.p,--x.l,hput(&labels,x,&(Label){mel}))OR
Q('@'==c,++x.p,--x.l,vput(&refs,&(Ref){x,mel}),mel+=4)OR
Q('!'==c,Macro m={0};++x.p,--x.l,vini(&m.ws,8,SZ(S));WH(';'!=*next(t).p,vput(&m.ws,t));hput(&macros,x,&m);)OR
Q(':'==c,++x.p,--x.l,lini(hput(&label->c,x)))OR
Q('@'==c,++x.p,--x.l,rini(vput(&refs),x),mel+=4)OR
Q('!'==c,Macro m={0};++x.p,--x.l,vini(&m.ws,8,SZ(S));WH(';'!=*next(t).p,*(S*)vput(&m.ws)=*t)*(Macro*)hput(&macros,x)=m;)OR
Q('`'==c,Macro*m;++x.p,--x.l;Q(m=Hget(Macro,macros,x),Vfor(S,m->ws,y,i,pass1(&y)))OR tw(x),die(" unknown macro"))OR
Q('-'==c,builtin(t))OR
Q(';'==c,N(label->p,die("; at top-level"))label=label->p)OR
Q(2!=x.l||OPSZ==(o=op(x.p)),tw(x),die(" unknown inst"))OR
mb(mel++,o);}
_ V pass2(V){Label*l;
Vfor(Ref,refs,r,i,Q(l=Hget(Label,labels,r.n),mw(r.a,l->a))OR tw(r.n),die(" unknown ref"))}
Vfor(Ref,refs,r,i,Q(l=lget(r.p,r.n),mw(r.a,l->a))OR tw(r.n),die(" unknown ref"))}
_ V frun(F f){B*in;W l;S t={0};
fseek(f,0,SEEK_END),l=ftell(f),fseek(f,0,SEEK_SET),in=mk(l+1),fread(in,1,l,f),in[l]=0,t.p=in;
@ -63,7 +68,8 @@ _ V frun(F f){B*in;W l;S t={0};
I main(I ac,C**av){FILE *f;
Q(3!=ac,die("usage: as INPUT.ASM OUTPUT.ROM"))
hini(&labels,64,SZ(Label)),hini(&macros,64,SZ(Macro)),vini(&refs,64,SZ(Ref));
label=&(Label){0,0,{0}};
hini(&label->c,64,SZ(Label)),hini(&macros,64,SZ(Macro)),vini(&refs,64,SZ(Ref));
WIF(f,av[1],"rb",frun(f);)
WIF(f,av[2],"wb",fwrite(meb+0x100,1,mel-0x100,f))
printf("done: %d bytes wrote\n",mel-0x100);

22
t/u.c
View File

@ -1,17 +1,22 @@
#include"../u.h"
#define AEQ(a,b)Q((a)!=(b),die("assertion failed at line %d",__LINE__))
#define AEQ(a,b)Q((a)!=(b),die("assertion failed at line %d\n",__LINE__))
V tsl(V){
AEQ(4,Sl("meow").l);}
V tseql(V){
AEQ(0,seql(Sl("meow"),Sl("rewr")));
AEQ(1,seql(Sl("meow"),Sl("meow")));}
V tsnxt(V){
S n=Sl("meow/rewr/:3");
AEQ(1,seql(Sl("meow"),snxt(n,'/')))
AEQ(1,seql(Sl("rewr"),snxt(S0,'/')))
AEQ(1,seql(Sl(":3"),snxt(S0,'/')))
AEQ(0,snxt(S0,'/').l)}
V thputget(V){Ht h;
hini(&h,4,SZ(W));
hput(&h,Sl("meow"),(W[]){1});
hput(&h,Sl("rewr"),(W[]){2});
V thputgetgrw(V){Ht h;
hini(&h,1,SZ(W));
*(W*)hput(&h,Sl("meow"))=1;
*(W*)hput(&h,Sl("rewr"))=2;
AEQ(1,*Hget(W,h,Sl("meow")));
AEQ(2,*Hget(W,h,Sl("rewr")));}
V thgetnul(V){Ht h;
@ -19,7 +24,7 @@ V thgetnul(V){Ht h;
AEQ(0,Hget(W,h,Sl("meow")));}
V thgrw(V){Ht h;
hini(&h,2,SZ(W));
hput(&h,Sl("meow"),(W[]){1});
*(W*)hput(&h,Sl("meow"))=1;
hgrw(&h,8);
AEQ(1,*Hget(W,h,Sl("meow"))); }
@ -27,8 +32,9 @@ I main(V){
/*S*/
tsl();
tseql();
tsnxt();
/*Ht*/
thputget();
thputgetgrw();
thgetnul();
thgrw();
}

9
u.c
View File

@ -1,12 +1,13 @@
#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,V*a){Q(v->l>=v->c,vgrw(v,(v->c*3)/2))memcpy(vget(*v,v->l++),a,v->z);}
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(;i<x.l;++i){N(d==x.p[i],b=i;for(;i<x.l;++i)Q(d==x.p[i],break)R(S){i-b,x.p+b})}R S0;}
W fnv1a(S s){W h=16777619;Sfor(s,c,i,h^=c,c*=2166136261)R h;}
V hini(Ht*h,W c,W z){*h=(Ht){z,c,0,mk(c*SZ(S)),mk(c*z)};}
V hgrw(Ht*h,W c){Ht j=*h;h->k=mk(c*SZ(S)),h->v=mk(c*h->z),h->c=c;Hfor(j,k,v,i,hput(h,k,v));del(j.k),del(j.v);}
V hput(Ht*h,S k,V*v){W c;W i=hind(*h,k);Q((c=h->c*3/2)<h->l++,hgrw(h,c))h->k[i]=k,memcpy(h->v+i*h->z,v,h->z);}
W hind(Ht h,S k){W j,i=fnv1a(k);x:j=i%h.c;Q(0!=h.k[j].l&&!seql(k,h.k[j]),++i;goto x)R j;}
V hgrw(Ht*h,W c){Ht j=*h;h->k=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;}

6
u.h
View File

@ -5,13 +5,15 @@ typedef struct{W z,c,l;B*p;}Vec;
#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 vput(Vec*,V*);
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;
@ -19,6 +21,6 @@ typedef struct{W z,c,l;S*k;B*v;}Ht;
#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);
V hput(Ht*,S,V*);
W hind(Ht,S);
V*hget(Ht,S);
V*hput(Ht*,S);

View File

@ -5,15 +5,18 @@
{ source code }
-org #100 { `-org` is an assembler built-in that sets the origin }
:entry { `:entry` is a label definition }
pw @hello { `pw` is an instruction, and all words with no }
pw @data/hello { `pw` is an instruction, and all words with no }
{ colour prefix are treated as such. }
:loop
du fb
du no pw @end jc { `@end` is a 32-bit reference to `:end` below }
`term:0 io `inc { `term literally includes `pb #0` from dev.inc }
pw @loop ju
:end
; :end
dd dd
ex
; ex
;
:hello "hello, world!" `nl #00
:data
:hello "hello, world!" `nl #00 ;
;