nomsu/core/collections.nom

141 lines
4.1 KiB
Plaintext
Raw Normal View History

2018-12-14 20:21:03 -08:00
#!/usr/bin/env nomsu -V5.12.12.8
2018-05-15 18:55:55 -07:00
#
This file contains code that supports manipulating and using collections like lists
and dictionaries.
use "core/metaprogramming.nom"
use "core/control_flow.nom"
use "core/operators.nom"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# List functionality:
test:
2018-12-14 20:21:03 -08:00
$list = [1, 2, 3, 4, 5]
$visited = {}
for $i = $x in $list:
$visited.$i = (yes)
assume ($visited == {1, 2, 3, 4, 5})
$visited = {}
for $x in $list:
$visited.$x = (yes)
assume ($visited == {1, 2, 3, 4, 5})
assume (($list|2 nd to last) == 4)
assume (($list|first) == 1)
assume ($list|has 3)
assume (($list|index of 3) == 3)
assume ((size of $list) == 5)
$list|add 6
assume (($list|last) == 6)
$list|pop
assume (($list|last) == 5)
$list|remove index 1
assume (($list|first) == 2)
2018-08-30 14:26:32 -07:00
assume (([1, 2] + [3, 4]) == [1, 2, 3, 4])
# Dict functionality
test:
2018-12-14 20:21:03 -08:00
$dict = {x: 1, y: 2, z: 3}
assume (size of $dict) == 3
assume [: for $ in {x: 1}: add $] == [{key: "x", value: 1}]
assume [: for $k = $v in {x: 1}: add {key: $k, value: $v}] == [..]
{key: "x", value: 1}
assume ({x: 1, y: 1} + {y: 10, z: 10}) == {x: 1, y: 11, z: 10}
assume ({x: 1, y: 1} | {y: 10, z: 10}) == {x: 1, y: 1, z: 10}
assume ({x: 1, y: 1} & {y: 10, z: 10}) == {y: 1}
assume ({x: 1, y: 1} ~ {y: 10, z: 10}) == {x: 1, z: 10}
test:
assume (([[1, 2], [3, 4]] flattened) == [1, 2, 3, 4])
2018-12-14 20:21:03 -08:00
externally ($lists flattened) means:
$flat = []
for $item in recursive $lists:
if ($item is a "List"):
for $ in $item:
recurse $item on $
..else:
2018-12-14 20:21:03 -08:00
$flat|add $item
return $flat
2018-06-18 15:44:29 -07:00
test:
assume ((entries in {x: 1}) == [{key: "x", value: 1}])
2018-12-14 20:21:03 -08:00
(entries in $dict) parses as [: for $k = $v in $dict: add {key: $k, value: $v}]
test:
assume ((keys in {x: 1}) == ["x"])
2018-12-14 20:21:03 -08:00
[keys in $dict, keys of $dict] all parse as [: for $k = $v in $dict: add $k]
test:
assume ((values in {x: 1}) == [1])
2018-12-14 20:21:03 -08:00
[values in $dict, values of $dict] all parse as [: for $k = $v in $dict: add $v]
# Metatable stuff
test:
2018-12-14 20:21:03 -08:00
$t = {}
set $t's metatable to {__tostring: $ -> "XXX"}
assume ("\$t" == "XXX")
2018-12-14 20:21:03 -08:00
(set $dict's metatable to $metatable) compiles to \
.."setmetatable(\($dict as lua expr), \($metatable as lua expr));"
2018-06-18 15:44:29 -07:00
2018-12-14 20:21:03 -08:00
[$'s metatable, $'metatable] all compile to "getmetatable(\($ as lua expr))"
test:
2018-12-14 20:21:03 -08:00
assume (({} with fallback $ -> ($ + 1)).10 == 11)
2018-12-14 20:21:03 -08:00
($dict with fallback $key -> $value) compiles to "
(function(d)
local mt = {}
for k,v in pairs(getmetatable(d) or {}) do mt[k] = v end
2018-12-14 20:21:03 -08:00
mt.__index = function(self, \($key as lua expr))
local value = \($value as lua expr)
self[\($key as lua expr)] = value
return value
end
return setmetatable(d, mt)
2018-12-14 20:21:03 -08:00
end)(\($dict as lua expr))"
# Sorting
test:
2018-12-14 20:21:03 -08:00
$x = [3, 1, 2]
sort $x
assume ($x == [1, 2, 3])
sort $x by $ = (- $)
assume ($x == [3, 2, 1])
$keys = {1: 999, 2: 0, 3: 50}
sort $x by $ = $keys.$
assume ($x == [2, 3, 1])
(sort $items) compiles to "table.sort(\($items as lua expr));"
[sort $items by $item = $key_expr, sort $items by $item -> $key_expr] \
..all parse as (..)
do:
2018-12-14 20:21:03 -08:00
$keys = ({} with fallback $item -> $key_expr)
lua> "table.sort(\$items, function(x,y) return \$keys[x] < \$keys[y] end)"
2018-06-18 15:44:29 -07:00
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2018-06-18 15:44:29 -07:00
test:
assume ((sorted [3, 1, 2]) == [1, 2, 3])
2018-12-14 20:21:03 -08:00
externally [$items sorted, sorted $items] all mean:
$copy = [: for $ in $items: add $]
sort $copy
return $copy
2018-12-14 20:21:03 -08:00
[$items sorted by $item = $key, $items sorted by $item -> $key] all parse as (..)
result of:
2018-12-14 20:21:03 -08:00
$copy = [: for $ in $items: add $]
sort $copy by $item = $key
return $copy
2018-06-18 15:44:29 -07:00
test:
assume ((unique [1, 2, 1, 3, 2, 3]) == [1, 2, 3])
2018-12-14 20:21:03 -08:00
externally (unique $items) means:
$unique = []
$seen = {}
for $ in $items:
unless $seen.$:
$unique|add $
$seen.$ = (yes)
return $unique