diff options
| author | Bruce Hill <bitbucket@bruce-hill.com> | 2018-02-02 15:48:28 -0800 |
|---|---|---|
| committer | Bruce Hill <bitbucket@bruce-hill.com> | 2018-02-02 15:49:42 -0800 |
| commit | 505fec2a61d2571317cc4bbc36ec0f4822a63f9d (patch) | |
| tree | c2b37e9db8e2f958fbca0caa0a9c4924912a37a9 /core/collections.nom | |
| parent | 513c721198b2256235a95c98d161ab1bb51e6671 (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.nom | 204 |
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? |
