diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2019-01-14 15:42:48 -0800 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2019-01-14 15:43:24 -0800 |
| commit | c1c32688a4afc43f6addb99b8b5fa878944a70e3 (patch) | |
| tree | c886f21b5b08a9053aa74fcba4b241dae5ede76d /lib/core/collections.nom | |
| parent | 2309b696fc34b24f05f6658b94f9105ca8ee76e4 (diff) | |
Overhaul in progress, mostly working. Moved all the nomsu packages into
lib/, including core/*. Changes to how nomsu environments and importing
work.
Diffstat (limited to 'lib/core/collections.nom')
| -rw-r--r-- | lib/core/collections.nom | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/lib/core/collections.nom b/lib/core/collections.nom new file mode 100644 index 0000000..4cf54cd --- /dev/null +++ b/lib/core/collections.nom @@ -0,0 +1,145 @@ +#!/usr/bin/env nomsu -V6.14 +# + This file contains code that supports manipulating and using collections like lists + and dictionaries. + +use "core/metaprogramming" +use "core/control_flow" +use "core/operators" + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# List functionality: +test: + $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) + assume (([1, 2] + [3, 4]) == [1, 2, 3, 4]) + +# Dict functionality +test: + $dict = {.x = 1, .y = 2, .z = 3} + assume (size of $dict) == 3 + 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]) + +externally ($lists flattened) means: + $flat = [] + for $item in recursive $lists: + if ($item is a "List"): + for $ in $item: + recurse $item on $ + ..else: + $flat, add $item + return $flat + +test: + assume ((entries in {.x = 1}) == [{.key = "x", .value = 1}]) + +(entries in $dict) parses as [ + : for $k = $v in $dict: + add {.key = $k, .value = $v} +] + +test: + assume ((keys in {.x = 1}) == ["x"]) + +[keys in $dict, keys of $dict] all parse as [: for $k = $v in $dict: add $k] +test: + assume ((values in {.x = 1}) == [1]) +[values in $dict, values of $dict] all parse as [: for $k = $v in $dict: add $v] + +# Metatable stuff +test: + $t = {} + set $t's metatable to {.__tostring = ($ -> "XXX")} + assume ("\$t" == "XXX") + +(set $dict's metatable to $metatable) compiles to + "setmetatable(\($dict as lua expr), \($metatable as lua expr));" + +[$'s metatable, $'metatable] all compile to "getmetatable(\($ as lua expr))" +test: + assume (({} with fallback $ -> ($ + 1)).10 == 11) + +($dict with fallback $key -> $value) compiles to (" + (function(d) + local mt = {} + for k,v in pairs(getmetatable(d) or {}) do mt[k] = v end + 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) + end)(\($dict as lua expr)) +") + +# Sorting +test: + $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: + $keys = ({} with fallback $item -> $key_expr) + lua> "table.sort(\$items, function(x,y) return \$keys[x] < \$keys[y] end)" + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +test: + assume ((sorted [3, 1, 2]) == [1, 2, 3]) + +externally [$items sorted, sorted $items] all mean: + $copy = [: for $ in $items: add $] + sort $copy + return $copy + +[$items sorted by $item = $key, $items sorted by $item -> $key] all parse as + result of: + $copy = [: for $ in $items: add $] + sort $copy by $item = $key + return $copy + +test: + assume ((unique [1, 2, 1, 3, 2, 3]) == [1, 2, 3]) + +externally (unique $items) means: + $unique = [] + $seen = {} + for $ in $items: + unless $seen.$: + $unique, add $ + $seen.$ = (yes) + return $unique |
