std.qi 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773
  1. func Object(t, p=nil, o={}): return p !is nil? set_meta_table(p, get_meta_table(p) + t): set_meta_table(o, t)
  2. func is_object(o): return has_meta_table(o)
  3. func __class_wrapper(n, p, t, mt, st): return Object({
  4. "t": t,
  5. "mt": mt,
  6. "super": p,
  7. "__type": func (this) use (n): return n,
  8. "__str": func (this) use (n): return "<class " + n + ">",
  9. "__call": func (this, pargs) use (n, p) {
  10. var t = {}
  11. var mt = { "__type": func (this) use (n): n }
  12. if p {
  13. var i = 0
  14. for i < len(p) {
  15. t += p[i].t
  16. mt += p[i].mt
  17. i += 1
  18. }
  19. }
  20. t += this.t
  21. mt += this.mt
  22. mt.super = this.super
  23. var obj = set_meta_table(t, mt)
  24. if "constructor" in mt
  25. func_call(mt.constructor, [obj] + pargs)
  26. return obj
  27. }
  28. }, nil, st)
  29. class Error {
  30. msg = nil
  31. constructor (this, msg=nil) {
  32. this.msg = msg
  33. }
  34. __str (this): this.msg is nil? type(this): type(this) + ": " + this.msg
  35. }
  36. class AssertionError(Error)
  37. class TypeError(Error)
  38. class ValueError(Error)
  39. class IndexError(Error)
  40. class KeyError(Error)
  41. class RecursionError(Error)
  42. class NameError(Error)
  43. class IOError(Error)
  44. func isinstance(a, b): return type(a) == type(b)
  45. func head(l): return l[0]
  46. func tail(l): return slice(l, 1)
  47. func min(x, y): x < y? x: y
  48. func max(x, y): x > y? x: y
  49. func reverse(x) {
  50. if type(x) !in ("list", "string", "bytes")
  51. throw TypeError("expected first argument to be: list, string or bytes, but got: " + type(x))
  52. var r = []
  53. for var i = len(x)-1; i >= 0; i--
  54. list_push(r, x[i])
  55. if type(x) == "string"
  56. return list_join(r)
  57. elif type(x) == "bytes"
  58. return bytes(r)
  59. return r
  60. }
  61. set_pseudomethod("list.reverse", reverse)
  62. set_pseudomethod("string.reverse", reverse)
  63. set_pseudomethod("bytes.reverse", reverse)
  64. func range(f) {
  65. var t, s
  66. if len(arguments) >= 3 {
  67. t = arguments[1]
  68. s = arguments[2]
  69. } elif len(arguments) >= 2 {
  70. t = arguments[1]
  71. s = 1
  72. } else {
  73. t = f
  74. f = 0
  75. s = 1
  76. }
  77. if type(f) != "number"
  78. throw TypeError("expected first argument to be: number, but got: " + type(f))
  79. if type(t) != "number"
  80. throw TypeError("expected second argument to be: number, but got: " + type(t))
  81. if type(s) != "number"
  82. throw TypeError("expected third argument to be: number, but got: " + type(s))
  83. if f > t
  84. return reverse(range(t, f, s))
  85. var r = []
  86. for var i = f; i < t; i += s
  87. list_push(r, i)
  88. return r
  89. }
  90. let SEEK_SET = 0, SEEK_CUR = 1, SEEK_END = 2
  91. func frewind(file)
  92. return file.rewind()
  93. func read_stdin() {
  94. return str(fread(STDIN, -1))
  95. }
  96. func file_read(filename) {
  97. let file = fopen(filename, "r")
  98. defer fclose(file)
  99. return str(fread(file, -1))
  100. }
  101. func file_write(filename, data) {
  102. let file = fopen(filename, "w")
  103. defer fclose(file)
  104. fwrite(file, bytes(data))
  105. }
  106. func is_defined(name) {
  107. if type(name) != "string"
  108. throw TypeError("expected first argument to be: string, but got: " + type(name))
  109. inline `qi_bool b = qi_find(state, qi_get(state, "name")->value.string) != NULL`
  110. inline `return qi_make_boolean(state, b)`
  111. }
  112. func is_table(a) {
  113. inline `return qi_make_boolean(state, qi_get(state, "a")->type == QI_TABLE)`
  114. }
  115. func list_remove(l, x, first=false) {
  116. if type(l) != "list"
  117. throw TypeError("expected first argument to be: list, but got: " + type(l))
  118. repeat:
  119. for var i = 0; i < len(l); i++
  120. if l[i] == x {
  121. list_delete(l, i)
  122. if first
  123. break
  124. goto repeat
  125. }
  126. }
  127. set_pseudomethod("list.remove", list_remove)
  128. func list_index(l, x, many=false) {
  129. if type(l) != "list"
  130. throw TypeError("expected first argument to be: list, but got: " + type(l))
  131. var r = []
  132. for var i = 0; i < len(l); i++
  133. if l[i] == x
  134. list_push(r, i)
  135. return many? r: r? r[0]: -1
  136. }
  137. set_pseudomethod("list.index", list_index)
  138. set_pseudomethod("tuple.index", func (t, x): list_index(list(t), x))
  139. func list_join(l) {
  140. if type(l) != "list"
  141. throw TypeError("expected first argumient to be: list, but got: " + type(l))
  142. var r = ""
  143. var s
  144. if len(arguments) == 1
  145. s = ""
  146. else
  147. s = arguments[1]
  148. if type(s) != "string"
  149. throw TypeError("expected second argument to be: string, but got: " + type(s))
  150. var first = true
  151. for var x of l {
  152. if type(x) != "string"
  153. throw TypeError("expected sequence item to be: string, but got: " + type(x))
  154. if s != "" && !first
  155. r += s
  156. r += x
  157. first = false
  158. }
  159. return r
  160. }
  161. set_pseudomethod("list.join", list_join)
  162. func list_pop_at(l, i) {
  163. if type(l) != "list"
  164. throw TypeError("expected first argument to be: list, but got: " + type(l))
  165. if type(i) != "number"
  166. throw TypeError("expected second argument to be: number, but got: " + type(i))
  167. var x = l[i]
  168. list_delete(l, i)
  169. return x
  170. }
  171. set_pseudomethod("list.popAt", list_pop_at)
  172. func __cmp(x, y): x > y? 1: x < y? -1: 0
  173. func list_sort(l, cmp=__cmp) {
  174. if type(l) != "list"
  175. throw TypeError("expected first argument to be: list, but got: " + type(l))
  176. if type(cmp) != "function"
  177. throw TypeError("expected second argument to be: function, but got: " + type(cmp))
  178. if len(l) == 0
  179. return l
  180. var z = len(l)
  181. for var i = 0; i < z - 1; i++
  182. for var j = 0; j < z - 1 - i; j++
  183. if cmp(l[j], l[j+1]) > 0 {
  184. let tmp = l[j]
  185. l[j] = l[j+1]
  186. l[j+1] = tmp
  187. }
  188. return l
  189. }
  190. func list_sorted(l, cmp=__cmp) {
  191. l = list_copy(l)
  192. return list_sort(l, cmp)
  193. }
  194. set_pseudomethod("list.sort", list_sort)
  195. set_pseudomethod("list.sorted", list_sorted)
  196. func list_shift(l) {
  197. if type(l) != "list"
  198. throw TypeError("expected first argument to be: list, but got: " + type(l))
  199. if is_empty(l)
  200. throw IndexError("shift from empty list")
  201. var a = l[0]
  202. list_delete(l, 0)
  203. return a
  204. }
  205. func list_unshift(l, x) {
  206. list_insert(l, 0, x)
  207. }
  208. set_pseudomethod("list.shift", list_shift)
  209. set_pseudomethod("list.unshift", list_unshift)
  210. set_pseudomethod("list.insert", list_insert)
  211. set_pseudomethod("list.delete", list_delete)
  212. set_pseudomethod("list.__sub", func (l, e): list_delete(list_copy(l), e))
  213. func slice(l) {
  214. if type(l) !in ("list", "string", "bytes", "ustr")
  215. throw TypeError("expected first argument to be: list, string, bytes or ustr, but got: " + type(l))
  216. var r = []
  217. if len(arguments) == 2 {
  218. var f = arguments[1]
  219. if type(f) != "number"
  220. throw TypeError("expected second argument to be: number, but got: " + type(f))
  221. if f < 0
  222. f += len(l)
  223. for var i = f; i < len(l); i++
  224. list_push(r, l[i])
  225. } elif len(arguments) == 3 {
  226. var f = arguments[1], t = arguments[2]
  227. if type(f) != "number"
  228. throw TypeError("expected second argument to be: number, but got: " + type(f))
  229. if type(t) != "number"
  230. throw TypeError("expected third argument to be: number, but got: " + type(t))
  231. if f < 0
  232. f += len(l)
  233. if t < 0
  234. t += len(l)
  235. for var i = f; i < len(l) && i <= t; i++
  236. list_push(r, l[i])
  237. }
  238. if type(l) == "string"
  239. return list_join(r)
  240. elif type(l) == "bytes"
  241. return bytes(r)
  242. elif type(l) == "ustr"
  243. return ustr(r)
  244. return r
  245. }
  246. set_pseudomethod("list.slice", slice)
  247. set_pseudomethod("string.slice", slice)
  248. set_pseudomethod("bytes.slice", slice)
  249. let __slice = slice;
  250. func str_startswith(s, p) {
  251. if type(s) != "string"
  252. throw TypeError("expected first argument to be: string, but got: " + type(s))
  253. if len(s) < len(p)
  254. return false
  255. return slice(s, 0, len(p)-1) == p
  256. }
  257. set_pseudomethod("string.startsWith", str_startswith)
  258. func str_endswith(s, p) {
  259. if type(s) != "string"
  260. throw TypeError("expected first argument to be: string, but got: " + type(s))
  261. if len(s) < len(p)
  262. return false
  263. return slice(s, len(s) - len(p)) == p
  264. }
  265. set_pseudomethod("string.endsWith", str_endswith)
  266. func str_split(s) {
  267. if len(arguments) == 1 || arguments[1] == ""
  268. return list(s)
  269. if type(s) != "string"
  270. throw TypeError("expected first argument to be:!string, but got: " + type(s))
  271. var r = []
  272. var d = arguments[1]
  273. if type(d) != "string"
  274. throw TypeError("expected second argument to be: string, but got: " + type(s))
  275. var t = ""
  276. for var i = 0; i < len(s); i++ {
  277. if slice(s, i, i+len(d)-1) == d {
  278. list_push(r, t)
  279. t = ""
  280. i += len(d)-1
  281. continue
  282. }
  283. t += s[i]
  284. }
  285. if t != ""
  286. list_push(r, t)
  287. return r
  288. }
  289. set_pseudomethod("string.split", str_split)
  290. func str_replace(s, w, b) {
  291. if type(s) != "string"
  292. throw TypeError("expected first argument to be: string, but got: " + type(s))
  293. if type(w) != "string"
  294. throw TypeError("expected second argument to be: string, but got: " + type(w))
  295. if type(b) != "string"
  296. throw TypeError("expected third argument to be: string, but got: " + type(b))
  297. var r = ""
  298. for var i = 0; i < len(s); i++ {
  299. if slice(s, i, i+len(w)-1) == w {
  300. r += b
  301. i += len(w)-1
  302. continue
  303. }
  304. r += s[i]
  305. }
  306. return r
  307. }
  308. set_pseudomethod("string.replace", str_replace)
  309. func table_keys(t) {
  310. if type(t) != "table"
  311. throw TypeError("expected first argument to be: table, but got: " + type(t))
  312. var r = []
  313. for var k of t
  314. list_push(r, k)
  315. return r
  316. }
  317. set_pseudomethod("table.keys", table_keys)
  318. func table_values(t) {
  319. if type(t) != "table"
  320. throw TypeError("expected first argument to be: table, but got: " + type(t))
  321. var r = []
  322. for var k of t
  323. list_push(r, t[k])
  324. return r
  325. }
  326. set_pseudomethod("table.values", table_values)
  327. func reduce(f, xs) {
  328. if type(f) != "function"
  329. throw TypeError("expected first argument to be: function, but got: " + type(f))
  330. if type(xs) !in ("list", "tuple", "string", "bytes")
  331. throw TypeError("expected second argument to be: list, tuple, string or bytes, but got: " + type(xs))
  332. if len(xs) == 0
  333. throw ValueError("cannot reduce empty list")
  334. r = xs[0]
  335. for var x of slice(xs, 1)
  336. r = f(r, x)
  337. if type(xs) == "tuple"
  338. return tuple(r)
  339. elif type(xs) == "string"
  340. return list_join(r)
  341. elif type(xs) == "bytes"
  342. return bytes(r)
  343. return r
  344. }
  345. set_pseudomethod("list.reduce", func (xs, f): reduce(f, xs))
  346. set_pseudomethod("tuple.reduce", func (xs, f): reduce(f, xs))
  347. set_pseudomethod("string.reduce", func (xs, f): reduce(f, xs))
  348. set_pseudomethod("bytes.reduce", func (xs, f): reduce(f, xs))
  349. func sum(xs)
  350. return reduce(func (x, y): x + y, xs)
  351. set_pseudomethod("list.sum", sum)
  352. set_pseudomethod("tuple.sum", sum)
  353. func product(xs)
  354. return reduce(func (x, y): x * y, xs)
  355. set_pseudomethod("list.product", product)
  356. set_pseudomethod("tuple.product", product)
  357. func all(l): reduce(func (x, y): x && y, l)
  358. set_pseudomethod("list.all", all)
  359. set_pseudomethod("tuple.all", all)
  360. func any(l): reduce(func (x, y): x || y, l)
  361. set_pseudomethod("list.any", any)
  362. set_pseudomethod("tuple.any", any)
  363. func map(f, xs) {
  364. if type(f) != "function"
  365. throw TypeError("expected first argument to be: function, but got: " + type(f))
  366. if type(xs) !in ("list", "tuple", "string", "bytes")
  367. throw TypeError("expected second argument to be: list, tuple, string or bytes, but got: " + type(xs))
  368. if len(xs) == 0
  369. return xs
  370. var r = []
  371. for var x of xs
  372. list_push(r, f(x))
  373. if type(xs) == "tuple"
  374. return tuple(r)
  375. elif type(xs) == "string"
  376. return list_join(r)
  377. elif type(xs) == "bytes"
  378. return bytes(r)
  379. return r
  380. }
  381. set_pseudomethod("list.map", func (xs, f): map(f, xs))
  382. set_pseudomethod("tuple.map", func (xs, f): map(f, xs))
  383. set_pseudomethod("string.map", func (xs, f): map(f, xs))
  384. set_pseudomethod("bytes.map", func (xs, f): map(f, xs))
  385. func filter(f, xs) {
  386. if type(f) != "function"
  387. throw TypeError("expected first argument to be: function, but got: " + type(f))
  388. if type(xs) !in ("list", "tuple", "string", "bytes")
  389. throw TypeError("expected second argument to be: list, tuple, string or bytes, but got: " + type(xs))
  390. if len(xs) == 0
  391. return xs
  392. var r = []
  393. for var x of xs
  394. if f(x)
  395. list_push(r, x)
  396. if type(xs) == "tuple"
  397. return tuple(r)
  398. elif type(xs) == "string"
  399. return list_join(r)
  400. elif type(xs) == "bytes"
  401. return bytes(r)
  402. return r
  403. }
  404. set_pseudomethod("list.filter", func (xs, f): filter(f, xs))
  405. set_pseudomethod("tuple.filter", func (xs, f): filter(f, xs))
  406. set_pseudomethod("string.filter", func (xs, f): filter(f, xs))
  407. set_pseudomethod("bytes.filter", func (xs, f): filter(f, xs))
  408. func tuple_delete(t, x) {
  409. if type(t) != "tuple"
  410. throw TypeError("expected first argument to be: tuple, but got: " + type(t))
  411. var r = []
  412. for var e of t
  413. if e != x
  414. list_push(r, e)
  415. return tuple(r)
  416. }
  417. set_pseudomethod("tuple.delete", tuple_delete)
  418. set_pseudomethod("tuple.__sub", tuple_delete)
  419. func str_index(s, w) {
  420. if s == "" || w == ""
  421. return -1
  422. if type(s) != "string"
  423. throw TypeError("expected first argument to be: string, but got: " + type(s))
  424. if type(w) != "string"
  425. throw TypeError("expected second argument to be: string, but got: " + type(w))
  426. for var i = 0; i < len(s); i++
  427. if len(w) == 1 && s[i] == w
  428. return i
  429. elif slice(s, i, i+len(w)-1) == w
  430. return i
  431. return -1
  432. }
  433. set_pseudomethod("string.index", str_index)
  434. func str_lstrip(s, cs=" \t\n\r\x0b\x0c") {
  435. if type(s) != "string"
  436. throw TypeError("expected first argument to be: string, but got: " + type(s))
  437. if type(cs) != "string"
  438. throw TypeError("expected second argument to be: string, but got: " + type(cs))
  439. if s == ""
  440. return s
  441. var i
  442. for i = 0; s[i] in cs && i < len(s); i++
  443. pass
  444. return slice(s, i)
  445. }
  446. set_pseudomethod("string.lstrip", str_lstrip)
  447. func str_rstrip(s, cs=" \t\n\r\x0b\x0c") {
  448. if type(s) != "string"
  449. throw TypeError("expected first argument to be: string, but got: " + type(s))
  450. if type(cs) != "string"
  451. throw TypeError("expected second argument to be: string, but got: " + type(cs))
  452. if s == ""
  453. return s
  454. var k, i
  455. for k = 0, i = len(s)-1; s[i] in cs && i >= 0; k++
  456. i--
  457. return slice(s, 0, len(s)-k-1)
  458. }
  459. set_pseudomethod("string.rstrip", str_rstrip)
  460. func str_strip(s, cs=" \t\n\r\x0b\x0c") {
  461. if type(s) != "string"
  462. throw TypeError("expected first argument to be: string, but got: " + type(s))
  463. if type(cs) != "string"
  464. throw TypeError("expected second argument to be: string, but got: " + type(cs))
  465. return str_lstrip(str_rstrip(s, cs), cs)
  466. }
  467. set_pseudomethod("string.strip", str_strip)
  468. func zip() {
  469. if !arguments
  470. return []
  471. var l = map(len, arguments)
  472. l = reduce(min, l)
  473. var r = []
  474. for var i = 0; i < l; i++ {
  475. var t = []
  476. for var xs of arguments
  477. list_push(t, xs[i])
  478. list_push(r, t)
  479. }
  480. return r
  481. }
  482. func enumerate(l)
  483. if type(l) == "table"
  484. return zip(table_keys(l), table_values(l))
  485. else
  486. return zip(range(len(l)), l)
  487. func str_toupper(s) {
  488. if type(s) != "string"
  489. throw TypeError("expected first argument to be: string, but got: " + type(c))
  490. return map(func (c): c >= 'a' && c <= 'z'? chr(ord(c) - 32): c, s)
  491. }
  492. set_pseudomethod("string.toupper", str_toupper)
  493. func str_tolower(s) {
  494. if type(s) != "string"
  495. throw TypeError("expected first argument to be: string, but got: " + type(c))
  496. return map(func (c): c >= 'A' && c <= 'Z'? chr(ord(c) + 32): c, s)
  497. }
  498. set_pseudomethod("string.tolower", str_tolower)
  499. func hex(x) {
  500. if type(x) != "number"
  501. throw TypeError("expected first argument to be: number, but got: " + type(x))
  502. if x == 0
  503. return "0x0"
  504. let sgn = x < 0
  505. if sgn
  506. x = -x
  507. var r = ""
  508. for x > 0 {
  509. r = "0123456789abcdef"[x % 16] + r
  510. x //= 16
  511. }
  512. return (sgn? "-0x": "0x") + r
  513. }
  514. func oct(x) {
  515. if type(x) != "number"
  516. throw TypeError("expected first argument to be: number, but got: " + type(x))
  517. if x == 0
  518. return "0o0"
  519. let sgn = x < 0
  520. if sgn
  521. x = -x
  522. var r = ""
  523. for x > 0 {
  524. r = "01234567"[x % 8] + r
  525. x //= 8
  526. }
  527. return (sgn? "-0o": "0o") + r
  528. }
  529. func format(s) {
  530. if type(s) != "string"
  531. throw TypeError("expected first argument to be: string, but got: " + type(s))
  532. var r = ""
  533. var n = 1
  534. for var i = 0; i < len(s); i++
  535. switch s[i] {
  536. case '_'
  537. if i+1 < len(s) && s[i+1] == '_' {
  538. r += '_'
  539. i++
  540. continue
  541. }
  542. r += repr(arguments[n++])
  543. break
  544. default
  545. r += s[i]
  546. }
  547. return r
  548. }
  549. set_pseudomethod("string.format", format)
  550. func formatl(s, l) {
  551. if type(s) != "string"
  552. throw TypeError("expected first argument to be: string, but got: " + type(s))
  553. if type(l) != "list"
  554. throw TypeError("expected second argument to be: list, but got: " + type(l))
  555. return func_call(str_format, [s] + l)
  556. }
  557. set_pseudomethod("string.formatl", formatl)
  558. func formatd(s, t) {
  559. if type(s) != "string"
  560. throw TypeError("expected first argument to be: string, but got: " + type(s))
  561. var r = ""
  562. var n = 1
  563. for var i = 0; i < len(s); i++
  564. switch s[i] {
  565. case '{'
  566. if i+1 < len(s) && s[i+1] == '{' {
  567. r += '{'
  568. i++
  569. continue
  570. }
  571. var k = ''
  572. i++
  573. for i < len(s) && s[i] != '}'
  574. k += s[i++]
  575. if i >= len(s) || s[i] != '}'
  576. throw ValueError("unmatched { in format specifier")
  577. if !k
  578. throw ValueError("empty format key")
  579. r += repr(t[k])
  580. break
  581. default
  582. r += s[i]
  583. }
  584. return r
  585. }
  586. set_pseudomethod("string.formatd", formatd)
  587. func getch() return chr(fgetc(STDIN))
  588. func putch(c) fputc(STDOUT, c)
  589. func getline()
  590. return fgets(STDIN, 256)
  591. func input() {
  592. if len(arguments) > 0
  593. func_call(print, arguments)
  594. return str_rstrip(getline(), "\n\r")
  595. }
  596. func open(path, mode="r"): fopen(path, mode)
  597. set_pseudomethod("file.__enter", func () {})
  598. set_pseudomethod("file.__leave", func (f): fclose(f))
  599. set_pseudomethod("file.close", fclose)
  600. set_pseudomethod("file.flush", fflush)
  601. set_pseudomethod("file.seek", fseek)
  602. set_pseudomethod("file.getc", fgetc)
  603. set_pseudomethod("file.putc", fputc)
  604. set_pseudomethod("file.gets", fgets)
  605. set_pseudomethod("file.puts", fputs)
  606. set_pseudomethod("file.tell", ftell)
  607. set_pseudomethod("reference.deref", deref)
  608. set_pseudomethod("reference.set", ref_set)
  609. func assert(cond, msg=AssertionError())
  610. if !cond
  611. throw msg
  612. class ListIterator {
  613. constructor(this, l) {
  614. this.l = list(l)
  615. this.i = 0
  616. this.z = len(this.l)
  617. }
  618. __str(this): "<ListIterator>"
  619. __begin(this) {
  620. this.i = 0
  621. return this
  622. }
  623. __next(this) {
  624. if this.i < this.z
  625. return this.l[this.i++]
  626. }
  627. __end(this): this.i >= this.z
  628. }
  629. class OrderedTable {
  630. __data__ = nil
  631. constructor (this, v=nil) {
  632. this.__data__ = []
  633. if v !is nil {
  634. v = table(v)
  635. for var k of v
  636. this[k] = v[k]
  637. }
  638. }
  639. __type (this): "orderedtable"
  640. stringify (this, tempstack=[]) {
  641. if this in tempstack
  642. return "OrderedTable({...})"
  643. tempstack.push(this)
  644. var buf = "OrderedTable({"
  645. var f = true
  646. for var [k, v] of this.__data__ {
  647. if f
  648. f = false
  649. else buf += ", "
  650. k = k.replace(`\`, `\\`).replace(`"`, `\"`)
  651. if type(v) is "orderedtable"
  652. v = v.stringify(tempstack)
  653. buf += f`"${k}": ${v}`
  654. }
  655. buf += "})"
  656. return buf
  657. }
  658. __str (this) {
  659. return this.stringify([])
  660. }
  661. keys (this) {
  662. let keys = []
  663. for var [k, _] of this.__data__
  664. keys.push(k)
  665. return keys
  666. }
  667. values (this) {
  668. let values = []
  669. for var [_, v] of this.__data__
  670. values.push(v)
  671. return values
  672. }
  673. delete (this, k) {
  674. del this[k]
  675. }
  676. copy (this) {
  677. return OrderedTable(this.__data__)
  678. }
  679. get (this, k, d=nil) {
  680. k = str(k)
  681. for var [ok, v] of this.__data__
  682. if ok == k
  683. return v
  684. return d
  685. }
  686. __iter (this): ListIterator(this.keys())
  687. __len (this): len(this.__data__)
  688. __in (this, k) {
  689. k = str(k)
  690. for var [ok, _] of this.__data__
  691. if ok == k
  692. return true
  693. return false
  694. }
  695. __del (this, k) {
  696. k = str(k)
  697. for var [i, ok] of zip(range(len(this)), this.keys())
  698. if ok == k {
  699. del this.__data__[i]
  700. return
  701. }
  702. throw KeyError(k)
  703. }
  704. __index (this, k) {
  705. k = str(k)
  706. for var [ok, v] of this.__data__
  707. if ok == k
  708. return v
  709. throw KeyError(k)
  710. }
  711. __index_set (this, k, v) {
  712. k = str(k)
  713. for var [i, ok] of zip(range(len(this)), this.keys())
  714. if ok == k {
  715. this.__data__[i] = (ok, v)
  716. return
  717. }
  718. this.__data__.push((k, v))
  719. }
  720. }