std.qi 19 KB

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