123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520 |
- func head(l): return l[0]
- func tail(l): return slice(l, 1)
- func min(x, y): x < y? x: y
- func max(x, y): x > y? x: y
- func reverse(x) {
- if type(x) !in ("list", "string", "bytes")
- throw "expected first argument to be: list, string or bytes, but got: " + type(x)
- var r = []
- for var i = len(x)-1; i >= 0; i--
- list_push(r, x[i])
- if type(x) == "string"
- return list_join(r)
- elif type(x) == "bytes"
- return bytes(r)
- return r
- }
- set_pseudomethod("list.reverse", reverse)
- set_pseudomethod("string.reverse", reverse)
- set_pseudomethod("bytes.reverse", reverse)
- func range(f) {
- var t, s
- if len(arguments) >= 3 {
- t = arguments[1]
- s = arguments[2]
- } elif len(arguments) >= 2 {
- t = arguments[1]
- s = 1
- } else {
- t = f
- f = 0
- s = 1
- }
- if type(f) != "number"
- throw "expected first argument to be: number, but got: " + type(f)
- if type(t) != "number"
- throw "expected second argument to be: number, but got: " + type(t)
- if type(s) != "number"
- throw "expected third argument to be: number, but got: " + type(s)
- if f > t
- return reverse(range(t, f, s))
- var r = []
- for var i = f; i < t; i += s
- list_push(r, i)
- return r
- }
- let SEEK_SET = 0, SEEK_CUR = 1, SEEK_END = 2
- func frewind(file)
- return file.rewind()
- func file_read(filename) {
- let file = fopen(filename, "r")
- defer fclose(file)
- return str(fread(file, -1))
- }
- func file_write(filename, data) {
- let file = fopen(filename, "w")
- defer fclose(file)
- fwrite(file, bytes(data))
- }
- func is_defined(name) {
- if type(name) != "string"
- throw "expected first argument to be: string, but got: " + type(name)
- inline `bool b = qi_find(state, qi_get(state, "name")->value.string) != NULL`
- inline `return qi_make_boolean(state, b)`
- }
- func list_remove(l, x, first=false) {
- if type(l) != "list"
- throw "expected first argument to be: list, but got: " + type(l)
- repeat:
- for var i = 0; i < len(l); i++
- if l[i] == x {
- list_delete(l, i)
- if first
- break
- goto repeat
- }
- }
- set_pseudomethod("list.remove", list_remove)
- func list_join(l) {
- if type(l) != "list"
- throw "expected first argument to be: list, but got: " + type(l)
- var r = ""
- var s
- if len(arguments) == 1
- s = ""
- else
- s = arguments[1]
- if type(s) != "string"
- throw "expected second argument to be: string, but got: " + type(s)
- var first = true
- for var x of l {
- if type(x) != "string"
- throw "expected sequence item to be: string, but got: " + type(x)
- if s != "" && !first
- r += s
- r += x
- first = false
- }
- return r
- }
- set_pseudomethod("list.join", list_join)
- func list_pop_at(l, i) {
- if type(l) != "list"
- throw "expected first argument to be: list, but got: " + type(l)
- if type(i) != "number"
- throw "expected second argument to be: number, but got: " + type(i)
- var x = l[i]
- list_delete(l, i)
- return x
- }
- set_pseudomethod("list.popAt", list_pop_at)
- func list_sort(l, cmp=func (x, y): x > y) {
- if type(l) != "list"
- throw "expected first argument to be: list, but got: " + type(l)
- if type(cmp) != "function"
- throw "expected second argument to be: function, but got: " + type(cmp)
- if len(l) == 0
- return l
- var z = len(l)
- for var i = 0; i < z - 1; i++
- for var j = 0; j < z - 1 - i; j++
- if cmp(l[j], l[j+1]) {
- let tmp = l[j]
- l[j] = l[j+1]
- l[j+1] = tmp
- }
- return l
- }
- func list_sorted(l, cmp=func (x, y): x > y) {
- l = list_copy(l)
- return list_sort(l, cmp)
- }
- set_pseudomethod("list.sort", list_sort)
- set_pseudomethod("list.sorted", list_sorted)
- func list_shift(l) {
- if type(l) != "list"
- throw "expected first argument to be: list, but got: " + type(l)
- if is_empty(l)
- throw "shift from empty list"
- var a = l[0]
- list_delete(l, 0)
- return a
- }
- func list_unshift(l, x) {
- list_insert(l, 0, x)
- }
- set_pseudomethod("list.shift", list_shift)
- set_pseudomethod("list.unshift", list_unshift)
- func slice(l) {
- if type(l) !in ("list", "string", "bytes")
- throw "expected first argument to be: list, string or bytes, but got: " + type(l)
- var r = []
- if len(arguments) == 2 {
- var f = arguments[1]
- if type(f) != "number"
- throw "expected second argument to be: number, but got: " + type(f)
- if f < 0
- f += len(l)
- for var i = f; i < len(l); i++
- list_push(r, l[i])
- } elif len(arguments) == 3 {
- var f = arguments[1], t = arguments[2]
- if type(f) != "number"
- throw "expected second argument to be: number, but got: " + type(f)
- if type(t) != "number"
- throw "expected third argument to be: number, but got: " + type(t)
- if f < 0
- f += len(l)
- if t < 0
- t += len(l)
- for var i = f; i < len(l) && i <= t; i++
- list_push(r, l[i])
- }
- if type(l) == "string"
- return list_join(r)
- elif type(l) == "bytes"
- return bytes(r)
- return r
- }
- set_pseudomethod("list.slice", slice)
- set_pseudomethod("string.slice", slice)
- set_pseudomethod("bytes.slice", slice)
- let __slice = slice;
- func str_startswith(s, p) {
- if type(s) != "string"
- throw "expected first argument to be: string, but got: " + type(s)
- if len(s) < len(p)
- return false
- return slice(s, 0, len(p)-1) == p
- }
- set_pseudomethod("string.startsWith", str_startswith)
- func str_endswith(s, p) {
- if type(s) != "string"
- throw "expected first argument to be: string, but got: " + type(s)
- if len(s) < len(p)
- return false
- return slice(s, len(s) - len(p)) == p
- }
- set_pseudomethod("string.endsWith", str_endswith)
- func str_split(s) {
- if len(arguments) == 1 || arguments[1] == ""
- return list(s)
- if type(s) != "string"
- throw "expected first argument to be:!string, but got: " + type(s)
- var r = []
- var d = arguments[1]
- if type(d) != "string"
- throw "expected second argument to be: string, but got: " + type(s)
- var t = ""
- for var i = 0; i < len(s); i++ {
- if slice(s, i, i+len(d)-1) == d {
- list_push(r, t)
- t = ""
- i += len(d)-1
- continue
- }
- t += s[i]
- }
- if t != ""
- list_push(r, t)
- return r
- }
- set_pseudomethod("string.split", str_split)
- func str_replace(s, w, b) {
- if type(s) != "string"
- throw "expected first argument to be: string, but got: " + type(s)
- if type(w) != "string"
- throw "expected second argument to be: string, but got: " + type(w)
- if type(b) != "string"
- throw "expected third argument to be: string, but got: " + type(b)
- var r = ""
- for var i = 0; i < len(s); i++ {
- if slice(s, i, i+len(w)-1) == w {
- r += b
- i += len(w)-1
- continue
- }
- r += s[i]
- }
- return r
- }
- set_pseudomethod("string.replace", str_replace)
- func table_keys(t) {
- if type(t) != "table"
- throw "expected first argument to be: table, but got: " + type(t)
- var r = []
- for var k of t
- list_push(r, k)
- return r
- }
- set_pseudomethod("table.keys", table_keys)
- func table_values(t) {
- if type(t) != "table"
- throw "expected first argument to be: table, but got: " + type(t)
- var r = []
- for var k of t
- list_push(r, t[k])
- return r
- }
- set_pseudomethod("table.values", table_values)
- func reduce(f, xs) {
- if type(f) != "function"
- throw "expected first argument to be: function, but got: " + type(f)
- if type(xs) !in ("list", "tuple", "string", "bytes")
- throw "expected second argument to be: list, tuple, string or bytes, but got: " + type(xs)
- if len(xs) == 0
- throw "cannot reduce empty list"
- r = xs[0]
- for var x of slice(xs, 1)
- r = f(r, x)
- if type(xs) == "tuple"
- return tuple(r)
- elif type(xs) == "string"
- return list_join(r)
- elif type(xs) == "bytes"
- return bytes(r)
- return r
- }
- set_pseudomethod("list.reduce", func (xs, f): reduce(f, xs))
- set_pseudomethod("tuple.reduce", func (xs, f): reduce(f, xs))
- set_pseudomethod("string.reduce", func (xs, f): reduce(f, xs))
- set_pseudomethod("bytes.reduce", func (xs, f): reduce(f, xs))
- func sum(xs)
- return reduce(func (x, y): x + y, xs)
- set_pseudomethod("list.sum", sum)
- set_pseudomethod("tuple.sum", sum)
- func product(xs)
- return reduce(func (x, y): x * y, xs)
- set_pseudomethod("list.product", product)
- set_pseudomethod("tuple.product", product)
- func map(f, xs) {
- if type(f) != "function"
- throw "expected first argument to be: function, but got: " + type(f)
- if type(xs) !in ("list", "tuple", "string", "bytes")
- throw "expected second argument to be: list, tuple, string or bytes, but got: " + type(xs)
- if len(xs) == 0
- return xs
- var r = []
- for var x of xs
- list_push(r, f(x))
- if type(xs) == "tuple"
- return tuple(r)
- elif type(xs) == "string"
- return list_join(r)
- elif type(xs) == "bytes"
- return bytes(r)
- return r
- }
- set_pseudomethod("list.map", func (xs, f): map(f, xs))
- set_pseudomethod("tuple.map", func (xs, f): map(f, xs))
- set_pseudomethod("string.map", func (xs, f): map(f, xs))
- set_pseudomethod("bytes.map", func (xs, f): map(f, xs))
- func filter(f, xs) {
- if type(f) != "function"
- throw "expected first argument to be: function, but got: " + type(f)
- if type(xs) !in ("list", "tuple", "string", "bytes")
- throw "expected second argument to be: list, tuple, string or bytes, but got: " + type(xs)
- if len(xs) == 0
- return xs
- var r = []
- for var x of xs
- if f(x)
- list_push(r, x)
- if type(xs) == "tuple"
- return tuple(r)
- elif type(xs) == "string"
- return list_join(r)
- elif type(xs) == "bytes"
- return bytes(r)
- return r
- }
- set_pseudomethod("list.filter", func (xs, f): filter(f, xs))
- set_pseudomethod("tuple.filter", func (xs, f): filter(f, xs))
- set_pseudomethod("string.filter", func (xs, f): filter(f, xs))
- set_pseudomethod("bytes.filter", func (xs, f): filter(f, xs))
- func str_index(s, w) {
- if s == "" || w == ""
- return -1
- if type(s) != "string"
- throw "expected first argument to be: string, but got: " + type(s)
- if type(w) != "string"
- throw "expected second argument to be: string, but got: " + type(w)
- for var i = 0; i < len(s); i++
- if len(w) == 1 && s[i] == w
- return i
- elif slice(s, i, i+len(w)-1) == w
- return i
- return -1
- }
- set_pseudomethod("string.index", str_index)
- func str_lstrip(s, cs=" \t\n\r\x0b\x0c") {
- if type(s) != "string"
- throw "expected first argument to be: string, but got: " + type(s)
- if type(cs) != "string"
- throw "expected second argument to be: string, but got: " + type(cs)
- if s == ""
- return s
- for var i = 0; s[i] in cs && i < len(s); i++
- pass
- return slice(s, i)
- }
- set_pseudomethod("string.lstrip", str_lstrip)
- func str_rstrip(s, cs=" \t\n\r\x0b\x0c") {
- if type(s) != "string"
- throw "expected first argument to be: string, but got: " + type(s)
- if type(cs) != "string"
- throw "expected second argument to be: string, but got: " + type(cs)
- if s == ""
- return s
- for var k = 0, i = len(s)-1; s[i] in cs && i >= 0; k++
- i--
- return slice(s, 0, len(s)-k-1)
- }
- set_pseudomethod("string.rstrip", str_rstrip)
- func str_strip(s, cs=" \t\n\r\x0b\x0c") {
- if type(s) != "string"
- throw "expected first argument to be: string, but got: " + type(s)
- if type(cs) != "string"
- throw "expected second argument to be: string, but got: " + type(cs)
- return str_lstrip(str_rstrip(s, cs), cs)
- }
- set_pseudomethod("string.strip", str_strip)
- func table_get(t, k, d=nil) {
- if type(t) != "table"
- throw "expected first argument to be: table, but got: " + type(t)
- if type(k) != "string"
- throw "expected second argument to be: string, but got: " + type(k)
- if k !in t
- return d
- return t[k]
- }
- set_pseudomethod("table.get", table_get)
- func zip() {
- if !arguments
- return []
- var l = map(len, arguments)
- l = reduce(min, l)
- var r = []
- for var i = 0; i < l; i++ {
- var t = []
- for var xs of arguments
- list_push(t, xs[i])
- list_push(r, t)
- }
- return r
- }
- func enumerate(l)
- if type(l) == "table"
- return zip(table_keys(l), table_values(l))
- else
- return zip(range(len(l)), l)
- func str_toupper(s) {
- if type(s) != "string"
- throw "expected first argument to be: string, but got: " + type(c)
- return map(func (c): c >= 'a' && c <= 'z'? chr(ord(c) - 32): c, s)
- }
- set_pseudomethod("string.toupper", str_toupper)
- func str_tolower(s) {
- if type(s) != "string"
- throw "expected first argument to be: string, but got: " + type(c)
- return map(func (c): c >= 'A' && c <= 'Z'? chr(ord(c) + 32): c, s)
- }
- set_pseudomethod("string.tolower", str_tolower)
- func Object(t, p=nil): return p !is nil? set_meta_table(p, get_meta_table(p) + t): set_meta_table({}, t)
- func is_object(o): return has_meta_table(o)
- func __class_wrapper(n, p, t, mt, st): return Object(st + {
- t: t,
- mt: mt,
- super: [],
- __type: func (this) use (n): return n,
- __str: func (this) use (n): return "<class " + n + ">",
- __call: func (this, pargs) use (p) {
- var t = {}
- var mt = {}
- for var other of p {
- t += other.t
- mt += other.mt
- list_push(this.super, other)
- }
- if len(this.super) == 1
- this.super = this.super[0]
- t += this.t
- mt += this.mt
- t.super = this.super
- obj = set_meta_table(t, mt)
- if "constructor" in mt
- func_call(mt.constructor, [obj] + pargs)
- return obj
- }
- })
- func format(s) {
- if type(s) != "string"
- throw "expected first argument to be: string, but got: " + type(s)
- var r = ""
- var n = 1
- for var i = 0; i < len(s); i++
- switch s[i] {
- case '_'
- if i+1 < len(s) && s[i+1] == '_' {
- r += '_'
- i++
- continue
- }
- r += repr(arguments[n++])
- break
- default
- r += s[i]
- }
- return r
- }
- set_pseudomethod("string.format", format)
- func formatl(s, l) {
- if type(s) != "string"
- throw "expected first argument to be: string, but got: " + type(s)
- if type(l) != "list"
- throw "expected second argument to be: list, but got: " + type(l)
- return func_call(str_format, [s] + l)
- }
- set_pseudomethod("string.formatl", formatl)
- func formatd(s, t) {
- if type(s) != "string"
- throw "expected first argument to be: string, but got: " + type(s)
- var r = ""
- var n = 1
- for var i = 0; i < len(s); i++
- switch s[i] {
- case '{'
- if i+1 < len(s) && s[i+1] == '{' {
- r += '{'
- i++
- continue
- }
- var k = ''
- i++
- for i < len(s) && s[i] != '}'
- k += s[i++]
- if i >= len(s) || s[i] != '}'
- throw "unmatched { in format specifier"
- if !k
- throw "empty format key"
- r += repr(t[k])
- break
- default
- r += s[i]
- }
- return r
- }
- set_pseudomethod("string.formatd", formatd)
- func getch() return chr(fgetc(STDIN))
- func putch(c) fputc(STDOUT, c)
- func getline()
- return fgets(STDIN, 256)
- func input() {
- if len(arguments) > 0
- func_call(print, arguments)
- return str_rstrip(getline(), "\n\r")
- }
- func open(path, mode="r"): fopen(path, mode)
- func assert(cond, msg="assertion failed")
- if !cond
- throw msg
|