// K parser-tokenizer v.1.25 / token classes ZZZ:_ci 0 YYY:_ci 1 NUL:_ci 255 BLA:" " RPA:")" LPA:"(" RBR:"]" LBR:"[" RCU:"}" LCU:"{" LEF:LPA,LBR,LCU RIG:RPA,RBR,RCU SEP:";" NEW:"\n" EOL:SEP,NEW COL:":" AMD:"@" MIN:"-" DOT:"." BAR:"_" OPR:"~!#$%^&*=+|<,>?",AMD,MIN,BAR VRB:OPR,DOT,COL SYM:"`" QUO:"\"" FSL:"/" ESC:"\\" TIC:"'" ADV:FSL,TIC,ESC ALF:_ci,/97 65+\:!26 NAM:ALF,YYY NUM:"0123456789" ALL:_ci!256 CHR:ALL _dvl BLA,QUO,SYM,RIG,LEF,EOL,VRB,ADV,NAM,NUM,NUL KEY:$`do`if`while BOX:LBR,RBR COM:"," / (automata , states) x classes V:" . . QUO SYM NAM NUM VRB DOT COL ADV BLA RIG LEF NUL EOL CHR S S quo sym nam num vrb vrb vrb tok bla tok lef nul eol chr nul nul quo sym nam num vrb vrb vrb adv bla rig lef nul eol chr sym sym quo sym sy1 tok vrb sy1 vrb adv sy2 rig lef nul eol chr sym sy1 quo sy1 sy1 sy1 vrb sy1 vrb adv sy2 rig lef nul eol chr sym sy2 quo sy1 nam num vrb vrb vrb adv sy2 rig lef nul eol chr nam nam quo sym na1 na1 vrb tok vrb adv bla rig lef nul eol chr nam na1 quo sym na1 na1 vrb tok vrb adv bla rig lef nul eol chr num num quo sym sym nu1 vrb tok vrb adv nu1 rig lef nul eol chr num nu1 quo sym sym nu1 vrb tok vrb adv nu1 rig lef nul eol chr quo quo *qu quo quo quo quo quo quo quo quo quo quo quo quo quo quo *qu quo sym nam num vrb vrb vrb adv bla rig lef nul eol chr *vb vrb quo sym nam num vrb vrb vr1 adv bla rig lef nul eol chr *vb vr1 quo sym nam num vrb vrb vrb adv bla rig lef nul eol chr *av adv quo sym nam num vrb vrb ad1 adv bla rig lef nul eol chr *av ad1 quo sym nam num vrb vrb adv adv bla rig lef nul eol chr bla bla quo sym nam num vrb vrb vrb tok bla rig lef nul eol chr rig rig quo sym nam nam vrb vrb vrb adv bla rig lef nul eol chr lef lef quo sym nam num vrb vrb vrb tok bla rig lef nul eol chr eol eol quo sym nam num vrb vrb vrb tok bla rig lef nul eol chr err tok tok tok tok tok tok tok tok tok tok tok tok tok tok tok err chr chr chr chr chr chr chr chr chr chr chr chr chr chr chr " / V -> tokenizer wxyz:{ a:`$b:cut[BLA]'sqz cut[NEW]deb x / dissect V c:0+\1_#:'1_ a[=-1_ a[;0];1] / X _ w:,{x@&x>0}1+c@&(1+c)_lin&"*"=*:'2_ b[;0] / singletons w,:,{-1*x@&x<0} -1*1+&"*"=*:'2_ b[;1] / self-enders d:@[256#0N;_ic .:'2_*a;:;!-2+#*a] / Y _ic"..." m:1+(2_ a[;1])?/:/:1_2_'a / Z\ (w;c;d;m)} / (W;X;Y;Z) / string analysis sqz:{x@&~&/'x=BLA} / no blank rows cut:{1_'(&y=x)_ y:x,y} / cut y on x glu:{1_,/x,/:y} / glu y's with x deb:{x@&~0&':BLA=x} / delete extra blanks dlb:{((x=BLA)?0)_ x} / delete leading blanks dtb:|dlb@|: / delete trailing blanks dbe:{_dv[dtb'x]""} / trim each / string synthesis par:1!RPA,LPA, / parenthesize string bra:1!RBR,LBR, / enclose in [] cur:1!RCU,LCU, / enclose in {} sep:{x,SEP,y} / x;y bla:{x,BLA,y} / x y / mates esc:1_0{y&~x}\ESC= / mark escapes (2*h/t je) qu:{(-1!b)&b:(~=)\(~-1!esc x)&QUO=x} / quoted contents quo:{qu[x]|x=QUO} / with quotes unq:~quo@ / unquoted unc:{:[FSL=*x;"";#j:,/{ss[x;y,FSL]}[x i:&unq x]'BLA,LCU;i[1|&/j]#x;x]} / where not commented lrm:{-1_(1!b)|b:>/+\'unq[s]&/:x=\:s:BLA,y} / l-r match / general tokenizer @[_d;`W`X`Y`Z;:;wxyz V]; / tokenizer globals / tokenize T:{[s]:[#s;qck[u]unl_[t 1]chop[u]tok[u]chr[u]1_0 Z\Y _ic sub u:*t:unl rbl BLA,s;s]} / tokenize chop:{[u;s]dbe(&(0,-1_ s _lin W 1)|((s _lin*W)&0=':s)|(1=-/X(k;k-1))|(~=)':0,k:X _binl s)_ u} / string -> tokens / errors qck:{[t;s]:[~#s;s;(QUO=**|s)&~QUO=*|*|s;err[t;#t]"open quotation";s]} / open quotation? chr:{[t;s]:[(#s)>e:s?1+*|X;err[t;e]"bad character";s]} / bad character? tok:{[t;s]:[(#s)>e:s?*|X;err[t;e]"bad token";s]} / bad transition? err:{`0:("",x;((0|y)#""),"^ ",z);'z} / ^ error / lambdas unl:{mask[NUL;lrm[LCU,RCU]]x} / {..} -> NUL unl_:{@[y;&y~\:,NUL;:;x]} / NUL -> {..} rbl:{ssr[x;RCU,LCU;RCU,AMD,LCU]} / }{ -> }@{ rbl_:{ssr[x;RCU,AMD,LCU;RCU,LCU]} / }@{ -> }{ / masked _ssr/_ss ss_:{{{:[(#y)&#x;z++/'((&x=ZZZ)_binl z)#\:-1+#:'y;z]}[x]. y}.{(y;(z;_ss[y]x))}[z]. mask[ZZZ;x]y} / mask, _ss, adjust ss:ss_[quo] / _ss w/quotes masked ssr_:{[q;x;y;z]{,/@[x;&ZZZ=x;:;y]}.@[mask[ZZZ;q;x];0;_ssr[;y;z]]} / mask, _ssr, unmask ssr:ssr_[quo] / _ssr w/quotes masked mask:{({x _di 1_ y}/[@[z;k;:;{y#x,BLA,y#BLA}[x]'j];|k];z k:i+!:'j:+/'(i:&0>':b)_ b:y z)} / mask y'z with x / left-right unbalanced, overlap unb:{~(*|=/b)&~|/L)&(ll)&(l>L)&r>R} / overlap? r2n:{:[#x;-1 2#x;x]} / 2 x n olp:{|//x{|//x{lro . x,y}\:/:y}\:/:x} / 1 iff overlap lr0:{-/+\'x=\:" ",y} / lr at all levels lr1:{&(~=)':~x {0}{0}{0}m I64:(~*@[.:;"0j";:])#"j" / 64bit db0:{_ssr[x;YYY;"x"]} / YYY -> x db1:{fill[x;"x";1;"[a-zA-Z][?.][^a-zA-Z.]"]} / x. -> x db2:{{fill[x;YYY;1;"[^a-zA-Z][?",y,"][a-zA-Z]"]}/[x;"._"]} / .x|_x -> YYY db3:{fill/[fill[;"x";1;"[a-zA-Z]_"]/x;"x";!2;(".[a-zA-Z]";"[a-zA-Z].")]} / x_x -> xxx nom:db0 db1 db2 db3@ / names - legal _. nil:{fill[x;"z";!2;"()"]} / () -> zz iof:{fill[x;"+";1;"[^0-9a-zA-Z][0-9]:"]} / : n -> :n xqu:{@[x;&qu x;:;"x"]} / ".." -> "xx" sub:iof nom num nil lrx xqu@ / in T / :[ pre-processing ite:{{ssr[x;:[y _in"*?";bra y;y],":[[]";y," :["]}/[ssr[x;"::[[]";": :["];VRB]} / X:[ -> X :[ / pseudo-system-variable pre-processing sys:{1_ sva/[BLA,x;(BLA;SEP;LPA;LCU;LBR,BOX)]} / adv -> sys sva:{ssr/[x;(y,TIC;y,ESC);(*y),'("_sig ";"_esc ")]} / '|\ -> _sig|_esc asv:{ssr/[x;("_sig ";"_esc ");TIC,ESC]} / _sig|_esc -> '|\ / pre/post-tokenize pre:sys ite@$: / pre-tokenize post:rbl_ asv@ / post-unparse / display parse-tree d:{:[4:y;,(x+#y)$y;,/_f[x+1]'y]}[-1] / display parse-tree / parse: E:E;e|e e:nve|te| t:n|v v:tA|V n:t[E]|(E)|N P:{I::0;{:[lp[x]&2=#x;x 1;x]}{:[lp x;(,,SEP),1_ x;x]}trm J::LPA,x} / parse (adapted from atw) cl:{:[~4:x;"n";io[x]|sf[x]|&/x _lin VRB;"v";"asn"(&/'x _lin/:(LBR,ADV,COL;EOL,RPA,RBR,BLA))?1]} / class of token sf:{(BAR~*x)&(2<#x)&&/(1_ x)_lin NAM} / system verbs io:{(&/(-1_ x)_lin NUM)&(COL~*|x)&2=#x} / n: jx:{ix -1+I+:1} / next token ix:{:[x<#J;J x;BLA]} / safe indexing ob:{:[(COL~**x)|sf[x]|"n"=cl x;(,,LBR),,x;x]} / :[ x[ -> [ x if _f[ or f[ gp:{x(1;)(~3>#x)|"v"=cl x 1} / (v) -> (v) lp:{(LPA~*x)&~x~LPA,RPA} / ( but not () Exp:{|/(EOL,LPA,LBR)=*jx`}{exp trm`}\ / (expression) trm:{:["s"=cl ix I;"";{"a"=cl ix I}{:[LBR=*ix I;Exp ob x;(jx`;x)]}/ :[~lp ix I;jx`;gp Exp ix I]]} / term ("" = ::) exp:{:["s"=cl ix I;x;vrb[f:trm`]>vrb`;(f;x;exp trm`);(x;exp f)]} / expression vrb:{cl[ix I-1]_in"va"} / verb or adverb? / typed parse-tree t:{:[~4:x;_f'x;~#x;BLA;x _in+,LBR,BLA,LPA,SEP,LCU;*x;NEW=*x;SEP;LBR=*x;LCU;cl x]} / typed parse-tree / prefix normal form FAF:1 / functional adverb form PFA:0 / project function app N:{:[@x;y;SEP~*x;sep/N'[1_ x;1_ y];LCU~*x;lf[x]y;LPA~*x;mf[x]y;LBR~**x;bf[x]y;@*x;vf[x]y;wf[x]y]} / prefix normal form N_:,(+,("/";"\\";"'";"':");("{x/y}";"{x\\y}";"{x'y}";"{x':y}")) / monadic adverb N_,:,(N_[0;0],("/:";"\\:");("{y x/z}";"{y x\\z}";"{y x'z}";"{y x':z}";"{y x/:z}";"{y x\\:z}")) / dyadic adverb vf:{:[1=#x;N[*x;*y];COL _in*y;N[x 1;y 1],y[0],N[x 2]y 2;N[*x;*y],fa@N'[1_ x;1_ y]]} / verb/noun form af:{:[4:x;par N[*x;*y],y 1;par _f[|*x;|*y],y 1]} / native adverb form ff:{a:N_[z;1;,N_[z;0]?*y];:[4:x;N["n",1_ x]a,1_ y;N["nn"]a,,_f[x 1;y 1;z]]} / functional adverb form wf:{:[FAF;ff[*x;*y;-2+#x];af[|*x;|*y]],fa@N'[1_ x;1_ y]} / derived verb bf:{f:{@[x;0;*1_]};:[(LBR,COL)~,/*y;COL,bra@sep/N'[1_ x;1_ y];N[f x]f y]} / [ and :[.. fa:{:[PFA;,/bra';bra@sep/]x} / function application lf:{cur y[0],N[1_ x]1_ y} / {.. mf:{par@sep/N'[1_ x;1_ y]} / (.. / minimizing unparser PAR:0 / 1/0 = parenthesize EAT:0 / x y (0) or x@y (1) U:{:[@x;y;SEP~*x;sep/U'[1_ x;1_ y];LCU~*x;fn[x]y;LPA~*x;li[x]y;LBR~**x;ap[x]y;4:x;ef[x]y;cf[x]y]} / recursive unparse fn:{cur@:[BOX~a:*y;"";a],U[1_ x]1_ y} / ({..;..) -> {[.. li:{par@sep/U'[1_ x;1_ y]} / (..;x;..) ap:{:["vn "~*1_*x;U . rc[x]y;rp[*1_*x;U . rg[*1_*x;*1_*y]],bra@sep/U'[1_ x;1_ y]]} / f[..;x;..] rp:{:[("a"~*x)|(2<#x)|(@x)|((**x)_in LBR,LCU)|x~LPA,"v";y;par y]} / x | (v -> v else (..) rc:{((x[0;1];x 1);(y[0;1];y 1))} / reduce composition rg:{:[x~"(v";("v";y 1);(x;y)]} / reduce group ef:{cp@:[1=#x;U[*x;*y];3=#x;vnn . y;2=#x;df[x]. y;pf[x]y]} / elementary forms cp:{:[PAR;up x;x]} / PAR -> use parens up:{:[fp x;x;par x]} / .. -> (..) fp:{:[~LPA=*x;0;&/-1_-/+\'x=/:LPA,RPA]} / fully parenthesized df:{(nn;vn;{y,x};{y,x};,)[(5 2#"nnvnavanvv")?x]} / dyadic forms pf:{U[*x;*y],:[1=#x;"";bra@sep/U'[1_ x;1_ y]]} / poly/niladic form vnn:{:[#y;xyz[x;y]z;x,bra@sep/(y;z)]} / n v n xyz:{y,:[sd x;syz;io x;myz;BAR~*x;byz;an[*x]&an@*|y;spx;ac[x]z;xsp;{z;x}][x;y;z],z} / dyadic space xsp:{y;z;x,BLA} / "x " spx:{y;z;BLA,x,:[ac[x]z;BLA;""]} / " x" | " x " byz:{:[al@*|y;BLA;""],x,:[al[*z]&BAR~*|x;BLA;""]} / x _ | _a y myz:{z;:[an@*|y;BLA,x;x]} / x n: y syz:{sy[myz[x;y]z]z} / x _f y sy:{:[an@*y;x,BLA;x]} / _f x ac:{((*|x)_in ADV)&COL=*y} / [/\'] : an:{x _in NAM,NUM,DOT,BAR} / alphanumeric? nu:{x _in MIN,DOT,NUM} / nunmeric? nn:{:[ac[x]y;x,BLA;rb x;x,("";AMD)EAT;nu[*x]&nu@*y;par x;nu[*y]|an@*y;x,(BLA,AMD)EAT;x],y} / elementary n n rb:{(*|x)_in RPA,RBR,RCU,ADV,COL} / right-bounded? lb:{(**x)_in LPA,LBR,LCU} / left-bounded? vn:{:[x~,BAR;by[x]y;sd x;sy[x]y;ac[x]y;x,BLA;x],y} / elementary v n cf:{cp@:[3=#x;Vnn[x]y;2=#x;Vn[x]y;pf[x]y]} / complex forms Vnn:{vnn[U[*x;*y];la[x 1;U[x 1]y 1]]U[x 2]y 2} / complex n v n la:{:[lb[**x]|(3<#x)|@x;y;up y]} / complex left arg Vn:{xx[x]. U'[x;y]} / complex v n xx:{:["a"~*x;vn[cp va[x]z]y;lr[x]y;nn[y]z;vn[vy[x]y]z]} / x x lr:{("n"~**x)|(LCU~*y)|(LPA~**x)|RBR~*|y} / left-right vy:{:["a"~**x;y;BLA _in"",*x;y;@*x;y;par y]} / complex y -> (y) va:{:[lb[x 1]|"a"~*x 1;y;par y]} / elementary v a by:{:[al@*y;x,BLA;x]} / _ x al:{x _in NAM} / alpha? sd:{sf[x]|x~,DOT} / f_ | . / minimize directory minimize:{i:&7=4::'b:.:'a:!x;.+(a i;f'b i)} / minimize all fns in x / format parse/unparse f:{ f:cix e:phy@$x;h:f _'e;g:new f#'e;k:nyn post 2_ U[t a]a:rec nny g / -> split, parse, unparse new nbl@:[NEW _in k;alc new phy[ind k],'h;phy[k],'h]} / align and indent / # blank lines NBL:1 / # of blank lines nbl:{x@&~NBL<{y*x+y}\0=(#dlb@)'x} / max runs of blank lines (h/t mw) nny:{ssr[x;NEW]NEW,YYY,NEW} / \n -> \n,YYY,\n nyn:{ssr[x;SEP,YYY,SEP]NEW} / ;,YYY,; -> \n / indentation IND:1 / 0 1 2 ... ind:{nbn{,/@[x;i;,;(IND*(-/+\'b&/:y=\:x)i:0,&(NEW=x)&b:unq x)#'BLA]}/[x;+(LEF;RIG)]} / indent pairs across lines / comment alignment ALC:1 / -1 0 1 alc:{(lal;nal;ral)[1+ALC][f]'[c;f:cix c:cut[NEW]x]} / align trailing comments lal:{:[z<2+IND;dlb y;(z#y),z _ y]} / left shove AL=-1 nal:{:[z<2+IND;"";z#y]} / no comments AL=0 ral:{:[~#y;y;z<2+IND;dlb y;z=#y;y;,/@[y;z|-1++/(y=BLA)?0;:;(1+(|/x)-z)#BLA]]} / right align AL=1 cix:{@[0|-1+{&/,/{ss[BLA,x,y,FSL;y,FSL]}[@[x;&quo x;:;BLA]]'BLA,LCU}'x;0;+;(LCU,FSL)~2#*x]} / comments (n.b. {/) / recursive parser R:{rec glu[SEP]@(dtb dlb unc@)'phy@$x} / flatten and parse phy:{1_'(&unq[x]&x=NEW)_ x:NEW,x} / new -> physical lines new:glu[NEW] / physical -> new lines rec:{app NUM[0],SEP,dlb x} / x -> 0;x app:{pil{:[~#*x;x 1;4:x 1;@[x;0;,/];,/x]}@[abc x;1;p]} / recursive parse abc:{:[~LCU=*x;("";x);LBR=*a:wcu x;arg a;bdy[x]a]} / args-body-cut wcu:{(LCU=*x)_(-RCU=*-1#x)_ x:(-LBR=*|x)_ x} / {..} -> .. arg:{(,(i#x)_dv BLA;(i:1+x?RBR)_ x)} / {[X]Y} -> (X;Y) bdy:{(,BOX,(-LBR=*|x)#x;y)} / X Y -> ("[]",X;Y) pil:{:[~4:x;_f'x;LCU=*x;app dlb x;x]} / parse internal lambdas / script transform k:{i:((*dlb@)'d:0:x)?ESC;a:cur NEW,nbn[new i#d],NEW;(2_ nnb 1_-1_ f a),new i _ d} / (transform above \),below \ nbn:{_ssr[x;NEW;NEW,BLA]} / \n -> \n," " nnb:{_ssr[x;NEW,BLA;NEW]} / \n," " -> \n / simplify functional expressions S:{stm . unr[x]sis y} / X -> ..Y..Z stm:{:[((LBR,"v")~*x)|(LCU~*x)|~~4:x;(,x;,y);(SEP,x;(,,SEP),y)]} / s or s;..;s or {s;..;s} unr:{:[4:x;{(x;y)};LCU=a:**x;fla;LBR=a;flb;LPA=a;fls;sim][x]y} / unrold sis:{I::-1;J::,/(+,26#ALF)_dvl nip x;x} / var pool var:{x;"",J I+:1} / next var flb:{:[(,COL)~a:*|*y;fco;a _in KEY;fkw;ffn][x]y} / [ .. fco:{pco[+-1_+*r;+(,(*x;*y)),(,*|+*r),lao .'1_ r:unr'[1_ x;1_ y]]} / :[ .. pco:{:[~#x;y;x,'+,y]} / co-prefix lao:{:[4:x;(x;y);(lat[x]a;lap[y;glu[SEP]a]a:nip[y]_dvl ass y)]} / co-lambda object lat:{(,(LBR;(LCU;SEP),x)),(#y)#"n"} / co-lambda type lap:{(,(,LBR;(bra[y];,SEP),x)),z} / co-lambda parse fkw:{{:[4:y;();-1_ y],,x,:[4:y;,y;-1#y],z}'[(1#x;1#y);unr[x 1]y 1;+unr'[2_ x;2_ y]]} / do/if/while[ .. ffn:{{(|.[|x;0 0;{LBR,x}];|.[|y;0 0;{(,LBR;x)}])}. unr[@[x;0;*|:]]@[y;0;*|:]} / f[ .. fla:{{(2#x;2#y),'+unr'[2_ x;2_ y]}.:[SEP=x 1;(x;y);((*x),SEP,,1_ x;((1#y;,SEP),,1_ y))]} / {[ .. fla:{:[SEP=x 1;(2#x;2#y),'+unr'[2_ x;2_ y];(1#x;1#y),'unr[1_ x;1_ y]]} / {[ .. sim:{i:&~@:'x;v:var'i;s:,'/(syn').+a:set'[x i;y i;v];x[i]:"n";y[i]:a[;2];s,'+,trn .(x;y)} / simplify (x;y) trn:{:[(2<#x)&&/x="n";+((*x;*y);_f . 1_'(x;y));(x;y)]} / n .. n -> (n;.. n) syn:{((-1_*r),,("v";"n";*|*r);(-1_*|r),,(,COL;z;*|*|r::[4:x;+,(x;y);unr[x]y]))} / synthesize assignments fls:{lsr . sim . lsa[x]y} / (.. lsa:{:[LPA~*x;(LPA,|1_ x;(,,LPA),|1_ y);(x;y)]} / flip list arguments lsr:{i:-1+#x;a:lsa[x i]y i;x[i]:a 0;y[i]:a 1;(x;y)} / flip list result set:{:[(,COL)~*y;(x 2;y 2;y 1);(x;y;z)]} / a:b:.. -> b:.. nip:{:[~4:x;?,/_f'x;(*x)_in ALF;,x;()]} / names in parse-tree ass:{:[4:x;();(,COL)~*x;x[,1],?,/_f'x 2;?,/_f'x]} / variables assigned / minimize names in lambda M:{min[ntm y;x]sis y} / minimize names ntm:{(k;var'k:?eol[x],anl 1_ x)} / names to minimize min:{mna[x].(*y;*z){(,x),y}'mnm[x;1_ y]1_ z} / arguments + body mna:{(y;:[BOX~*y;z;@[z;0;_ssr/[;*x;x 1]]])} / minimize arguments mnm:{:[LCU~*y;min[ntm sis z;y]z;~@y;+_f[x]'[y;z];(#*x)>i:x[0]?z;(y;x[1;i]);(y;z)]} / minimize names until lambda / lambda analysis (unused assignments) u:{anl[a]_dvl rnl a:1_*r x} / =assignments-references rnl:{:[RBR~*|*x;();4:x;:[(*x)_in ALF;,x;()];?,/_f'x@:[(,COL)~*x;2]]} / references until lambda aol:{:[#r:eol x;r;,/(.+(`x`y`z;(+,:)'(,"x";"xy";"xyz")))`$and[nnl 1_ x;a:+,"xyz"]]} / arguments of lambda eol:{:[BOX~*x;();cut[SEP]1_-1_*x]} / explicit arguments of lambda nnl:{:[RBR~*|*x;();~4:x;?,/_f'x;(*x)_in ALF;,x;()]} / names until lambda anl:{:[RBR~*|*x;();4:x;();(,COL)~*x;x[,1],?,/_f'x 2;?,/_f'x]} / assignments until lambda and:{x@&x _lin y} / intersect / evaluate parse-tree e:{:[~4:x;_f'x;(*x)_in ALF,YYY;`$x;SYM=*x;,`$1_ x;. x]} / parse-tree for ? and ! / apply/console a:{`0:," c ",($x),1!"\"\"",y;c x y;} / echo, apply, print c:`0:{:[4:x;,x;x]}@ / console / entry points r:2_ R@ v:T pre@ w:post'v@ p:P v@ s:{U .'(S').(t k;k:r x)} m:{U .'(M').(t k;k:r x)} n:{(N').(t k;k:r x)} / simple kdb parser kdb:{ k:`$(s?BLA)#s:lrb x u:cl4[key k]BLA,*a:unp s r:@[@[u;_n;kdp'con@];&YYY _in'u;unp_;a 1] k,r} kdp:{:[#x;e p x;()]} lrb:{ssr/[dlb x;LPA,RPA;(BLA,LPA,BLA;BLA,RPA,BLA)]} con:{:[#x;1_'(&(COM=x)&unq[x]&~lrm[LPA,RPA]x)_ x:COM,x;x]} unp:{.[mask[YYY;lrm[LPA,RPA]]x;(1;);1_-1_]} unp_:{:[~4:x;x _f\:y;(`$YYY)~*x;kdb y;x]} K:(`select`update`delete;`by`from`where) key:{:[x _in*K;BLA,'($x,K 1),'BLA;0#]} cl4:{@[(#x)#,"";j;:;(#:'x j)_'(*:'i j:&0<#:'i:y ss/:x)_ y]} / nest links nest:{(*x;(-8_ x 1),blk[y 1],-8#x 1)} / simple kdb translator ten:{:[2=#x 3;qt2;qt1]x} qt1:{t:*x 3;s:sel'x 4;w:bdy . x 2 1;o::[`update=*x;,ord@,/x 2 1;()];(t;glu[NEW;dnu s,w,o])} ord:{:[#a:{:[@x;x;x 1]}'x;"";()]} qt2:{t:tab .+$x[4;&b:lrt x;1 2];l:lnk t;s:sel'x[4;&~b];w:bdy . x 2 1;(`$*t;l,gnb[dnu s,w],"")} lrt:{DOT _in/:$x[4;;1]} lnk:{""} tab:{,/+{(**x;?x 1)}@/:(+fln'x;+fln'y)} fln:{{(glu[DOT;-1_ x];*|x)}cut[DOT]x} tb2:{"table2=",x 1} col:{"col=",glu[COM;x 2]} cl2:{:[~/x 2 3;();"col2=",glu[COM;x 3]]} bdy:{:[#x;,tbu[x]y;#*y;wbe'y;()]} sel:{:[#x;"";()]} wbe:{:[@x;();""]} tbu:{:[#x;"",gnb[(tco nsf@)'$y],"";()]} nsf:{:[COL~**x;(|x 2),,x 1;|x]} tco:{""} fmt:{:[-3=t:4:x;TIC,x,TIC;6=t;"NA";5=t;dic x;@x;atm x;4=t:4:*x;fun x;7=t;prm x;glu[BLA;_f'x]]} atm:{:[x _in(0N;0n);"NA";$x]} dic:{par glu[BLA]{x,":",ten y}.'+($!x;x[])} fun:{($*x),LPA,glu[SEP;fmt'1_ x],RPA} prm:{:[2=4:x;($*x),fmt x 1;LPA,fmt[x 1],($*x),fmt[x 2],RPA]} dnu:{x@&0<#:'x} gnb:{NEW,glu[NEW,BLA;x],NEW} blk:{_ssr[NEW,x;NEW;NEW,(1+|/(+/&\)'BLA=cut[NEW;x])#BLA]} \ aa:ten kdb"select f:a+b,g from t.a,u.b where t.a.xx=u.b.ww,t.a.yy=u.b.zz,q=r" bb:ten kdb"select k:x+1 from u,v where u.q=v.r" cc:ten kdb"select a:99-x from v,w where v.s=w.t,i Op Fs By Ts Wh Op -> select|update|delete Ts -> from F_ Fs -> @ | F_ By -> @ | by F_ Wh -> @ | where F_ L_ -> E_ | E_ , L F_ -> E_ | ( L_ ) E_ -> S_ | K_ K_ -> ... = up to the next top-level keyword ? select 1+(select f from t)`f from ... \ / tests x:("x;y";"(x;y)";"f[x;y]";"x+y";"x+*y";"1+3*x";"(+x)%y";"(+/x)%#x";"x+m[*i]/y";"2+/";"+/2";"{[a;b]a+{[x;y]x-y}/b}";"foo[3+1]4-5";"3,/:\\:+/'2+a";"1 2[3 4]";"{}{}";"{{}}";"(1+2)3-4";"`a`b`c 1";"{0!x} / make x length y, padding with 0 crop: {{+pad[y]'+pad[z]'x}[y]. x} / make y dimension x, padding with 0 tess: {{y#z#'x}[y]. x} / make y dimension x, tesselating bitmap full: {,((w|h)*2 2\'0 1 3 2;("";x))} / background color x x:$(dim;grid;scale;pad;crop;tess;full) &~x~'f'x \ foo:{/header a:x+ y b:{[c; d] / one m :10 , " / fooooo" / quoted comment if[x; ((y)); z] if[ xyz while[abc rr:a+1;qq:b-2+(3*x) `0::[a+b;`hello;`goodbye] \c-3] 'def] / signal!!!! / comment on empty line, followed by two empty lines one of which will be deleted foo(c-d+ 10)}[x ]y / two r: a + b / three r } `0:,f foo \ `0:d r"{[a;b] a + {x - y}/b}" [a;b] + a / [] - x y b \ unroll cases: a+b .. foo[a+b;c] [ f do/if/while[a;b;..;c] [ do/if/while :[a;b;..;c] [ : {[a;..;b]..c..} [..] \ basic parsing: nn parses to (n;n) vn parses to (v;n) (but will change a dyadic prim to monadic prim) nv parses to (v;n;) nvn parses to (v;n;n) vv parses to (v;v) / explicit iteration: t:{:[q`;"";x y]}[{r::[~l k I;j`;3>#x:E k I;x 1;x];while["a"=c k I;r::[LBR=*k I;E r;(j`;r)]];r}] / vector notation (deprecated) vec:{awt/[x;(,glu[BLA]@;,,/);(num1';sym1')]} / (n;..;n) -> n .. n (je) awt:{,/(::;y)[b c]@'(c:&~0~':b:z x)_ x} / apply y to x where z sym1:{SYM=*x} / symbol? num1:{(~COL=*|x)&((*x)_in NUM)|((DOT=*x)&(*1_ x)_in NUM)|(MIN=*x)&|/(1_ x)_lin NUM} / number? \ reference ========= a/c apply x to y / echo to console v pre-parsing tokenizer w split string s into list of words (tokenizer) p parse k expression (top level only) r recursively parse k expression t type-tree (isomorphic to parse-tree) d display parse-tree as a simple indented list f format k expression (unparse parse) k format k script s simplify k statement m minimize k lambda n prefix normal form u unused assignments PAR fully parenthesized (1/0) IND indent (n) ALC right align, left shove, none (1/-1/0) EAT explicit @ (1,0) NBL max # of consecutive blank lines (n) FAF functional adverb form (1/0) PFA project function application (0/1) 0. apply/console ---------------- a[`f]"a+b-c" c f"a+b-c" a+b-c c"abc" abc 1. words -------- w"a+b-c*+/'d" (,"a" ,"+" ,"b" ,"-" ,"c" ,"*" ,"+" ,"/" ,"'" ,"d") 2. parse -------- top-level parsing: p"a+b-c*+/'d" (,"+" ,"a" (,"-" ,"b" (,"*" ,"c" ((,"'" (,"/" ,"+")) ,"d")))) p treats lambdas as atoms (see r below): p"x+{[a;b]a-b}[a;b]" (,"+" ,"x" ((,"[" "{[a;b]a-b}") ,"a" ,"b")) 3. recursive parse ------------------ recursive parsing penetrates lambdas: r"x+{[a;b]a-b}[a;b]" ,(,"+" ,"x" ((,"[" ("[a;b]" ,"-" ,"a" ,"b")) ,"a" ,"b")) 4. type ------- type-tree: t r"x+{[a;b]a-b}[a;b]" ("v" "n" (("[";"{vnn") "n" "n")) 6. diagram ---------- d r"x+{[a;b]a-b}[a;b]" (,"+" ,"x" " [" " [a;b]" " -" " a" " b" " a" " b") 7. format (unparse) ------------------- parse, then unparse into minimal form: f"a+f/'b" "a+f/'b f"a+(b-c)" "a+b-c" 8. format .k script ------------------- format all objects in a script: aa:k"kparse.k" 9. simplify k statement ----------------------- analyze complex expressions into a series of assignments of simple expressions: c s"f+/c" a:+/;a f c c s":[a+b-c;q;r]" d:b-c;:[a+d;q;r] c s":[x;r:(c-q:2+d)+e;f*g-h]" :[x;{[d;c;e]q:2+d;b:c-q;a:b+e;r:a}[d;c;e];{[g;h;f]j:g-h;f*j}[g;h;f]] c s"do[a+b-c;d+3;f+4]" e:b-c;do[a+e;d+3;f+4] c s"a+b;c-d" a+b c-d c s"f[a;g[b+c]]" e:b+c;d:g[e];f[a d] c s"+/'(a*b)-xx:c+d" g:+/;e:g';h:a*b;xx:c+d;f:h-xx;e f c s"(a;(b+c;;q-r);c:d-10)" c:d-10;g:q-r;h:b+c;f:(h;;g);(a;f;c) 10. minimize k lambda --------------------- replace arguments and local variables with single-letter names: c m"{[xxx;yyy]bb:aa+xxx;{xxx:x};f[yyy;aa;bb]}" {[a;b]c:aa+a;{a:x};f[b;aa;c]} 11. prefix normal form ---------------------- PFA:0 FAF:0 c n"+/x-y" (+/)[-[x;y]] c n"0+/x-y" (+/)[0;-[x;y]] c n"+/'x-y" ((+/)')[-[x;y]] PFA:0 FAF:1 c n"+/x-y {x/y}[+][-[x;y]] c n"0+/x-y {y x/z}[+][0;-[x;y]] c n"+/'x-y" {x'y}[{x/y}[+]][-[x;y]] PFA:1 FFA:1 c n"x+y-z" +[x][-[y][z]] PFA:0 FFA:1 c n"x+y-z" +[x;-[y;z]] 12. unused assignments ---------------------- u{a:10;b:20;{qq:abc};c:a+b;d:30} (,"c" ,"d") example ------- input is sloppy k: foo:{/header a:x+ y b:{[c; d] / one m :10 , " / fooooo" / quoted comment if[x; ((y)); z] if[ xyz while[abc rr:a+1;qq:b-2+(3*x) `0::[a+b;`hello;`goodbye] \c-3] 'def] / signal!!!! / delete all but one empty line foo(c-d+ 10)}[x ]y / two r: a + b / three r } output is maximally simplified, indented, with comments aligned to the right: IND:5 `0:,f foo {/header a:x+y b:{[c;d] / one m:10," / fooooo" / quoted comment if[x;y;z] if[xyz while[abc rr:a+1;qq:b-2+3*x `0::[a+b;`hello;`goodbye] \c-3] 'def] / signal!!!! / delete all but one empty line foo c-d+10}[x]y / two r:a+b / three r} 13. kdb parser -------------- maximal form: O F by K from T where A minimal form: O F from T O can be select, update, delete. T can be t or t,u. A can have t.f=u.g for links. kdb"select q:sum f,sum g by k,l from t where h=20,i 1010 translator -------------------------- `0:,ten[kdb"update f:x+y,g from t where h=20,i `0:,ten[kdb"select f:x+y,g from t where h=20,i `0:,ten[kdb"select q:sum f,sum g by k,l from t where h=20,i `0:,ten[kdb"select f:a+b,g from t,u where t.a=u.z,t.b=u.b,q=r"]1 aa:ten kdb"select f:a+b,g from t,u where t.a=u.z,t.b=u.b,q=r" bb:ten kdb"select k:x+1 from u,v where u.q=v.r" cc:ten kdb"select a:99-x from v,w where v.s=w.t,i