diff options
Diffstat (limited to 'core')
| -rw-r--r-- | core/collections.nom | 234 | ||||
| -rw-r--r-- | core/control_flow.nom | 354 | ||||
| -rw-r--r-- | core/coroutines.nom | 17 | ||||
| -rw-r--r-- | core/errors.nom | 55 | ||||
| -rw-r--r-- | core/io.nom | 9 | ||||
| -rw-r--r-- | core/math.nom | 172 | ||||
| -rw-r--r-- | core/metaprogramming.nom | 152 | ||||
| -rw-r--r-- | core/operators.nom | 136 | ||||
| -rw-r--r-- | core/scopes.nom | 33 | ||||
| -rw-r--r-- | core/text.nom | 38 |
10 files changed, 612 insertions, 588 deletions
diff --git a/core/collections.nom b/core/collections.nom index ce3f61e..100781b 100644 --- a/core/collections.nom +++ b/core/collections.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V1 +#!/usr/bin/env nomsu -V2.2.4.3 # This file contains code that supports manipulating and using collections like lists and dictionaries. @@ -8,173 +8,165 @@ use "core/control_flow.nom" use "core/operators.nom" # List/dict functions: - # Indexing -test: assume: (2nd to last in [1,2,3,4,5]) is 4 +test: assume ((2 nd to last in [1, 2, 3, 4, 5]) is 4) 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: Lua value "utils.nth_to_last(\(%list as lua expr), \(%index as lua expr))" +..to (Lua value "utils.nth_to_last(\(%list as lua expr), \(%index as lua expr))") -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -parse [last in %list] as: 1st to last in %list -parse [first in %list] as: %list.1 +parse [last in %list] as (1 st to last in %list) +parse [first in %list] as %list.1 # Membership testing -test: assume: 3 is in [1,2,3,4,5] -action [%item is in %list, %list contains %item, %list has %item] - for %key = %value in %list - if (%key is %item): return (yes) +test: assume (3 is in [1, 2, 3, 4, 5]) +action [%item is in %list, %list contains %item, %list has %item]: + for %key = %value in %list: if (%key is %item): return (yes) return (no) -test: assume: 99 isn't in [1,2,3] +test: assume (99 isn't in [1, 2, 3]) 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) + %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) -test: assume: {x:no} has key "x" -parse [%list has key %index, %list has index %index] as - %list.%index != (nil) +test: assume ({"x": no} has key "x") +parse [%list has key %index, %list has index %index] as (%list.%index != (nil)) +test: + assume ({"x": no} doesn't have key "y") + assume (not ({"x": no} doesn't have key "x")) -test - assume: {x:no} doesn't have key "y" - assume: not: {x:no} doesn't have key "x" parse [..] %list doesn't have key %index, %list does not have key %index %list doesn't have index %index, %list does not have index %index -..as - %list.%index = (nil) +..as (%list.%index = (nil)) -compile [number of keys in %list] to +compile [number of keys in %list] to (..) Lua value "utils.size(\(%list as lua expr))" -test - %list <- [1,2,3,4,5] +test: + %list <- [1, 2, 3, 4, 5] append 6 to %list - assume: (last in %list) is 6 + assume ((last in %list) is 6) pop from %list - assume: (last in %list) is 5 + assume ((last in %list) is 5) remove index 1 from %list - assume: (first in %list) is 2 + assume ((first in %list) is 2) -compile [append %item to %list, add %item to %list, to %list add %item, to %list append %item] to - Lua "table.insert(\(%list as lua expr), \(%item as lua expr))" +compile [..] + append %item to %list, add %item to %list, to %list add %item + to %list append %item +..to (Lua "table.insert(\(%list as lua expr), \(%item as lua expr))") -compile [pop from %list, remove last from %list] to +compile [pop from %list, remove last from %list] to (..) Lua value "table.remove(\(%list as lua expr))" -compile [remove index %index from %list] to +compile [remove index %index from %list] to (..) Lua value "table.remove(\(%list as lua expr), \(%index as lua expr))" -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # List Comprehension -test: assume: ((% * %) for % in [1,2,3]) = [1,4,9] -parse [%expression for %item in %iterable] as - result of +test: assume (((% * %) for % in [1, 2, 3]) = [1, 4, 9]) +parse [%expression for %item in %iterable] as (..) + result of: %comprehension <- [] - for %item in %iterable - add %expression to %comprehension + for %item in %iterable: add %expression to %comprehension return %comprehension parse [..] %expression for %index in %start to %stop via %step %expression for %index in %start to %stop by %step -..as - result of +..as (..) + result of: %comprehension <- [] - for %index in %start to %stop via %step - add %expression to %comprehension + for %index in %start to %stop via %step: add %expression to %comprehension return %comprehension -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -test: assume: ((% * %) for % in 1 to 3) = [1,4,9] -parse [%expression for %var in %start to %stop] as +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +test: assume (((% * %) for % in 1 to 3) = [1, 4, 9]) +parse [%expression for %var in %start to %stop] as (..) %expression for %var in %start to %stop via 1 -test: assume: ("\%k,\%v" for %k = %v in {x:1}) = ["x,1"] +test: assume (("\%k,\%v" for %k = %v in {"x": 1}) = ["x,1"]) parse [..] %expression for %key = %value in %iterable - %expression for (%key,%value) in %iterable -..as - result of + %expression for %key %value in %iterable +..as (..) + result of: %comprehension <- [] - for %key = %value in %iterable - add %expression to %comprehension + for %key = %value in %iterable: add %expression to %comprehension return %comprehension + # Dict comprehensions -test: assume: ((% * %) = % for % in [1,2,3]) = {1:1,4:2,9:3} -parse [..] - %key = %value for %item in %iterable - (%key,%value) for %item in %iterable -..as - result of +test: assume (((% * %) = % for % in [1, 2, 3]) = {1: 1, 4: 2, 9: 3}) +parse [%key = %value for %item in %iterable, %key %value for %item in %iterable] +..as (..) + result of: %comprehension <- {} - for %item in %iterable - %comprehension.%key <- %value + for %item in %iterable: %comprehension.%key <- %value return %comprehension -test: assume: (%k = (%v * %v) for %k = %v in {x:1,y:2,z:3}) = {x:1,y:4,z:9} +test: + assume (..) + (%k = (%v * %v) for %k = %v in {"x": 1, "y": 2, "z": 3}) = {"x": 1, "y": 4, "z": 9} + parse [..] %key = %value for %src_key = %src_value in %iterable - (%key,%value) for (%src_key,%src_value) in %iterable -..as - result of + %key %value for %src_key %src_value in %iterable +..as (..) + result of: %comprehension <- {} - for %src_key = %src_value in %iterable - %comprehension.%key <- %value + for %src_key = %src_value in %iterable: %comprehension.%key <- %value return %comprehension parse [..] %key = %value for %item in %start to %stop via %step - (%key,%value) for %item in %start to %stop via %step -..as - result of + %key %value for %item in %start to %stop via %step +..as (..) + result of: %comprehension <- {} - for %item in %start to %stop via %step - %comprehension.%key <- %value + for %item in %start to %stop via %step: %comprehension.%key <- %value return %comprehension -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -test: assume: ((% * %) = % for % in 1 to 3) = {1:1,4:2,9:3} + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +test: assume (((% * %) = % for % in 1 to 3) = {1: 1, 4: 2, 9: 3}) parse [..] %key = %value for %item in %start to %stop - (%key,%value) for %item in %start to %stop -..as: %key = %value for %item in %start to %stop via 1 + %key %value for %item in %start to %stop +..as (%key = %value for %item in %start to %stop via 1) -test: assume: ([[1,2],[3,4]] flattened) = [1,2,3,4] -action [%lists flattened] +test: assume (([[1, 2], [3, 4]] flattened) = [1, 2, 3, 4]) +action [%lists flattened]: %flat <- [] - for %list in %lists - for %item in %list - add %item to %flat + for %list in %lists: for %item in %list: add %item to %flat return %flat -test: assume: (entries in {x:1}) = [{key:"x",value:1}] -parse [entries in %dict] as: {key:%k, value:%v} for %k = %v in %dict - -test: assume: (keys in {x:1}) = ["x"] -parse [keys in %dict, keys of %dict] as: %k for %k = %v in %dict - -test: assume: (values in {x:1}) = [1] -parse [values in %dict, values of %dict] as: %v for %k = %v in %dict +test: assume ((entries in {"x": 1}) = [{"key": "x", "value": 1}]) +parse [entries in %dict] as ({"key": %k, "value": %v} for %k = %v in %dict) +test: assume ((keys in {"x": 1}) = ["x"]) +parse [keys in %dict, keys of %dict] as (%k for %k = %v in %dict) +test: assume ((values in {"x": 1}) = [1]) +parse [values in %dict, values of %dict] as (%v for %k = %v in %dict) # Metatable stuff -test +test: %t <- {} - set %t's metatable to {__tostring:[%]->"XXX"} - assume: "\%t" = "XXX" -compile [set %dict's metatable to %metatable] to + set %t 's metatable to {"__tostring": [%] -> "XXX"} + assume ("\%t" = "XXX") + +compile [set %dict 's metatable to %metatable] to (..) Lua "setmetatable(\(%dict as lua expr), \(%metatable as lua expr));" -test: assume: ({} with fallback % -> (% + 1)).10 = 11 -compile [%dict with fallback %key -> %value] to +test: assume (({} with fallback % -> (% + 1)).10 = 11) +compile [%dict with fallback %key -> %value] to (..) Lua value ".." setmetatable(\(%dict as lua expr), {__index=function(self, \(%key as lua expr)) local value = \(%value as lua expr) @@ -182,48 +174,44 @@ compile [%dict with fallback %key -> %value] to return value end}) + # Sorting -test - %x <- [3,1,2] +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} + 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] -compile [sort %items] to: Lua "table.sort(\(%items as lua expr));" -parse [..] - sort %items by %item = %key_expr - sort %items by %item -> %key_expr -..as - do + assume (%x = [2, 3, 1]) + +compile [sort %items] to (Lua "table.sort(\(%items as lua expr));") +parse [sort %items by %item = %key_expr, sort %items by %item -> %key_expr] 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] -action [%items sorted, sorted %items] +test: assume ((sorted [3, 1, 2]) = [1, 2, 3]) +action [%items sorted, sorted %items]: %copy <- (% for % in %items) sort %copy return %copy -parse [..] - %items sorted by %item = %key - %items sorted by %item -> %key -..as - result of + +parse [%items sorted by %item = %key, %items sorted by %item -> %key] as (..) + result of: %copy <- (% for % in %items) sort %copy by %item = %key return %copy -test: assume: (unique [1,2,1,3,2,3]) = [1,2,3] -action [unique %items] +test: assume ((unique [1, 2, 1, 3, 2, 3]) = [1, 2, 3]) +action [unique %items]: %unique <- [] %seen <- {} - for % in %items - unless: %seen.% + for % in %items: + unless %seen.%: add % to %unique %seen.% <- (yes) return %unique - diff --git a/core/control_flow.nom b/core/control_flow.nom index 5de062d..bb30e49 100644 --- a/core/control_flow.nom +++ b/core/control_flow.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V1 +#!/usr/bin/env nomsu -V2.2.4.3 # This file contains compile-time actions that define basic control flow structures like "if" statements and loops. @@ -10,19 +10,21 @@ use "core/errors.nom" # No-Op test: do nothing -compile [do nothing] to: Lua "" +compile [do nothing] to (Lua "") # Conditionals test: if (no): barf "conditional fail" -compile [if %condition %if_body] to +compile [if %condition %if_body] to (..) Lua ".." if \(%condition as lua expr) then \(%if_body as lua statements) end -test: unless (yes): barf "conditional fail" -parse [unless %condition %unless_body] as: if (not %condition) %unless_body -compile [if %condition %if_body else %else_body, unless %condition %else_body else %if_body] to +test: unless (yes): barf "conditional fail" +parse [unless %condition %unless_body] as (if (not %condition) %unless_body) +compile [..] + if %condition %if_body else %else_body, unless %condition %else_body else %if_body +..to (..) Lua ".." if \(%condition as lua expr) then \(%if_body as lua statements) @@ -30,7 +32,7 @@ compile [if %condition %if_body else %else_body, unless %condition %else_body el \(%else_body as lua statements) end -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Conditional expression (ternary operator) # Note: this uses a function instead of "(condition and if_expr or else_expr)" @@ -40,18 +42,20 @@ compile [..] %when_true_expr if %condition otherwise %when_false_expr %when_false_expr unless %condition else %when_true_expr %when_false_expr unless %condition then %when_true_expr -..to +..to (..) + # If %when_true_expr is guaranteed to be truthy, we can use Lua's idiomatic equivalent of a conditional expression: (cond and if_true or if_false) - if: {Text:yes, List:yes, Dict:yes, Number:yes}.(%when_true_expr.type) - return + if {"Text": yes, "List": yes, "Dict": yes, "Number": yes}.(%when_true_expr.type): + return (..) Lua value ".." (\(%condition as lua expr) and \(%when_true_expr as lua expr) or \(%when_false_expr as lua expr)) - ..else + ..else: + # Otherwise, need to do an anonymous inline function (yuck, too bad lua doesn't have a proper ternary operator!) To see why this is necessary consider: (random()<.5 and false or 99) - return + return (..) Lua value ".." ((function() if \(%condition as lua expr) then @@ -61,19 +65,21 @@ compile [..] end end)()) + # GOTOs -compile [=== %label ===, --- %label ---, *** %label ***] to +compile [=== %label ===, --- %label ---, *** %label ***] to (..) Lua "::label_\(%label as lua identifier)::" -compile [go to %label] to + +compile [go to %label] to (..) Lua "goto label_\(%label as lua identifier)" # Basic loop control -compile [do next] to: Lua "continue" -compile [stop] to: Lua "break" +compile [do next] to (Lua "continue") +compile [stop] to (Lua "break") # Helper function #TODO: do "using % compile %" instead so it's actually a helper function -compile [%tree has subtree %subtree where %condition] to +compile [%tree has subtree %subtree where %condition] to (..) Lua value ".." (function() for \(%subtree as lua expr) in coroutine.wrap(function() \(%tree as lua expr):map(coroutine.yield) end) do @@ -84,294 +90,271 @@ compile [%tree has subtree %subtree where %condition] to return false end)() -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # While loops -compile [do next repeat] to: Lua "goto continue_repeat" -compile [stop repeating] to: Lua "goto stop_repeat" -compile [repeat while %condition %body] to - %lua <- +compile [do next repeat] to (Lua "goto continue_repeat") +compile [stop repeating] to (Lua "goto stop_repeat") +compile [repeat while %condition %body] to: + %lua <- (..) Lua ".." while \(%condition as lua expr) do \(%body as lua statements) - if - %body has subtree % where: (%.type = "Action") and (%.stub is "do next repeat") - ..:to %lua write "\n ::continue_repeat::" + + if (..) + %body has subtree % where ((%.type = "Action") and (%.stub is "do next repeat")) + ..: to %lua write "\n ::continue_repeat::" + to %lua write "\nend --while-loop" - if - %body has subtree % where: (%.type = "Action") and (%.stub is "stop repeating") - .. - %lua <- + if (%body has subtree % where ((%.type = "Action") and (%.stub is "stop repeating"))): + %lua <- (..) Lua ".." do -- scope of "stop repeating" label \%lua ::stop_repeat:: end -- end of "stop repeating" label scope + return %lua -parse [repeat %body] as: repeat while (yes) %body -parse [repeat until %condition %body] as: repeat while (not %condition) %body -compile [..] - repeat %n times %body -..to - %lua <- - Lua ".." - for i=1,\(%n as lua expr) do - \(%body as lua statements) - if - %body has subtree % where: (%.type = "Action") and (%.stub is "do next repeat") - ..: to %lua write "\n ::continue_repeat::" +parse [repeat %body] as (repeat while (yes) %body) +parse [repeat until %condition %body] as (repeat while (not %condition) %body) +compile [repeat %n times %body] to: + %lua <- (Lua "for i=1,\(%n as lua expr) do\n \(%body as lua statements)") + if (%body has subtree % where ((%.type = "Action") and (%.stub is "do next repeat"))): + to %lua write "\n ::continue_repeat::" + to %lua write "\nend --numeric for-loop" - if - %body has subtree % where: (%.type = "Action") and (%.stub is "stop repeating") - .. - %lua <- + if (%body has subtree % where ((%.type = "Action") and (%.stub is "stop repeating"))): + %lua <- (..) Lua ".." do -- scope of "stop repeating" label \%lua ::stop_repeat:: end -- end of "stop repeating" label scope + return %lua -# For loop control flow -compile [stop %var] to - Lua "goto stop_\(%var as lua identifier)" -compile [do next %var] to - Lua "goto continue_\(%var as lua identifier)" -compile [=== stop %var ===, --- stop %var ---, *** stop %var ***] to +# For loop control flow +compile [stop %var] to (Lua "goto stop_\(%var as lua identifier)") +compile [do next %var] to (Lua "goto continue_\(%var as lua identifier)") +compile [===stop %var ===, ---stop %var ---, ***stop %var ***] to (..) Lua "::stop_\(%var as lua identifier)::" -compile [=== next %var ===, --- next %var ---, *** next %var ***] to + +compile [===next %var ===, ---next %var ---, ***next %var ***] to (..) Lua "::continue_\(%var as lua identifier)::" -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Numeric range for loops compile [..] for %var in %start to %stop by %step %body for %var in %start to %stop via %step %body -..to +..to: # This uses Lua's approach of only allowing loop-scoped variables in a loop assume (%var.type is "Var") or barf "Loop expected variable, not: \%var" - %lua <- + %lua <- (..) Lua ".." for \(%var as lua expr)=\(%start as lua expr),\(%stop as lua expr),\(%step as lua expr) do \(%body as lua statements) - if - %body has subtree % where - (%.type = "Action") and - (%.stub is "do next %") and - %.(3).1 = %var.1 - ..: to %lua write "\n \(compile as: === next %var ===)" + + if (..) + %body has subtree % where (..) + (%.type = "Action") and ((%.stub is "do next %") and (%.(3).1 = %var.1)) + ..: to %lua write "\n \(compile as (===next %var ===))" + to %lua write "\nend --numeric for-loop" - - if - %body has subtree % where - (%.type = "Action") and - (%.stub is "stop %") and - %.(2).1 = %var.1 - .. - %lua <- + if (..) + %body has subtree % where (..) + (%.type = "Action") and ((%.stub is "stop %") and (%.(2).1 = %var.1)) + ..: + %lua <- (..) Lua ".." do -- scope for stopping for-loop \%lua - \(compile as: === stop %var ===) + \(compile as (===stop %var ===)) end -- end of scope for stopping for-loop - + return %lua -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +parse [for %var in %start to %stop %body] as (..) + for %var in %start to %stop via 1 %body -parse [for %var in %start to %stop %body] as: for %var in %start to %stop via 1 %body # For-each loop (lua's "ipairs()") -compile [for %var in %iterable %body] to +compile [for %var in %iterable %body] to: # This uses Lua's approach of only allowing loop-scoped variables in a loop assume (%var.type is "Var") or barf "Loop expected variable, not: \%var" - %lua <- + %lua <- (..) Lua ".." for i,\(%var as lua identifier) in ipairs(\(%iterable as lua expr)) do \(%body as lua statements) - if - %body has subtree % where - (%.type = "Action") and - (%.stub is "do next %") and - %.3.(1) = %var.(1) - ..: to %lua write (Lua "\n\(compile as: === next %var ===)") + + if (..) + %body has subtree % where (..) + (%.type = "Action") and ((%.stub is "do next %") and (%.(3).1 = %var.1)) + ..: to %lua write (Lua "\n\(compile as (===next %var ===))") + to %lua write "\nend --foreach-loop" - if - %body has subtree % where - (%.type = "Action") and - (%.stub is "stop %") and - %.2.(1) = %var.(1) - .. - %lua <- + if (..) + %body has subtree % where (..) + (%.type = "Action") and ((%.stub is "stop %") and (%.(2).1 = %var.1)) + ..: + %lua <- (..) Lua ".." do -- scope for stopping for-loop \%lua - \(compile as: === stop %var ===) + \(compile as (===stop %var ===)) end -- end of scope for stopping for-loop + return %lua + # Dict iteration (lua's "pairs()") -compile [..] - for %key = %value in %iterable %body - for (%key,%value) in %iterable %body -..to +compile [for %key = %value in %iterable %body, for %key %value in %iterable %body] to: # This uses Lua's approach of only allowing loop-scoped variables in a loop assume (%key.type is "Var") or barf "Loop expected variable, not: \%key" assume (%value.type is "Var") or barf "Loop expected variable, not: \%value" - %lua <- + %lua <- (..) Lua ".." for \(%key as lua identifier),\(%value as lua identifier) in pairs(\(%iterable as lua expr)) do \(%body as lua statements) - if - %body has subtree % where - (%.type = "Action") and - (%.stub is "do next %") and - %.3.(1) = %key.(1) - ..: to %lua write (Lua "\n\(compile as: === next %key ===)") - - if - %body has subtree % where - (%.type = "Action") and - (%.stub is "do next %") and - %.3.(1) = %value.(1) - ..: to %lua write (Lua "\n\(compile as: === next %value ===)") - to %lua write "\nend --foreach-loop" + if (..) + %body has subtree % where (..) + (%.type = "Action") and ((%.stub is "do next %") and (%.(3).1 = %key.1)) + ..: to %lua write (Lua "\n\(compile as (===next %key ===))") + + if (..) + %body has subtree % where (..) + (%.type = "Action") and ((%.stub is "do next %") and (%.(3).1 = %value.1)) + ..: to %lua write (Lua "\n\(compile as (===next %value ===))") + + to %lua write "\nend --foreach-loop" %stop_labels <- (Lua "") - if - %body has subtree % where - (%.type = "Action") and - (%.stub is "stop %") and - %.2.(1) = %key.(1) - ..: to %stop_labels write "\n\(compile as: === stop %key ===)" - - if - %body has subtree % where - (%.type = "Action") and - (%.stub is "stop %") and - %.2.(1) = %value.(1) - ..: to %stop_labels write "\n\(compile as: === stop %value ===)" - - if: (length of "\%stop_labels") > 0 - %lua <- - Lua ".." - do -- scope for stopping for % = % loop - \%lua\%stop_labels - end + if (..) + %body has subtree % where (..) + (%.type = "Action") and ((%.stub is "stop %") and (%.(2).1 = %key.1)) + ..: to %stop_labels write "\n\(compile as (===stop %key ===))" + + if (..) + %body has subtree % where (..) + (%.type = "Action") and ((%.stub is "stop %") and (%.(2).1 = %value.1)) + ..: to %stop_labels write "\n\(compile as (===stop %value ===))" + + if ((length of "\%stop_labels") > 0): + %lua <- (..) + Lua "do -- scope for stopping for % = % loop\n \%lua\%stop_labels\nend" + return %lua -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Switch statement/multi-branch if -compile [when %body] to +compile [when %body] to: %code <- (Lua "") %fallthroughs <- [] %is_first <- (yes) %seen_else <- (no) - %branches <- - %body if (%body.type = "Block") else [%body] - for %func_call in %branches - assume (%func_call.type is "Action") or barf ".." - Invalid format for 'when' statement. Only '*' blocks are allowed. - with {..} - %star: %func_call.1 - %condition: %func_call.2 - %action: %func_call.3 - .. - assume (%star = "*") or barf ".." - Invalid format for 'when' statement. Lines must begin with '*' + %branches <- (%body if (%body.type = "Block") else [%body]) + for %func_call in %branches: + assume (%func_call.type is "Action") or barf "Invalid format for 'when' statement. Only '*' blocks are allowed." + with {%star: %func_call.1, %condition: %func_call.2, %action: %func_call.3}: + assume (%star = "*") or barf "Invalid format for 'when' statement. Lines must begin with '*'" assume %condition or barf ".." - Invalid format for 'when' statement. Lines must begin with '*' and have a condition or the word "else" - if: %action is (nil) + Invalid format for 'when' statement. Lines must begin with '*' and have a condition \ + ..or the word "else" + + if (%action is (nil)): lua> "table.insert(\%fallthroughs, \(%condition as lua expr))" do next %func_call - - if: %condition = "else" + + if (%condition = "else"): assume (not %is_first) or barf "'else' clause cannot be first in 'when % = ?' block" to %code write "\nelse\n " - to %code write: %action as lua statements + to %code write (%action as lua statements) %seen_else <- (yes) - ..else + ..else: assume (not %seen_else) or barf "'else' clause needs to be last in 'when' block" lua> "table.insert(\%fallthroughs, \(%condition as lua expr))" to %code write "\("if" if %is_first else "\nelseif") " - for %i = %condition in %fallthroughs + for %i = %condition in %fallthroughs: if (%i > 1): to %code write " or " to %code write %condition + to %code write " then\n " to %code write (%action as lua statements) - + %fallthroughs <- [] %is_first <- (no) - + assume (%fallthroughs = []) or barf "Unfinished fallthrough conditions in 'when' block" assume ((length of "\%code") > 0) or barf "Empty body for 'when' block" to %code write "\nend --when" return %code + # Switch statement -compile [when %branch_value = ? %body, when %branch_value is ? %body] to +compile [when %branch_value = ? %body, when %branch_value is ? %body] to: %code <- (Lua "") %fallthroughs <- [] %is_first <- (yes) %seen_else <- (no) - %branches <- - %body if (%body.type = "Block") else [%body] - for %func_call in %branches - assume (%func_call.type is "Action") or barf ".." - Invalid format for 'when' statement. Only '*' blocks are allowed. - with {%star:%func_call.1, %condition:%func_call.2, %action:%func_call.3} - assume (%star = "*") or barf ".." - Invalid format for 'when' statement. Lines must begin with '*' + %branches <- (%body if (%body.type = "Block") else [%body]) + for %func_call in %branches: + assume (%func_call.type is "Action") or barf "Invalid format for 'when' statement. Only '*' blocks are allowed." + with {%star: %func_call.1, %condition: %func_call.2, %action: %func_call.3}: + assume (%star = "*") or barf "Invalid format for 'when' statement. Lines must begin with '*'" assume %condition or barf ".." - Invalid format for 'when' statement. Lines must begin with '*' and have a condition or the word "else" - if: %action is (nil) + Invalid format for 'when' statement. Lines must begin with '*' and have a condition \ + ..or the word "else" + + if (%action is (nil)): lua> "table.insert(\%fallthroughs, \(%condition as lua expr))" do next %func_call - - if: %condition = "else" + + if (%condition = "else"): assume (not %is_first) or barf "'else' clause cannot be first in 'when % = ?' block" to %code write "\nelse\n " - to %code write: %action as lua statements - ..else + to %code write (%action as lua statements) + ..else: assume (not %seen_else) or barf "'else' clause needs to be last in 'when % = ?' block" to %code write "\("if" if %is_first else "\nelseif") " lua> "table.insert(\%fallthroughs, \(%condition as lua expr))" - for %i = % in %fallthroughs - if: %i > 1 - to %code write " or " - if: (%.type is "Text") or (%.type is "Number") + for %i = % in %fallthroughs: + if (%i > 1): to %code write " or " + if ((%.type is "Text") or (%.type is "Number")): to %code write "branch_value == \%" - ..else - to %code write "utils.equivalent(branch_value, \%)" + ..else: to %code write "utils.equivalent(branch_value, \%)" + to %code write "then\n " to %code write (%action as lua statements) - + %fallthroughs <- [] %is_first <- (no) assume (%fallthroughs = []) or barf "Unfinished fallthrough conditions in 'when' block" assume ((length of "\%code") > 0) or barf "No body for 'when % = ?' block!" to %code write "\nend" - %code <- + %code <- (..) Lua ".." do --when % = ? local branch_value = \(%branch_value as lua expr) \%code end --when % = ? + return %code + # Do/finally -compile [do %action] to +compile [do %action] to (..) Lua ".." do \(%action as lua statements) end --do - -compile [do %action then always %final_action] to +compile [do %action then always %final_action] to (..) Lua ".." do local fell_through = false @@ -384,23 +367,24 @@ compile [do %action then always %final_action] to if not fell_through then return ret end end + # Inline thunk: -compile [result of %body] to - Lua value "(\(compile as: [] -> %body))()" +compile [result of %body] to (Lua value "(\(compile as ([] -> %body)))()") # Recurion control flow -compile [for %var in recursive %structure %body] to - with local compile actions - compile [recurse %v on %x] to +compile [for %var in recursive %structure %body] to (..) + with local compile actions: + compile [recurse %v on %x] to (..) Lua "table.insert(stack\(%v as lua id), \(%x as lua expr))" - return + + return (..) Lua ".." do local stack\(%var as lua id) = list{\(%structure as lua expr)} while #stack\(%var as lua id) > 0 do \(%var as lua expr) = table.remove(stack\(%var as lua id), 1) \(%body as lua statements) - \(compile as: === next %var ===) + \(compile as (===next %var ===)) end - \(compile as: === stop %var ===) + \(compile as (===stop %var ===)) end diff --git a/core/coroutines.nom b/core/coroutines.nom index 8a1f8c9..c14042c 100644 --- a/core/coroutines.nom +++ b/core/coroutines.nom @@ -1,18 +1,15 @@ -#!/usr/bin/env nomsu -V1 +#!/usr/bin/env nomsu -V2.2.4.3 # This file defines the code that creates and manipulates coroutines use "core/metaprogramming.nom" +compile [coroutine %body, generator %body] to (..) + Lua value "(function()\n \(%body as lua statements)\nend)" -compile [coroutine %body, generator %body] to - Lua value ".." - (function() - \(%body as lua statements) - end) -compile [->] to: Lua value "coroutine.yield(true)" -compile [-> %] to: Lua value "coroutine.yield(true, \(% as lua expr))" -compile [for % in coroutine %co %body] to +compile [->] to (Lua value "coroutine.yield(true)") +compile [-> %] to (Lua value "coroutine.yield(true, \(% as lua expr))") +compile [for % in coroutine %co %body] to (..) Lua ".." for junk,\(% as lua expr) in coroutine.wrap(\(%co as lua expr)) do \(%body as lua statements) - end + end
\ No newline at end of file diff --git a/core/errors.nom b/core/errors.nom index c6551b5..42348a9 100644 --- a/core/errors.nom +++ b/core/errors.nom @@ -1,32 +1,34 @@ -#!/usr/bin/env nomsu -V1 +#!/usr/bin/env nomsu -V2.2.4.3 # This file contains basic error reporting code use "core/metaprogramming.nom" - -compile [traceback] to: Lua value "debug.traceback()" -compile [traceback %] to: Lua value "debug.traceback('', \(% as lua expr))" -compile [barf] to: Lua "error(nil, 0);" -compile [barf %msg] to: Lua "error(\(%msg as lua expr), 0);" -compile [assume %condition] to - lua> "local \%assumption = 'Assumption failed: '..tostring(nomsu:tree_to_nomsu(\%condition))" - return +compile [traceback] to (Lua value "debug.traceback()") +compile [traceback %] to (Lua value "debug.traceback('', \(% as lua expr))") +compile [barf] to (Lua "error(nil, 0);") +compile [barf %msg] to (Lua "error(\(%msg as lua expr), 0);") +compile [assume %condition] to: + lua> ".." + local \%assumption = 'Assumption failed: '..tostring(nomsu:tree_to_nomsu(\%condition)) + + return (..) Lua ".." if not \(%condition as lua expr) then error(\(quote "\%assumption"), 0) end -compile [assume %condition or barf %message] to +compile [assume %condition or barf %message] to (..) Lua ".." if not \(%condition as lua expr) then error(\(%message as lua expr), 0) end + # Try/except compile [..] try %action and if it succeeds %success or if it barfs %msg %fallback try %action and if it barfs %msg %fallback or if it succeeds %success -..to +..to (..) Lua ".." do local fell_through = false @@ -50,20 +52,23 @@ compile [..] end end -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + parse [..] try %action and if it succeeds %success or if it barfs %fallback try %action and if it barfs %fallback or if it succeeds %success -..as: try %action and if it succeeds %success or if it barfs (=lua "") %fallback -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -parse [try %action] as - try %action and if it succeeds: do nothing - ..or if it barfs: do nothing -parse [try %action and if it barfs %fallback] as - try %action and if it succeeds: do nothing - ..or if it barfs %fallback -parse [try %action and if it barfs %msg %fallback] as - try %action and if it succeeds: do nothing - ..or if it barfs %msg %fallback -parse [try %action and if it succeeds %success] as - try %action and if it succeeds %success or if it barfs: do nothing +..as (try %action and if it succeeds %success or if it barfs (=lua "") %fallback) + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +parse [try %action] as (..) + try %action and if it succeeds (do nothing) or if it barfs (do nothing) + +parse [try %action and if it barfs %fallback] as (..) + try %action and if it succeeds (do nothing) or if it barfs %fallback + +parse [try %action and if it barfs %msg %fallback] as (..) + try %action and if it succeeds (do nothing) or if it barfs %msg %fallback + +parse [try %action and if it succeeds %success] as (..) + try %action and if it succeeds %success or if it barfs (do nothing)
\ No newline at end of file diff --git a/core/io.nom b/core/io.nom index 55c5702..e04c88b 100644 --- a/core/io.nom +++ b/core/io.nom @@ -1,10 +1,9 @@ -#!/usr/bin/env nomsu -V1 +#!/usr/bin/env nomsu -V2.2.4.3 # This file contains basic input/output code use "core/metaprogramming.nom" - -compile [say %message] to +compile [say %message] to (..) lua> ".." if \%message.type == "Text" then return LuaCode(tree.source, "print(", \(%message as lua expr), ");"); @@ -12,10 +11,10 @@ compile [say %message] to return LuaCode(tree.source, "print(tostring(", \(%message as lua expr), "));"); end -compile [ask %prompt] to +compile [ask %prompt] to (..) lua> ".." if \%prompt.type == "Text" then return LuaCode.Value(tree.source, "(io.write(", \(%prompt as lua expr), ") and io.read())"); else return LuaCode.Value(tree.source, "(io.write(tostring(", \(%prompt as lua expr), ")) and io.read())"); - end + end
\ No newline at end of file diff --git a/core/math.nom b/core/math.nom index 5717482..9d432e7 100644 --- a/core/math.nom +++ b/core/math.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V1 +#!/usr/bin/env nomsu -V2.2.4.3 # This file defines some common math literals and functions @@ -9,91 +9,119 @@ use "core/control_flow.nom" use "core/collections.nom" # Literals: -compile [infinity, inf] to: Lua value "math.huge" -compile [not a number, NaN, nan] to: Lua value "(0/0)" -compile [pi, Pi, PI] to: Lua value "math.pi" -compile [tau, Tau, TAU] to: Lua value "(2*math.pi)" -compile [golden ratio] to: Lua value "((1+math.sqrt(5))/2)" -compile [e] to: Lua value "math.exp(1)" +compile [infinity, inf] to (Lua value "math.huge") +compile [not a number, NaN, nan] to (Lua value "(0/0)") +compile [pi, Pi, PI] to (Lua value "math.pi") +compile [tau, Tau, TAU] to (Lua value "(2*math.pi)") +compile [golden ratio] to (Lua value "((1+math.sqrt(5))/2)") +compile [e] to (Lua value "math.exp(1)") # Functions: -compile [% as a number, % as number] to: Lua value "tonumber(\(% as lua expr))" -compile [absolute value %, | % |, abs %] to: Lua value "math.abs(\(% as lua expr))" -compile [square root %, square root of %, √%, sqrt %] to: Lua value "math.sqrt(\(% as lua expr))" -compile [sine %, sin %] to: Lua value "math.sin(\(% as lua expr))" -compile [cosine %, cos %] to: Lua value "math.cos(\(% as lua expr))" -compile [tangent %, tan %] to: Lua value "math.tan(\(% as lua expr))" -compile [arc sine %, asin %] to: Lua value "math.asin(\(% as lua expr))" -compile [arc cosine %, acos %] to: Lua value "math.acos(\(% as lua expr))" -compile [arc tangent %, atan %] to: Lua value "math.atan(\(% as lua expr))" -compile [arc tangent %y / %x, atan2 %y %x] to: Lua value "math.atan2(\(%y as lua expr), \(%x as lua expr))" -compile [hyperbolic sine %, sinh %] to: Lua value "math.sinh(\(% as lua expr))" -compile [hyperbolic cosine %, cosh %] to: Lua value "math.cosh(\(% as lua expr))" -compile [hyperbolic tangent %, tanh %] to: Lua value "math.tanh(\(% as lua expr))" -compile [e^%, exp %] to: Lua value "math.exp(\(% as lua expr))" -compile [natural log %, ln %, log %] to: Lua value "math.log(\(% as lua expr))" -compile [log % base %base, log base %base of %] to: Lua value "math.log(\(% as lua expr), \(%base as lua expr))" -compile [floor %] to: Lua value "math.floor(\(% as lua expr))" -compile [ceiling %, ceil %] to: Lua value "math.ceil(\(% as lua expr))" -compile [round %, % rounded] to: Lua value "math.floor(\(% as lua expr) + .5)" -action [%n to the nearest %rounder] +compile [% as a number, % as number] to (Lua value "tonumber(\(% as lua expr))") +compile [absolute value %, | % |, abs %] to (..) + Lua value "math.abs(\(% as lua expr))" + +compile [square root %, square root of %, √ %, sqrt %] to (..) + Lua value "math.sqrt(\(% as lua expr))" + +compile [sine %, sin %] to (Lua value "math.sin(\(% as lua expr))") +compile [cosine %, cos %] to (Lua value "math.cos(\(% as lua expr))") +compile [tangent %, tan %] to (Lua value "math.tan(\(% as lua expr))") +compile [arc sine %, asin %] to (Lua value "math.asin(\(% as lua expr))") +compile [arc cosine %, acos %] to (Lua value "math.acos(\(% as lua expr))") +compile [arc tangent %, atan %] to (Lua value "math.atan(\(% as lua expr))") +compile [arc tangent %y / %x, atan2 %y %x] to (..) + Lua value "math.atan2(\(%y as lua expr), \(%x as lua expr))" + +compile [hyperbolic sine %, sinh %] to (Lua value "math.sinh(\(% as lua expr))") +compile [hyperbolic cosine %, cosh %] to (..) + Lua value "math.cosh(\(% as lua expr))" + +compile [hyperbolic tangent %, tanh %] to (..) + Lua value "math.tanh(\(% as lua expr))" + +compile [e^ %, exp %] to (Lua value "math.exp(\(% as lua expr))") +compile [natural log %, ln %, log %] to (Lua value "math.log(\(% as lua expr))") +compile [log % base %base, log base %base of %] to (..) + Lua value "math.log(\(% as lua expr), \(%base as lua expr))" + +compile [floor %] to (Lua value "math.floor(\(% as lua expr))") +compile [ceiling %, ceil %] to (Lua value "math.ceil(\(% as lua expr))") +compile [round %, % rounded] to (Lua value "math.floor(\(% as lua expr) + .5)") +action [%n to the nearest %rounder] (..) =lua "(\%rounder)*math.floor((\%n / \%rounder) + .5)" + # Any/all/none -compile [all of %items, all %items] to - unless: %items.type is "List" - return: Lua value "utils.all(\(%items as lua expr))" +compile [all of %items, all %items] to: + unless (%items.type is "List"): + return (Lua value "utils.all(\(%items as lua expr))") + %clauses <- ((% as lua expr) for % in %items) - return: Lua value "(\(%clauses joined with " and "))" -parse [not all of %items, not all %items] as: not (all of %items) -compile [any of %items, any %items] to - unless: %items.type is "List" - return: Lua value "utils.any(\(%items as lua expr))" + return (Lua value "(\(%clauses joined with " and "))") + +parse [not all of %items, not all %items] as (not (all of %items)) +compile [any of %items, any %items] to: + unless (%items.type is "List"): + return (Lua value "utils.any(\(%items as lua expr))") + %clauses <- ((% as lua expr) for % in %items) - return: Lua value "(\(%clauses joined with " or "))" -parse [none of %items, none %items] as: not (any of %items) -compile [sum of %items, sum %items] to - unless: %items.type is "List" - return: Lua value "utils.sum(\(%items as lua expr))" + return (Lua value "(\(%clauses joined with " or "))") + +parse [none of %items, none %items] as (not (any of %items)) +compile [sum of %items, sum %items] to: + unless (%items.type is "List"): + return (Lua value "utils.sum(\(%items as lua expr))") + %clauses <- ((% as lua expr) for % in %items) - return: Lua value "(\(%clauses joined with " + "))" -compile [product of %items, product %items] to - unless: %items.type is "List" - return: Lua value "utils.product(\(%items as lua expr))" + return (Lua value "(\(%clauses joined with " + "))") + +compile [product of %items, product %items] to: + unless (%items.type is "List"): + return (Lua value "utils.product(\(%items as lua expr))") + %clauses <- ((% as lua expr) for % in %items) - return: Lua value "(\(%clauses joined with " * "))" -action [avg of %items, average of %items] - =lua "(utils.sum(\%items)/#\%items)" -compile [min of %items, smallest of %items, lowest of %items] to + return (Lua value "(\(%clauses joined with " * "))") + +action [avg of %items, average of %items] (=lua "(utils.sum(\%items)/#\%items)") +compile [min of %items, smallest of %items, lowest of %items] to (..) Lua value "utils.min(\(%items as lua expr))" -compile [max of %items, biggest of %items, largest of %items, highest of %items] to - Lua value "utils.max(\(%items as lua expr))" -parse [min of %items by %item = %value_expr] as - result of - <- {%best:nil, %best_key:nil} - for %item in %items + +compile [max of %items, biggest of %items, largest of %items, highest of %items] +..to (Lua value "utils.max(\(%items as lua expr))") + +parse [min of %items by %item = %value_expr] as (..) + result of: + <- {%best: nil, %best_key: nil} + for %item in %items: %key <- %value_expr - if: (%best = (nil)) or (%key < %best_key) - <- {%best:%item, %best_key:%key} + if ((%best = (nil)) or (%key < %best_key)): + <- {%best: %item, %best_key: %key} + return %best -parse [max of %items by %item = %value_expr] as - result of - <- {%best:nil, %best_key:nil} - for %item in %items + +parse [max of %items by %item = %value_expr] as (..) + result of: + <- {%best: nil, %best_key: nil} + for %item in %items: %key <- %value_expr - if: (%best = (nil)) or (%key > %best_key) - <- {%best:%item, %best_key:%key} + if ((%best = (nil)) or (%key > %best_key)): + <- {%best: %item, %best_key: %key} + return %best + # Random functions -action [seed random with %] - lua> ".." - math.randomseed(\%); - for i=1,20 do math.random(); end -parse [seed random] as: seed random with (=lua "os.time()") -compile [random number, random, rand] to: Lua value "math.random()" -compile [random int %n, random integer %n, randint %n] to: Lua value "math.random(\(%n as lua expr))" -compile [random from %low to %high, random number from %low to %high, rand %low %high] to - Lua value "math.random(\(%low as lua expr), \(%high as lua expr))" -action [random choice from %elements, random choice %elements, random %elements] +action [seed random with %] (..) + lua> "math.randomseed(\%);\nfor i=1,20 do math.random(); end" + +parse [seed random] as (seed random with (=lua "os.time()")) +compile [random number, random, rand] to (Lua value "math.random()") +compile [random int %n, random integer %n, randint %n] to (..) + Lua value "math.random(\(%n as lua expr))" + +compile [random from %low to %high, random number from %low to %high, rand %low %high] +..to (Lua value "math.random(\(%low as lua expr), \(%high as lua expr))") + +action [random choice from %elements, random choice %elements, random %elements] (..) =lua "\%elements[math.random(#\%elements)]" diff --git a/core/metaprogramming.nom b/core/metaprogramming.nom index 17b3be4..f78ab50 100644 --- a/core/metaprogramming.nom +++ b/core/metaprogramming.nom @@ -1,10 +1,9 @@ -#!/usr/bin/env nomsu -V1 +#!/usr/bin/env nomsu -V2.2.4.3 # This File contains actions for making actions and compile-time actions and some helper functions to make that easier. lua> "NOMSU_CORE_VERSION = 2" - lua> ".." nomsu.COMPILE_ACTIONS["% -> %"] = function(nomsu, tree, \%args, \%body) local lua = LuaCode.Value(tree.source, "function(") @@ -29,73 +28,71 @@ lua> ".." return lua end -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ lua> ".." nomsu.COMPILE_ACTIONS["compile % to %"] = function(nomsu, tree, \%actions, \%body) local \%args = {"nomsu", "tree", unpack(table.map(\%actions[1]:get_args(), function(a) return tostring(nomsu:compile(a)) end))} local lua = LuaCode(tree.source, "nomsu.COMPILE_ACTIONS[", repr(\%actions[1].stub), - "] = ", \(compile as: %args -> %body)) + "] = ", \(compile as (%args -> %body))) for i=2,#\%actions do local alias = \%actions[i] local \%alias_args = {"nomsu", "tree", unpack(table.map(alias:get_args(), function(a) return tostring(nomsu:compile(a)) end))} - lua:append("\nnomsu.COMPILE_ACTIONS[", repr(alias.stub), "] = ") + lua:append("\\nnomsu.COMPILE_ACTIONS[", repr(alias.stub), "] = ") if utils.equivalent(\%args, \%alias_args) then lua:append("nomsu.COMPILE_ACTIONS[", repr(\%actions[1].stub), "]") else lua:append("function(") lua:concat_append(\%alias_args, ", ") - lua:append(")\n return nomsu.COMPILE_ACTIONS[", repr(\%actions[1].stub), "](") + lua:append(")\\n return nomsu.COMPILE_ACTIONS[", repr(\%actions[1].stub), "](") lua:concat_append(\%args, ", ") - lua:append(")\nend") + lua:append(")\\nend") end end return lua end -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -compile [call %fn with %args] to +compile [call %fn with %args] to (..) lua> ".." local lua = LuaCode.Value(tree.source, nomsu:compile(\%fn), "(") lua:concat_append(table.map(\%args, function(a) return nomsu:compile(a) end), ", ") lua:append(")") return lua -compile [local action %actions %body] to +compile [local action %actions %body] to (..) lua> ".." local fn_name = "A"..string.as_lua_id(\%actions[1].stub) local \%args = table.map(\%actions[1]:get_args(), function(a) return tostring(nomsu:compile(a)) end) - local lua = LuaCode(tree.source, fn_name, " = ", \(compile as: %args -> %body)) + local lua = LuaCode(tree.source, fn_name, " = ", \(compile as (%args -> %body))) lua:add_free_vars({fn_name}) for i=2,#\%actions do local alias = \%actions[i] local alias_name = "A"..string.as_lua_id(alias.stub) lua:add_free_vars({alias_name}) local \%alias_args = table.map(alias:get_args(), function(a) return tostring(nomsu:compile(a)) end) - lua:append("\n", alias_name, " = ") + lua:append("\\n", alias_name, " = ") if utils.equivalent(\%args, \%alias_args) then lua:append(fn_name) else lua:append("function(") lua:concat_append(\%alias_args, ", ") - lua:append(")\n return ", fn_name, "(") + lua:append(")\\n return ", fn_name, "(") lua:concat_append(\%args, ", ") - lua:append(")\nend") + lua:append(")\\nend") end end return lua -compile [action %actions %body] to +compile [action %actions %body] to (..) lua> ".." - local lua = \(compile as: local action %actions %body) + local lua = \(compile as (local action %actions %body)) lua:remove_free_vars(table.map(\%actions, function(a) return "A"..string.as_lua_id(a.stub) end)) return lua -compile [action %action] to - Lua value "A\(%action.stub as lua id)" - -compile [parse %actions as %body] to +compile [action %action] to (Lua value "A\(%action.stub as lua id)") +compile [parse %actions as %body] to (..) lua> ".." local replacements = {} for i,arg in ipairs(\%actions[1]:get_args()) do @@ -115,56 +112,52 @@ compile [parse %actions as %body] to end local \%new_body = LuaCode(\%body.source, "__MANGLE_INDEX = (__MANGLE_INDEX or 0) + 1", - "\nlocal tree = ", make_tree(\%body), - "\nlocal lua = nomsu:compile(tree); return lua") - local ret = \(compile as: compile %actions to %new_body) + "\\nlocal tree = ", make_tree(\%body), + "\\nlocal lua = nomsu:compile(tree); return lua") + local ret = \(compile as (compile %actions to %new_body)) return ret -compile [%tree as lua expr] to +compile [%tree as lua expr] to (..) Lua value "nomsu:compile(\(=lua "nomsu:compile(\%tree):as_expr()")):as_expr()" -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -compile [%tree as lua] to - Lua value "nomsu:compile(\(%tree as lua expr))" +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -compile [%tree as lua statements] to +compile [%tree as lua] to (Lua value "nomsu:compile(\(%tree as lua expr))") +compile [%tree as lua statements] to (..) Lua value "nomsu:compile(\(%tree as lua expr)):as_statements()" -compile [%tree as lua return] to +compile [%tree as lua return] to (..) Lua value "nomsu:compile(\(%tree as lua expr)):as_statements('return ')" -compile [remove action %action] to - Lua ".." - A\(=lua "string.as_lua_id(\(%action.stub))") = nil +compile [remove action %action] to (..) + Lua "A\(=lua "string.as_lua_id(\(%action.stub))") = nil" -compile [%tree as nomsu] to +compile [%tree as nomsu] to (..) Lua value "nomsu:tree_to_nomsu(\(%tree as lua expr))" -compile [%tree as inline nomsu] to +compile [%tree as inline nomsu] to (..) Lua value "nomsu:tree_to_nomsu(\(%tree as lua expr), true)" -action [%var as lua identifier, %var as lua id] +action [%var as lua identifier, %var as lua id] (..) lua> ".." if type(\%var) == 'string' then return string.as_lua_id(\%var) elseif \%var.type == 'Var' then return string.as_lua_id(\%var[1]) elseif \%var.type == 'Action' then return "A"..string.as_lua_id(\%var.stub) end - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -compile [% is syntax tree] to - Lua value "AST.is_syntax_tree(\(% as lua expr))" +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -compile [% is %kind syntax tree] to +compile [% is syntax tree] to (Lua value "AST.is_syntax_tree(\(% as lua expr))") +compile [% is %kind syntax tree] to (..) Lua value "AST.is_syntax_tree(\(% as lua expr), \(%kind as lua expr))" -compile [%tree with %t -> %replacement] to +compile [%tree with %t -> %replacement] to (..) Lua value ".." \(%tree as lua expr):map(function(\(%t as lua expr)) \(%replacement as lua return) end) -action [%tree with vars %replacements] +action [%tree with vars %replacements] (..) =lua ".." \%tree:map(function(\%t) if \%t.type == "Var" then @@ -172,68 +165,69 @@ action [%tree with vars %replacements] end end) -compile [declare locals in %code] to +compile [declare locals in %code] to (..) Lua value "\(%code as lua expr):declare_locals()" -compile [declare locals %locals in %code] to +compile [declare locals %locals in %code] to (..) Lua value "\(%code as lua expr):declare_locals(\(%locals as lua expr))" -compile [add free vars %vars to %code] to +compile [add free vars %vars to %code] to (..) Lua "\(%code as lua expr):add_free_vars(\(%vars as lua expr));" -compile [remove free vars %vars from %code] to +compile [remove free vars %vars from %code] to (..) Lua "\(%code as lua expr):remove_free_vars(\(%vars as lua expr));" -compile [%lua <-write %code, to %lua write %code] to: Lua "\(%lua as lua expr):append(\(%code as lua expr));" +compile [%lua <-write %code, to %lua write %code] to (..) + Lua "\(%lua as lua expr):append(\(%code as lua expr));" -compile [to %lua write %code joined by %glue] to: Lua "\(%lua as lua expr):concat_append(\(%code as lua expr), \(%glue as lua expr));" +compile [to %lua write %code joined by %glue] to (..) + Lua "\(%lua as lua expr):concat_append(\(%code as lua expr), \(%glue as lua expr));" -compile [quote %s] to - Lua value ".." - repr(\(%s as lua expr)) -compile [type of %obj] to: Lua value "type(\(%obj as lua expr))" - -compile [parse %text] to - Lua value ".." - nomsu:parse(NomsuCode("\("\(%text.source)")", \(%text as lua expr))) +compile [quote %s] to (Lua value "repr(\(%s as lua expr))") +compile [type of %obj] to (Lua value "type(\(%obj as lua expr))") +compile [parse %text] to (..) + Lua value "nomsu:parse(NomsuCode(\"\(%text.source)\", \(%text as lua expr)))" -compile [parse %text from %filename] to +compile [parse %text from %filename] to (..) Lua value ".." nomsu:parse(NomsuCode(Source(\(%filename as lua expr), 1, #\(%text as lua expr)), \(%text as lua expr))) -compile [run %nomsu_code] to - Lua value "nomsu:run(\(%nomsu_code as lua expr), \(=lua "repr(tostring(\(%nomsu_code.source)))"))" - -action [run tree %tree, %tree as value] - lua> ".." - return nomsu:run(\%tree) +compile [run %nomsu_code] to (..) + Lua value ".." + nomsu:run(\(%nomsu_code as lua expr), \(=lua "repr(tostring(\(%nomsu_code.source)))")) -compile [compile %block, compiled %block, %block compiled] to +action [run tree %tree, %tree as value] (lua> "return nomsu:run(\%tree)") +compile [compile %block, compiled %block, %block compiled] to (..) Lua value "nomsu:compile(\(%block as lua))" + # Return statement is wrapped in a do..end block because Lua is unhappy if you put code after a return statement, unless you wrap it in a block. -compile [return] to: Lua "do return; end" -compile [return %return_value] to: Lua "do return \(%return_value as lua expr) end" +compile [return] to (Lua "do return; end") +compile [return %return_value] to (..) + Lua "do return \(%return_value as lua expr) end" + # Literals -compile [yes] to: Lua value "true" -compile [no] to: Lua value "false" -compile [nothing, nil, null] to: Lua value "nil" -compile [Nomsu syntax version] to: Lua value "NOMSU_SYNTAX_VERSION" -compile [Nomsu compiler version] to: Lua value "NOMSU_COMPILER_VERSION" -compile [core version] to: Lua value "NOMSU_CORE_VERSION" -compile [lib version] to: Lua value "NOMSU_LIB_VERSION" -compile [command line args] to: Lua value "arg" - -~~~~ -compile [with local compile actions %body] to +compile [yes] to (Lua value "true") +compile [no] to (Lua value "false") +compile [nothing, nil, null] to (Lua value "nil") +compile [Nomsu syntax version] to (Lua value "NOMSU_SYNTAX_VERSION") +compile [Nomsu compiler version] to (Lua value "NOMSU_COMPILER_VERSION") +compile [core version] to (Lua value "NOMSU_CORE_VERSION") +compile [lib version] to (Lua value "NOMSU_LIB_VERSION") +compile [command line args] to (Lua value "arg") + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +compile [with local compile actions %body] to (..) Lua ".." do local nomsu = table.fork(nomsu, {COMPILE_ACTIONS=table.fork(nomsu.COMPILE_ACTIONS)}) \(%body as lua statements) end -action [Nomsu version] +action [Nomsu version]: use "lib/version.nom" - return "\(Nomsu syntax version).\(core version).\(Nomsu compiler version).\(lib version)" + return ".." + \(Nomsu syntax version).\(core version).\(Nomsu compiler version).\(lib version) diff --git a/core/operators.nom b/core/operators.nom index 995b561..eeb5e7a 100644 --- a/core/operators.nom +++ b/core/operators.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V1 +#!/usr/bin/env nomsu -V2.2.4.3 # This file contains definitions of operators like "+" and "and". @@ -6,14 +6,17 @@ use "core/metaprogramming.nom" use "core/errors.nom" # Comparison Operators -compile [%x < %y] to: Lua value "(\(%x as lua expr) < \(%y as lua expr))" -compile [%x > %y] to: Lua value "(\(%x as lua expr) > \(%y as lua expr))" -compile [%x <= %y] to: Lua value "(\(%x as lua expr) <= \(%y as lua expr))" -compile [%x >= %y] to: Lua value "(\(%x as lua expr) >= \(%y as lua expr))" -compile [%a is %b, %a = %b, %a == %b] to +compile [%x < %y] to (Lua value "(\(%x as lua expr) < \(%y as lua expr))") +compile [%x > %y] to (Lua value "(\(%x as lua expr) > \(%y as lua expr))") +compile [%x <= %y] to (Lua value "(\(%x as lua expr) <= \(%y as lua expr))") +compile [%x >= %y] to (Lua value "(\(%x as lua expr) >= \(%y as lua expr))") +compile [%a is %b, %a = %b, %a == %b] to (..) Lua value "(\(%a as lua expr) == \(%b as lua expr))" -compile [%a isn't %b, %a is not %b, %a not= %b, %a != %b] to + +compile [%a isn't %b, %a is not %b, %a not= %b, %a != %b] to (..) Lua value "(\(%a as lua expr) ~= \(%b as lua expr))" + + # For strict identity checking, use (%x's id) is (%y's id) lua> ".." do @@ -31,12 +34,13 @@ lua> ".." end }) end -compile [%'s id, id of %] to: Lua value "IDS[\(% as lua expr)]" -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +compile [% 's id, id of %] to (Lua value "IDS[\(% as lua expr)]") + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Variable assignment operator -compile [%var <- %value] to +compile [%var <- %value] to: lua> "local \%var_lua = \(%var as lua)" assume %var_lua.is_value or barf "Invalid target for assignment: \%var" lua> ".." @@ -46,7 +50,7 @@ compile [%var <- %value] to end end) local \%value_lua = \(%value as lua) - + assume %value_lua.is_value or barf "Invalid value for assignment: \%value" lua> ".." local lua = LuaCode(tree.source, \%var_lua, ' = ', \%value_lua, ';') @@ -55,10 +59,12 @@ compile [%var <- %value] to end return lua + # Simultaneous mutli-assignments like: x,y,z = 1,x,3; -compile [<- %assignments, assign %assignments] to +compile [<- %assignments, assign %assignments] to: assume (%assignments.type is "Dict") or barf ".." Expected a Dict for the assignments part of '<- %' statement, not \%assignments + lua> ".." local lhs, rhs = LuaCode(tree.source), LuaCode(tree.source) for i, item in ipairs(\%assignments) do @@ -84,21 +90,23 @@ compile [<- %assignments, assign %assignments] to end return LuaCode(tree.source, lhs, " = ", rhs, ";") -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -compile [external %var <- %value] to +compile [external %var <- %value] to: %var_lua <- (%var as lua) assume %var_lua.is_value or barf "Invalid target for assignment: \%var" %value_lua <- (%value as lua) assume %value_lua.is_value or barf "Invalid value for assignment: \%value" - return: Lua "\%var_lua = \%value_lua;" + return (Lua "\%var_lua = \%value_lua;") -compile [with external %externs %body] to +compile [with external %externs %body] to: %body_lua <- (%body as lua statements) - lua> "\%body_lua:remove_free_vars(table.map(\%externs, function(v) return tostring(nomsu:compile(v)) end))" + lua> ".." + \%body_lua:remove_free_vars(table.map(\%externs, function(v) return tostring(nomsu:compile(v)) end)) + return %body_lua -compile [with %assignments %body] to +compile [with %assignments %body] to: %lua <- (%body as lua statements) lua> ".." local lhs, rhs = LuaCode(tree.source), LuaCode(tree.source) @@ -124,57 +132,79 @@ compile [with %assignments %body] to end end \%lua:remove_free_vars(vars) - \%lua:prepend("local ", lhs, " = ", rhs, ";\n") - return + \%lua:prepend("local ", lhs, " = ", rhs, ";\\n") + + return (..) Lua ".." do \%lua end -- 'with' block + # Math Operators -compile [%x wrapped around %y, %x mod %y] to: Lua value "(\(%x as lua expr) % \(%y as lua expr))" +compile [%x wrapped around %y, %x mod %y] to (..) + Lua value "(\(%x as lua expr) % \(%y as lua expr))" + # 3-part chained comparisons # (uses a lambda to avoid re-evaluating middle value, while still being an expression) -parse [%x < %y < %z] as: =lua "(function(x,y,z) return x < y and y < z; end)(\%x,\%y,\%z)" -parse [%x <= %y < %z] as: =lua "(function(x,y,z) return x <= y and y < z; end)(\%x,\%y,\%z)" -parse [%x < %y <= %z] as: =lua "(function(x,y,z) return x < y and y <= z; end)(\%x,\%y,\%z)" -parse [%x <= %y <= %z] as: =lua "(function(x,y,z) return x <= y and y <= z; end)(\%x,\%y,\%z)" -parse [%x > %y > %z] as: =lua "(function(x,y,z) return x > y and y > z; end)(\%x,\%y,\%z)" -parse [%x >= %y > %z] as: =lua "(function(x,y,z) return x >= y and y > z; end)(\%x,\%y,\%z)" -parse [%x > %y >= %z] as: =lua "(function(x,y,z) return x > y and y >= z; end)(\%x,\%y,\%z)" -parse [%x >= %y >= %z] as: =lua "(function(x,y,z) return x >= y and y >= z; end)(\%x,\%y,\%z)" -# TODO: optimize for common case where x,y,z are all either variables or number literals +parse [%x < %y < %z] as (..) + =lua "(function(x,y,z) return x < y and y < z; end)(\%x,\%y,\%z)" +parse [%x <= %y < %z] as (..) + =lua "(function(x,y,z) return x <= y and y < z; end)(\%x,\%y,\%z)" +parse [%x < %y <= %z] as (..) + =lua "(function(x,y,z) return x < y and y <= z; end)(\%x,\%y,\%z)" +parse [%x <= %y <= %z] as (..) + =lua "(function(x,y,z) return x <= y and y <= z; end)(\%x,\%y,\%z)" +parse [%x > %y > %z] as (..) + =lua "(function(x,y,z) return x > y and y > z; end)(\%x,\%y,\%z)" +parse [%x >= %y > %z] as (..) + =lua "(function(x,y,z) return x >= y and y > z; end)(\%x,\%y,\%z)" +parse [%x > %y >= %z] as (..) + =lua "(function(x,y,z) return x > y and y >= z; end)(\%x,\%y,\%z)" +parse [%x >= %y >= %z] as (..) + =lua "(function(x,y,z) return x >= y and y >= z; end)(\%x,\%y,\%z)" +# TODO: optimize for common case where x,y,z are all either variables or number literals # Boolean Operators -compile [%x and %y] to: Lua value "(\(%x as lua expr) and \(%y as lua expr))" -compile [%x or %y] to: Lua value "(\(%x as lua expr) or \(%y as lua expr))" +compile [%x and %y] to (Lua value "(\(%x as lua expr) and \(%y as lua expr))") +compile [%x or %y] to (Lua value "(\(%x as lua expr) or \(%y as lua expr))") # Bitwise Operators # TODO: support bit.???() for luajit and bit32.??? for lua 5.2 -compile [%a OR %b, %a | %b] to: Lua value "(\(%a as lua expr) | \(%b as lua expr))" -compile [%a XOR %b] to: Lua value "(\(%a as lua expr) ^ \(%b as lua expr))" -compile [%a AND %b, %a & %b] to: Lua value "(\(%a as lua expr) & \(%b as lua expr))" -compile [NOT %, ~ %] to: Lua value "~(\(% as lua expr))" -compile [%x LSHIFT %shift, %x << %shift] to: Lua value "(\(%x as lua expr) << \(%shift as lua expr))" -compile [%x RSHIFT %shift, %x >>> %shift] to: Lua value "(\(%x as lua expr) >>> \(%shift as lua expr))" -compile [%x ARSHIFT %shift, %x >> %shift] to: Lua value "(\(%x as lua expr) >> \(%shift as lua expr))" -# TODO: implement OR, XOR, AND for multiple operands? +compile [%a OR %b, %a | %b] to (..) + Lua value "(\(%a as lua expr) | \(%b as lua expr))" + +compile [%a XOR %b] to (Lua value "(\(%a as lua expr) ^ \(%b as lua expr))") +compile [%a AND %b, %a & %b] to (..) + Lua value "(\(%a as lua expr) & \(%b as lua expr))" + +compile [NOT %, ~ %] to (Lua value "~(\(% as lua expr))") +compile [%x LSHIFT %shift, %x << %shift] to (..) + Lua value "(\(%x as lua expr) << \(%shift as lua expr))" +compile [%x RSHIFT %shift, %x >>> %shift] to (..) + Lua value "(\(%x as lua expr) >>> \(%shift as lua expr))" + +compile [%x ARSHIFT %shift, %x >> %shift] to (..) + Lua value "(\(%x as lua expr) >> \(%shift as lua expr))" + + +# TODO: implement OR, XOR, AND for multiple operands? # Unary operators -compile [- %] to: Lua value "(- \(% as lua expr))" -compile [not %] to: Lua value "(not \(% as lua expr))" -test: assume: (length of [1,2,3]) = 3 -compile [length of %list, || %list ||] to: Lua value "(#\(%list as lua expr))" +compile [- %] to (Lua value "(- \(% as lua expr))") +compile [not %] to (Lua value "(not \(% as lua expr))") +test: assume ((length of [1, 2, 3]) = 3) +compile [length of %list, || %list ||] to (Lua value "(#\(%list as lua expr))") -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Update operators -parse [%var + <- %, %var +<- %] as: %var <- (%var + %) -parse [%var - <- %, %var -<- %] as: %var <- (%var - %) -parse [%var * <- %, %var *<- %] as: %var <- (%var * %) -parse [%var / <- %, %var /<- %] as: %var <- (%var / %) -parse [%var ^ <- %, %var ^<- %] as: %var <- (%var ^ %) -parse [%var and <- %] as: %var <- (%var and %) -parse [%var or <- %] as: %var <- (%var or %) -parse [wrap %var around %] as: %var <- (%var wrapped around %) +parse [%var + <- %, %var +<- %] as (%var <- (%var + %)) +parse [%var - <- %, %var -<- %] as (%var <- (%var - %)) +parse [%var * <- %, %var *<- %] as (%var <- (%var * %)) +parse [%var / <- %, %var /<- %] as (%var <- (%var / %)) +parse [%var ^ <- %, %var ^<- %] as (%var <- (%var ^ %)) +parse [%var and<- %] as (%var <- (%var and %)) +parse [%var or<- %] as (%var <- (%var or %)) +parse [wrap %var around %] as (%var <- (%var wrapped around %)) diff --git a/core/scopes.nom b/core/scopes.nom index 19b9e49..256ddd5 100644 --- a/core/scopes.nom +++ b/core/scopes.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V1 +#!/usr/bin/env nomsu -V2.2.4.3 # This file contains definitions pertaining to variable scoping @@ -6,28 +6,21 @@ use "core/metaprogramming.nom" use "core/operators.nom" use "core/collections.nom" use "core/control_flow.nom" - -compile [with local %locals %body, with local %locals do %body] to +compile [with local %locals %body, with local %locals do %body] to: %body_lua <- (%body as lua statements) - when %locals.type = ? - * "Dict" - %body_lua <- - Lua ".." - \(compile as: <- %locals) - \%body_lua - declare locals - "\(%.1 as lua)" for % in %locals - .. in %body_lua - * "List" - declare locals - "\(% as lua)" for % in %locals - .. in %body_lua + when %locals.type = ?: + * "Dict": + %body_lua <- (Lua "\(compile as (<- %locals))\n\%body_lua") + declare locals ("\(%.1 as lua)" for % in %locals) in %body_lua + + * "List": + declare locals ("\(% as lua)" for % in %locals) in %body_lua * "Var" - * "Action" + * "Action": declare locals ["\(%locals as lua)"] in %body_lua - * else - barf "Unexpected local: \(%locals as nomsu)" - return + *else (barf "Unexpected local: \(%locals as nomsu)") + + return (..) Lua ".." do \%body_lua diff --git a/core/text.nom b/core/text.nom index 514334b..fa0d908 100644 --- a/core/text.nom +++ b/core/text.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V1 +#!/usr/bin/env nomsu -V2.2.4.3 # This file contains some definitions of text escape sequences, including ANSI console color codes. @@ -6,36 +6,39 @@ use "core/metaprogramming.nom" # Text functions -action [%texts joined with %glue] +action [%texts joined with %glue] (..) lua> ".." local text_bits = {} for i,bit in ipairs(\%texts) do text_bits[i] = stringify(bit) end return table.concat(text_bits, \%glue) -parse [joined %texts, %texts joined] as: %texts joined with "" -compile [capitalized %text, %text capitalized] to +parse [joined %texts, %texts joined] as (%texts joined with "") +compile [capitalized %text, %text capitalized] to (..) Lua value "((\(%text as lua expr)):gsub('%l', string.upper, 1))" -compile [%text with %sub instead of %patt, %text with %patt replaced by %sub, %text s/%patt / %sub] to +compile [..] + %text with %sub instead of %patt, %text with %patt replaced by %sub + %text s/ %patt / %sub +..to (..) Lua value "((\(%text as lua expr)):gsub(\(%patt as lua expr), \(%sub as lua expr)))" -action [lines in %text, lines of %text] +action [lines in %text, lines of %text] (..) lua> ".." local result = list{} - for line in (\%text):gmatch('[^\n]+') do + for line in (\%text):gmatch('[^\\n]+') do result[#result+1] = line end return result -compile [for %match where %text matches %patt %body] to +compile [for %match where %text matches %patt %body] to (..) Lua ".." for \(%match as lua expr) in \(%text as lua expr):gmatch(\(%patt as lua expr)) do \(%body as lua statements) - \(compile as: === next %match ===) + \(compile as (===next %match ===)) end - \(compile as: === stop %match ===) + \(compile as (===stop %match ===)) -compile [%expr for %match where %text matches %patt] to +compile [%expr for %match where %text matches %patt] to (..) Lua value ".." (function() local ret = list{} @@ -45,19 +48,22 @@ compile [%expr for %match where %text matches %patt] to return ret end)() -compile [%text matches %pattern] to +compile [%text matches %pattern] to (..) Lua value "(\(%text as lua expr):match(\(%pattern as lua expr)) and true or false)" + # Text literals lua> ".." do local escapes = { - nl="\\\\n", newline="\\\\n", tab="\\\\t", bell="\\\\a", cr="\\\\r", ["carriage return"]="\\\\r", - backspace="\\\\b", ["form feed"]="\\\\f", formfeed="\\\\f", ["vertical tab"]="\\\\v", + nl="\\\\n", newline="\\\\n", tab="\\\\t", bell="\\\\a", cr="\\\\r", + ["carriage return"]="\\\\r", backspace="\\\\b", ["form feed"]="\\\\f", + formfeed="\\\\f", ["vertical tab"]="\\\\v", }; for name, e in pairs(escapes) do local lua = "'"..e.."'" - nomsu.COMPILE_ACTIONS[name] = (function(nomsu, tree) return LuaCode.Value(tree.source, lua) end) + nomsu.COMPILE_ACTIONS[name] = function(nomsu, tree) + return LuaCode.Value(tree.source, lua) + end end end - |
