repl.k 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. #!k
  2. \d repl
  3. banner:"ngn/k, (c) 2019-2024 ngn, GNU AGPLv3. type \\ for more info\n"
  4. prompt:," " /use 0x0720 for emacs integration
  5. (opn;sem;cls):"(;)"
  6. (opn;sem;cls):("( ";" ; ";" )") /uncomment this line for extra spacing
  7. lines:cols:999
  8. upd:{(lines;cols)::`I$"\n"\`x(("/usr/bin/env";"tput";"-S");"lines\ncols\n")}
  9. lim:{(x<#y)(x#)/y}
  10. dd:{(x<#y)(,[;".."](x-2)#)/y}
  11. fmt:{upd[];$[(::)~x;"";(1<#x)&|/`m`M`A=@x;mMA x;(dd[cols]`k@lim[cols]x),"\n"]}
  12. fmtx:{$[(::)~x;"";`k[x],"\n"]}
  13. mMA:{(P;f;q):((,"!/+(";dct;,")");(("+![";" +(");tbl;")]");(,,"(";lst;,")"))`m`M`A?t:@x
  14. w:cols-#*P;u:w-#q;h:lines-2
  15. x:$[h<(`M=t)+#x;,[;,".."](h-1)#f[w;u;h#x];f[w;u;x]]
  16. ,[;"\n"]@"\n"/@[;-1+#x;,;q]P[!#x],'x}
  17. lst:{[w;u;x](((-1+#x)#w),u)dd'`k'lim[cols]'x}
  18. dct:{[w;u;x]k:(|/#'k)$k:`k'!x;par'(((-1+#x)#w-3),u-3)dd'sem/'+(k;`k'.x)}
  19. tbl:{[w;u;x]h:`k'!x;d:`k''.x;W:(#'h)|/'#''d
  20. r:,$[`S~@!x;dd[w](""opn),(""sem)/;par@dd[w-2]@sem/]W$'h
  21. r,par'dd[w-2]'sem/'+@[W;&~^`i`d?_@'.x;-:]$'d}
  22. cell:{$[|/`i`d=@y;-x;x]$z}
  23. par:{opn,x,cls}
  24. cmds:(,"a")!{`1:1:joinpath[dirname`argv 0]"LICENSE";}
  25. basename:{*|"/"\x}
  26. dirname:{$[#x:"/"/-1_"/"\x;x;,"."]}
  27. joinpath:{$[x~,".";y;"/"~*|x;x,y;x,"/",y]}
  28. line0:{c:{0x07~*-2#*x}{(l;r):x;(1:1;r,,(-2_l))}/(x;());"\n"/(*|c),,*c}
  29. line1:{$[#x;;:0];x:-1_x;$[(3>#x)&("\\"=*x)&~^(!cmds)?x 1;cmds[x 1]x 1;.[`1:(fmt;fmtx)[" "~*x]@.:;,x;{`0:`err[]}]];`1:prompt;1}
  30. line:line1@line0@
  31. $["repl.k"~basename`argv 1;{cmds::@[cmds;x[1]1;:;{y;`0:x}2_x]}'{(&x~\:80#"-")_x:(1+*&x~\:,"/")_-1_x}@0:`argv 1;];
  32. run:{`1:banner,prompt;{line@1:`}::/`;}
  33. \d .
  34. $[(~"kw"~`argv 0)&~"--non-interactive"~*x;repl.run[];]
  35. /
  36. --------------------------------------------------------------------------------
  37. \ help \\ exit
  38. \a license(AGPLv3) \l file.k load
  39. \0 types \d foo set namespace; restore with \d .
  40. \+ verbs \t:n expr time(elapsed milliseconds after n runs)
  41. \: I/O verbs \v variables
  42. \' adverbs \f functions
  43. \` symbols \cd path change directory
  44. \h summary \other command(through /bin/sh)
  45. --------------------------------------------------------------------------------
  46. \0
  47. Types:
  48. list atom
  49. `A generic list () ,"ab" (0;`1;"2";{3};%)
  50. `I `i int 0N -9223372036854775807 01b
  51. `F `f float -0w -0.0 0.0 0w 1.2e308 0n
  52. `C `c char "a" 0x6263 "d\0\"\n\r\t"
  53. `S `s symbol ` `a `"file.txt" `b`cd`"ef"
  54. `M `m table&dict +`a`b!(0 1;"23") (0#`)!()
  55. `o lambda {1+x*y#z} {[a;b]+/*/2#,a,b}
  56. `p projection 1+ {z}[0;1] @[;i;;]
  57. `q composition *|: 1+{x*y}@
  58. `r derived verb +/ 2\ {y,x}':
  59. `u monadic verb +: 0::
  60. `v dyadic verb + 0:
  61. `w adverb ' /:
  62. `x external func
  63. --------------------------------------------------------------------------------
  64. \:
  65. I/O verbs
  66. 0:x read lines
  67. x 0:y write lines
  68. 1:x read bytes
  69. x 1:y write bytes
  70. <s open fd:<`"file.txt"
  71. >i close >fd
  72. x can be a file descriptor (int) or symbol or string such as
  73. "file.txt"
  74. "/path/to/file"
  75. "host:port"
  76. ":port" /host defaults to 127.0.0.1
  77. --------------------------------------------------------------------------------
  78. \+
  79. Verbs: : + - * % ! & | < > = ~ , ^ # _ $ ? @ . 0: 1:
  80. notation: [c]har [i]nt [n]umber(int|float|char) [s]ymbol [a]tom [d]ict
  81. [f]unc(monad) [F]unc(dyad) [xyz]any
  82. special: var:y set a:1;a -> 1
  83. var::y global a:1;{a::2}[];a -> 2
  84. (v;..):y unpack (b;(c;d)):(2 3;4 5);c -> 4
  85. :x return {:x+1;2}[3] -> 4
  86. :[x;y;..] cond :[0;`a;"\0";`b;`;`c;();`d;`e] -> `e
  87. o[..] recur {:[x<2;x;+/o'x-1 2]}9 -> 34
  88. [..] progn [0;1;2;3] -> 3
  89. :: self f:(::);f 12 -> 12
  90. : right f:(:);f[1;2] -> 2 "abc":'"d" -> "ddd"
  91. +x flip +("ab";"cd") -> ("ac";"bd")
  92. N+N add 1 2+3 -> 4 5
  93. -N negate - 1 2 -> -1 -2
  94. N-N subtract 1-2 3 -> -1 -2
  95. *x first *`a`b -> `a *(0 1;"cd") -> 0 1
  96. N*N multiply 1 2*3 4 -> 3 8
  97. %N sqrt %25 -> 5.0 %-1 -> 0n
  98. N%N divide 2 3%4 -> 0.5 0.75
  99. !i enum !3 -> 0 1 2 !-3 -> -3 -2 -1
  100. !I odometer !2 3 -> (0 0 0 1 1 1;0 1 2 0 1 2)
  101. !d keys !`a`b!0 1 -> `a`b
  102. !S ns keys a.b.c:1;a.b.d:2;!`a`b -> `c`d
  103. x!y dict `a`b!1 2 -> `a`b!1 2
  104. i!I div -10!1234 567 -> 123 56
  105. i!I mod 10!1234 567 -> 4 7
  106. &I where &3 -> 0 0 0 &1 0 1 4 2 -> 0 2 3 3 3 3 4 4
  107. &x deepwhere &(0 1 0;1 0 0;1 1 1) -> (0 1 2 2 2;1 0 0 1 2)
  108. N&N min/and 2&-1 3 -> -1 2 0 0 1 1&0 1 0 1 -> 0 0 0 1
  109. |x reverse |"abc" -> "cba" |12 -> 12
  110. N|N max/or 2|-1 3 -> 2 3 0 0 1 1|0 1 0 1 -> 0 1 1 1
  111. <X ascend <"abacus" -> 0 2 1 3 5 4
  112. >X descend >"abacus" -> 4 5 3 1 0 2
  113. <s open fd:<`"/path/to/file.txt"
  114. >i close >fd
  115. N<N less 0 2<1 -> 1 0
  116. N>N more 0 1>0 2 -> 0 0
  117. =X group ="abracadabra" -> "abrcd"!(0 3 5 7 10;1 8;2 9;,4;,6)
  118. =i unitmat =3 -> (1 0 0;0 1 0;0 0 1)
  119. N=N equal 0 1 2=0 1 3 -> 1 1 0
  120. ~x not ~(0 2;``a;"a \0";::;{}) -> (1 0;1 0;0 0 1;1;0)
  121. x~y match 2 3~2 3 -> 1 "4"~4 -> 0 0~0.0 -> 0
  122. ,x enlist ,0 -> ,0 ,0 1 -> ,0 1 ,`a!1 -> +(,`a)!,,1
  123. x,y concat 0,1 2 -> 0 1 2 "a",1 -> ("a";1)
  124. d,d merge (`a`b!0 1),`b`c!2 3 -> `a`b`c!0 2 3
  125. ^x null ^(" a";0 1 0N;``a;0.0 0n) -> (1 0;0 0 1;1 0;0 1)
  126. a^y fill 1^0 0N 2 3 0N -> 0 1 2 3 1 "b"^" " -> "b"
  127. X^y without "abracadabra"^"bc" -> "araadara"
  128. #x length #"abc" -> 3 #4 -> 1 #`a`b`c!0 1 0 -> 3
  129. i#y take 5#"abc" -> "abcab" -5#`a`b`c -> `b`c`a`b`c
  130. X#d take keys `c`d`f#`a`b`c`d!1 2 3 4 -> `c`d`f!3 4 0N
  131. I#y reshape 2 3#` -> (```;```)
  132. f#y replicate (3>#:')#(0;2 1 3;5 4) -> (0;5 4) {2}#"ab" -> "aabb"
  133. _n floor _12.34 -12.34 -> 12 -13
  134. _c lowercase _"Ab" -> "ab"
  135. i_Y drop 2_"abcde" -> "cde" -2_`a`b`c -> ,`a
  136. X_d drop keys `a`c_`a`b`c!0 1 2 -> (,`b)!,1
  137. I_Y cut 2 4 4_"abcde" -> ("cd";"";,"e")
  138. f_Y weed out (3>#:')_(0;2 1 3;5 4) -> ,2 1 3
  139. X_i delete "abcde"_2 -> "abde"
  140. $x string $(12;"ab";`cd;+) -> ("12";(,"a";,"b");"cd";,"+")
  141. i$C pad 5$"abc" -> "abc " -3$"a" -> " a"
  142. s$y cast `c$97 -> "a" `i$-1.2 -> -1 `$"a" -> `a
  143. s$y int `I$"-12" -> -12
  144. ?X distinct ?"abacus" -> "abcus"
  145. ?i uniform ?2 -> 0.6438163747387873 0.8852656305774402 /random
  146. X?y find "abcde"?"bfe" -> 1 0N 4
  147. i?x roll 3?1000 -> 11 398 293 1?0 -> ,-8164324247243690787
  148. i?x deal -3?1000 -> 11 398 293 /guaranteed distinct
  149. @x type @1 -> `i @"ab" -> `C @() -> `A @(@) -> `v
  150. x@y apply(1) {x+1}@2 -> 3 "abc"@1 -> "b" (`a`b!0 1)@`b -> 1
  151. .S get a:1;.`a -> 1 b.c:2;.`b`c -> 2
  152. .C eval ."1+2" -> 3
  153. .d values .`a`b!0 1 -> 0 1
  154. x.y apply(n) {x*y+1}. 2 3 -> 8 (`a`b`c;`d`e`f). 1 0 -> `d
  155. @[x;y;f] amend @["ABC";1;_:] -> "AbC" @[2 3;1;{-x}] -> 2 -3
  156. @[x;y;F;z] amend @["abc";1;:;"x"] -> "axc" @[2 3;0;+;4] -> 6 3
  157. .[x;y;f] drill .[("AB";"CD");1 0;_:] -> ("AB";"cD")
  158. .[x;y;F;z] drill .[("ab";"cd");1 0;:;"x"] -> ("ab";"xd")
  159. .[f;y;f] try .[+;1 2;"E:",] -> 3 .[+;1,`;"E:",] -> "E:'type\n"
  160. ?[x;y;z] splice ?["abcd";1 3;"xyz"] -> "axyzd"
  161. --------------------------------------------------------------------------------
  162. \`
  163. Special symbols:
  164. `j?C parse json `j?"{\"a\":1,\"b\":[true,\"c\"]}" -> `a`b!(1.0;(1;,"c"))
  165. `k@x pretty-print `k("ab";2 3) -> "(\"ab\";2 3)"
  166. `p@C parse k
  167. `hex@C hexadecimal `hex"ab" -> "6162"
  168. `pri@i primes `pri 20 -> 2 3 5 7 11 13 17 19
  169. `x@x fork-exec `x(("/bin/wc";"-l");"a\nbc\nd\n") -> "3\n"
  170. `t[] current time (microseconds)
  171. `argv[] list of cmd line args (also in global variable x)
  172. `env[] dict of env variables
  173. `prng[] `prng@I get/set pseudo-random number generator internal state
  174. s:`prng[];r:9?0;`prng s;r~9?0 -> 1
  175. `prng@0 use current time to set state
  176. `err@C throw error
  177. `sin@N trigonometry `sin 12.34 -> -0.22444212919135995
  178. `exp@N exponential `exp 1 -> 2.7182818284590455
  179. `ln@N logarithm `ln 2 -> 0.6931471805599453
  180. `exit@i exit
  181. --------------------------------------------------------------------------------
  182. \'
  183. Adverbs: ' / \ ': /: \:
  184. f' each1 #'("abc";3 4 5 6) -> 3 4
  185. x F' each2 2 3#'"ab" -> ("aa";"bbb")
  186. X' binsearch 1 3 5 7 9'8 9 0 -> 3 4 -1
  187. F/ fold +/1 2 3 -> 6
  188. F\ scan +\1 2 3 -> 1 3 6
  189. x F/ seeded / 10+/1 2 3 -> 16
  190. x F\ seeded \ 10+\1 2 3 -> 11 13 16
  191. i f/ n-do 5(2*)/1 -> 32
  192. i f\ n-dos 5(2*)\1 -> 1 2 4 8 16 32
  193. f f/ while (1<){:[2!x;1+3*x;-2!x]}/3 -> 1
  194. f f\ whiles (1<){:[2!x;1+3*x;-2!x]}\3 -> 3 10 5 16 8 4 2 1
  195. f/ converge {1+1.0%x}/1 -> 1.618033988749895
  196. f\ converges (-2!)\100 -> 100 50 25 12 6 3 1 0
  197. C/ join "ra"/("ab";"cadab";"") -> "abracadabra"
  198. C\ split "ra"\"abracadabra" -> ("ab";"cadab";"")
  199. I/ decode 24 60 60/1 2 3 -> 3723 2/1 1 0 1 -> 13
  200. I\ encode 24 60 60\3723 -> 1 2 3 2\13 -> 1 1 0 1
  201. i': window 3':"abcdef" -> ("abc";"bcd";"cde";"def")
  202. i f': stencil 3{x,"."}':"abcde" -> ("abc.";"bcd.";"cde.")
  203. F': eachprior -':12 13 11 17 14 -> 12 1 -2 6 -3
  204. x F': seeded ': 10-':12 13 11 17 14 -> 2 1 -2 6 -3
  205. x F/: eachright 1 2*/:3 4 -> (3 6;4 8)
  206. x F\: eachleft 1 2*\:3 4 -> (3 4;6 8)
  207. --------------------------------------------------------------------------------
  208. \h
  209. : SET RETURN :[c;t;f] COND
  210. + add flip
  211. - subtract negate ' each|slide|bin
  212. * multiply first / fold|join |dec|comment
  213. % divide sqrt \ scan|split|enc|trace
  214. ! mod|dict enum|key ': eachprior
  215. & min|and where /: eachright
  216. | max|or reverse \: eachleft
  217. < less ascend
  218. > more descend /
  219. = equal group multiline comment
  220. ~ match not \
  221. , concat enlist
  222. ^ without null 0: lines i/o
  223. # reshape length 1: bytes i/o
  224. _ drop|cut floor
  225. $ cast string
  226. ? find|rnd uniq ?[a;i;b] splice
  227. @ apply(1) type @[x;i;[f;]y] amend
  228. . apply(n) eval .[x;i;[f;]y] drill
  229. grammar: E:E;e|e e:nve|te| t:n|v v:tA|V n:t[E]|(E)|{E}|N
  230. limits: 8args 16locals 256globals 256bytecode 2048stack
  231. \