diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2018-12-14 20:21:03 -0800 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2018-12-14 20:21:03 -0800 |
| commit | 4fe63f253f58f87ab986fea38902d95f2a5ea338 (patch) | |
| tree | 12094f1c69b8ab375eb17507c959c43f9295c6c2 /core | |
| parent | 6abec65843f0f37f7fc6032ac5db0fff3db71815 (diff) | |
Auto-updated to version 5
Diffstat (limited to 'core')
| -rw-r--r-- | core/collections.nom | 154 | ||||
| -rw-r--r-- | core/control_flow.nom | 556 | ||||
| -rw-r--r-- | core/coroutines.nom | 33 | ||||
| -rw-r--r-- | core/errors.nom | 76 | ||||
| -rw-r--r-- | core/id.nom | 50 | ||||
| -rw-r--r-- | core/io.nom | 32 | ||||
| -rw-r--r-- | core/math.nom | 178 | ||||
| -rw-r--r-- | core/metaprogramming.nom | 334 | ||||
| -rw-r--r-- | core/operators.nom | 248 | ||||
| -rw-r--r-- | core/text.nom | 60 |
10 files changed, 857 insertions, 864 deletions
diff --git a/core/collections.nom b/core/collections.nom index c34e8bc..d24152b 100644 --- a/core/collections.nom +++ b/core/collections.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V4.12.12.8 +#!/usr/bin/env nomsu -V5.12.12.8 # This file contains code that supports manipulating and using collections like lists and dictionaries. @@ -11,34 +11,34 @@ use "core/operators.nom" # 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) + $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 % in {x: 1}: add %] == [{key: "x", value: 1}] - assume [: for %k = %v in {x: 1}: add {key: %k, value: %v}] == [..] + $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} @@ -48,93 +48,93 @@ test: 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 % +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 + $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}] +(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] +[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] +[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") + $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));" +(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))" +[$'s metatable, $'metatable] all compile to "getmetatable(\($ as lua expr))" test: - assume (({} with fallback % -> (% + 1)).10 == 11) + assume (({} with fallback $ -> ($ + 1)).10 == 11) -(%dict with fallback %key -> %value) compiles to "\ - ..(function(d) +($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 + 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))" + 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] \ + $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)" + $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 +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 (..) +[$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 + $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 +externally (unique $items) means: + $unique = [] + $seen = {} + for $ in $items: + unless $seen.$: + $unique|add $ + $seen.$ = (yes) + return $unique diff --git a/core/control_flow.nom b/core/control_flow.nom index eca92ce..03861e3 100644 --- a/core/control_flow.nom +++ b/core/control_flow.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V4.12.12.8 +#!/usr/bin/env nomsu -V5.12.12.8 # This file contains compile-time actions that define basic control flow structures like "if" statements and loops. @@ -19,22 +19,22 @@ test: if (no): barf "conditional fail" -(if %condition %if_body) compiles to "\ - ..if \(%condition as lua expr) then - \(%if_body as lua) +(if $condition $if_body) compiles to " + if \($condition as lua expr) then + \($if_body as lua) end" test: unless (yes): barf "conditional fail" -(unless %condition %unless_body) parses as (if (not %condition) %unless_body) -[if %condition %if_body else %else_body, unless %condition %else_body else %if_body] \ -..all compile to "\ - ..if \(%condition as lua expr) then - \(%if_body as lua) +(unless $condition $unless_body) parses as (if (not $condition) $unless_body) +[if $condition $if_body else $else_body, unless $condition $else_body else $if_body] \ +..all compile to " + if \($condition as lua expr) then + \($if_body as lua) else - \(%else_body as lua) + \($else_body as lua) end" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -47,26 +47,26 @@ test: assume ((1 if (no) else 2) == 2) [..] - %when_true_expr if %condition else %when_false_expr - %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 + $when_true_expr if $condition else $when_false_expr + $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 ..all compile 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, List, Dict, Number}.(%when_true_expr.type): - return (Lua "(\(%condition as lua expr) and \(%when_true_expr as lua expr) or \(%when_false_expr as lua expr))") + if {Text, List, Dict, Number}.($when_true_expr.type): + return (Lua "(\($condition as lua expr) and \($when_true_expr as lua expr) or \($when_false_expr as lua expr))") ..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 (..) - Lua "\ - ..((function() - if \(%condition as lua expr) then - return \(%when_true_expr as lua expr) + Lua " + ((function() + if \($condition as lua expr) then + return \($when_true_expr as lua expr) else - return \(%when_false_expr as lua expr) + return \($when_false_expr as lua expr) end end)())" @@ -74,212 +74,212 @@ test: # GOTOs test: - %i = 0 - --- %loop --- - %i += 1 - unless (%i == 10): - go to %loop - assume (%i == 10) + $i = 0 + --- $loop --- + $i += 1 + unless ($i == 10): + go to $loop + assume ($i == 10) --- (Loop) --- - %i -= 1 - unless (%i == 0): + $i -= 1 + unless ($i == 0): go to (Loop) - assume (%i == 0) + assume ($i == 0) -(--- %label ---) compiles to "\ - ..::label_\(..) - (%label.stub::as lua id) if (%label.type == "Action") else (..) - %label as lua identifier +(--- $label ---) compiles to " + ::label_\(..) + ($label.stub|as lua id) if ($label.type == "Action") else (..) + $label as lua identifier ..::" -(go to %label) compiles to "\ - ..goto label_\(..) - (%label.stub::as lua id) if (%label.type == "Action") else (..) - %label as lua identifier +(go to $label) compiles to " + goto label_\(..) + ($label.stub|as lua id) if ($label.type == "Action") else (..) + $label as lua identifier .." # Basic loop control -(stop %var) compiles to: - if %var: - return (Lua "goto stop_\(%var as lua identifier)") +(stop $var) compiles to: + if $var: + return (Lua "goto stop_\($var as lua identifier)") ..else: return (Lua "break") -(do next %var) compiles to: - if %var: - return (Lua "goto continue_\(%var as lua identifier)") +(do next $var) compiles to: + if $var: + return (Lua "goto continue_\($var as lua identifier)") ..else: return (Lua "goto continue") -(---stop %var ---) compiles to "::stop_\(%var as lua identifier)::" -(---next %var ---) compiles to "::continue_\(%var as lua identifier)::" +(---stop $var ---) compiles to "::stop_\($var as lua identifier)::" +(---next $var ---) compiles to "::continue_\($var as lua identifier)::" # While loops test: - %x = 0 - repeat while (%x < 10): %x += 1 - assume (%x == 10) - repeat while (%x < 20): stop - assume (%x == 10) - repeat while (%x < 20): - %x += 1 + $x = 0 + repeat while ($x < 10): $x += 1 + assume ($x == 10) + repeat while ($x < 20): stop + assume ($x == 10) + repeat while ($x < 20): + $x += 1 if (yes): do next barf "Failed to 'do next'" - assume (%x == 20) + assume ($x == 20) -(repeat while %condition %body) compiles to: - %lua = (Lua "while \(%condition as lua expr) do\n \(%body as lua)") - if (%body has subtree \(do next)): - %lua::add "\n ::continue::" - %lua::add "\nend --while-loop" - return %lua +(repeat while $condition $body) compiles to: + $lua = (Lua "while \($condition as lua expr) do\n \($body as lua)") + if ($body has subtree \(do next)): + $lua|add "\n ::continue::" + $lua|add "\nend --while-loop" + return $lua -(repeat %body) parses as (repeat while (yes) %body) -(repeat until %condition %body) parses as (repeat while (not %condition) %body) +(repeat $body) parses as (repeat while (yes) $body) +(repeat until $condition $body) parses as (repeat while (not $condition) $body) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test: - %nums = [] - for %x in 1 to 5: - %nums::add %x - assume (%nums == [1, 2, 3, 4, 5]) - %nums = [] - for %x in 1 to 5 via 2: - %nums::add %x - assume (%nums == [1, 3, 5]) - %nums = [] - for %outer in 1 to 100: - for %inner in %outer to (%outer + 2): - if (%inner == 2): - %nums::add -2 - do next %inner - %nums::add %inner - if (%inner == 5): - stop %outer - assume (%nums == [1, -2, 3, -2, 3, 4, 3, 4, 5]) + $nums = [] + for $x in 1 to 5: + $nums|add $x + assume ($nums == [1, 2, 3, 4, 5]) + $nums = [] + for $x in 1 to 5 via 2: + $nums|add $x + assume ($nums == [1, 3, 5]) + $nums = [] + for $outer in 1 to 100: + for $inner in $outer to ($outer + 2): + if ($inner == 2): + $nums|add -2 + do next $inner + $nums|add $inner + if ($inner == 5): + stop $outer + assume ($nums == [1, -2, 3, -2, 3, 4, 3, 4, 5]) # Numeric range for loops [..] - for %var in %start to %stop by %step %body - for %var in %start to %stop via %step %body + for $var in $start to $stop by $step $body + for $var in $start to $stop via $step $body ..all compile to: # This uses Lua's approach of only allowing loop-scoped variables in a loop - %lua = (Lua "for \(%var as lua identifier)=\(%start as lua expr),\(%stop as lua expr),\(%step as lua expr) do") - %lua::add "\n " (%body as lua) - if (%body has subtree \(do next)): - %lua::add "\n ::continue::" + $lua = (Lua "for \($var as lua identifier)=\($start as lua expr),\($stop as lua expr),\($step as lua expr) do") + $lua|add "\n " ($body as lua) + if ($body has subtree \(do next)): + $lua|add "\n ::continue::" - if (%body has subtree \(do next %var)): - %lua::add "\n " (\(---next %var ---) as lua) + if ($body has subtree \(do next $var)): + $lua|add "\n " (\(---next $var ---) as lua) - %lua::add "\nend -- numeric for " (%var as lua identifier) " loop" - if (%body has subtree \(stop %var)): - %lua = (..) - Lua "\ - ..do -- scope for (stop \(%var as lua identifier)) - \%lua - \(\(---stop %var ---) as lua) - end -- scope for (stop \(%var as lua identifier))" - return %lua + $lua|add "\nend -- numeric for " ($var as lua identifier) " loop" + if ($body has subtree \(stop $var)): + $lua = (..) + Lua " + do -- scope for (stop \($var as lua identifier)) + \$lua + \(\(---stop $var ---) as lua) + end -- scope for (stop \($var as lua identifier))" + return $lua ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -(for %var in %start to %stop %body) parses as (..) - for %var in %start to %stop via 1 %body +(for $var in $start to $stop $body) parses as (..) + for $var in $start to $stop via 1 $body test: - %x = 0 + $x = 0 repeat 5 times: - %x += 1 - assume %x == 5 + $x += 1 + assume $x == 5 -(repeat %n times %body) parses as (for (=lua "_XXX_") in 1 to %n %body) +(repeat $n times $body) parses as (for (=lua "_XXX_") in 1 to $n $body) test: - %a = [10, 20, 30, 40, 50] - %b = [] - for %x in %a: - %b::add %x - assume (%a == %b) - %b = [] - for %x in %a: - if (%x == 10): - do next %x + $a = [10, 20, 30, 40, 50] + $b = [] + for $x in $a: + $b|add $x + assume ($a == $b) + $b = [] + for $x in $a: + if ($x == 10): + do next $x - if (%x == 50): - stop %x + if ($x == 50): + stop $x - %b::add %x - assume (%b == [20, 30, 40]) + $b|add $x + assume ($b == [20, 30, 40]) # For-each loop (lua's "ipairs()") -(for %var in %iterable at %i %body) compiles to: +(for $var in $iterable at $i $body) compiles to: # This uses Lua's approach of only allowing loop-scoped variables in a loop - %lua = (..) - Lua "\ - ..for \(%i as lua identifier),\(%var as lua identifier) in ipairs(\(%iterable as lua expr)) do + $lua = (..) + Lua " + for \($i as lua identifier),\($var as lua identifier) in ipairs(\($iterable as lua expr)) do " - %lua::add (%body as lua) - if (%body has subtree \(do next)): - %lua::add "\n ::continue::" + $lua|add ($body as lua) + if ($body has subtree \(do next)): + $lua|add "\n ::continue::" - if (%body has subtree \(do next %var)): - %lua::add "\n " (\(---next %var ---) as lua) + if ($body has subtree \(do next $var)): + $lua|add "\n " (\(---next $var ---) as lua) - %lua::add "\nend --for \(%var as lua identifier) loop" - if (%body has subtree \(stop %var)): - %inner_lua = %lua - %lua = (Lua "do -- scope for stopping for-loop\n ") - %lua::add %inner_lua "\n " - %lua::add (\(---stop %var ---) as lua) - %lua::add "\nend -- end of scope for stopping for-loop" - return %lua - -(for %var in %iterable %body) parses as (..) - for %var in %iterable at (=lua "__") %body + $lua|add "\nend --for \($var as lua identifier) loop" + if ($body has subtree \(stop $var)): + $inner_lua = $lua + $lua = (Lua "do -- scope for stopping for-loop\n ") + $lua|add $inner_lua "\n " + $lua|add (\(---stop $var ---) as lua) + $lua|add "\nend -- end of scope for stopping for-loop" + return $lua + +(for $var in $iterable $body) parses as (..) + for $var in $iterable at (=lua "__") $body test: - %d = {a: 10, b: 20, c: 30, d: 40, e: 50} - %result = [] - for %k = %v in %d: - if (%k == "a"): - do next %k + $d = {a: 10, b: 20, c: 30, d: 40, e: 50} + $result = [] + for $k = $v in $d: + if ($k == "a"): + do next $k - if (%v == 20): - do next %v + if ($v == 20): + do next $v - %result::add "\%k = \%v" - assume ((%result sorted) == ["c = 30", "d = 40", "e = 50"]) + $result|add "\$k = \$v" + assume (($result sorted) == ["c = 30", "d = 40", "e = 50"]) # Dict iteration (lua's "pairs()") -[for %key = %value in %iterable %body, for %key %value in %iterable %body] \ +[for $key = $value in $iterable $body, for $key $value in $iterable $body] \ ..all compile to: - %lua = (Lua "for \(%key as lua identifier),\(%value as lua identifier) in pairs(\(%iterable as lua expr)) do") - %lua::add "\n " (%body as lua) - if (%body has subtree \(do next)): - %lua::add "\n ::continue::" + $lua = (Lua "for \($key as lua identifier),\($value as lua identifier) in pairs(\($iterable as lua expr)) do") + $lua|add "\n " ($body as lua) + if ($body has subtree \(do next)): + $lua|add "\n ::continue::" - if (%body has subtree \(do next %key)): - %lua::add "\n " (\(---next %key ---) as lua) + if ($body has subtree \(do next $key)): + $lua|add "\n " (\(---next $key ---) as lua) - if (%body has subtree \(do next %value)): - %lua::add "\n " (\(---next %value ---) as lua) + if ($body has subtree \(do next $value)): + $lua|add "\n " (\(---next $value ---) as lua) - %lua::add "\nend --foreach-loop" - %stop_labels = (Lua "") - if (%body has subtree \(stop %key)): - %stop_labels::add "\n" (\(---stop %key ---) as lua) + $lua|add "\nend --foreach-loop" + $stop_labels = (Lua "") + if ($body has subtree \(stop $key)): + $stop_labels|add "\n" (\(---stop $key ---) as lua) - if (%body has subtree \(stop %value)): - %stop_labels::add "\n" (\(---stop %value ---) as lua) + if ($body has subtree \(stop $value)): + $stop_labels|add "\n" (\(---stop $value ---) as lua) - if ((size of "\%stop_labels") > 0): - %inner_lua = %lua - %lua = (Lua "do -- scope for stopping for % = % loop\n ") - %lua::add %inner_lua %stop_labels "\nend" + if ((size of "\$stop_labels") > 0): + $inner_lua = $lua + $lua = (Lua "do -- scope for stopping for % = % loop\n ") + $lua|add $inner_lua $stop_labels "\nend" - return %lua + return $lua ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -287,7 +287,7 @@ test: when: (1 == 2) (100 < 0): barf "bad conditional" - (1 == 0) (1 == 1) %not_a_variable.x: do nothing + (1 == 0) (1 == 1) $not_a_variable.x: do nothing (1 == 1): barf "bad conditional" @@ -298,52 +298,51 @@ test: barf "bad conditional" # Multi-branch conditional (if..elseif..else) -(when %body) compiles to: - %code = (Lua "") - %clause = "if" - %else_allowed = (yes) - unless (%body.type is "Block"): - compile error at %body "'if' expected a Block, but got a \(%body.type)." "\ - ..Perhaps you forgot to put a ':' after 'if'?" +(when $body) compiles to: + $code = (Lua "") + $clause = "if" + $else_allowed = (yes) + unless ($body.type is "Block"): + compile error at $body "'if' expected a Block, but got a \($body.type)." \ + .."Perhaps you forgot to put a ':' after 'if'?" - for %line in %body: + for $line in $body: unless (..) - ((%line.type is "Action") and ((size of %line) >= 2)) and (..) - %line.(size of %line) is "Block" syntax tree + (($line.type is "Action") and ((size of $line) >= 2)) and (..) + $line.(size of $line) is "Block" syntax tree ..: - compile error at %line "Invalid line for the body of an 'if' block." "\ - ..Each line should contain one or more conditional expressions followed by a block, or "else" followed \ + compile error at $line "Invalid line for the body of an 'if' block." " + Each line should contain one or more conditional expressions followed by a block, or "else" followed \ ..by a block." - %action = %line.(size of %line) - if ((%line.1 is "else") and ((size of %line) == 2)): - unless %else_allowed: - compile error at %line "You can't have two 'else' blocks." "\ - ..Merge all of the 'else' blocks together." + $action = $line.(size of $line) + if (($line.1 is "else") and ((size of $line) == 2)): + unless $else_allowed: + compile error at $line "You can't have two 'else' blocks." \ + .."Merge all of the 'else' blocks together." - unless ((size of "\%code") > 0): - compile error at %line "\ - ..You can't have an 'else' block without a preceding condition" - .."\ - ..If you want the code in this block to always execute, you don't need a conditional block around it. \ + unless ((size of "\$code") > 0): + compile error at $line \ + .."You can't have an 'else' block without a preceding condition" " + If you want the code in this block to always execute, you don't need a conditional block around it. \ ..Otherwise, make sure the 'else' block comes last." - %code::add "\nelse\n " (%action as lua) - %else_allowed = (no) + $code|add "\nelse\n " ($action as lua) + $else_allowed = (no) ..else: - %code::add %clause " " - for %i in 1 to ((size of %line) - 1): - if (%i > 1): - %code::add " or " - %code::add (%line.%i as lua expr) - %code::add " then\n " (%action as lua) - %clause = "\nelseif" + $code|add $clause " " + for $i in 1 to ((size of $line) - 1): + if ($i > 1): + $code|add " or " + $code|add ($line.$i as lua expr) + $code|add " then\n " ($action as lua) + $clause = "\nelseif" - if ((size of "\%code") == 0): - compile error at %body "'if' block has an empty body." "\ - ..This means nothing would happen, so the 'if' block should be deleted." + if ((size of "\$code") == 0): + compile error at $body "'if' block has an empty body." \ + .."This means nothing would happen, so the 'if' block should be deleted." - %code::add "\nend --when" - return %code + $code|add "\nend --when" + return $code test: if 5 is: @@ -360,81 +359,80 @@ test: barf "bad switch statement" # Switch statement -[if %branch_value is %body, when %branch_value is %body] all compile to: - %code = (Lua "") - %clause = "if" - %else_allowed = (yes) +[if $branch_value is $body, when $branch_value is $body] all compile to: + $code = (Lua "") + $clause = "if" + $else_allowed = (yes) define mangler - unless (%body.type is "Block"): - compile error at %body "'if' expected a Block, but got a \(%body.type)" "\ - ..Perhaps you forgot to put a ':' after the 'is'?" + unless ($body.type is "Block"): + compile error at $body "'if' expected a Block, but got a \($body.type)" \ + .."Perhaps you forgot to put a ':' after the 'is'?" - for %line in %body: + for $line in $body: unless (..) - ((%line.type is "Action") and ((size of %line) >= 2)) and (..) - %line.(size of %line) is "Block" syntax tree + (($line.type is "Action") and ((size of $line) >= 2)) and (..) + $line.(size of $line) is "Block" syntax tree ..: - compile error at %line "Invalid line for 'if' block." "\ - ..Each line should contain expressions followed by a block, or "else" followed by a block" - %action = %line.(size of %line) - if ((%line.1 is "else") and ((size of %line) == 2)): - unless %else_allowed: - compile error at %line "You can't have two 'else' blocks." "\ - ..Merge all of the 'else' blocks together." + compile error at $line "Invalid line for 'if' block." " + Each line should contain expressions followed by a block, or "else" followed by a block" + $action = $line.(size of $line) + if (($line.1 is "else") and ((size of $line) == 2)): + unless $else_allowed: + compile error at $line "You can't have two 'else' blocks." \ + .."Merge all of the 'else' blocks together." - unless ((size of "\%code") > 0): - compile error at %line "\ - ..You can't have an 'else' block without a preceding condition" - .."\ - ..If you want the code in this block to always execute, you don't need a conditional block around it. \ + unless ((size of "\$code") > 0): + compile error at $line \ + .."You can't have an 'else' block without a preceding condition" " + If you want the code in this block to always execute, you don't need a conditional block around it. \ ..Otherwise, make sure the 'else' block comes last." - %code::add "\nelse\n " (%action as lua) - %else_allowed = (no) + $code|add "\nelse\n " ($action as lua) + $else_allowed = (no) ..else: - %code::add %clause " " - for %i in 1 to ((size of %line) - 1): - if (%i > 1): - %code::add " or " - %code::add "\(mangle "branch value") == " (%line.%i as lua expr) - %code::add " then\n " (%action as lua) - %clause = "\nelseif" + $code|add $clause " " + for $i in 1 to ((size of $line) - 1): + if ($i > 1): + $code|add " or " + $code|add "\(mangle "branch value") == " ($line.$i as lua expr) + $code|add " then\n " ($action as lua) + $clause = "\nelseif" - if ((size of "\%code") == 0): - compile error at %body "'if' block has an empty body." "\ - ..This means nothing would happen, so the 'if' block should be deleted." + if ((size of "\$code") == 0): + compile error at $body "'if' block has an empty body." \ + .."This means nothing would happen, so the 'if' block should be deleted." - %code::add "\nend --when" + $code|add "\nend --when" return (..) - Lua "\ - ..do --if % is... - local \(mangle "branch value") = \(%branch_value as lua expr) - \%code + Lua " + do --if % is... + local \(mangle "branch value") = \($branch_value as lua expr) + \$code end -- if % is..." # Do/finally -(do %action) compiles to "do\n \(%action as lua)\nend -- do" +(do $action) compiles to "do\n \($action as lua)\nend -- do" test: - %d = {} + $d = {} try: do: - %d.x = "bad" + $d.x = "bad" barf ..then always: - %d.x = "good" - assume (%d.x == "good") + $d.x = "good" + assume ($d.x == "good") -(do %action then always %final_action) compiles to: +(do $action then always $final_action) compiles to: define mangler return (..) - Lua "\ - ..do + Lua " + do local \(mangle "fell_through") = false local \(mangle "ok"), \(mangle "ret") = pcall(function() - \(%action as lua) + \($action as lua) \(mangle "fell_through") = true end) - \(%final_action as lua) + \($final_action as lua) if not \(mangle "ok") then error(ret, 0) end if not \(mangle "fell_through") then return ret end end" @@ -443,41 +441,41 @@ test: assume ((result of: return 99) == 99) # Inline thunk: -(result of %body) compiles to "\(\(-> %body) as lua)()" +(result of $body) compiles to "\(\(-> $body) as lua)()" test: - %t = [1, [2, [[3], 4], 5, [[[6]]]]] - %flat = [] - for % in recursive %t: - if ((lua type of %) is "table"): - for %2 in %: - recurse % on %2 + $t = [1, [2, [[3], 4], 5, [[[6]]]]] + $flat = [] + for $ in recursive $t: + if ((lua type of $) is "table"): + for $2 in $: + recurse $ on $2 ..else: - %flat::add % - assume (sorted %flat) == [1, 2, 3, 4, 5, 6] + $flat|add $ + assume (sorted $flat) == [1, 2, 3, 4, 5, 6] # Recurion control flow -(for %var in recursive %structure %body) compiles to: +(for $var in recursive $structure $body) compiles to: with local compile actions: define mangler - (recurse %v on %x) compiles to (..) - Lua "table.insert(\(mangle "stack \(%v.1)"), \(%x as lua expr))" + (recurse $v on $x) compiles to (..) + Lua "table.insert(\(mangle "stack \($v.1)"), \($x as lua expr))" - %lua = (..) - Lua "\ - ..do - local \(mangle "stack \(%var.1)") = List{\(%structure as lua expr)} - while #\(mangle "stack \(%var.1)") > 0 do - \(%var as lua expr) = table.remove(\(mangle "stack \(%var.1)"), 1) - \(%body as lua)" + $lua = (..) + Lua " + do + local \(mangle "stack \($var.1)") = List{\($structure as lua expr)} + while #\(mangle "stack \($var.1)") > 0 do + \($var as lua expr) = table.remove(\(mangle "stack \($var.1)"), 1) + \($body as lua)" - if (%body has subtree \(do next)): - %lua::add "\n ::continue::" + if ($body has subtree \(do next)): + $lua|add "\n ::continue::" - if (%body has subtree \(do next %var)): - %lua::add "\n \(\(---next %var ---) as lua)" + if ($body has subtree \(do next $var)): + $lua|add "\n \(\(---next $var ---) as lua)" - %lua::add "\n end -- Recursive loop" - if (%body has subtree \(stop %var)): - %lua::add "\n \(\(---stop %var ---) as lua)" - %lua::add "\nend -- Recursive scope" - return %lua + $lua|add "\n end -- Recursive loop" + if ($body has subtree \(stop $var)): + $lua|add "\n \(\(---stop $var ---) as lua)" + $lua|add "\nend -- Recursive scope" + return $lua diff --git a/core/coroutines.nom b/core/coroutines.nom index f34f0c9..9f6f6f4 100644 --- a/core/coroutines.nom +++ b/core/coroutines.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V4.12.12.8 +#!/usr/bin/env nomsu -V5.12.12.8 # This file defines the code that creates and manipulates coroutines @@ -9,28 +9,27 @@ use "core/control_flow.nom" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test: - %co = (..) + $co = (..) ->: yield 4 yield 5 repeat 3 times: yield 6 - %nums = [] - for % in coroutine %co: - %nums::add % - assume (%nums == [4, 5, 6, 6, 6]) or barf "Coroutine iteration failed" - %d = {x: 0} - %co2 = (..) + $nums = [] + for $ in coroutine $co: $nums|add $ + assume ($nums == [4, 5, 6, 6, 6]) or barf "Coroutine iteration failed" + $d = {x: 0} + $co2 = (..) coroutine: - %d.x += 1 + $d.x += 1 yield 1 - %d.x += 1 + $d.x += 1 yield - %d.x += 1 - repeat while ((coroutine status of %co2) != "dead"): resume %co2 - assume %d.x == 3 -(coroutine %body) parses as (coroutine from (-> %body)) -(for % in coroutine %co %body) compiles to "\ - ..for \(% as lua expr) in coroutine_wrap(\(%co as lua expr)) do - \(%body as lua) + $d.x += 1 + repeat while ((coroutine status of $co2) != "dead"): resume $co2 + assume $d.x == 3 +(coroutine $body) parses as (coroutine from (-> $body)) +(for $ in coroutine $co $body) compiles to " + for \($ as lua expr) in coroutine_wrap(\($co as lua expr)) do + \($body as lua) end" diff --git a/core/errors.nom b/core/errors.nom index a7e4cff..07b743c 100644 --- a/core/errors.nom +++ b/core/errors.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V4.12.12.8 +#!/usr/bin/env nomsu -V5.12.12.8 # This file contains basic error reporting code @@ -6,68 +6,68 @@ use "core/metaprogramming.nom" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -(barf %msg) compiles to "\ - ..error(\(=lua "\%msg and \(%msg as lua expr) or 'nil'"), 0);" +(barf $msg) compiles to \ +.."error(\(=lua "\$msg and \($msg as lua expr) or 'nil'"), 0);" -(assume %condition) compiles to: - lua> "local \%assumption = 'Assumption failed: '..tostring((\%condition):get_source_code())" +(assume $condition) compiles to: + lua> "local \$assumption = 'Assumption failed: '..tostring((\$condition):get_source_code())" return (..) - Lua "\ - ..if not \(%condition as lua expr) then - error(\(quote "\%assumption"), 0) + Lua " + if not \($condition as lua expr) then + error(\(quote "\$assumption"), 0) end" -(assume %a == %b) compiles to: - lua> "local \%assumption = 'Assumption failed: '..tostring(\(\(%a == %b) as nomsu))" +(assume $a == $b) compiles to: + lua> "local \$assumption = 'Assumption failed: '..tostring(\(\($a == $b) as nomsu))" define mangler return (..) - Lua "\ - ..do - local \(mangle "a"), \(mangle "b") = \(%a as lua expr), \(%b as lua expr) + Lua " + do + local \(mangle "a"), \(mangle "b") = \($a as lua expr), \($b as lua expr) if \(mangle "a") ~= \(mangle "b") then - error(\(quote "\%assumption").."\\n"..tostring(\(mangle "a")).." != "..tostring(\(mangle "b")), 0) + error(\(quote "\$assumption").."\\n"..tostring(\(mangle "a")).." != "..tostring(\(mangle "b")), 0) end end" -(assume %condition or barf %message) compiles to "\ - ..if not \(%condition as lua expr) then - error(\(%message as lua expr), 0) +(assume $condition or barf $message) compiles to " + if not \($condition as lua expr) then + error(\($message as lua expr), 0) end" test: try (barf) and if it succeeds: barf "try failed." - %worked = (no) + $worked = (no) try (barf) and if it barfs: - %worked = (yes) - assume %worked or barf "try/catch failed" - %x = 1 + $worked = (yes) + assume $worked or barf "try/catch failed" + $x = 1 try: - %x = 2 - do (barf) then always: %x = 3 + $x = 2 + do (barf) then always: $x = 3 ..and if it barfs: do nothing - assume (%x == 3) or barf "do/then always failed" + assume ($x == 3) or barf "do/then always failed" # Try/except [..] - 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 -..all compile to "\ - ..do + 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 +..all compile to " + do local fell_through = false local err, erred = nil, false local ok, ret = xpcall(function() - \(%action as lua) + \($action as lua) fell_through = true - end, function(\(=lua "\%fallback and \(%msg as lua expr) or ''")) + end, function(\(=lua "\$fallback and \($msg as lua expr) or ''")) local ok, ret = pcall(function() - \((=lua "\%fallback or \%msg") as lua) + \((=lua "\$fallback or \$msg") as lua) end) if not ok then err, erred = ret, true end end) if ok then - \(%success as lua) + \($success as lua) if not fell_through then return ret end @@ -87,14 +87,14 @@ test: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -(try %action) parses as (..) - try %action and if it succeeds (do nothing) or if it barfs (do nothing) +(try $action) parses as (..) + try $action and if it succeeds (do nothing) or if it barfs (do nothing) #(try %action and if it barfs %fallback) parses as (..) try %action and if it succeeds (do nothing) or if it barfs %fallback -(try %action and if it barfs %msg %fallback) parses as (..) - try %action and if it succeeds (do nothing) or if it barfs %msg %fallback +(try $action and if it barfs $msg $fallback) parses as (..) + try $action and if it succeeds (do nothing) or if it barfs $msg $fallback -(try %action and if it succeeds %success) parses as (..) - try %action and if it succeeds %success or if it barfs (do nothing) +(try $action and if it succeeds $success) parses as (..) + try $action and if it succeeds $success or if it barfs (do nothing) diff --git a/core/id.nom b/core/id.nom index 78af96c..6512bf5 100644 --- a/core/id.nom +++ b/core/id.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V4.12.12.8 +#!/usr/bin/env nomsu -V5.12.12.8 # A simple UUID function based on RFC 4122: http://www.ietf.org/rfc/rfc4122.txt @@ -10,29 +10,29 @@ use "core/control_flow.nom" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -%NaN_surrogate = {} -%nil_surrogate = {} -%obj_by_id = {} -set %obj_by_id's metatable to {__mode: "v"} -%id_by_obj = {} -set %id_by_obj's metatable to {..} - __mode: "k", __index: for (%self %key): - if (%key == (nil)): - return %self.%nil_surrogate +$NaN_surrogate = {} +$nil_surrogate = {} +$obj_by_id = {} +set $obj_by_id's metatable to {__mode: "v"} +$id_by_obj = {} +set $id_by_obj's metatable to {..} + __mode: "k", __index: for ($self $key): + if ($key == (nil)): + return $self.$nil_surrogate - if (%key != %key): - return %self.%NaN_surrogate + if ($key != $key): + return $self.$NaN_surrogate --- (retry) --- - %id = (uuid) - if (%obj_by_id.%id != (nil)): go to (retry) - %self.%key = %id - %obj_by_id.%id = %key - return %id + $id = (uuid) + if ($obj_by_id.$id != (nil)): go to (retry) + $self.$key = $id + $obj_by_id.$id = $key + return $id externally (uuid) means: # Set all the other bits to randomly (or pseudo-randomly) chosen values. - %bytes = [..] + $bytes = [..] # time-low, time-mid, time-high-and-version randint (2 ^ (4 * 8)), randint (2 ^ (2 * 8)), randint (2 ^ (2 * 8 - 4)) # clock-seq-and-reserved, clock-seq-low @@ -43,20 +43,20 @@ externally (uuid) means: # Set the four most significant bits (bits 12 through 15) of the # time_hi_and_version field to the 4-bit version number from # Section 4.1.3. - %bytes.3 += 0x4000 + $bytes.3 += 0x4000 # Set the two most significant bits (bits 6 and 7) of the # clock_seq_hi_and_reserved to zero and one, respectively. - %bytes.4 += 0xC0 - return (=lua "('%08x-%04x-%04x-%02x%02x-%6x%6x'):format(unpack(\%bytes))") + $bytes.4 += 0xC0 + return (=lua "('%08x-%04x-%04x-%02x%02x-%6x%6x'):format(unpack(\$bytes))") # For strict identity checking, use (%x's id) == (%y's id) test: assume (([] == []) and ((id of []) != (id of []))) seed random with 0 - %x = [] - assume ((id of %x) == (id of %x)) + $x = [] + assume ((id of $x) == (id of $x)) seed random with 0 - assume ((id of %x) != (id of [])) + assume ((id of $x) != (id of [])) seed random -externally [id of %, %'s id, %'id] all mean %id_by_obj.% +externally [id of $, $'s id, $'id] all mean $id_by_obj.$ diff --git a/core/io.nom b/core/io.nom index 8f22b07..4bf2028 100644 --- a/core/io.nom +++ b/core/io.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V4.12.12.8 +#!/usr/bin/env nomsu -V5.12.12.8 # This file contains basic input/output code @@ -6,26 +6,26 @@ use "core/metaprogramming.nom" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -(say %message) compiles to: - lua> "\ - ..if \%message.type == "Text" then - return LuaCode("say(", \(%message as lua expr), ");"); +(say $message) compiles to: + lua> " + if \$message.type == "Text" then + return LuaCode("say(", \($message as lua expr), ");"); else - return LuaCode("say(tostring(", \(%message as lua expr), "));"); + return LuaCode("say(tostring(", \($message as lua expr), "));"); end" -(say %message inline) compiles to: - lua> "\ - ..if \%message.type == "Text" then - return LuaCode("io.write(", \(%message as lua expr), ")"); +(say $message inline) compiles to: + lua> " + if \$message.type == "Text" then + return LuaCode("io.write(", \($message as lua expr), ")"); else - return LuaCode("io.write(tostring(", \(%message as lua expr), "))"); + return LuaCode("io.write(tostring(", \($message as lua expr), "))"); end" -(ask %prompt) compiles to: - lua> "\ - ..if \%prompt.type == "Text" then - return LuaCode("(io.write(", \(%prompt as lua expr), ") and io.read())"); +(ask $prompt) compiles to: + lua> " + if \$prompt.type == "Text" then + return LuaCode("(io.write(", \($prompt as lua expr), ") and io.read())"); else - return LuaCode("(io.write(tostring(", \(%prompt as lua expr), ")) and io.read())"); + return LuaCode("(io.write(tostring(", \($prompt as lua expr), ")) and io.read())"); end" diff --git a/core/math.nom b/core/math.nom index 2bc3e6f..8ee5d62 100644 --- a/core/math.nom +++ b/core/math.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V4.12.12.8 +#!/usr/bin/env nomsu -V5.12.12.8 # This file defines some common math literals and functions @@ -12,10 +12,10 @@ use "core/collections.nom" # Literals: test: - assume (all of [inf, NaN, pi, tau, golden ratio, e]) or barf "\ - ..math constants failed" - %nan = (NaN) - assume (%nan != %nan) or barf "NaN failed" + assume (all of [inf, NaN, pi, tau, golden ratio, e]) or barf \ + .."math constants failed" + $nan = (NaN) + assume ($nan != $nan) or barf "NaN failed" [infinity, inf] all compile to "math.huge" [not a number, NaN, nan] all compile to "(0/0)" [pi, Pi, PI] all compile to "math.pi" @@ -26,8 +26,8 @@ test: # Functions: test: assume (("5" as a number) == 5) -((% as a number)'s meaning) = ((tonumber %)'s meaning) -((% as number)'s meaning) = ((tonumber %)'s meaning) +(($ as a number)'s meaning) = ((tonumber $)'s meaning) +(($ as number)'s meaning) = ((tonumber $)'s meaning) test: assume (..) all of [..] @@ -35,38 +35,38 @@ test: arc tangent 5, arc tangent 5 / 10, hyperbolic sine 5, hyperbolic cosine 5 hyperbolic tangent 5, e^ 5, ln 5, log base 2 of 5, floor 5, ceiling 5, round 5 ..or barf "math functions failed" -[absolute value %, | % |, abs %] all compile to "math.abs(\(% as lua expr))" -[square root %, square root of %, √ %, sqrt %] all compile to "\ - ..math.sqrt(\(% as lua expr))" -[sine %, sin %] all compile to "math.sin(\(% as lua expr))" -[cosine %, cos %] all compile to "math.cos(\(% as lua expr))" -[tangent %, tan %] all compile to "math.tan(\(% as lua expr))" -[arc sine %, asin %] all compile to "math.asin(\(% as lua expr))" -[arc cosine %, acos %] all compile to "math.acos(\(% as lua expr))" -[arc tangent %, atan %] all compile to "math.atan(\(% as lua expr))" -[arc tangent %y / %x, atan2 %y %x] all compile to "\ - ..math.atan2(\(%y as lua expr), \(%x as lua expr))" -[hyperbolic sine %, sinh %] all compile to "math.sinh(\(% as lua expr))" -[hyperbolic cosine %, cosh %] all compile to "math.cosh(\(% as lua expr))" -[hyperbolic tangent %, tanh %] all compile to "math.tanh(\(% as lua expr))" -[e^ %, exp %] all compile to "math.exp(\(% as lua expr))" -[natural log %, ln %, log %] all compile to "math.log(\(% as lua expr))" -[log % base %base, log base %base of %] all compile to "\ - ..math.log(\(% as lua expr), \(%base as lua expr))" -(floor %) compiles to "math.floor(\(% as lua expr))" -[ceiling %, ceil %] all compile to "math.ceil(\(% as lua expr))" -[round %, % rounded] all compile to "math.floor(\(% as lua expr) + .5)" +[absolute value $, | $ |, abs $] all compile to "math.abs(\($ as lua expr))" +[square root $, square root of $, √ $, sqrt $] all compile to \ +.."math.sqrt(\($ as lua expr))" +[sine $, sin $] all compile to "math.sin(\($ as lua expr))" +[cosine $, cos $] all compile to "math.cos(\($ as lua expr))" +[tangent $, tan $] all compile to "math.tan(\($ as lua expr))" +[arc sine $, asin $] all compile to "math.asin(\($ as lua expr))" +[arc cosine $, acos $] all compile to "math.acos(\($ as lua expr))" +[arc tangent $, atan $] all compile to "math.atan(\($ as lua expr))" +[arc tangent $y / $x, atan2 $y $x] all compile to \ +.."math.atan2(\($y as lua expr), \($x as lua expr))" +[hyperbolic sine $, sinh $] all compile to "math.sinh(\($ as lua expr))" +[hyperbolic cosine $, cosh $] all compile to "math.cosh(\($ as lua expr))" +[hyperbolic tangent $, tanh $] all compile to "math.tanh(\($ as lua expr))" +[e^ $, exp $] all compile to "math.exp(\($ as lua expr))" +[natural log $, ln $, log $] all compile to "math.log(\($ as lua expr))" +[log $ base $base, log base $base of $] all compile to \ +.."math.log(\($ as lua expr), \($base as lua expr))" +(floor $) compiles to "math.floor(\($ as lua expr))" +[ceiling $, ceil $] all compile to "math.ceil(\($ as lua expr))" +[round $, $ rounded] all compile to "math.floor(\($ as lua expr) + .5)" test: assume ((463 to the nearest 100) == 500) or barf "rounding failed" assume ((2.6 to the nearest 0.25) == 2.5) or barf "rounding failed" -externally (%n to the nearest %rounder) means (..) - =lua "(\%rounder)*math.floor((\%n / \%rounder) + .5)" +externally ($n to the nearest $rounder) means (..) + =lua "(\$rounder)*math.floor((\$n / \$rounder) + .5)" # Any/all -externally [all of %items, all %items] all mean: - for % in %items: - unless %: +externally [all of $items, all $items] all mean: + for $ in $items: + unless $: return (no) return (yes) @@ -82,10 +82,10 @@ externally [all of %items, all %items] all mean: %lua::add ")" return %lua -[not all of %items, not all %items] all parse as (not (all of %items)) -externally [any of %items, any %items] all mean: - for % in %items: - if %: +[not all of $items, not all $items] all parse as (not (all of $items)) +externally [any of $items, any $items] all mean: + for $ in $items: + if $: return (yes) return (no) @@ -101,14 +101,14 @@ externally [any of %items, any %items] all mean: %lua::add ")" return %lua -[none of %items, none %items] all parse as (not (any of %items)) +[none of $items, none $items] all parse as (not (any of $items)) # Sum/product -externally [sum of %items, sum %items] all mean: - %total = 0 - for % in %items: - %total += % - return %total +externally [sum of $items, sum $items] all mean: + $total = 0 + for $ in $items: + $total += $ + return $total #[sum of %items, sum %items] all compile to: unless (%items.type is "List"): @@ -122,11 +122,11 @@ externally [sum of %items, sum %items] all mean: %lua::add ")" return %lua -externally [product of %items, product %items] all mean: - %prod = 1 - for % in %items: - %prod *= % - return %prod +externally [product of $items, product $items] all mean: + $prod = 1 + for $ in $items: + $prod *= $ + return $prod #[product of %items, product %items] all compile to: unless (%items.type is "List"): @@ -140,61 +140,61 @@ externally [product of %items, product %items] all mean: %lua::add ")" return %lua -externally [avg of %items, average of %items] all mean (..) - (sum of %items) / (size of %items) +externally [avg of $items, average of $items] all mean (..) + (sum of $items) / (size of $items) # Min/max -externally [min of %items, smallest of %items, lowest of %items] all mean: - %best = (nil) - for % in %items: - if ((%best == (nil)) or (% < %best)): %best = % - return %best +externally [min of $items, smallest of $items, lowest of $items] all mean: + $best = (nil) + for $ in $items: + if (($best == (nil)) or ($ < $best)): $best = $ + return $best externally [..] - max of %items, biggest of %items, largest of %items, highest of %items + max of $items, biggest of $items, largest of $items, highest of $items ..all mean: - %best = (nil) - for % in %items: - if ((%best == (nil)) or (% > %best)): %best = % - return %best + $best = (nil) + for $ in $items: + if (($best == (nil)) or ($ > $best)): $best = $ + return $best test: - assume ((min of [3, -4, 1, 2] by % = (% * %)) == 1) - assume ((max of [3, -4, 1, 2] by % = (% * %)) == -4) + assume ((min of [3, -4, 1, 2] by $ = ($ * $)) == 1) + assume ((max of [3, -4, 1, 2] by $ = ($ * $)) == -4) -(min of %items by %item = %value_expr) parses as (..) +(min of $items by $item = $value_expr) parses 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 - return %best - -(max of %items by %item = %value_expr) parses as (..) + $best = (nil) + $best_key = (nil) + for $item in $items: + $key = $value_expr + if (($best == (nil)) or ($key < $best_key)): + $best = $item + $best_key = $key + return $best + +(max of $items by $item = $value_expr) parses 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 - return %best + $best = (nil) + $best_key = (nil) + for $item in $items: + $key = $value_expr + if (($best == (nil)) or ($key > $best_key)): + $best = $item + $best_key = $key + return $best # Random functions -externally (seed random with %) means: - lua> "math.randomseed(\%);\nfor i=1,20 do math.random(); end" +externally (seed random with $) means: + lua> "math.randomseed(\$);\nfor i=1,20 do math.random(); end" (seed random) parses as (seed random with (=lua "os.time()")) [random number, random, rand] all compile to "math.random()" -[random int %n, random integer %n, randint %n] all compile to "\ - ..math.random(\(%n as lua expr))" +[random int $n, random integer $n, randint $n] all compile to \ +.."math.random(\($n as lua expr))" -[random from %low to %high, random number from %low to %high, rand %low %high] \ -..all compile to "math.random(\(%low as lua expr), \(%high as lua expr))" +[random from $low to $high, random number from $low to $high, rand $low $high] \ +..all compile to "math.random(\($low as lua expr), \($high as lua expr))" externally [..] - random choice from %elements, random choice %elements, random %elements -..all mean (=lua "\%elements[math.random(#\%elements)]") + random choice from $elements, random choice $elements, random $elements +..all mean (=lua "\$elements[math.random(#\$elements)]") diff --git a/core/metaprogramming.nom b/core/metaprogramming.nom index 9fcf26a..6353933 100644 --- a/core/metaprogramming.nom +++ b/core/metaprogramming.nom @@ -1,12 +1,12 @@ -#!/usr/bin/env nomsu -V4.12.12.8 +#!/usr/bin/env nomsu -V5.12.12.8 # This File contains actions for making actions and compile-time actions and some helper functions to make that easier. lua> "NOMSU_CORE_VERSION = 12" lua> "NOMSU_LIB_VERSION = 8" -lua> "\ - ..do +lua> " + do local mangle_index = 0 function mangler() local my_mangle_index = mangle_index @@ -20,19 +20,19 @@ lua> "\ return LuaCode("local mangle = mangler()") end" -lua> "\ - ..compile.action["1 ->"] = function(compile, \%args, \%body) - if \%args and not \%body then \%args, \%body = {}, \%args end - local body_lua = SyntaxTree:is_instance(\%body) and compile(\%body) or \%body - if SyntaxTree:is_instance(\%body) and \%body.type ~= "Block" then body_lua:prepend("return ") end +lua> " + compile.action["1 ->"] = function(compile, \$args, \$body) + if \$args and not \$body then \$args, \$body = {}, \$args end + local body_lua = SyntaxTree:is_instance(\$body) and compile(\$body) or \$body + if SyntaxTree:is_instance(\$body) and \$body.type ~= "Block" then body_lua:prepend("return ") end local lua = LuaCode("(function(") - if SyntaxTree:is_instance(\%args) and (\%args.type == "Action" or \%args.type == "MethodCall") then - \%args = \%args:get_args() - elseif SyntaxTree:is_instance(\%args) and \%args.type == "Var" then \%args = {\%args} end - for i, arg in ipairs(\%args) do + if SyntaxTree:is_instance(\$args) and (\$args.type == "Action" or \$args.type == "MethodCall") then + \$args = \$args:get_args() + elseif SyntaxTree:is_instance(\$args) and \$args.type == "Var" then \$args = {\$args} end + for i, arg in ipairs(\$args) do local arg_lua = SyntaxTree:is_instance(arg) and compile(arg):text() or arg if arg_lua == "..." then - if i < #\%args then + if i < #\$args then compile_error_at(SyntaxTree:is_instance(arg) and arg or nil, "Extra arguments must come last.", "Try removing any arguments after (*extra arguments*)") end @@ -51,10 +51,10 @@ lua> "\ compile.action["->"] = compile.action["1 ->"] compile.action["for"] = compile.action["1 ->"]" -lua> "\ - ..compile.action["what 1 compiles to"] = function(compile, \%action) - local lua = LuaCode("compile.action[", \%action.stub:as_lua(), "](") - local lua_args = table.map(\%action:get_args(), compile) +lua> " + compile.action["what 1 compiles to"] = function(compile, \$action) + local lua = LuaCode("compile.action[", \$action.stub:as_lua(), "](") + local lua_args = table.map(\$action:get_args(), compile) table.insert(lua_args, 1, "compile") lua:concat_add(lua_args, ", ") lua:add(")") @@ -73,48 +73,48 @@ test: test: lua> "do" loc x - assume (%x is 99) or barf "Compile to statements with locals failed." + assume ($x is 99) or barf "Compile to statements with locals failed." lua> "end" - assume (%x is (nil)) or barf "Failed to properly localize a variable." + assume ($x is (nil)) or barf "Failed to properly localize a variable." (asdf) compiles to: - %tmp = "" - return (Lua %tmp) + $tmp = "" + return (Lua $tmp) test: asdf - assume (%tmp is (nil)) or barf "compile to is leaking variables" + assume ($tmp is (nil)) or barf "compile to is leaking variables" -lua> "\ - ..compile.action["1 compiles to"] = function(compile, \%action, \%body) - local \%args = List{\(\%compile), unpack(\%action:get_args())} - if \%body.type == "Text" then - \%body = SyntaxTree{source=\%body.source, type="Action", "Lua", \%body} +lua> " + compile.action["1 compiles to"] = function(compile, \$action, \$body) + local \$args = List{\(\$compile), unpack(\$action:get_args())} + if \$body.type == "Text" then + \$body = SyntaxTree{source=\$body.source, type="Action", "Lua", \$body} end - return LuaCode("compile.action[", \%action.stub:as_lua(), - "] = ", \(\(%args -> %body) as lua)) + return LuaCode("compile.action[", \$action.stub:as_lua(), + "] = ", \(\($args -> $body) as lua)) end" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -(%actions all compile to %body) compiles to: - lua> "\ - ..if \%actions.type ~= "List" then - compile_error(\%actions, "This should be a list of actions.") +($actions all compile to $body) compiles to: + lua> " + if \$actions.type ~= "List" then + compile_error(\$actions, "This should be a list of actions.") end - local lua = \(\(%actions.1 compiles to %body) as lua) - local \%args = List{\(\%compile), unpack(\%actions[1]:get_args())} - local \%compiled_args = List(table.map(\%args, compile)) - for i=2,#\%actions do - local alias = \%actions[i] - local \%alias_args = List{\(\%compile), unpack(alias:get_args())} + local lua = \(\($actions.1 compiles to $body) as lua) + local \$args = List{\(\$compile), unpack(\$actions[1]:get_args())} + local \$compiled_args = List(table.map(\$args, compile)) + for i=2,#\$actions do + local alias = \$actions[i] + local \$alias_args = List{\(\$compile), unpack(alias:get_args())} lua:add("\\ncompile.action[", alias.stub:as_lua(), "] = ") - if \%alias_args == \%args then - lua:add("compile.action[", \%actions[1].stub:as_lua(), "]") + if \$alias_args == \$args then + lua:add("compile.action[", \$actions[1].stub:as_lua(), "]") else lua:add("function(") - lua:concat_add(table.map(\%alias_args, compile), ", ") - lua:add(") return compile.action[", \%actions[1].stub:as_lua(), "](") - lua:concat_add(\%compiled_args, ", ") + lua:concat_add(table.map(\$alias_args, compile), ", ") + lua:add(") return compile.action[", \$actions[1].stub:as_lua(), "](") + lua:concat_add(\$compiled_args, ", ") lua:add(") end") end end @@ -123,41 +123,41 @@ lua> "\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test: - (foo %x) means "outer" - with {((foo %)'s meaning)}: - (foo %x) means: - %y = (%x + 1) - return %y + (foo $x) means "outer" + with {((foo $)'s meaning)}: + (foo $x) means: + $y = ($x + 1) + return $y assume ((foo 10) == 11) or barf "Action didn't work." - assume (%y is (nil)) or barf "Action leaked a local into globals." - (baz %) parses as (foo %) + assume ($y is (nil)) or barf "Action leaked a local into globals." + (baz $) parses as (foo $) assume ((foo 1) == "outer") -(%action means %body) compiles to: - lua> "\ - .. +($action means $body) compiles to: + lua> " + local lua = LuaCode() - if \%action.type == "MethodCall" then - lua:add(compile(\%action[1]), ".", \%action[2].stub:as_lua_id()) - elseif \%action.type == "Action" then - lua:add(\%action.stub:as_lua_id()) - lua:add_free_vars({\%action.stub:as_lua_id()}) + if \$action.type == "MethodCall" then + lua:add(compile(\$action[1]), ".", \$action[2].stub:as_lua_id()) + elseif \$action.type == "Action" then + lua:add(\$action.stub:as_lua_id()) + lua:add_free_vars({\$action.stub:as_lua_id()}) else - compile_error_at(\%action, "Expected an action or method call here") + compile_error_at(\$action, "Expected an action or method call here") end - lua:add(" = ", \(\(%action -> %body) as lua), ";") + lua:add(" = ", \(\($action -> $body) as lua), ";") return lua" -(%actions all mean %body) compiles to: - lua> "\ - ..local lua = \(\(%actions.1 means %body) as lua) - local first_def = (\%actions[1].type == "MethodCall" - and LuaCode(compile(\%actions[1][1]), ".", \%actions[1].stub:as_lua_id()) - or LuaCode(\%actions[1].stub:as_lua_id())) - local \%args = List(\%actions[1]:get_args()) - for i=2,#\%actions do - local alias = \%actions[i] - local \%alias_args = List(alias:get_args()) +($actions all mean $body) compiles to: + lua> " + local lua = \(\($actions.1 means $body) as lua) + local first_def = (\$actions[1].type == "MethodCall" + and LuaCode(compile(\$actions[1][1]), ".", \$actions[1].stub:as_lua_id()) + or LuaCode(\$actions[1].stub:as_lua_id())) + local \$args = List(\$actions[1]:get_args()) + for i=2,#\$actions do + local alias = \$actions[i] + local \$alias_args = List(alias:get_args()) lua:add("\\n") if alias.type == "MethodCall" then lua:add(compile(alias[1]), ".", alias.stub:as_lua_id()) @@ -165,10 +165,10 @@ test: lua:add(alias.stub:as_lua_id()) lua:add_free_vars({alias_name}) end - if \%args == \%alias_args then + if \$args == \$alias_args then lua:add(" = ", first_def, ";") else - lua:add(" = ", \(\(%alias_args -> %actions.1) as lua), ";") + lua:add(" = ", \(\($alias_args -> $actions.1) as lua), ";") end end return lua" @@ -182,46 +182,46 @@ test: assume ((baz1) == "baz1") assume ((baz2) == "baz2") -(externally %action means %body) compiles to: - lua> "\ - ..local lua = \(\(%action means %body) as lua) - lua:remove_free_vars({\%action.stub:as_lua_id()}) +(externally $action means $body) compiles to: + lua> " + local lua = \(\($action means $body) as lua) + lua:remove_free_vars({\$action.stub:as_lua_id()}) return lua" -(externally %actions all mean %body) compiles to: - lua> "\ - ..local lua = \(\(%actions all mean %body) as lua) - lua:remove_free_vars(table.map(\%actions, function(a) return a.stub:as_lua_id() end)) +(externally $actions all mean $body) compiles to: + lua> " + local lua = \(\($actions all mean $body) as lua) + lua:remove_free_vars(table.map(\$actions, function(a) return a.stub:as_lua_id() end)) return lua" test: - assume (((say %)'s meaning) == (=lua "say")) + assume (((say $)'s meaning) == (=lua "say")) -(%action's meaning) compiles to (Lua (%action.stub::as lua id)) +($action's meaning) compiles to (Lua ($action.stub|as lua id)) test: - (swap %x and %y) parses as (..) + (swap $x and $y) parses as (..) do: - %tmp = %x - %x = %y - %y = %tmp + $tmp = $x + $x = $y + $y = $tmp test: - [%1, %2] = [1, 2] - swap %1 and %2 - assume ((%1 == 2) and (%2 == 1)) or barf "\ - ..'parse % as %' failed on 'swap % and %'" - [%tmp, %tmp2] = [1, 2] - swap %tmp and %tmp2 - assume ((%tmp == 2) and (%tmp2 == 1)) or barf "\ - ..'parse % as %' variable mangling failed." - -(%actions all parse as %body) compiles to: - lua> "\ - ..local replacements = {} - if \%actions.type ~= "List" then - compile_error(\%actions, "This should be a list.") + [$1, $2] = [1, 2] + swap $1 and $2 + assume (($1 == 2) and ($2 == 1)) or barf \ + .."'parse % as %' failed on 'swap % and %'" + [$tmp, $tmp2] = [1, 2] + swap $tmp and $tmp2 + assume (($tmp == 2) and ($tmp2 == 1)) or barf \ + .."'parse % as %' variable mangling failed." + +($actions all parse as $body) compiles to: + lua> " + local replacements = {} + if \$actions.type ~= "List" then + compile_error(\$actions, "This should be a list.") end - for i,arg in ipairs(\%actions[1]:get_args()) do + for i,arg in ipairs(\$actions[1]:get_args()) do replacements[arg[1]] = compile(arg):text() end local function make_tree(t) @@ -254,33 +254,33 @@ test: return t:as_lua() end end - local \%new_body = LuaCode:from(\%body.source, + local \$new_body = LuaCode:from(\$body.source, "local mangle = mangler()", - "\\nreturn ", make_tree(\%body)) - local ret = \(\(%actions all compile to %new_body) as lua) + "\\nreturn ", make_tree(\$body)) + local ret = \(\($actions all compile to $new_body) as lua) return ret" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -[%action parses as %body] all parse as ([%action] all parse as %body) +[$action parses as $body] all parse as ([$action] all parse as $body) #(%tree as lua expr) compiles to "compile(\(=lua "compile(\%tree, true)"), true)" -externally (%tree as lua expr) means: - lua> "\ - ..local tree_lua = compile(\%tree) - if \%tree.type == 'Block' then - tree_lua = LuaCode:from(\%tree.source, '(function()\\n ', tree_lua, '\\nend)()') - elseif \%tree.type == 'MethodCall' and #\%tree > 2 then - compile_error_at(\%tree, "This must be a single value instead of "..(#\%tree - 1).." method calls.", +externally ($tree as lua expr) means: + lua> " + local tree_lua = compile(\$tree) + if \$tree.type == 'Block' then + tree_lua = LuaCode:from(\$tree.source, '(function()\\n ', tree_lua, '\\nend)()') + elseif \$tree.type == 'MethodCall' and #\$tree > 2 then + compile_error_at(\$tree, "This must be a single value instead of "..(#\$tree - 1).." method calls.", "Replace this with a single method call.") end return tree_lua" -externally [%var as lua identifier, %var as lua id] all mean: - lua> "\ - ..local lua = \(%var as lua) +externally [$var as lua identifier, $var as lua id] all mean: + lua> " + local lua = \($var as lua) if not lua:text():is_a_lua_id() then - compile_error(\%var, + compile_error(\$var, "This is supposed to be something that compiles to a valid Lua identifier.", "This should probably be a variable.") end @@ -295,50 +295,50 @@ test: assume (third arg 5 6 7 8) == 7 (*extra arguments*) compiles to "..." -(% is syntax tree) compiles to "SyntaxTree:is_instance(\(% as lua expr))" -externally (% is %kind syntax tree) means (..) - =lua "SyntaxTree:is_instance(\%) and \%.type == \%kind" +($ is syntax tree) compiles to "SyntaxTree:is_instance(\($ as lua expr))" +externally ($ is $kind syntax tree) means (..) + =lua "SyntaxTree:is_instance(\$) and \$.type == \$kind" -(%tree with %t -> %replacement) compiles to "\ - ..\(%tree as lua expr):map(function(\(%t as lua expr)) +($tree with $t -> $replacement) compiles to " + \($tree as lua expr):map(function(\($t as lua expr)) \(..) - (%replacement as lua) if (%replacement.type == "Block") else "\ - ..return \(%replacement as lua expr)" + ($replacement as lua) if ($replacement.type == "Block") else \ + .."return \($replacement as lua expr)" .. end)" -externally (%tree with vars %replacements) means (..) - =lua "\ - ..\%tree:map(function(\%t) - if \%t.type == "Var" then - return \%replacements[\%t[1]] +externally ($tree with vars $replacements) means (..) + =lua " + \$tree:map(function(\$t) + if \$t.type == "Var" then + return \$replacements[\$t[1]] end end)" -(tree %tree with vars %replacements) compiles to "\ - ..\(=lua "(\%tree):as_lua()"):map(function(t) +(tree $tree with vars $replacements) compiles to " + \(=lua "(\$tree):as_lua()"):map(function(t) if t.type == "Var" then - return \(%replacements as lua expr)[t[1]] + return \($replacements as lua expr)[t[1]] end end)" -(%tree has subtree %match_tree) compiles to "\ - ..(function() - local match_tree = \(%match_tree as lua expr) - for subtree in coroutine_wrap(function() \(%tree as lua expr):map(yield) end) do +($tree has subtree $match_tree) compiles to " + (function() + local match_tree = \($match_tree as lua expr) + for subtree in coroutine_wrap(function() \($tree as lua expr):map(yield) end) do if subtree == match_tree then return true end end end)()" -externally (match %tree with %patt) means: - lua> "\ - ..if \%patt.type == "Var" then return Dict{[\%patt[1]]=\%tree} end - if \%patt.type == "Action" and \%patt.stub ~= \%tree.stub then return nil end - if #\%patt ~= #\%tree then return nil end +externally (match $tree with $patt) means: + lua> " + if \$patt.type == "Var" then return Dict{[\$patt[1]]=\$tree} end + if \$patt.type == "Action" and \$patt.stub ~= \$tree.stub then return nil end + if #\$patt ~= #\$tree then return nil end local matches = Dict{} - for \%i=1,#\%patt do - if SyntaxTree:is_instance(\%tree[\%i]) then - local submatch = \(match %tree.%i with %patt.%i) + for \($i)=1,#\$patt do + if SyntaxTree:is_instance(\$tree[\$i]) then + local submatch = \(match $tree.$i with $patt.$i) if not submatch then return nil end for k,v in pairs(submatch) do if matches[k] and matches[k] ~= v then return nil end @@ -351,44 +351,44 @@ externally (match %tree with %patt) means: test: assume ((quote "one\n\"two\"") == "\"one\\n\\\"two\\\"\"") -(quote %s) compiles to "tostring(\(%s as lua expr)):as_lua()" +(quote $s) compiles to "tostring(\($s as lua expr)):as_lua()" test: assume (lua type of {}) == "table" assume (type of {}) == "Dict" assume ({} is a "Dict") assume ("" is text) assume ("" isn't a "Dict") -externally (% is text) means (=lua "\(lua type of %) == 'string'") -externally [% is not text, % isn't text] all mean (..) - =lua "\(lua type of %) ~= 'string'" +externally ($ is text) means (=lua "\(lua type of $) == 'string'") +externally [$ is not text, $ isn't text] all mean (..) + =lua "\(lua type of $) ~= 'string'" -externally (type of %) means: - lua> "\ - ..local lua_type = \(lua type of %) +externally (type of $) means: + lua> " + local lua_type = \(lua type of $) if lua_type == 'string' then return 'Text' elseif lua_type == 'table' or lua_type == 'userdata' then - local mt = getmetatable(\%) + local mt = getmetatable(\$) if mt and mt.__type then return mt.__type end end return lua_type" -[% is a %type, % is an %type] all parse as ((type of %) == %type) -[% isn't a %type, % isn't an %type, % is not a %type, % is not an %type] \ -..all parse as ((type of %) != %type) +[$ is a $type, $ is an $type] all parse as ((type of $) == $type) +[$ isn't a $type, $ isn't an $type, $ is not a $type, $ is not an $type] \ +..all parse as ((type of $) != $type) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test: assume ((run "return (2 + 99)") == 101) - %x = 0 - externally (set to %) means: - external %x = % + $x = 0 + externally (set to $) means: + external $x = $ run "set to 1" - assume %x == 1 + assume $x == 1 assume (run \(return \(\(5) + \(5)))) == 10 -(run %nomsu_code) compiles to "run_1_in(\(%nomsu_code as lua expr), _ENV)" -[compile %block, compiled %block, %block compiled] all compile to "\ - ..compile(\(%block as lua))" +(run $nomsu_code) compiles to "run_1_in(\($nomsu_code as lua expr), _ENV)" +[compile $block, compiled $block, $block compiled] all compile to \ +.."compile(\($block as lua))" test: (foo) means: @@ -398,8 +398,8 @@ test: # 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. (return (*extra arguments*)) compiles to: - lua> "\ - ..local lua = \(Lua "do return ") + lua> " + local lua = \(Lua "do return ") for i=1,select('#',...) do if i > 1 then lua:add(", ") end lua:add(_1_as_lua((select(i, ...)))) @@ -419,12 +419,12 @@ test: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -(with local compile actions %body) compiles to "\ - ..do +(with local compile actions $body) compiles to " + do --local compile = _1_forked(compile) local old_action = compile.action compile.action = _1_forked(old_action) - \(%body as lua) + \($body as lua) compile.action = old_action end" diff --git a/core/operators.nom b/core/operators.nom index bc8068e..bc658b1 100644 --- a/core/operators.nom +++ b/core/operators.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V4.12.12.8 +#!/usr/bin/env nomsu -V5.12.12.8 # This file contains definitions of operators like "+" and "and". @@ -11,115 +11,115 @@ test: assume (all [1 < 2, 2 > 1, 1 <= 2, 2 >= 1, 1 == 1, 1 != 2]) # Comparison Operators -(%x < %y) compiles to "(\(%x as lua expr) < \(%y as lua expr))" -(%x > %y) compiles to "(\(%x as lua expr) > \(%y as lua expr))" -(%x <= %y) compiles to "(\(%x as lua expr) <= \(%y as lua expr))" -(%x >= %y) compiles to "(\(%x as lua expr) >= \(%y as lua expr))" -[%a is %b, %a == %b] all compile to "(\(%a as lua expr) == \(%b as lua expr))" -[%a isn't %b, %a is not %b, %a not= %b, %a != %b] all compile to "\ - ..(\(%a as lua expr) ~= \(%b as lua expr))" +($x < $y) compiles to "(\($x as lua expr) < \($y as lua expr))" +($x > $y) compiles to "(\($x as lua expr) > \($y as lua expr))" +($x <= $y) compiles to "(\($x as lua expr) <= \($y as lua expr))" +($x >= $y) compiles to "(\($x as lua expr) >= \($y as lua expr))" +[$a is $b, $a == $b] all compile to "(\($a as lua expr) == \($b as lua expr))" +[$a isn't $b, $a is not $b, $a not= $b, $a != $b] all compile to \ +.."(\($a as lua expr) ~= \($b as lua expr))" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test: - %x = 10 - assume (%x == 10) - [%x, %y] = [10, 20] - assume ((%x == 10) and (%y == 20)) or barf "mutli-assignment failed." - [%x, %y] = [%y, %x] - assume ((%y == 10) and (%x == 20)) or barf "swapping vars failed." - %vals = [4, 5] - [%x, %y] = (unpack %vals) - assume ((%x == 4) and (%y == 5)) or barf "unpacking failed" + $x = 10 + assume ($x == 10) + [$x, $y] = [10, 20] + assume (($x == 10) and ($y == 20)) or barf "mutli-assignment failed." + [$x, $y] = [$y, $x] + assume (($y == 10) and ($x == 20)) or barf "swapping vars failed." + $vals = [4, 5] + [$x, $y] = (unpack $vals) + assume (($x == 4) and ($y == 5)) or barf "unpacking failed" # Variable assignment operator -(%var = %value) compiles to: - lua> "\ - ..local lua = LuaCode() - if \%var.type == "List" then - for i, \%assignment in ipairs(\%var) do +($var = $value) compiles to: + lua> " + local lua = LuaCode() + if \$var.type == "List" then + for i, \$assignment in ipairs(\$var) do if i > 1 then lua:add(", ") end - local assignment_lua = \(%assignment as lua expr) + local assignment_lua = \($assignment as lua expr) lua:add(assignment_lua) - if \%assignment.type == 'Var' then + if \$assignment.type == 'Var' then lua:add_free_vars({assignment_lua:text()}) end end lua:add(' = ') - if \%value.type == "List" then - if #\%value ~= #\%var then - compile_error_at(\%value, - "This assignment has too "..(#\%value > #\%var and "many" or "few").." values.", + if \$value.type == "List" then + if #\$value ~= #\$var then + compile_error_at(\$value, + "This assignment has too "..(#\$value > #\$var and "many" or "few").." values.", "Make sure it has the same number of values on the left and right hand side of the '\ ..=' operator.") end - for i, \%val in ipairs(\%value) do + for i, \$val in ipairs(\$value) do if i > 1 then lua:add(", ") end - local val_lua = \(%val as lua expr) + local val_lua = \($val as lua expr) lua:add(val_lua) end lua:add(";") else - lua:add(\(%value as lua expr), ';') + lua:add(\($value as lua expr), ';') end else - local var_lua = \(%var as lua expr) + local var_lua = \($var as lua expr) lua:add(var_lua) - if \%var.type == 'Var' then + if \$var.type == 'Var' then lua:add_free_vars({var_lua:text()}) end - lua:add(' = ', \(%value as lua expr), ';') + lua:add(' = ', \($value as lua expr), ';') end return lua" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test: - [%foozle, %y] = ["outer", "outer"] + [$foozle, $y] = ["outer", "outer"] externally (set global x local y) means: - external %foozle = "inner" - %y = "inner" + external $foozle = "inner" + $y = "inner" set global x local y - assume ((%foozle == "inner") and (%y == "outer")) or barf "external failed." -(external %var = %value) compiles to "\(%var as lua) = \(%value as lua)" + assume (($foozle == "inner") and ($y == "outer")) or barf "external failed." +(external $var = $value) compiles to "\($var as lua) = \($value as lua)" test: - [%foozle, %y] = ["outer", "outer"] + [$foozle, $y] = ["outer", "outer"] externally (set global x local y) means: - with external [%foozle]: - %foozle = "inner" - %y = "inner" + with external [$foozle]: + $foozle = "inner" + $y = "inner" set global x local y - assume ((%foozle == "inner") and (%y == "outer")) or barf "\ - ..'with external' failed." + assume (($foozle == "inner") and ($y == "outer")) or barf \ + .."'with external' failed." -(with external %externs %body) compiles to: - %body_lua = (%body as lua) - lua> "\%body_lua:remove_free_vars(table.map(\%externs, function(v) return compile(v):text() end))" - return %body_lua +(with external $externs $body) compiles to: + $body_lua = ($body as lua) + lua> "\$body_lua:remove_free_vars(table.map(\$externs, function(v) return compile(v):text() end))" + return $body_lua test: - [%x, %y] = [1, 2] - with {%z, %x: 999}: - assume %z == (nil) - %z = 999 - assume (%z == 999) or barf "'with' failed." - assume (%x == 999) or barf "'with' assignment failed." - assume (%x == 1) or barf "'with' scoping failed" - assume (%z == (nil)) or barf "'with' scoping failed" - -(with %assignments %body) compiles to: - %lua = (%body as lua) - lua> "\ - ..local lhs, rhs = LuaCode(), LuaCode() + [$x, $y] = [1, 2] + with {$z, $x: 999}: + assume $z == (nil) + $z = 999 + assume ($z == 999) or barf "'with' failed." + assume ($x == 999) or barf "'with' assignment failed." + assume ($x == 1) or barf "'with' scoping failed" + assume ($z == (nil)) or barf "'with' scoping failed" + +(with $assignments $body) compiles to: + $lua = ($body as lua) + lua> " + local lhs, rhs = LuaCode(), LuaCode() local vars = {} - for i, item in ipairs(\%assignments) do - local \%target, \%value = item[1], item[2] - local target_lua = \(%target as lua) + for i, item in ipairs(\$assignments) do + local \$target, \$value = item[1], item[2] + local target_lua = \($target as lua) if not target_lua:text():is_lua_id() then - compile_error_at(\%target, "Invalid target for 'with' scope assignment.", + compile_error_at(\$target, "Invalid target for 'with' scope assignment.", "This should be either a variable or an action's meaning.") end - local value_lua = \%value and \(%value as lua) or "nil" + local value_lua = \$value and \($value as lua) or "nil" if i > 1 then lhs:add(", ") rhs:add(", ") @@ -128,35 +128,35 @@ test: rhs:add(value_lua) vars[i] = target_lua:text() end - \%lua:remove_free_vars(vars) - \%lua:prepend("local ", lhs, " = ", rhs, ";\\n")" - return (Lua "do\n \%lua\nend -- 'with' block") + \$lua:remove_free_vars(vars) + \$lua:prepend("local ", lhs, " = ", rhs, ";\\n")" + return (Lua "do\n \$lua\nend -- 'with' block") # Math Operators test: assume ((5 wrapped around 2) == 1) or barf "mod not working" -[%x wrapped around %y, %x mod %y] all compile to "\ - ..((\(%x as lua expr)) % (\(%y as lua expr)))" +[$x wrapped around $y, $x mod $y] all compile to \ +.."((\($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) test: - %calls = 0 + $calls = 0 (one) means: - external %calls = (%calls + 1) + external $calls = ($calls + 1) return 1 assume (0 <= (one) <= 2) or barf "Three-way chained comparison failed." - assume (%calls == 1) or barf "\ - ..Three-way comparison evaluated middle value multiple times" -(%x < %y < %z) parses as (((%a %b %c) -> ((%a < %b) and (%b < %c))) %x %y %z) -(%x <= %y < %z) parses as (((%a %b %c) -> ((%a <= %b) and (%b < %c))) %x %y %z) -(%x < %y <= %z) parses as (((%a %b %c) -> ((%a < %b) and (%b <= %c))) %x %y %z) -(%x <= %y <= %z) parses as (((%a %b %c) -> ((%a <= %b) and (%b <= %c))) %x %y %z) -(%x > %y > %z) parses as (((%a %b %c) -> ((%a > %b) and (%b > %c))) %x %y %z) -(%x >= %y > %z) parses as (((%a %b %c) -> ((%a >= %b) and (%b > %c))) %x %y %z) -(%x > %y >= %z) parses as (((%a %b %c) -> ((%a > %b) and (%b >= %c))) %x %y %z) -(%x >= %y >= %z) parses as (((%a %b %c) -> ((%a >= %b) and (%b >= %c))) %x %y %z) + assume ($calls == 1) or barf \ + .."Three-way comparison evaluated middle value multiple times" +($x < $y < $z) parses as ((($a $b $c) -> (($a < $b) and ($b < $c))) $x $y $z) +($x <= $y < $z) parses as ((($a $b $c) -> (($a <= $b) and ($b < $c))) $x $y $z) +($x < $y <= $z) parses as ((($a $b $c) -> (($a < $b) and ($b <= $c))) $x $y $z) +($x <= $y <= $z) parses as ((($a $b $c) -> (($a <= $b) and ($b <= $c))) $x $y $z) +($x > $y > $z) parses as ((($a $b $c) -> (($a > $b) and ($b > $c))) $x $y $z) +($x >= $y > $z) parses as ((($a $b $c) -> (($a >= $b) and ($b > $c))) $x $y $z) +($x > $y >= $z) parses as ((($a $b $c) -> (($a > $b) and ($b >= $c))) $x $y $z) +($x >= $y >= $z) parses as ((($a $b $c) -> (($a >= $b) and ($b >= $c))) $x $y $z) # TODO: optimize for common case where x,y,z are all either variables or number literals # Boolean Operators @@ -165,8 +165,8 @@ test: assume (((no) and (barfer)) == (no)) assume ((no) or (yes)) assume ((yes) or (barfer)) -(%x and %y) compiles to "(\(%x as lua expr) and \(%y as lua expr))" -(%x or %y) compiles to "(\(%x as lua expr) or \(%y as lua expr))" +($x and $y) compiles to "(\($x as lua expr) and \($y as lua expr))" +($x or $y) compiles to "(\($x as lua expr) or \($y as lua expr))" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -183,32 +183,32 @@ test: # Lua 5.3 introduced bit operators like | and &. Use them when possible, otherwise fall back to bit.bor(), bit.band(), etc. lua> "if \((is jit) or ((Lua version) == "Lua 5.2")) then" -[NOT %, ~ %] all compile to "bit.bnot(\(% as lua expr))" -[%x OR %y, %x | %y] all compile to "\ - ..bit.bor(\(%x as lua expr), \(%y as lua expr))" +[NOT $, ~ $] all compile to "bit.bnot(\($ as lua expr))" +[$x OR $y, $x | $y] all compile to \ +.."bit.bor(\($x as lua expr), \($y as lua expr))" -[%x XOR %y, %x ~ %y] all compile to "\ - ..bit.bxor(\(%x as lua expr), \(%y as lua expr))" +[$x XOR $y, $x ~ $y] all compile to \ +.."bit.bxor(\($x as lua expr), \($y as lua expr))" -[%x AND %y, %x & %y] all compile to "\ - ..bit.band(\(%x as lua expr), \(%y as lua expr))" +[$x AND $y, $x & $y] all compile to \ +.."bit.band(\($x as lua expr), \($y as lua expr))" -[%x LSHIFT %shift, %x << %shift] all compile to "\ - ..bit.lshift(\(%x as lua expr), \(%shift as lua expr))" +[$x LSHIFT $shift, $x << $shift] all compile to \ +.."bit.lshift(\($x as lua expr), \($shift as lua expr))" -[%x RSHIFT %shift, %x >> %shift] all compile to "\ - ..bit.rshift(\(%x as lua expr), \(%shift as lua expr))" +[$x RSHIFT $shift, $x >> $shift] all compile to \ +.."bit.rshift(\($x as lua expr), \($shift as lua expr))" lua> "else" -[NOT %, ~ %] all compile to "~(\(% as lua expr))" -[%x OR %y, %x | %y] all compile to "(\(%x as lua expr) | \(%y as lua expr))" -[%x XOR %y, %x ~ %y] all compile to "(\(%x as lua expr) ~ \(%y as lua expr))" -[%x AND %y, %x & %y] all compile to "(\(%x as lua expr) & \(%y as lua expr))" -[%x LSHIFT %shift, %x << %shift] all compile to "\ - ..(\(%x as lua expr) << \(%shift as lua expr))" +[NOT $, ~ $] all compile to "~(\($ as lua expr))" +[$x OR $y, $x | $y] all compile to "(\($x as lua expr) | \($y as lua expr))" +[$x XOR $y, $x ~ $y] all compile to "(\($x as lua expr) ~ \($y as lua expr))" +[$x AND $y, $x & $y] all compile to "(\($x as lua expr) & \($y as lua expr))" +[$x LSHIFT $shift, $x << $shift] all compile to \ +.."(\($x as lua expr) << \($shift as lua expr))" -[%x RSHIFT %shift, %x >> %shift] all compile to "\ - ..(\(%x as lua expr) >> \(%shift as lua expr))" +[$x RSHIFT $shift, $x >> $shift] all compile to \ +.."(\($x as lua expr) >> \($shift as lua expr))" lua> "end" @@ -216,29 +216,29 @@ lua> "end" test: assume ((- 5) == -5) assume ((not (yes)) == (no)) -(- %) compiles to "(- \(% as lua expr))" -(not %) compiles to "(not \(% as lua expr))" +(- $) compiles to "(- \($ as lua expr))" +(not $) compiles to "(not \($ as lua expr))" test: assume ((size of [1, 2, 3]) == 3) -(size of %list) compiles to "(#\(%list as lua expr))" -(%list is empty) compiles to "(#\(%list as lua expr) == 0)" +(size of $list) compiles to "(#\($list as lua expr))" +($list is empty) compiles to "(#\($list as lua expr) == 0)" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Update operators test: - %x = 1 - %x += 1 - assume (%x == 2) or barf "+= failed" - %x *= 2 - assume (%x == 4) or barf "*= failed" - wrap %x around 3 - assume (%x == 1) or barf "wrap around failed" -(%var += %) parses as (%var = ((%var or 0) + %)) -(%var -= %) parses as (%var = ((%var or 0) - %)) -(%var *= %) parses as (%var = ((%var or 1) * %)) -(%var /= %) parses as (%var = (%var / %)) -(%var ^= %) parses as (%var = (%var ^ %)) -(%var and= %) parses as (%var = (%var and %)) -(%var or= %) parses as (%var = (%var or %)) -(wrap %var around %) parses as (%var = (%var wrapped around %)) + $x = 1 + $x += 1 + assume ($x == 2) or barf "+= failed" + $x *= 2 + assume ($x == 4) or barf "*= failed" + wrap $x around 3 + assume ($x == 1) or barf "wrap around failed" +($var += $) parses as ($var = (($var or 0) + $)) +($var -= $) parses as ($var = (($var or 0) - $)) +($var *= $) parses as ($var = (($var or 1) * $)) +($var /= $) parses as ($var = ($var / $)) +($var ^= $) parses as ($var = ($var ^ $)) +($var and= $) parses as ($var = ($var and $)) +($var or= $) parses as ($var = ($var or $)) +(wrap $var around $) parses as ($var = ($var wrapped around $)) diff --git a/core/text.nom b/core/text.nom index fcdf678..8b500f7 100644 --- a/core/text.nom +++ b/core/text.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V4.12.12.8 +#!/usr/bin/env nomsu -V5.12.12.8 # This file contains some definitions of text escape sequences, including ANSI console color codes. @@ -12,35 +12,31 @@ use "core/control_flow.nom" test: assume "\[1, 2, 3]" == "[1, 2, 3]" assume "foo = \(1 + 2)!" == "foo = 3!" - assume "one\ntwo" == "\ - ..one - two" - assume "nogap" == "\ - ..no\ - ..gap" - assume (["x", "y"]::joined with ",") == "x,y" - assume (["x", "y"]::joined) == "xy" - assume ("BAR"::byte 2) == 65 - assume ("BAR"::bytes 1 to 2) == [66, 65] - assume ("asdf"::capitalized) == "Asdf" - assume ("asdf"::uppercase) == "ASDF" - assume ("asdf"::with "s" -> "X") == "aXdf" - assume ("one\ntwo\n"::lines) == ["one", "two", ""] - (%spec とは %body) parses as (%spec means %body) + assume "one\ntwo" == "one\ntwo" + assume "nogap" == "nogap" + assume (["x", "y"]|joined with ",") == "x,y" + assume (["x", "y"]|joined) == "xy" + assume ("BAR"|byte 2) == 65 + assume ("BAR"|bytes 1 to 2) == [66, 65] + assume ("asdf"|capitalized) == "Asdf" + assume ("asdf"|uppercase) == "ASDF" + assume ("asdf"|with "s" -> "X") == "aXdf" + assume ("one\ntwo\n"|lines) == ["one", "two", ""] + ($spec とは $body) parses as ($spec means $body) test: - %こんにちは = "こんにちは" - (% と言う) とは "\(%)世界" - assume (%こんにちは と言う) == "こんにちは世界" + $こんにちは = "こんにちは" + ($ と言う) とは "\($)世界" + assume ($こんにちは と言う) == "こんにちは世界" -(%expr for %match in %text matching %patt) compiles to: +($expr for $match in $text matching $patt) compiles to: define mangler return (..) - Lua "\ - ..(function() + Lua " + (function() local \(mangle "comprehension") = List{} - for \(%match as lua expr) in (\(%text as lua expr)):gmatch(\(%patt as lua expr)) do - \(mangle "comprehension")[#\(mangle "comprehension")+1] = \(%expr as lua) + for \($match as lua expr) in (\($text as lua expr)):gmatch(\($patt as lua expr)) do + \(mangle "comprehension")[#\(mangle "comprehension")+1] = \($expr as lua) end return \(mangle "comprehension") end)()" @@ -51,17 +47,17 @@ test: test: assume (0xDEADBEEF as hex) == "0xDEADBEEF" -externally (%num as hex) means: - if (%num < 0): - return ("-0x%X"::formatted with (- %num)) +externally ($num as hex) means: + if ($num < 0): + return ("-0x%X"|formatted with (- $num)) ..else: - return ("0x%X"::formatted with %num) + return ("0x%X"|formatted with $num) # Text literals -%escapes = {..} +$escapes = {..} 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 = %str in %escapes: - with {%lua: Lua (quote %str)}: - %compile.action.%name = (-> %lua) +for $name = $str in $escapes: + with {$lua: Lua (quote $str)}: + $compile.action.$name = (-> $lua) |
