Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<stdio.h>
- #include<stdlib.h>
- #include<string.h>
- #include<setjmp.h>
- #include<ctype.h>
- #include<gc.h>
- #include<unicode/ustdio.h>
- #include<unicode/ustring.h>
- #define free
- typedef UChar UC;
- typedef UC*US;
- typedef char C;
- typedef C*S;
- #define CUS const US
- typedef S*SS;
- typedef int I;
- typedef long long L;
- typedef double D;
- typedef size_t Z;
- typedef void U;
- typedef U*P;
- typedef P*PS;
- typedef enum{N,Y}B;
- #define R return
- #define BK break
- #define SW(e) switch(e) {
- #define CS(e) case e:
- #define DO(v) for(I v=0;;){
- #define EL default:
- #define ES }else{
- #define EIF(e) }else if(e){
- #define WH(e) while(e){
- #define WY while(Y){
- #define NL() putchar('\n')
- jmp_buf J;
- L ln, cl;
- B ir=N;
- US erh;
- #define sh(s)erh=u8_strdup(s); //set help
- #define eh()erh=u8_strconv_from_locale(""); //erase help
- U e(S s){fprintf(stderr,"|%s\n",s);if(u8_strlen(erh)>0){fprintf(stderr,"|\t%s\n",erh);free(erh);eh();}if(ir)longjmp(J,1);else exit(1);} //report error
- #define XE e("syntax error")
- #define TE e("type error")
- #define PE e("parse error")
- #define SPE e("spelling error")
- #define DE e("domain error")
- #define SE e("stack error")
- #define YE e("syntax error")
- #define ME e("memory error")
- #define IE e("arity error")
- #define BE e("balance error")
- P al(Z z){P r;if(!(r=GC_MALLOC(z)))ME;R r;} //alloc
- P als(Z z){R al(sizeof(C)*(z+1));} //alloc str
- P alu(Z z){R al(sizeof(UC)*(z+1));} //alloc ustr
- #define rl(p,z)if(!(p=GC_REALLOC(p,z)))ME; //realloc
- #define FR(e) // nope
- #define MC(s,d,c) memcpy(s,d,c)
- #define SL(e) strlen(e)
- #define USL(e) u8_strlen(e)
- #define SZ(e) sizeof(e)
- #define NUL(e) memcpy(e,0,SZ(e))
- #define NLU(e,s) memcpy(e,0,s)
- #define NLS(e) e[0]=0
- #define MZ 2048
- US rel(){Z z;S r=als(MZ);if(!fgets(r,MZ,stdin)){if(feof(stdin)){*r=0;R u8_strconv_from_locale(r);}else DE;}z=strlen(r);if(r[z-1]=='\n')r[z-1]=0;if(z>1&&r[z-2]=='\r')r[z-2]=0;R u8_strconv_from_locale(r);} //read line
- typedef struct{PS s;Z t,z;}AE; // stack element
- typedef AE*A; // stack
- A ma(Z z){A s=al(sizeof(AE));s->s=al(z*sizeof(P));
- s->t=0;s->z=z;R s;} //make stack
- U u(A s,P v){if(v==NULL)R;if(s->t+1>s->z)SE;s->s[s->t++]=v;} //put
- P t(A s){if(s->t==0)SE;R s->s[--s->t];} //take
- P sk(A s){if(s->t==0)SE;R s->s[s->t-1];} //seek
- Z l(A s){R s->t;} //len
- U fa(A s){FR(s->s);FR(s);} //free stack
- A Ma=0; //main stack
- typedef enum{TD,TS,TL,TC,TP,TV}T; // type
- typedef struct VB VB;typedef VB* V;
- typedef V(*DYAD)(V,V);
- typedef V(*MONAD)(V);
- V mvv(UC o);
- struct VB{T t;union{D d;struct{UC o;I a;DYAD d;MONAD m;}v;struct{US s;Z z;}s;A l;struct{V x,y;}p;};};typedef VB*V; // value
- US tos(V m,B q){
- Z z;I i;US b,t;Z lx;US tx;
- SW(m->t)
- CS(TV)b=alu(2);b[0]=m->v.o;b[1]=0;BK;
- CS(TD)b=alu(MZ);sprintf(b,"%.15g",m->d);if(b[0]=='-')b[0]='_';BK;
- CS(TS)b=alu(m->s.z+(q?4:0));if(q)b[0]='\'';MC(b+1,m->s.s,m->s.z);if(q)b[u8_strlen(b)]='\'';b[u8_strlen(b)]=0;BK;
- CS(TL)b=alu(1);b[0]='[';z=1;for(i=0;i<l(m->l);++i){Z l;if(i){rl(b,z+1);b[z++]=' ';}t=tos(m->l->s[i],Y);l=u8_strlen(t);rl(b,z+l);MC(b+z,t,l);z+=l;FR(t);}rl(b,z+2);b[z]=']';b[z+1]=0;BK;
- CS(TC)b=alu(m->s.z+3);b[0]='{';MC(b+1,m->s.s,m->s.z);MC(b+1+m->s.z,"}",2);BK;
- CS(TP)t=tos(m->p.x,Y);tx=tos(m->p.x,Y);z=u8_strlen(t);lx=u8_strlen(tx);b=al(z+lx+5);sprintf(b,"(%s: %s)",t,tx);FR(t);FR(tx);BK;
- EL DE;}
- R b;
- } //value to str
- V mv(){R al(SZ(VB));} //make value
- V mvd(D d){V m=mv();m->t=TD;m->d=d;R m;} //make number value
- V mcv(US s,Z z){V m=mv();m->t=TC;m->s.s=u8_strdup(s);
- m->s.z=z;R m;} //make code value
- V mvcn(US s,Z z){V m=mv();m->t=TC;
- m->s.s=s;m->s.z=z;R m;} //make code (non-copy) value
- V mvs(US s){V m=mv();m->t=TS;m->s.s=u8_strdup(s);
- m->s.z=u8_strlen(s);R m;} //make str value
- V msc(UC c){UC b[]={c,0};R mvs(b);} //make str value from char
- V mvl(A l){V m=mv();m->t=TL;m->l=l;R m;} //make list value
- V mvp(V x,V y){V m=mv();m->t=TP;
- m->p.x=x;m->p.y=y;R m;} //make pair value
- Z ll(V s){R l(s->l);} //list len
- V lat(V s,Z i){R s->l->s[i];} //list at
- U frm(V m){
- SW(m->t)
- CS(TS)CS(TC)FR(m->s.s);BK;
- CS(TL)while(l(m->l))frm(t(m->l));fa(m->l);BK;
- CS(TD)CS(TV)BK;
- CS(TP)frm(m->p.x);frm(m->p.y);BK;
- }FR(m);
- } //free value
- V d(V);V da(V m){A s=ma(MZ);Z i=0;for(i=0;i<l(m->l);++i)u(s,d(m->l->s[i]));R mvl(s);} //dup array
- V d(V m){
- Z z;S s;
- SW(m->t)
- CS(TV)R mvv(m->v.o);
- CS(TC)R mcv(m->s.s,m->s.z);
- CS(TS)R mvs(m->s.s);
- CS(TD)R mvd(m->d);
- CS(TL)R da(m);BK;
- CS(TP)R mvp(d(m->p.x),d(m->p.y));
- EL DE;}R 0;
- } //dup val
- B eq(V a,V b){
- if(a->t!=b->t)R N;
- SW(a->t)
- CS(TV)R a->v.a==b->v.a&&a->v.o==b->v.o;
- CS(TS)CS(TC)R a->s.z!=b->s.z?0:memcmp(a->s.s,b->s.s,a->s.z)==0;
- CS(TD)R a->d==b->d;
- CS(TP)R eq(a->p.x,b->p.x)&&eq(a->p.y,b->p.y);
- EL TE;}R N;
- } //equal
- B tr(V m){
- SW(m->t)
- CS(TV)R Y;
- CS(TS)CS(TC)R m->s.z!=0;
- CS(TL)R l(m->l)!=0;
- CS(TP)R tr(m->p.x)&&tr(m->p.y);
- CS(TD)R m->d!=0;
- }
- } //truthy
- US ucts(UC c){US b=alu(2);b[0]=c;b[1]=0;
- R b;} //char to ustr
- typedef struct _VR{UC s[256];V v;struct _VR *n;}ENV; //environment
- ENV*v[512]; //main environment
- L h(US s){US q;L k;
- for(k=0,q=s;*q;q++)k=(k<<3)^*q;
- R k%512;} //hash
- V fe(US s){ENV*p;L k;k=h(s);
- for(p=v[k];p;p=p->n)if(u8_strcmp(s,p->s)==0)R p->v;
- R 0;} //find entry
- U be(US s,V x){ENV*p;L k;k=h(s);
- for(p=v[k];p;p=p->n)if(!u8_strcmp(s,p->s)){p->v=x;R;}
- p=al(sizeof(ENV));u8_strncpy(p->s,s,255);p->s[255]=0;
- p->v=x;p->n=v[k];v[k]=p;} //bind entry
- D pd(S s){S err;D r=strtod(s,&err);
- if(r==0&&!isspace(*err)&&s==err)PE;
- R r;} //parse number
- I r(US s,B q);
- US tra(US s,B inl);
- #define ud(s,d)u(s,mvd(d)) //put number
- #define us(s,r)u(s,mvs(r))
- typedef enum{SN,SR,SD,SC,SL,SV}E; //state (none, string, number, code, list, var)
- #define IS(s) if(st == s) {
- #define NO(s) if(st != s) {
- #define NOT(s) (st != s)
- #define OR(s) || st == s
- #define SI(s) st = s
- #define D(n)V D##n(V x,V y)
- #define M(n)V M##n(V x)
- US Dtos(UC o,V x,V y){US b=alu(1024);u8_snprintf(b,1024,"%U%U%c",tos(x,Y),tos(y,Y),o);
- R b;} //dyad to string
- US Mtos(UC o,V x){US b=alu(1024);u8_snprintf(b,1024,"%U%c",tos(x,Y),o);R b;} //monad to string
- #define TED(o)sh(Dtos(o,x,y));TE;
- #define TEM(o)sh(Mtos(o,x));TE;
- #define _tcD(o,ty,x,y)if(x->t!=ty||y->t!=ty){TED(o);}
- #define tcD(o,ty)_tcD(o,ty,x,y)
- #define tcDV(o,tyx,tyy)if(x->t!=tyx||y->t!=tyy){TED(o);}
- #define tcM(o,ty)if(x->t!=ty){TEM(o);}
- D(plus){tcD('+',TD);R mvd(x->d+y->d);}
- D(minus){tcD('-',TD);R mvd(x->d-y->d);}
- D(star){tcD('*',TD);R mvd(x->d*y->d);}
- V apD(DYAD f,V x,V y);
- D(reduce){tcDV('/',TV,TL);if(x->v.a!=2){sh(Dtos('/',x,y));IE;}if(ll(y)<1){sh(Dtos('/',x,y));e("length error");}if(ll(y)==1)R lat(y,0);V b;Z i;b=t(y->l);
- for(i=0;i<ll(y);i++){b=apD(x->v.d,b,lat(y,i));}R b;}
- M(apply){tcM('@',TC);L _ln,_cl;_ln=ln;_cl=cl;r(x->s.s,N);ln=_ln;cl=_cl;R NULL;}
- M(negate){tcM('_',TD);R mvd(-x->d);}
- V mvv(UC o){V m=mv();m->t=TV;m->v.o=o;
- SW(o)
- CS('+')m->v.a=2;m->v.d=Dplus;BK;
- CS('-')m->v.a=2;m->v.d=Dminus;BK;
- CS('*')m->v.a=2;m->v.d=Dstar;BK;
- CS('_')m->v.a=1;m->v.m=Mnegate;BK;
- EL sh(ucts(o));PE;}R m;} //make ref
- V apD(DYAD f,V x,V y){V s;I i;
- if(x->t==TL&&y->t==TL){if(ll(x)!=ll(y))e("rank error");s=mvl(ma(MZ));for(i=0;i<ll(x);i++){u(s->l,apD(f,lat(x,i),lat(y,i)));}R s;}
- if(x->t==TL){s=mvl(ma(MZ));for(i=0;i<ll(x);i++){u(s->l,apD(f,lat(x,i),y));}R s;}
- if(y->t==TL){s=mvl(ma(MZ));for(i=0;i<ll(y);i++){u(s->l,apD(f,x,lat(y,i)));}R s;}
- R f(x,y);} //apply dyad
- V apM(MONAD f,V x){V s;I i;
- if(x->t==TL){s=mvl(ma(MZ));for(i=0;i<ll(x);i++){u(s->l,apM(f,lat(x,i)));}R s;}
- R f(x);} //apply monad
- #define mAD(o)if(l(la)<2){if(l(la)==1){sh(Mtos(c,t(la)));}else{sh(ucts(c));}IE;}y=t(la);x=t(la);u(la,D##o(x,y)); //make atomic dyad
- #define mD(o)if(l(la)<2){if(l(la)==1){sh(Mtos(c,t(la)));}else{sh(ucts(c));}IE;}y=t(la);x=t(la);u(la,apD(D##o,x,y)); //make dyad
- #define mM(o)if(l(la)<1){sh(ucts(c));IE;}x=t(la);u(la,apM(M##o,x)); //make monad
- #define PRELOG if(!Ma){Ma=ma(MZ);u(Ma,ma(MZ*2));}
- #define PROLOG PRELOG;ln=1;cl=0;
- #define ul(s)u8_strconv_from_locale(s)
- I r(US s,B q) {
- PROLOG;L _ln,_cl;
- A la=sk(Ma);E st=SN;UC c;V x,y;US nb;Z nr,red;L bl,cbl;B ru=N;
- DO(i)if(ru)BK;cl++;c=s[i++];
- if((isdigit(c)||c=='.')&&NOT(SR)&&NOT(SL)&&NOT(SC)){NO(SD)SI(SD);red=256;nr=0;nb=alu(red);NLS(nb);}
- nr++;if(nr>=red){red*=2;rl(nb,red);}u8_strncat(nb,&c,1);}
- if(isalpha(c)&&NOT(SR)&&NOT(SL)&&NOT(SC)&&NOT(SD)){NO(SV)SI(SV);nb=alu(256);nr=0;NLS(nb);}
- if(nr>=255)ME;u8_strncat(nb,&c,1);}
- IS(SV)if(!isalpha(c)){SI(SN);if(c==':'){x=t(la);be(nb,x);ES x=fe(nb);if(!x){sh(nb);e("name error");}u(la,d(x));}if(c!=':'){cl--;i--;}}}
- else IS(SC)if(cbl<0||c==0)BE;if(nr>=red){red*=2;rl(nb,red);}if(c=='{')cbl++;if(c=='}')cbl--;if(cbl==0){SI(SN);u(la,mcv(nb,u8_strlen(nb)));ES nr++;u8_strncat(nb,&c,1);}}
- else IS(SL)if(bl<0||c==0)BE;if(nr>=red){red*=2;rl(nb,red);}if(c=='[')bl++;if(c==']')bl--;if(bl==0){SI(SN);u(Ma,ma(MZ));_ln=ln;_cl=cl;r(nb,N);ln=_ln;cl=_cl;u(la,mvl(t(Ma)));ES nr++;u8_strncat(nb,&c,1);}}
- else IS(SR)if(c==0)BE;if(c=='\''){SI(SN);nb[nr+1]=0;us(la,nb);}else{nr++;if(nr>=red){red*=2;rl(nb,red);}u8_strncat(nb,&c,1);}}
- else IS(SD)if(!isdigit(c)&&c!='.'){SI(SN);nr=0;ud(la,pd(u8_strconv_to_locale(nb)));FR(nb);cl--;i--;}
- ES SW(c)
- CS('\'')red=128;nb=alu(red);nr=0;SI(SR);BK;
- CS('+')mD(plus);BK;
- CS('-')mD(minus);BK;
- CS('*')mD(star);BK;
- CS('/')mAD(reduce);BK;
- CS(':')if(!ispunct(s[i])){sh(ul(":"));PE;}u(la,mvv(s[i]));cl++;i++;BK;
- CS('@')mM(apply);BK;
- CS('_')mM(negate);BK;
- CS('[')red=256;nr=0;bl=1;nb=alu(red);SI(SL);BK;
- CS('{')red=256;nr=0;cbl=1;nb=alu(red);SI(SC);BK;
- CS(' ')CS('\t')CS('\r')BK;
- CS('\n')ln++;BK;
- CS(0)IS(SR OR(SC)OR(SL))BE;}IS(SV)e("syntax error");}ru=Y;BK;
- EL sh(ucts(c));SPE;BK;}}
- }if(ir&&q&&l(la))printf("%s\n",tos(sk(la),Y));R 0;} //run
- U il() {US in;printf("sara\t\\\\ to exit\n\n");ir=Y;WH(Y)putchar('\t');if(!setjmp(J)){in=rel();if(u8_strcmp(in,ul("\\\\"))==0)exit(0);r(in,Y);}if(Ma){A la=sk(Ma);while(l(la))frm(t(la));fa(la);fa(Ma);Ma=0;}}} //interactive loop
- I main(I ac,SS a){GC_INIT();PROLOG;eh();il();R 0;}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement