mirror of https://git.cro.wtf/kip.git
as:fix -inc bug&fmt
This commit is contained in:
parent
18eac84dec
commit
48a9197068
11
a.c
11
a.c
|
@ -1,13 +1,12 @@
|
|||
#include"a.h"
|
||||
#undef malloc
|
||||
#undef realloc
|
||||
#undef free
|
||||
#undef fopen
|
||||
#undef chdir
|
||||
NR V die(IM C*f,...)VA(f,vfprintf(stderr,f,ap),fputc('\n',stderr),exit(1))
|
||||
V asrt(B b,IM C*m){N(b,die(m))}
|
||||
V*mk(W sz){V*p;N(p=calloc(1,sz),die("oom"))R p;}
|
||||
V*remk(V*p,W sz){N(p=realloc(p,sz),die("oom"))R p;}
|
||||
V del(V*p){free(p);}
|
||||
F xopen(IM C*n,IM C*p){F f;N(f=fopen(n,p),die("unable to open file `%s`",n))R f;}
|
||||
V xcd(IM C*n){Q(chdir(n),die("unable to cd into directory `%s`",n));}
|
||||
F xopen(IM C*n,IM C*p){F f;N(f=fopen(n,p),die("unable to open file `%s`",n))R f;}
|
||||
V xpc(F f,B c){Q(c!=fputc(c,f),die("error writing to file"))}
|
||||
V xr(F f,V*p,W z,W n){Q(n>fread(p,z,n,f),die("error reading from file"))}
|
||||
V xw(F f,V*p,W z,W n){Q(n>fwrite(p,z,n,f),die("error writing to file"))}
|
||||
V xww(F f,W w){xpc(f,w<<24),xpc(f,w<<16),xpc(f,w<<8),xpc(f,w);}
|
||||
|
|
11
a.h
11
a.h
|
@ -28,10 +28,9 @@ V asrt(B,IM C*);
|
|||
V*mk(W);
|
||||
V*remk(V*,W);
|
||||
V del(V*);
|
||||
F xopen(IM C*,IM C*);
|
||||
V xcd(IM C*);
|
||||
#define malloc B use_mk_instead[-1]
|
||||
#define realloc B use_remk_instead[-1]
|
||||
#define free B use_del_instead[-1]
|
||||
#define fopen B use_xopen_instead[-1]
|
||||
#define chdir B use_xcd_instead[-1]
|
||||
F xopen(IM C*,IM C*);
|
||||
V xpc(F,B);
|
||||
V xr(F,V*,W,W);
|
||||
V xw(F,V*,W,W);
|
||||
V xww(F,W);
|
||||
|
|
68
as.c
68
as.c
|
@ -1,77 +1,71 @@
|
|||
#include"u.h"
|
||||
|
||||
#define BE(y,...)Q(seql(Sl(y),x),__VA_ARGS__)OR
|
||||
#define MEMSZ 0x40000
|
||||
#define OPSZ 36
|
||||
|
||||
typedef struct l{W a;struct l*p;Ht c;}Label;
|
||||
typedef struct{Vec ws;}Macro;
|
||||
typedef struct{S n;W a;Label*p;}Ref;
|
||||
|
||||
_ B orq=0,meb[MEMSZ];
|
||||
_ W org=0,mel;
|
||||
V mb(W i,B b){Q(i>=MEMSZ||i<org,die("memory overflow or underflow {ip=%x}",i))meb[i-org]=b;}
|
||||
V mh(W i,H h){mb(i,h>>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;i<l;++i)mb(dst+i,src[i]);}
|
||||
_ Label*label;
|
||||
_ Ht macros;
|
||||
_ Vec refs;
|
||||
_ V finp(F);
|
||||
|
||||
#define OPSZ 36
|
||||
_ V mb(W i,B b){Q(i>=MEMSZ||i<org,die("memory overflow or underflow {ip=%x}",i))meb[i-org]=b;}
|
||||
_ V mh(W i,H h){mb(i,h>>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;i<l;++i)mb(dst+i,src[i]);}
|
||||
_ V rini(Ref*r,S n){*r=(Ref){n,mel,label};}
|
||||
_ 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;}
|
||||
_ B ops[OPSZ*2]="npexpbphpwfbfhfwmbmhmwioiissdrswduovadsumudianorxrslsrsaeqltgtnojujccacc";
|
||||
_ B op(B x[2]){W i=0;WH(i++<OPSZ,Q(ops[i*2]==x[0]&&ops[1+i*2]==x[1],R i));R OPSZ;}
|
||||
_ B htob(B h){R h>='a'&&h<='f'?h-'a'+10:h>='A'&&h<='F'?h-'F'+10:h>='0'&&h<='9'?h-'0':16;}
|
||||
_ B ws(B x){R' '==x||'\t'==x||'\r'==x||'\n'==x;}
|
||||
|
||||
_ V tw(S t){fprintf(stderr,"`%.*s`",t.l,t.p);}
|
||||
_ V tasrt(S t,C c){Q(c!=*t.p,tw(t),die(" expected %c",c))}
|
||||
_ B tz(S t){R t.l<4?1:t.l<6?2:t.l<10?4:(tw(t),die(" >=32 bits"),0);}
|
||||
_ V tto4b(S w,B*bs){W b;++w.p,--w.l;Sfor(w,a,i,Q(16>(b=htob(a)),bs[i/2]=(i%2?bs[i/2]:0)<<4|b)OR tw(w),die(" unknown char `%c`\n",a))}
|
||||
_ W tton(S w){W b;W r;r=0,++w.p,--w.l;Sfor(w,a,i,Q(16>(b=htob(a)),r<<=4,r|=b)OR tw(w),die(" unknown char `%c`\n",a));R r;}
|
||||
|
||||
_ 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,++*l;
|
||||
Q(0==c,R*t)OR
|
||||
Q('"'==c,WH('"'!=(*p)[(*l)++],))OR
|
||||
Q('{'==c,WH('}'!=(*p)[(*l)++],))OR WH(!ws((*p)[*l]),++*l);
|
||||
R*t;}
|
||||
|
||||
typedef struct l{W a;struct l*p;Ht c;}Label;
|
||||
typedef struct{Vec ws;}Macro;
|
||||
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);
|
||||
_ V builtin(S*t){FILE*f;S y,x=*t;++x.p,--x.l;
|
||||
BE("org",tasrt(next(t),'#'),mel=tton(*t);N(orq,orq=1,org=mel))
|
||||
BE("res",tasrt(next(t),'#'),mel+=tton(*t))
|
||||
BE("emb",tasrt(y=next(t),'"'),y.p[y.l-1]=0;WIF(f,(C*)y.p+1,"rb",mel+=fread(meb+mel,1,(W)0-1,f)))
|
||||
BE("inc",tasrt(y=next(t),'"'),y.p[y.l-1]=0;WIF(f,(C*)y.p+1,"rb",frun(f)))
|
||||
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))
|
||||
BE("emb",y=next(t),tasrt(y,'"'),y.p[y.l-1]=0;WIF(f,(C*)y.p+1,"rb",mel+=fread(meb+mel,1,(W)0-1,f)))
|
||||
BE("inc",y=next(t),tasrt(y,'"'),y.p[y.l-1]=0;WIF(f,(C*)y.p+1,"rb",finp(f)))
|
||||
tw(x),die(" unknown builtin");}
|
||||
|
||||
_ 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),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,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(¯os,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,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,builtin(t))OR
|
||||
Q(';'==c,N(label->p,die("; at top-level"))label=label->p)OR
|
||||
Q('~'==c,++x.p,--x.l,o|=0x40,pass1(&x))OR
|
||||
Q(2!=x.l||OPSZ==(o|=op(x.p)),tw(x),die(" unknown inst"))OR
|
||||
mb(mel++,o),o=0;}
|
||||
|
||||
_ V pass2(V){Label*l;
|
||||
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;
|
||||
WH(0!=*next(&t).p,pass1(&t));pass2();}
|
||||
|
||||
_ V finp(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),xr(f,in,1,l),in[l]=0,t.p=in;
|
||||
WH(0!=*next(&t).p,pass1(&t))}
|
||||
_ V fout(F f){pass2();xw(f,meb,1,mel-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));
|
||||
WIF(f,av[1],"rb",frun(f);)
|
||||
WIF(f,av[2],"wb",fwrite(meb,1,mel-org,f))
|
||||
WIF(f,av[1],"rb",finp(f))
|
||||
WIF(f,av[2],"wb",fout(f))
|
||||
printf("done: %d bytes wrote\n",mel-org);
|
||||
R 0;}
|
||||
|
|
Loading…
Reference in New Issue