aboutsummaryrefslogtreecommitdiff
path: root/core/collections.nom
diff options
context:
space:
mode:
authorBruce Hill <bitbucket@bruce-hill.com>2018-02-02 15:48:28 -0800
committerBruce Hill <bitbucket@bruce-hill.com>2018-02-02 15:49:42 -0800
commit505fec2a61d2571317cc4bbc36ec0f4822a63f9d (patch)
treec2b37e9db8e2f958fbca0caa0a9c4924912a37a9 /core/collections.nom
parent513c721198b2256235a95c98d161ab1bb51e6671 (diff)
Restructured the nomsu files to group all the essentials into core/ and
all the optionals into lib/. lib/core.nom and tests/all.nom are no longer needed now.
Diffstat (limited to 'core/collections.nom')
-rw-r--r--core/collections.nom204
1 files changed, 204 insertions, 0 deletions
diff --git a/core/collections.nom b/core/collections.nom
new file mode 100644
index 0000000..6882c96
--- /dev/null
+++ b/core/collections.nom
@@ -0,0 +1,204 @@
+#..
+ 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/dict functions:
+
+# Indexing
+immediately:
+ compile [..]
+ %index st to last in %list, %index nd to last in %list, %index rd to last in %list
+ %index th to last in %list
+ ..to {expr:"utils.nth_to_last(\(%list as lua expr), \(%index as lua expr))"}
+
+immediately:
+ parse [first in %list, first %list] as: 1 st in %list
+ parse [last in %list, last %list] as: 1 st to last in %list
+
+# Membership testing
+immediately:
+ action [%item is in %list, %list contains %item, %list has %item]
+ for %key = %value in %list
+ if (%key is %item): return (yes)
+ return (no)
+
+ action [..]
+ %item isn't in %list, %item is not in %list
+ %list doesn't contain %item, %list does not contain %item
+ %list doesn't have %item, %list does not have %item
+ ..:
+ for %key = %value in %list
+ if (%key is %item): return (no)
+ return (yes)
+
+immediately:
+ # Note: it's important to have the space after "[" to prevent confusion if %index is a string
+ compile [%list has key %index, %list has index %index] to {..}
+ expr: ".."
+ ((\(%list as lua expr))[ \(%index as lua expr)] ~= nil)
+
+ # Note: it's important to have the space after "[" to prevent confusion if %index is a string
+ compile [..]
+ %list doesn't have key %index, %list does not have key %index
+ %list doesn't have index %index, %list does not have index %index
+ ..to {expr:"((\(%list as lua expr))[ \(%index as lua expr)] == nil)"}
+
+ compile [length of %list, size of %list, size %list, number of %list, len %list] to:
+ {expr:"utils.size(\(%list as lua expr))"}
+
+ compile [append %item to %list, add %item to %list] to:
+ {statements:"table.insert(\(%list as lua expr), \(%item as lua expr))"}
+
+ compile [pop from %list, remove last from %list] to:
+ {statements:"table.remove(\(%list as lua expr))"}
+
+ compile [remove index %index from %list] to:
+ {statements:"table.remove(\(%list as lua expr), \(%index as lua expr))"}
+
+# List Comprehension
+immediately:
+ compile [%expression for %item in %iterable] to:
+ assume ((%item's "type") is "Var") or barf ".."
+ List comprehension has the wrong type for the loop variable. Expected Var, but got: \(%item's "type")
+ return {..}
+ expr:".."
+ (function()
+ local comprehension = {};
+ for i,\(%item as lua expr) in ipairs(\(%iterable as lua expr)) do
+ comprehension[i] = \(%expression as lua expr);
+ end
+ return comprehension;
+ end)()
+ parse [%expression for all %iterable] as: %expression for % in %iterable
+
+ compile [..]
+ %expression for %index from %start to %stop via %step
+ %expression for %index from %start to %stop by %step
+ ..to:
+ assume ((%index's "type") is "Var") or barf ".."
+ List comprehension has the wrong type for the loop variable. Expected Var, but got: \(%index's "type")
+ return {..}
+ expr:".."
+ (function()
+ local comprehension = {};
+ for \(%index as lua expr)=\(%start as lua expr),\(%stop as lua expr),\(%step as lua expr) do
+ comprehension[\(%index as lua expr)] = \(%expression as lua expr);
+ end
+ return comprehension;
+ end)()
+ parse [%expression for all ] as: %expression for % in %iterable
+ parse [%expression for %var from %start to %stop] as: %expression for %var from %start to %stop via 1
+ parse [..]
+ %expression for all %start to %stop by %step
+ %expression for all %start to %stop via %step
+ ..as: %expression for % from %start to %stop via %step
+ parse [%expression for all %start to %stop] as: %expression for all %start to %stop via 1
+
+ compile [%expression for %key = %value in %iterable] to:
+ assume ((%key's "type") is "Var") or barf ".."
+ List comprehension has the wrong type for the key loop variable. Expected Var, but got: \(%key's "type")
+ assume ((%value's "type") is "Var") or barf ".."
+ List comprehension has the wrong type for the value loop variable. Expected Var, but got: \(%value's "type")
+ return {..}
+ expr: ".."
+ (function()
+ local comprehension = {};
+ for \(%key as lua expr), \(%value as lua expr) in pairs(\(%iterable as lua expr)) do
+ table.insert(comprehension, \(%expression as lua expr));
+ end
+ return comprehension;
+ end)()
+
+# Dict comprehensions
+immediately:
+ compile [%key = %value for %item in %iterable] to:
+ assume ((%item's "type") is "Var") or barf ".."
+ Dict comprehension has the wrong type for the loop variable. Expected Var, but got: \(%item's "type")
+ # Note: it's important to have the space after "[" to prevent confusion if %key is a string
+ return {..}
+ expr: ".."
+ (function()
+ local comprehension = {};
+ for i,\(%item as lua expr) in ipairs(\(%iterable as lua expr)) do
+ comprehension[ \(%key as lua expr)] = \(%value as lua expr)
+ end
+ return comprehension;
+ end)()
+ parse [%key = %value for all %iterable] as: %key = %value for % in %iterable
+
+ compile [%key = %value for %src_key = %src_value in %iterable] to:
+ assume ((%src_key's "type") is "Var") or barf ".."
+ Dict comprehension has the wrong type for the key loop variable. Expected Var, but got: \(%src_key's "type")
+ assume ((%src_value's "type") is "Var") or barf ".."
+ Dict comprehension has the wrong type for the value loop variable. Expected Var, but got: \(%src_value's "type")
+ # Note: it's important to have the space after "[" to prevent confusion if %key is a string
+ return {..}
+ expr: ".."
+ (function()
+ local comprehension = {};
+ for \(%src_key as lua expr), \(%src_value as lua expr) in pairs(\(%iterable as lua expr)) do
+ comprehension[ \(%key as lua expr)] = \(%value as lua expr);
+ end
+ return comprehension;
+ end)()
+
+immediately:
+ action [%lists flattened]:
+ %flat <- []
+ for %list in %lists:
+ for %item in %list:
+ add %item to %flat
+ return %flat
+
+ parse [entries in %dict] as: {key:%k, value:%v} for %k = %v in %dict
+ parse [keys in %dict] as: %k for %k = %v in %dict
+ parse [values in %dict] as: %v for %k = %v in %dict
+
+# Sorting:
+immediately:
+ compile [sort %items] to {statements:"table.sort(\(%items as lua expr))"}
+ compile [sort %items by %key_expr] to {..}
+ statements: ".."
+ utils.sort(\(%items as lua expr), function(\(\% as lua expr))
+ return \(%key_expr as lua expr);
+ end)
+
+immediately:
+ action [%items sorted, sorted %items]:
+ %copy <- (% for all %items)
+ sort %copy
+ return %copy
+ action [%items sorted by %key]:
+ %copy <- (% for all %items)
+ sort %copy by %key
+ return %copy
+
+ action [unique %items]:
+ %unique <- []
+ %seen <- {}
+ for all %items:
+ unless: % in %seen
+ add % to %unique
+ (% in %seen) <- (yes)
+ return %unique
+
+immediately:
+ # Metatable stuff
+ compile [set %dict's metatable to %metatable] to {..}
+ statements: "setmetatable(\(%dict as lua expr), \(%metatable as lua expr));"
+
+ compile [new counter] to {expr:"setmetatable({}, {__index=function() return 0; end})"}
+
+ compile [new default dict] to {..}
+ expr: ".."
+ setmetatable({}, {__index=function(self, key)
+ t = {};
+ self[key] = t;
+ return t;
+ end})
+
+# TODO: maybe make a generator/coroutine?