// parallel excel O:(("=";"<";">";"<>";"<=";">=") / relations ,"&" / join "+-" / plus, minus "*/" / times, divide ,"^" / power ,"_" / unary minus ,"IF" / ternary functions ("AND";"OR";"MIN";"MAX") / binary functions ,"NOT" / unary functions ("SUM";"AVG";"TRANSPOSE";"CHOOSE") / list functions ,"," / range union ," " / range intersect ,"!" / at ,":" / cell range ,";" / arg separator ,"(" / left paren ,")" / right paren ,Z:_ci 255) / end of string G:(("IF";"AND";"OR";"MIN";"MAX");("SUM";"AVG";"TRANSPOSE";"CHOOSE")) V:2 2 2 2 2 1 3 2 1 1 2 2 2 2 -1 0 -2 0 / valence / =&+*^_321f, !:;()Zc : s -> right assoc, r -> left assoc P:("rsssssssssssssrsrrc" / = < > <> <= >= "rrssssssssssssrsrrc" / & "rrrsssssssssssrsrrc" / + - "rrrrssssssssssrsrrc" / * / "rrrrrsssssssssrsrrc" / ^ "rrrrrrssssssssrsrrc" / _ "rrrrrrrsssssssrsrrc" / 3 "rrrrrrrrssssssrsrrc" / 2 "rrrrrrrrrsssssrsrrc" / 1 "rrrrrrrrrrssssrsrrc" / f "rrrrrrrrrrrsssrsrrc" / , "rrrrrrrrrrrrssrsrrc" / "rrrrrrrrrrrrrsrsrrc" / ! "rrrrrrrrrrrrrrrrrrc" / : "rrrrrrrrrrrrrrrrrrc" / ; "sssssssssssssssss c" / ( "rrrrrrrrrrrrrrr rrc" / ) "ssssssssssssssss ac") / Z state:{{.[x;(;y);:;z]}/[((#x),256)#-1;y;+x]} D:"0123456789.%" C:(D,"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ";"[";"]";"\"") C,:,F:?(,//O)_dvl Z,*C M:state[(1 -1 -1 4 6 / 0 start 1 2 -1 4 6 / 1 constant 2 -1 3 -1 2 / 2 [ 1 -1 -1 4 6 / 3 ] 4 4 4 5 4 / 4 open quote 1 -1 -1 4 6 / 5 close quote 1 -1 -1 4 6)]_ic C / 6 operator I:0 3 5 / token class endpoints / tokenize: token:{sep neg min(()one/fsm x)two/("<>";"<=";">=")} / tokenize fsm:{cut[x]0 M\_ic x} / scan input cut:{{:[1=#x;*x;x]}'(&(~=)':I _binl y)_ x} / cut into vectors and atoms one:{x,:[&/y _lin F;y;,y]} / operator strings -> atoms two:{@[x;i;:[;y]]_di -1+i:&0{&/x~'(z;y)}[y]':x} / 2 char operators -> 1 min:{@[x;&{((y _in,/O)&~y~")")&x~"-"}':"(",x;:;"_"]} / - x -> _ x neg:{@[x;i;,;x i+1]_di 1+i:&{(y~"_")&(*x)_in D}':x} / _ n -> _n sep:{ / g(,) -> g(;) b:0#i:0;while[i<#x;c:x i / loop over tokens :[c _in*G;b,:1;c _in G 1;b,:0;c~")";b:-1_ b;(*|b)&c~",";x[i]:";"] / , -> ; in scope of g i+:1];x} / iterate / parse: parse:{T::();,/*|end oper/("";token[x],,Z;,Z;"")} / zero trace, parse end:{~&/x[1 2]~\:,Z} / o- and v-stack = Z? oper:{t:P . class'x[2 1;0];trace[t]x;A[`$t]. x} / apply operator to input class:{(|/'x _in/:O)?1} / syntax class trace:{T,:,(,/15 -15 15 15$',//'@[y;0;,;" | "]),5$x} / append to trace tree:{,(,*x),y} / parse-tree A.a:{[j;i;o;v](j;i;o;v)} / accept A.c:{[j;i;o;v](j,*i;1_ i;o;(,*i),v)} / constant -> v-stack A.s:{[j;i;o;v](j,*i;1_ i;(,*i),o;v)} / shift operator -> o-stack A.r:{[j;i;o;v]:[0 K load:{ SD[x]:+z SS[x]:+{:["="=*x;1_ x;_n]}''$y } store:{ `SD 1:SD `SS 1:SS } load2:{ SS[]:{:[~@x;parse x;x]}'''SS[] SR::.[SS;(;;);:[;()]] (!SS){((!#y),/:\:!#*y)locs[x]''y;}'SS[] } get:{`$$.W x} / get sheet set:{.W[x]:.[$y;(;);{:["="=*x;x;y]};z]} / set sheet vec:{s:^m:*x[];i:&2=4::'v:,/m;v[i]:+(,/'x[])[;i];.,(`s;s#v)} / vectorize test:{[n].W[]:{:[2=4:x;1.*n _draw 100;x]}'''.W[];} / replicate scalars / GUI show:{ TT[!`SD]:where'SD[] .[`SD;(.;`k);:[;".k.ssk[.k.ss _v]._i"]] SD[.;`bg]:bg SD..a::*!`SD Sheets::@[_n;!`SD;:[;"SD..a:_i"]] `show$`.k } bg:{ :[_n~x;0 _i _in+p:TT ss _v;990000 ~4:SS[ss _v]._i;99 (|/|/_i>'p)&|/_i _in'p;9900 999999]} .k..c:`form .k..a:(`Sheets`Deps;`SD) Deps:0 Deps..c:`check SD..c:`form SD..l:`Spreadsheets Sheets..c:`button ssk:{ if[(y,z)_in+t:TT x;:table[x;y]z] if[(|/z>t 1)&y _in t 0;:row[x;y;z;*|index[x;y]z]] if[(|/y>t 0)&z _in t 1;:col[x;y;z;*index[x;y]z]] :[Deps;dependency;analyze][x;y]z } dependency:{ if[0<#d:SR . x,y,z a:`show$e:trc .'d .[~a;`I;:;,/'d] .[~a;`f;:;(-|/#:'e)$] .[~a;`bg;:;990099] .[~a;`k;:;".k.dependency . ((~_v)`I)._i"] .[~a;`l;:;trc[x]y,z]] } analyze:{ d:,($SD[x]. y,z),"=" if[~4:f:SS[x]. y,z a:`show$e:d,indent[0]name[x;y,z]f .[~a;`I;:;(x;y;z)] .[~a;`f;:;(-|/#:'e)$] .[~a;`bg;:;999900] .[~a;`k;:;".k.ssfk[_v]._i"] .[~a;`l;:;trc[x]y,z]] } table:{matrix many[x;y]z} row:{[x;y;z;a]matrix many[x;y;a][0,z-a;]} col:{[x;y;z;a]matrix many[x;a;z][;0,y-a]} many:{ c:z+!(z+(z _ SD[x;y])?_n)-z r:y+!(y+(y _ SD[x;;z])?_n)-y m:+:[Deps;trc .'''SR[x;r;c];(r,/:\:c)forms[x]''SS[x;r;c]] m[;0]:,:'$SD[x;*r;c];m[0]:,:'$SD[x;r;*c] m} forms:{[t;i;f]:[4:f;,"";indent[0]f]} matrix:{ c:(|/#:')'x a:`show$e:,/'+c{:[x=#y;y;y,(x-#y)#,""]}/:'x .[~a;`bg;:;mbg[-1++\c]] .[~a;`f;:;{(-|/#:'_v@*_i)$x}] .[~a;`e;:;{~0 _in _i}] } mbg:{y;:[0 _in _i;808080;((_i[0]!2)!606060 909090)(x _bin*|_i)!2]} ssfk:{ if["."_in d:x . y b:`$*a:1_'(&"."=a)_ a:".",(+/&\d=" ")_ d i:i(SD[b]./:i:+TT b)?`$a 1 j:($SD[b;i 0])?a 2 k:($SD[b;;i 1])?a 3 analyze[b;k]j] } indent:{:[~4:y;(,(x#" "),*y),,/_f[x+1]'1_ y;,(x#" "),y]} ss:{`$*|1_'(&d=".")_ d:$x} name:{:[4:z;leaf[x;y]z;"!"~*z;leaf[`$z 1;y]z 2;@[z;1_!#z;_f[x;y]]]} leaf:{:[~"R"=*z;z;trc . r1c1[x;y]z]} r1c1:{(x;|++rc'[|^SS x;|y;(0,z?"C")_ z:(),z])} rc:{:[0=#z;!x;1=#z;y;rel[y;z].(0$_dvl[z]"RC[]")]} rel:{:["["_in y;x+z;z-1]} trc:{i:index[x]. y;($x),".",($SD[x]. i),".",($SD[x;i 0;y 1]),".",$SD[x;y 0;i 1]} index:{TT[x;;*|{x@&y[x]