SS.k 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. / utils (ppr -> pretty print)
  2. \d u
  3. \l utils.k
  4. / csv parser
  5. \d csv
  6. \l ngnk-libs/csv/csv.k
  7. \d .
  8. / excel pattern finder
  9. \l excelpm.k
  10. \d .
  11. / ====================================================================================
  12. / helpers ============================================================================
  13. / ====================================================================================
  14. slice: {[l;s;e] s_(e)#l}; / slice a list (l) from start (s) til end (e)
  15. listize: {1_(,/(";",)'{"(",x,")"}'x)}; / turn a list(l) of strings into a string representation of a k list
  16. 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)
  17. s2n: {[s] `i$s;}; / string to number
  18. parseidx: {core: slice[x;1;#x]; split[core;";"]}; / parse a string containing k index
  19. str: `k@;
  20. gi: {[r;c;rb;cb] / generate indices of a rowxcol table starting from row=rb and col=cb
  21. i: r#(,!c)
  22. i: ((!r)+rb) {x,'y}'(i+cb);
  23. :i
  24. };
  25. hasloops: {deps:&'x; d:deps; #,/((#deps)(,/'deps@)/d)>0}; / determine if dependency table contains loops
  26. order: { / come up with a order of calculations for a dependency graph
  27. deps: {$[+/x>0;&x;()]}'x;
  28. d: ?,/deps;
  29. all: !(#deps);
  30. :d,(all^d)
  31. };
  32. / ====================================================================================
  33. / excel formula handler ==============================================================
  34. / ====================================================================================
  35. mc: {[c;i] / generate indices for column-based indexing
  36. i: gi[(#table);i+1;0;c];
  37. :i
  38. };
  39. mr: {[r;i] / generate indices for row-based indexing
  40. i: gi[i+1;(#table[0]);r;0];
  41. :i
  42. };
  43. drr: {[s;e] / decode range of indices from start(s) to end(e) with one indicator missing (full rows or full column selection)
  44. r: $[s[0]<0;mc[s[1];(e[1]-s[1])];mr[s[0];(e[0]-s[0])]];
  45. :r
  46. };
  47. dre: {[s;e] / decode range of indices from start(s) to end(e) with both indices present
  48. :gi[(e[0]-s[0])+1;(e[1]-s[1])+1;s[0];s[1]]
  49. };
  50. dr: {[s;e] / decode range from start(s) to end(e)
  51. ln: (s[0]<0) | (s[1]<0);
  52. rn: (e[0]<0) | (e[1]<0);
  53. :$[ln|rn;drr[s;e];dre[s;e]]
  54. };
  55. dbit: {[b] / decode bit - refering to A3 or C5 part of A3:C5
  56. ci: (`i$(b@&(pat.testAtZ'b)))-65; // col index
  57. ri: (`i$(b@&(pat.test0t9'b)))-49; // row index
  58. ci: $[(#ci)>0;*ci;-1];
  59. ri: $[(#ri)>0;*ri;-1];
  60. :(ri;ci)
  61. };
  62. lr: {[f] / turn A3:C5 into left and right bits
  63. ci: *&(":"~'f);
  64. l: slice[f;0;ci];
  65. r: slice[f;ci+1;#f];
  66. lb: dbit[l];
  67. rb: dbit[r];
  68. :(lb;rb);
  69. };
  70. de:{[idx;cell] / decode excel string in a cell
  71. ci: cell[0];
  72. cell: cell[1];
  73. idx: (*idx);
  74. f: slice[cell;idx[0];idx[1]];
  75. l: slice[cell;0;idx[0]];
  76. r: slice[cell;idx[1];#cell];
  77. (fl;fr): lr[f];
  78. range: dr[fl;fr];
  79. i: (ci[0]*3) + ci[1];
  80. {
  81. i:(*y);
  82. i: (i[0]*3)+i[1];
  83. deps[x;i]: 1;
  84. }[(ci[0]*3)+ci[1];]'range;
  85. / compiled list
  86. cl: {i:(*x); "self[",(`k@x[0;0]),";",(`k@x[0;1]),"]"}'range;
  87. cl: l,"(",({x,";",y}/cl),")",r;
  88. table[ci[0];ci[1];1]:: cl;
  89. };
  90. / ====================================================================================
  91. / Compiler ===========================================================================
  92. / ====================================================================================
  93. tstkey: "States/Events"; / key indicating start of transition section
  94. cstkey: "Events"; / key indicating start of events condition section
  95. astkey: "Actions"; / key indicating start of actions section
  96. sectionkeys: (tstkey;cstkey;astkey);
  97. fname: "SS.csv";
  98. tname: "SS";
  99. lines: {x,"\n",y}/(0: fname);
  100. table:: csv.csv[lines];
  101. d: (#table)*(#table[0]);
  102. deps:: (d;d)#0;
  103. / excel patterns
  104. :pats: pat.run''table;
  105. u.ppr'table;
  106. // start with last to maintain prior index accuracy
  107. lasts:{:((#x[0])-1)_x[0]}''pats;
  108. firsts:{:$[(#x[0])>1;((#x[0])-1)#x[0];0]}''pats;
  109. f: pats {
  110. :$[x[2]=5;y;0]
  111. }''lasts;
  112. ti: gi[#table;#table[0];0;0];
  113. ptable:: table;
  114. table::ti {(,x),,y}''table;
  115. table {
  116. :$[y~0;0;de[y;x]]
  117. }''f;
  118. table {
  119. :$[y~0;0;de[y;x]]
  120. }''firsts;
  121. ord:order[deps];
  122. / ====================================================================================
  123. / Generator ==========================================================================
  124. / ====================================================================================
  125. compstr:: "/ compiled ",fname,"\n\n";
  126. al: {[l;indt] tab: "" {[x;y] x,"\t"}/(indt#0); compstr:: compstr,tab,l,"\n"}; // add line with indentation
  127. al[(tname,":{[]");0];
  128. al["self:(", (str (#table)),";", (str (#table[0])), ")#0;\n";1];
  129. {
  130. d: #table;
  131. i0: `i$(_(x%d));
  132. i1: x-(i0*d);
  133. al["self[",(str(i0)),";",(str(i1)),"]: ", table[i0;i1;1], ";";1];
  134. }'ord;
  135. al[":self";1];
  136. al[("};");0];
  137. `0: compstr;