123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- / ====================================================================================
- / Notes ==============================================================================
- / ====================================================================================
- / This code uses zipped lists in multiple occasions. Any hardcoded indexing in the code
- / is most probably a result of that.
- / \d changes the namespace before import to add a prefix to the functions imported to
- / avoid overlaps. It is used whe the imported file doesn't define a namespace itself.
- / ====================================================================================
- / Imports ============================================================================
- / ====================================================================================
- / utils (ppr -> pretty print)
- \d u
- \l utils.k
- / csv parser
- \d csv
- \l ngnk-libs/csv/csv.k
- \d .
- / excel pattern finder
- \l excelpm.k
- \d .
- / ====================================================================================
- / helpers ============================================================================
- / ====================================================================================
- slice: {[l;s;e] s_(e)#l}; / slice a list (l) from start (s) til end (e)
- listize: {1_(,/(";",)'{"(",x,")"}'x)}; / turn a list(l) of strings into a string representation of a k list
- split: {[l;di] idx: (-1,&(di~'l)),(#l); {slice[x;y[0]+1;y[1]+1]}[l]'(idx@(2':!#idx))}; / split a list(l) by delimiter (di)
- s2n: {[s] `i$s;}; / string to number
- parseidx: {core: slice[x;1;#x]; split[core;";"]}; / parse a string containing k index
- str: `k@;
- gi: {[r;c;rb;cb] / generate indices of a rowxcol sheet starting from row=rb and col=cb
- i: r#(,!c)
- i: ((!r)+rb) {x,'y}'(i+cb);
- :i
- };
- hasloops: {deps:&'x; d:deps; #,/((#deps)(,/'deps@)/d)>0}; / determine if dependency sheet contains loops
- order: { / come up with an order of calculations for a dependency graph
- deps: {$[+/x>0;&x;()]}'x;
- d: ?,/deps;
- all: !(#deps);
- :d,(all^d)
- };
- / ====================================================================================
- / excel formula handler ==============================================================
- / ====================================================================================
- mc: {[c;i] / generate indices for column-based indexing
- i: gi[(#sheet);i+1;0;c];
- :i
- };
- mr: {[r;i] / generate indices for row-based indexing
- i: gi[i+1;(#sheet[0]);r;0];
- :i
- };
- drr: {[s;e] / decode range of indices from start(s) to end(e) with one indicator missing (full rows or full column selection)
- r: $[s[0]<0;mc[s[1];(e[1]-s[1])];mr[s[0];(e[0]-s[0])]];
- :r
- };
- dre: {[s;e] / decode range of indices from start(s) to end(e) with both indices present
- :gi[(e[0]-s[0])+1;(e[1]-s[1])+1;s[0];s[1]]
- };
- dr: {[s;e] / decode range from start(s) to end(e)
- ln: (s[0]<0) | (s[1]<0);
- rn: (e[0]<0) | (e[1]<0);
- :$[ln|rn;drr[s;e];dre[s;e]]
- };
- dbit: {[b] / decode bit - refering to A3 or C5 part of A3:C5
- ci: (`i$(b@&(pat.testAtZ'b)))-65; // col index
- ri: (`i$(b@&(pat.test0t9'b)))-49; // row index
- ci: $[(#ci)>0;*ci;-1];
- ri: $[(#ri)>0;*ri;-1];
- :(ri;ci)
- };
- lr: {[f] / turn A3:C5 into left and right bits
- ci: *&(":"~'f);
- l: slice[f;0;ci];
- r: slice[f;ci+1;#f];
- lb: dbit[l];
- rb: dbit[r];
- :(lb;rb);
- };
- de:{[idx;cell] / decode excel string in a cell
- / unwrap input
- ci: cell[0]; / cell index
- cell: cell[1]; / cell string
- idx: (*idx); / index of detected excel string in cell string
- f: slice[cell;idx[0];idx[1]]; / excel string
- l: slice[cell;0;idx[0]]; / what's before the string
- r: slice[cell;idx[1];#cell]; / what's after the string
- (fl;fr): lr[f];
- range: dr[fl;fr];
- / register dependencies
- i: (ci[0]*3) + ci[1];
- {
- i:(*y);
- i: (i[0]*3)+i[1];
- deps[x;i]: 1;
- }[(ci[0]*3)+ci[1];]'range;
- / compiled list
- cl: {i:(*x); "self[",(`k@x[0;0]),";",(`k@x[0;1]),"]"}'range;
- cl: l,"(",({x,";",y}/cl),")",r;
- sheet[ci[0];ci[1];1]:: cl;
- };
- / ====================================================================================
- / Compiler ===========================================================================
- / ====================================================================================
- tstkey: "States/Events"; / key indicating start of transition section
- cstkey: "Events"; / key indicating start of events condition section
- astkey: "Actions"; / key indicating start of actions section
- sectionkeys: (tstkey;cstkey;astkey);
- fname: "SS.csv";
- tname: "SS";
- lines: {x,"\n",y}/(0: fname);
- sheet:: csv.csv[lines];
- d: (#sheet)*(#sheet[0]);
- deps:: (d;d)#0;
- / excel patterns
- :pats: pat.run''sheet;
- u.ppr'sheet;
- lasts:{:((#x[0])-1)_x[0]}''pats;
- firsts:{:$[(#x[0])>1;((#x[0])-1)#x[0];0]}''pats;
- / start with last to maintain prior index accuracy
- f: pats {
- :$[x[2]=5;y;0]
- }''lasts;
- ti: gi[#sheet;#sheet [0];0;0];
- sheet::ti {(,x),,y}''sheet; / zip sheet and indices
- sheet{
- :$[y~0;0;de[y;x]]
- }''f;
- sheet{
- :$[y~0;0;de[y;x]]
- }''firsts;
- ord:order[deps];
- / ====================================================================================
- / Generator ==========================================================================
- / ====================================================================================
- compstr:: "/ compiled ",fname,"\n\n";
- al: {[l;indt] tab: "" {[x;y] x,"\t"}/(indt#0); compstr:: compstr,tab,l,"\n"}; // add line with indentation
- al[(tname,":{[]");0];
- al["self:(", (str (#sheet)),";", (str (#sheet[0])), ")#0;\n";1];
- {
- d: #sheet;
- i0: `i$(_(x%d));
- i1: x-(i0*d);
- al["self[",(str(i0)),";",(str(i1)),"]: ", sheet[i0;i1;1], ";";1];
- }'ord;
- al[":self";1];
- al[("};");0];
- `0: compstr;
|