// unlambda 2 // http://www.eleves.ens.fr:8080/home/madore/programs/unlambda \e 0 \d .unl / builtins l:_ic / ^x lambda x m:-_ic / \$x variable x a:{a} / ` apply p:{`0:x;y} / .x print x q:{a,y,:[I~,x;i;v]} / ?x compare current character o:{a,x,:[#I::0:`;i;v]} / @ read current character b:{a,x,:[#I;h i;v]} / | reprint current character h:{p[*x]} / project print r:{`0:"\n";x} / print newline i:{x} / identity k:{y;x} / constant s:{a,a,x,z,a,y,z} / substitute c:{a,x,y} / call-with-current-continuation v:{v} / void d:{a,a,f,y,x} / delay (promise) f:{a,y,x} / force promise e:{a,t,x} / exit t:{t} / terminate / abstraction elimination (no shortcuts) L:{V@|*(M .)/(();|P x)} M:{(:[~#y;x;~1=4:*y;x,*y;0>*y;x,*y;|N[-*y;|x]];1_ y)} N:{,/(O[x].)/(();y)} O:{(:[~#z;y;a~*z;y,a,a,s;x~*z;y,i;y,a,k,*z];1_ z)} / eval E:{Z[x]/("";();P y)} Z:{:[#x . y;y;X . y]} X:{:[~#z;(x;y;z);a~*z;(x;y,a;1_ z);Y[x;y,*z;1_ z]]} Y:{:[3>i:(a,/:(t;c;d))?-2#y;(T;C;D)[i][x;-2_ y;B z];(3>#y)|a _in -2#y;(x;y;z);A[x;(-3_ y;-2#y);z]]} B:{(0,1+(+\-1 1 x~'a)?-1)_ x} C:{(x;y),,c[*z;.,`c,,(x;y),,z 1],z 1} D:{(x;y),,d[*z],z 1} T:{(x;*z;())} A:{:[5=4:*y 1;K[y[1;0;`c];y[1;1];z];J[x;y;z]]} K:{(2#x),,y,z,x 2} J:{I::x;(I;*y;y[1;0][y[1;1]],z)} / time-limited eval E_:{Z_[x;_t,z]/("";();P y;0)} Z_:{:[~y[1]>*-1#z;z;#x .-1_ z;z;(X .-1_ z),_t-*y]} / parse R:0 4_/:("^\$.?@|`iksrcvdfet";(l;m;p;q;o;b;a;i;k;s;r;c;v;d;f;e;t)) P:{Q@@[x;i;:;(,/R 1)(,/*R)?/:x i:&(x _lin,/*R)&-1!~{1_0 x\_ic y}[++1!0,,(!256)_lin _ic**R]x]} Q:{,/@[(|,)':x,i;_n;{:[x[0]_in*R 1;x[0][x[1]];x[0]_in R[1;1];*x;()]}]} / display U:{{`0:(\$x),":",(42\$:[40<#y;"--";""],40\$y),":",-42\$(-40\$z),:[40<#z;"--";""]}[x]. V'(y;z);0:`} V:{W{x,""}@,/{:[5=t:4:x;{"<",(\$x),":",y,":",z,">"}. V'x`c;~t;V'x;~t=1;_ssr/[\$x;\$,/R 1;,/*R];"^\$"[x<0],_ci __abs x]}'x} W:{_ssr/[_ssr/[x;("[[]\"";"\"[]]";"[[],"),".",'d;("";"";"["),c]_dvl d;c:_ci 1+!4;d:"(;,)"]} / file F:{{x@&(-1!x _lin**R)|~" "=x:("",x)_dvl"\b\r\n\t"}@,/{(x?"#")#x}'0:x,:[".unl"~-4#x\$:;"";".unl"]} \d .k / API e:.unl.E[{0#z}] t:.unl.E[.unl.U] f:e .unl.F@ l:.unl.L / time-limited versions e_:.unl.E_[{0#z}] t_:.unl.E_[.unl.U] f_:{e_[.unl.F x;y]} / run if[#_i;f _i 0] \ run unlambda/hello.unl: k unlambda unlambda/hello start unlambda: k unlambda f"unlambda/hello" / run unlambda/hello.unl" e"```skss" / evaluate ```skss t"```skss" / trace evaluation of ```skss Use ctl-c to interrupt infinite loops, e.g. f"unlambda/count" * ** *** **** ***** ****** ******* ******** ********* ********** *********** ************ ************* ************** *************** **************** / <-- ctl-c load: unlambda ... + 66 unlambda: stop Or use the time-limited interpreter: f_["unlambda/count";2] / evaluate for no more than 2 seconds