diff options
41 files changed, 954 insertions, 749 deletions
diff --git a/compatibility/2.3.nom b/compatibility/2.3.nom index daf3c36..75a5c2c 100644 --- a/compatibility/2.3.nom +++ b/compatibility/2.3.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file defines upgrades from Nomsu <2.3 to Nomsu 2.3 diff --git a/compatibility/2.4.nom b/compatibility/2.4.nom index 1d5463b..1279968 100644 --- a/compatibility/2.4.nom +++ b/compatibility/2.4.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file defines upgrades from Nomsu <2.4 to Nomsu 2.4 @@ -13,58 +13,68 @@ upgrade $tree to "2.4" as: if ((size of $tree) == 3): return $tree $conditions = [] $new_lines = [] - $body = (($tree.2 upgraded) if ($tree.2 is "Block" syntax tree) else [$tree.2 upgraded]) + $body = + ($tree.2 upgraded) if ($tree.2 is "Block" syntax tree) else [$tree.2 upgraded] + for $line in $body: when: - (not ($line is "Action" syntax tree)): $new_lines|add $line + (not ($line is "Action" syntax tree)): + $new_lines, add $line + ($line.stub is "*"): if ((size of $line) == 2): - $conditions|add $line.2 + $conditions, add $line.2 ..else: - $new_lines|add $line + $new_lines, add $line ($line.stub == "* else"): - $new_lines|add (\(else $block) with vars {block: $line.3}) + $new_lines, add (\(else $block) with vars {.block = $line.3}) else: - $conditions|add $line.2 + $conditions, add $line.2 $action = $line.3 unless ($action is "Block" syntax tree): $action = (=lua "SyntaxTree{type='Block', source=\$action.source, \$action}") - $conditions|add $action - $new_lines| - add (=lua "SyntaxTree{type='Action', source=\$conditions[1].source, unpack(\$conditions)}") + $conditions, add $action + $new_lines, add + =lua "SyntaxTree{type='Action', source=\$conditions[1].source, unpack(\$conditions)}" $conditions = [] - return (..) - \(when $body) with vars {..} - body: =lua "SyntaxTree{type='Block', source=\$tree[2].source, unpack(\$new_lines)}" + return + \(when $body) with vars { + .body = (=lua "SyntaxTree{type='Block', source=\$tree[2].source, unpack(\$new_lines)}") + } "if 1 is ?" "if 1 = ?": $values = [] $new_lines = [] - $body = (($tree.5 upgraded) if ($tree.5 is "Block" syntax tree) else [$tree.5 upgraded]) + $body = + ($tree.5 upgraded) if ($tree.5 is "Block" syntax tree) else [$tree.5 upgraded] + for $line in $body: when: - (not ($line is "Action" syntax tree)): $new_lines|add $line + (not ($line is "Action" syntax tree)): + $new_lines, add $line + ($line.stub is "*"): if ((size of $line) == 2): - $values|add $line.2 + $values, add $line.2 ..else: - $new_lines|add $line + $new_lines, add $line ($line.stub == "* else"): - $new_lines|add (\(else $block) with vars {block: $line.3}) + $new_lines, add (\(else $block) with vars {.block = $line.3}) else: - $values|add $line.2 + $values, add $line.2 $action = $line.3 unless ($action is "Block" syntax tree): $action = \(: $action) - $values|add $action - $new_lines| + $values, add $action + $new_lines, add (=lua "SyntaxTree{type='Action', source=\$values[1].source, unpack(\$values)}") $values = [] - return (..) - \(if $var is $body) with vars {..} - var: $tree.2 upgraded, body: =lua "SyntaxTree{type='Block', source=\$tree[5].source, unpack(\$new_lines)}" + return + \(if $var is $body) with vars { + .var = ($tree.2 upgraded), .body = (=lua "SyntaxTree{type='Block', source=\$tree[5].source, unpack(\$new_lines)}") + } diff --git a/compatibility/2.5.5.5.nom b/compatibility/2.5.5.5.nom index aff4b78..05bf705 100644 --- a/compatibility/2.5.5.5.nom +++ b/compatibility/2.5.5.5.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file defines upgrades from Nomsu <2.5.5.5 to Nomsu 2.5.5.5 @@ -6,9 +6,10 @@ use "compatibility/compatibility.nom" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -upgrade action [hash $, sha1 $] to "2.5.5.5" as (..) +upgrade action [hash $, sha1 $] to "2.5.5.5" as =lua "\(base64 decode (hash $)):gsub('.', function(c) return ('%x02'):format(c) end)" -upgrade action [file with hash $] to "2.5.5.5" as (..) - file with hash (..) - base64 (=lua "\$:gsub('..', function(xx) return string.char(tonumber(xx, 16)) end)") +upgrade action [file with hash $] to "2.5.5.5" as + file with hash + base64 + =lua "\$:gsub('..', function(xx) return string.char(tonumber(xx, 16)) end)" diff --git a/compatibility/2.5.nom b/compatibility/2.5.nom index b83f156..77fb228 100644 --- a/compatibility/2.5.nom +++ b/compatibility/2.5.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file defines upgrades from Nomsu <2.5 to Nomsu 2.5 @@ -6,8 +6,8 @@ use "compatibility/compatibility.nom" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -upgrade action (for $1 where $2 matches $3 $4) to "2.5" as (..) +upgrade action (for $1 where $2 matches $3 $4) to "2.5" as for $1 in $2 matching $3 $4 -upgrade action ($1 for $2 where $3 matches $4) to "2.5" as (..) +upgrade action ($1 for $2 where $3 matches $4) to "2.5" as $1 for $2 in $3 matching $4 diff --git a/compatibility/2.nom b/compatibility/2.nom index 03e2db7..b4b0efd 100644 --- a/compatibility/2.nom +++ b/compatibility/2.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file defines upgrades from Nomsu 1 to Nomsu 2 @@ -16,21 +16,23 @@ upgrade $tree to "2" as: unless ($false_body is "Block" syntax tree): $false_body = (=lua "Block(\$false_body.source, \$false_body)") - return (..) - \(if $cond $true_body else $false_body) with vars {..} - cond: $tree.2 upgraded, true_body: $true_body, false_body: $false_body + return + \(if $cond $true_body else $false_body) with vars { + .cond = ($tree.2 upgraded), .true_body = $true_body, .false_body = $false_body + } - $need_blocks = [..] + $need_blocks = [ "if", "unless", "for 1 in", "for 1 = 2 in", "repeat while 1", "repeat 1 times" "repeat", "repeat until 1", "for 1 in 2 to 3 by", "for 1 in 2 to 3 via" "for 1 in 2 to", "for 1 2 in", "do", "for 1 in recursive", "test", "with", "result of" "when" + ] for $n in $need_blocks: if ($tree.stub is $n): $bits = [: for $ in $tree: add (($ upgraded) if ($ is syntax tree) else $)] - unless (($bits|last) is "Block" syntax tree): - $body = ($bits|last) - $bits.(size of $bits) = (..) + unless (($bits, last) is "Block" syntax tree): + $body = ($bits, last) + $bits.(size of $bits) = =lua "SyntaxTree{type='Block', source=\$body.source, \$body}" return (=lua "SyntaxTree{type='Action', source=\$tree.source, unpack(\$bits)}") diff --git a/compatibility/3.5.5.6.nom b/compatibility/3.5.5.6.nom index 0d5f307..b3ee67e 100644 --- a/compatibility/3.5.5.6.nom +++ b/compatibility/3.5.5.6.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file defines upgrades from Nomsu <3.5.5.6 to Nomsu 3.5.5.6 @@ -6,6 +6,6 @@ use "compatibility/compatibility.nom" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -upgrade action "traceback" to "3.5.5.6" via (..) +upgrade action "traceback" to "3.5.5.6" via for $tree: compile error at $tree "'traceback' has been deprecated." diff --git a/compatibility/3.6.nom b/compatibility/3.6.nom index d2f9bb6..8fb52b5 100644 --- a/compatibility/3.6.nom +++ b/compatibility/3.6.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file defines upgrades from Nomsu <3.6 to 3.6 @@ -6,24 +6,27 @@ use "compatibility/compatibility.nom" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -upgrade action [..] +upgrade action [ append $item to $list, add $item to $list, to $list add $item, to $list append $item -..to "3.6" as ($list|add $item) +] to "3.6" as ($list, add $item) -upgrade action [add $item to $list at index $i] to "3.6" as (..) - $list|at index $i add $item +upgrade action [add $item to $list at index $i] to "3.6" as + $list, at index $i add $item -upgrade action [pop from $list, remove last from $list] to "3.6" as ($list|pop) -upgrade action [remove index $index from $list] to "3.6" as (..) - $list|remove index $index -upgrade action [to $1 write $2, $1 <-write $2] to "3.6" as ($1|add $2) -upgrade action [to $1 write $2 joined by $3] to "3.6" as ($1|add $2 joined by $3) -upgrade action [declare locals in $lua] to "3.6" as ($lua|declare locals) -upgrade action [declare locals $locs in $lua] to "3.6" as (..) - $lua|declare locals $locs +upgrade action [pop from $list, remove last from $list] to "3.6" as ($list, pop) +upgrade action [remove index $index from $list] to "3.6" as + $list, remove index $index +upgrade action [to $1 write $2, $1 <-write $2] to "3.6" as ($1, add $2) +upgrade action [to $1 write $2 joined by $3] to "3.6" as +..($1, add $2 joined by $3) -upgrade action [add free vars $vars to $lua] to "3.6" as (..) - $lua|add free vars $vars +upgrade action [declare locals in $lua] to "3.6" as ($lua, declare locals) -upgrade action [remove free vars $vars from $lua] to "3.6" as (..) - $lua|remove free vars $vars +upgrade action [declare locals $locs in $lua] to "3.6" as + $lua, declare locals $locs + +upgrade action [add free vars $vars to $lua] to "3.6" as + $lua, add free vars $vars + +upgrade action [remove free vars $vars from $lua] to "3.6" as + $lua, remove free vars $vars diff --git a/compatibility/3.7.nom b/compatibility/3.7.nom index 777585b..e81b9dc 100644 --- a/compatibility/3.7.nom +++ b/compatibility/3.7.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file defines upgrades from Nomsu <3.7 to 3.7 @@ -6,28 +6,37 @@ use "compatibility/compatibility.nom" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -upgrade action [$index st to last in $list] to "3.7" as ($list|$index st to last) -upgrade action [$index nd to last in $list] to "3.7" as ($list|$index nd to last) -upgrade action [$index rd to last in $list] to "3.7" as ($list|$index rd to last) -upgrade action [$index th to last in $list] to "3.7" as ($list|$index rd th last) -upgrade action [last in $list] to "3.7" as ($list|last) -upgrade action [first in $list] to "3.7" as ($list|first) -upgrade action [$item is in $list, $list contains $item, $list has $item] to \ -.."3.7" as ($list|has $item) +upgrade action [$index st to last in $list] to "3.7" as +..($list, $index st to last) -upgrade action [..] +upgrade action [$index nd to last in $list] to "3.7" as +..($list, $index nd to last) + +upgrade action [$index rd to last in $list] to "3.7" as +..($list, $index rd to last) + +upgrade action [$index th to last in $list] to "3.7" as +..($list, $index rd th last) + +upgrade action [last in $list] to "3.7" as ($list, last) + +upgrade action [first in $list] to "3.7" as ($list, first) +upgrade action [$item is in $list, $list contains $item, $list has $item] to +.."3.7" as ($list, has $item) + +upgrade 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 -..to "3.7" as (not ($list|has $item)) +] to "3.7" as (not ($list, has $item)) -upgrade action [$list has key $index, $list has index $index] to "3.7" as (..) +upgrade action [$list has key $index, $list has index $index] to "3.7" as $list.$index != (nil) -upgrade action [..] +upgrade action [ $list doesn't have key $index, $list does not have key $index $list doesn't have index $index, $list does not have index $index -..to "3.7" as ($list.$index == (nil)) +] to "3.7" as ($list.$index == (nil)) -upgrade action [..] +upgrade action [ number of keys in $list, len $list, || $list ||, length $list, length of $list -..to "3.7" as (size of $list) +] to "3.7" as (size of $list) diff --git a/compatibility/3.8.nom b/compatibility/3.8.nom index 7de2c71..3362a9c 100644 --- a/compatibility/3.8.nom +++ b/compatibility/3.8.nom @@ -1,19 +1,19 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file defines upgrades from Nomsu <3.8 to 3.8 (Text method changes) -upgrade action [$texts joined with $glue] to "3.8" as ($texts|joined with $glue) -upgrade action [$texts joined, joined $texts] to "3.8" as ($texts|joined) -upgrade action [byte $i of $text] to "3.8" as ($text|byte $i) -upgrade action [bytes $start to $stop of $text] to "3.8" as (..) - $text|bytes $start to $stop -upgrade action [bytes of $text] to "3.8" as ($text|bytes) -upgrade action [capitalized $text, $text capitalized] to "3.8" as (..) - $text|capitalized -upgrade action [uppercase $text, $text uppercase] to "3.8" as ($text|uppercase) -upgrade action [..] +upgrade action [$texts joined with $glue] to "3.8" as ($texts, joined with $glue) +upgrade action [$texts joined, joined $texts] to "3.8" as ($texts, joined) +upgrade action [byte $i of $text] to "3.8" as ($text, byte $i) +upgrade action [bytes $start to $stop of $text] to "3.8" as + $text, bytes $start to $stop +upgrade action [bytes of $text] to "3.8" as ($text, bytes) +upgrade action [capitalized $text, $text capitalized] to "3.8" as + $text, capitalized +upgrade action [uppercase $text, $text uppercase] to "3.8" as ($text, uppercase) +upgrade action [ $text with $sub instead of $patt, $text with $patt replaced by $sub $text s/ $patt / $sub -..to "3.8" as ($text|with $patt -> $sub) -upgrade action [$text matches $pattern] to "3.8" as ($text|matches $pattern) -upgrade action [$text matching $pattern] to "3.8" as ($text|matching $pattern).1 +] to "3.8" as ($text, with $patt -> $sub) +upgrade action [$text matches $pattern] to "3.8" as ($text, matches $pattern) +upgrade action [$text matching $pattern] to "3.8" as ($text, matching $pattern).1 diff --git a/compatibility/3.nom b/compatibility/3.nom index d6d71ad..6086bd0 100644 --- a/compatibility/3.nom +++ b/compatibility/3.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file defines upgrades from Nomsu <=2 to Nomsu 3 @@ -9,7 +9,7 @@ use "compatibility/compatibility.nom" upgrade action (method $spec $body) to "3" as (my action $spec $body) upgrade action (me) to "3" as $me upgrade action (@) to "3" as $me -upgrade action "as" to "3" via (..) +upgrade action "as" to "3" via for $tree: - compile error at $tree "Object API has changed and 'as' is no longer supported." \ + compile error at $tree "Object API has changed and 'as' is no longer supported." .."Use (%obj::action ...) instead of (as %obj: action ...)" diff --git a/compatibility/4.10.12.7.nom b/compatibility/4.10.12.7.nom index c5abe1a..228fee9 100644 --- a/compatibility/4.10.12.7.nom +++ b/compatibility/4.10.12.7.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file defines upgrades from Nomsu <4.10.12.7 to 4.10.12.7 use "compatibility/compatibility.nom" @@ -6,42 +6,53 @@ use "compatibility/compatibility.nom" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ upgrade action ($ as lua statements) to "4.10.12.7" as ($ as lua) -upgrade action ($ as lua return) to "4.10.12.7" as (..) +upgrade action ($ as lua return) to "4.10.12.7" as =lua "\$.type == 'Block' and \($ as lua) or 'return '..\($ as lua expr)" + upgrade action (Lua value $) to "4.10.12.7" as (Lua $) + upgrade action ($e for $ in $items) to "4.10.12.7" as [: for $ in $items: add $e] -upgrade action ($e for $k = $v in $items) to "4.10.12.7" as [..] +upgrade action ($e for $k = $v in $items) to "4.10.12.7" as [ : for $k = $v in $items: add $e +] -upgrade action ($e for $i in $start to $stop) to "4.10.12.7" as [..] +upgrade action ($e for $i in $start to $stop) to "4.10.12.7" as [ : for $i in $start to $stop: add $e +] -upgrade action ($e for $i in $start to $stop by $step) to "4.10.12.7" as [..] +upgrade action ($e for $i in $start to $stop by $step) to "4.10.12.7" as [ : for $i in $start to $stop by $step: add $e +] -upgrade action ($e for $i in $start to $stop via $step) to "4.10.12.7" as [..] +upgrade action ($e for $i in $start to $stop via $step) to "4.10.12.7" as [ : for $i in $start to $stop by $step: add $e +] -upgrade action ($k = $v for $ in $items) to "4.10.12.7" as {..} +upgrade action ($k = $v for $ in $items) to "4.10.12.7" as { : for $ in $items: add $k = $v +} -upgrade action ($k = $v for $k0 = $v0 in $items) to "4.10.12.7" as {..} +upgrade action ($k = $v for $k0 = $v0 in $items) to "4.10.12.7" as { : for $k0 = $v0 in $items: add $k = $v +} -upgrade action ($k = $v for $i in $start to $stop) to "4.10.12.7" as {..} +upgrade action ($k = $v for $i in $start to $stop) to "4.10.12.7" as { : for $i in $start to $stop: add $k = $v +} -upgrade action ($k = $v for $i in $start to $stop by $step) to "4.10.12.7" as {..} +upgrade action ($k = $v for $i in $start to $stop by $step) to "4.10.12.7" as { : for $i in $start to $stop by $step: add $k = $v +} -upgrade action ($k = $v for $i in $start to $stop via $step) to "4.10.12.7" as {..} +upgrade action ($k = $v for $i in $start to $stop via $step) to "4.10.12.7" as { : for $i in $start to $stop by $step: add $k = $v +} -upgrade action (parse $text from $filename) to "4.10.12.7" as (..) +upgrade action (parse $text from $filename) to "4.10.12.7" as (NomsuCode from (Source $filename 1 (size of $text)) $text) parsed upgrade action ($ as lua statements) to "4.10.12.7" as ($ as lua) -upgrade action (compile error at $pos $err hint $hint) to "4.10.12.7" as (..) +upgrade action (compile error at $pos $err hint $hint) to "4.10.12.7" as compile error at $pos $err $hint # In old code, it was okay to have imports at the top of the file in the same chunk, @@ -61,9 +72,10 @@ upgrade $tree to "4.10.12.7" as: $i += 1 return --- (insert chunk) --- - [$chunk1, $chunk2] = [..] - SyntaxTree {type: "Block", source: $first_chunk.source} - SyntaxTree {type: "Block", source: $first_chunk.source} + [$chunk1, $chunk2] = [ + SyntaxTree {.type = "Block", .source = $first_chunk.source} + SyntaxTree {.type = "Block", .source = $first_chunk.source} + ] for $j in 1 to ($i - 1): $chunk1.$j = $first_chunk.$j @@ -71,8 +83,10 @@ upgrade $tree to "4.10.12.7" as: for $j in $i to (size of $first_chunk): $chunk2.($j - $i + 1) = $first_chunk.$j - $new_tree = (..) - SyntaxTree {source: $tree.source, type: "FileChunks", 1: $chunk1, 2: $chunk2} + $new_tree = + SyntaxTree { + .source = $tree.source, .type = "FileChunks", .1 = $chunk1, .2 = $chunk2 + } for $i in 2 to (size of $tree): $new_tree.($i + 1) = $tree.$i diff --git a/compatibility/4.11.nom b/compatibility/4.11.nom index 38751d9..8f6aacc 100644 --- a/compatibility/4.11.nom +++ b/compatibility/4.11.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file defines upgrades from Nomsu <4.11 to Nomsu 4.11 (overhaul of function literals, deleting (if all of ...), etc. shorthand) @@ -8,16 +8,16 @@ use "compatibility/compatibility.nom" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Overhaul of function literals: -upgrade action "call 1 with" to "4.11" via (..) +upgrade action "call 1 with" to "4.11" via for ($tree $end_version): - $tree2 = {type: "Action", source: $tree.source, 1: $tree.2} + $tree2 = {.type = "Action", .source = $tree.source, .1 = $tree.2} for $arg in $tree.4 at $i: $tree2.($i + 1) = $arg return (SyntaxTree $tree2) upgrade action (-> $yield_value) to "4.11" as (yield $yield_value) # Replace set {%x:1, %y:2} with [%x, %y] = [1, 2] -upgrade action "set" to "4.11" via (..) +upgrade action "set" to "4.11" via for ($tree $end_version): [$lhs, $rhs] = [\[], \[]] $lhs.source = $tree.2.source @@ -25,71 +25,76 @@ upgrade action "set" to "4.11" via (..) for $entry in $tree.2 at $i: $lhs.$i = $entry.1 $rhs.$i = $entry.2 - return (SyntaxTree {type: "Action", source: $tree.source, 1: $lhs, 2: "=", 3: $rhs}) + + return + SyntaxTree { + .type = "Action", .source = $tree.source, .1 = $lhs, .2 = "=", .3 = $rhs + } -upgrade action "1 with 2 ~>" to "4.11" via (..) +upgrade action "1 with 2 ~>" to "4.11" via for $tree: - compile error at $tree "This method has been deprecated." \ + compile error at $tree "This method has been deprecated." .."Perhaps this could be use %tree::map instead." # Changing filesystem API: -upgrade action (for file $f in $path $body) to "4.11" as (..) +upgrade action (for file $f in $path $body) to "4.11" as for $f in (files for $path) $body -upgrade action ($expr for file $f in $path) to "4.11" as [..] +upgrade action ($expr for file $f in $path) to "4.11" as [ : for $f in (files for $path): add $expr +] -upgrade action (line $n in $text) to "4.11" as ($text|line $n) -upgrade action (line number of $pos in $text) to "4.11" as (..) - $text|line number at $pos +upgrade action (line $n in $text) to "4.11" as ($text, line $n) +upgrade action (line number of $pos in $text) to "4.11" as + $text, line number at $pos # Deduplicating goto labels: upgrade action [=== $label ===, *** $label ***] to "4.11" as (--- $label ---) -upgrade action [===stop $label ===, ***stop $label ***] to "4.11" as (..) +upgrade action [===stop $label ===, ***stop $label ***] to "4.11" as ---stop $label --- -upgrade action [===next $label ===, ***next $label ***] to "4.11" as (..) +upgrade action [===next $label ===, ***next $label ***] to "4.11" as ---next $label --- # Deprecating shorthand functions: -upgrade action [if all of $items $body, if all of $items then $body] to "4.11" as (..) +upgrade action [if all of $items $body, if all of $items then $body] to "4.11" as if (all of $items) $body -upgrade action [unless all of $items $body, unless all of $items then $body] to \ +upgrade action [unless all of $items $body, unless all of $items then $body] to .."4.11" as (if (not (all of $items)) $body) -upgrade action [if any of $items $body, if any of $items then $body] to "4.11" as (..) +upgrade action [if any of $items $body, if any of $items then $body] to "4.11" as if (any of $items) $body -upgrade action [unless any of $items $body, unless any of $items then $body] to \ +upgrade action [unless any of $items $body, unless any of $items then $body] to .."4.11" as (if (not (any of $items)) $body) -upgrade action [if none of $items $body, if none of $items then $body] to "4.11" \ +upgrade action [if none of $items $body, if none of $items then $body] to "4.11" ..as (if (not (any of $items)) $body) -upgrade action [unless none of $items $body, unless none of $items then $body] to \ +upgrade action [unless none of $items $body, unless none of $items then $body] to .."4.11" as (if (any of $items) $body) -upgrade action [..] +upgrade action [ if all of $items $body else $else, if all of $items then $body else $else -..to "4.11" as (if (all of $items) $body else $else) +] to "4.11" as (if (all of $items) $body else $else) -upgrade action [..] +upgrade action [ unless all of $items $body else $else, unless all of $items then $body else $else -..to "4.11" as (if (not (all of $items)) $body else $else) +] to "4.11" as (if (not (all of $items)) $body else $else) -upgrade action [..] +upgrade action [ if any of $items $body else $else, if any of $items then $body else $else -..to "4.11" as (if (any of $items) $body else $else) +] to "4.11" as (if (any of $items) $body else $else) -upgrade action [..] +upgrade action [ unless any of $items $body else $else, unless any of $items then $body else $else -..to "4.11" as (if (not (any of $items)) $body else $else) +] to "4.11" as (if (not (any of $items)) $body else $else) -upgrade action [..] +upgrade action [ if none of $items $body else $else, if none of $items then $body else $else -..to "4.11" as (if (not (any of $items)) $body else $else) +] to "4.11" as (if (not (any of $items)) $body else $else) -upgrade action [..] +upgrade action [ unless none of $items $body else $else, unless none of $items then $body else $else -..to "4.11" as (if (any of $items) $body else $else) +] to "4.11" as (if (any of $items) $body else $else) diff --git a/compatibility/4.12.nom b/compatibility/4.12.nom index 63525c6..8ab69ae 100644 --- a/compatibility/4.12.nom +++ b/compatibility/4.12.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file defines upgrades from Nomsu <4.11 to Nomsu 4.11 (overhaul of function literals, deleting (if all of ...), etc. shorthand) @@ -7,12 +7,12 @@ use "compatibility/compatibility.nom" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -upgrade action "do next repeat" to "4.12" via (..) +upgrade action "do next repeat" to "4.12" via for $tree: - compile error at $tree "This method has been deprecated." \ + compile error at $tree "This method has been deprecated." .."Use either (do next) or (go to (label)) instead." -upgrade action "stop repeating" to "4.12" via (..) +upgrade action "stop repeating" to "4.12" via for $tree: - compile error at $tree "This method has been deprecated." \ + compile error at $tree "This method has been deprecated." .."Use either (stop) or (go to (label)) instead." diff --git a/compatibility/4.8.10.nom b/compatibility/4.8.10.nom index 58b9818..d250f89 100644 --- a/compatibility/4.8.10.nom +++ b/compatibility/4.8.10.nom @@ -1,11 +1,11 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file defines upgrades from Nomsu <4.8.10 to 4.8.10 (renaming "action" -> "means") use "compatibility/compatibility.nom" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -upgrade action "local action" to "4.8.10" via (..) +upgrade action "local action" to "4.8.10" via for ($tree $end_version): $spec = $tree.3 $body = $tree.4 @@ -19,7 +19,7 @@ upgrade action "local action" to "4.8.10" via (..) else: return \($spec means $body) -upgrade action "action" to "4.8.10" via (..) +upgrade action "action" to "4.8.10" via for ($tree $end_version): $spec = $tree.2 $body = $tree.3 @@ -36,7 +36,7 @@ upgrade action "action" to "4.8.10" via (..) ..else: return \($spec's meaning) -upgrade action "compile 1 to" to "4.8.10" via (..) +upgrade action "compile 1 to" to "4.8.10" via for ($tree $end_version): $spec = $tree.2 $body = $tree.4 @@ -50,7 +50,7 @@ upgrade action "compile 1 to" to "4.8.10" via (..) else: return \($spec compiles to $body) -upgrade action "parse 1 as" to "4.8.10" via (..) +upgrade action "parse 1 as" to "4.8.10" via for ($tree $end_version): $spec = $tree.2 $body = $tree.4 diff --git a/compatibility/4.9.nom b/compatibility/4.9.nom index 26a20fb..5f8c28c 100644 --- a/compatibility/4.9.nom +++ b/compatibility/4.9.nom @@ -1,11 +1,11 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file defines upgrades from Nomsu <4.9 to 4.9 use "compatibility/compatibility.nom" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -upgrade action "if" to "4.9" via (..) +upgrade action "if" to "4.9" via for ($tree $end_version): if ((size of $tree) > 2): return $tree return \(when $tree.2) diff --git a/compatibility/compatibility.nom b/compatibility/compatibility.nom index 356a8e0..bc34c4f 100644 --- a/compatibility/compatibility.nom +++ b/compatibility/compatibility.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file contains code for defining ways to upgrade code between different versions of Nomsu. @@ -14,7 +14,7 @@ $ACTION_UPGRADES = ({} with fallback $ -> {}) externally (upgrade action $stub to $version via $upgrade_fn) means: $ACTION_UPGRADES.$version.$stub = $upgrade_fn -(upgrade $tree to $version as $body) parses as (..) +(upgrade $tree to $version as $body) parses as upgrade to $version via (($ $end_version) -> ($ with $tree -> $body)) (upgrade action $actions to $version as $body) compiles to: @@ -40,29 +40,30 @@ externally (upgrade action $stub to $version via $upgrade_fn) means: $args = [] for $k = $v in $t: if ((type of $k) == "number"): - $args|add (make tree $v) + $args, add (make tree $v) ..else: - $args|add "\($k)=\(make tree $v)" - return "SyntaxTree{\($args|joined with ", ")}" + $args, add "\($k)=\(make tree $v)" + return "SyntaxTree{\($args, joined with ", ")}" else: return (quote $t) unless ("\$lua" == ""): - $lua|add "\n" + $lua, add "\n" $retval = (make tree $body) - $lua|add (..) - Lua " + $lua, add + Lua (" upgrade_action_1_to_2_via(\(quote $action.stub), \($version as lua expr), function(\(\$tree as lua id)) return \$retval - end)" + end) + ") return $lua -externally [..] +externally [ $tree upgraded from $start_version to $end_version $tree upgraded to $end_version from $start_version -..all mean: +] all mean: unless ($tree is syntax tree): return $tree ($ver as list) means (($ as number) for $ in $ver matching "[0-9]+") $versions = {} @@ -77,19 +78,21 @@ externally [..] if (($ver as list) <= ($start_version as list)): do next $ver if (($ver as list) > ($end_version as list)): stop $ver if $ACTION_UPGRADES.$ver: - $tree = (..) + $tree = $tree with $ ->: if (($ is "Action" syntax tree) and $ACTION_UPGRADES.$ver.($.stub)): - $with_upgraded_args = {..} + $with_upgraded_args = { : for $k = $v in $: add $k = ($v upgraded from $start_version to $end_version) + } set $with_upgraded_args's metatable to ($'s metatable) return ($ACTION_UPGRADES.$ver.($.stub) $with_upgraded_args $end_version) if $UPGRADES.$ver: - $with_upgraded_args = {..} + $with_upgraded_args = { : for $k = $v in $tree: add $k = ($v upgraded from $start_version to $end_version) + } set $with_upgraded_args's metatable to ($tree's metatable) $tree = ($UPGRADES.$ver $with_upgraded_args $end_version) @@ -101,13 +104,13 @@ externally [..] return $tree -externally ($tree upgraded from $start_version) means (..) +externally ($tree upgraded from $start_version) means $tree upgraded from $start_version to (Nomsu version) -externally ($tree upgraded to $end_version) means (..) +externally ($tree upgraded to $end_version) means $tree upgraded from ($tree.version or (Nomsu version)) to $end_version -externally ($tree upgraded) means (..) +externally ($tree upgraded) means $tree upgraded from ($tree.version or (Nomsu version)) to (Nomsu version) externally (use $path from version $version) means: diff --git a/core/collections.nom b/core/collections.nom index d24152b..77da968 100644 --- a/core/collections.nom +++ b/core/collections.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file contains code that supports manipulating and using collections like lists and dictionaries. @@ -15,35 +15,36 @@ test: $visited = {} for $i = $x in $list: $visited.$i = (yes) - assume ($visited == {1, 2, 3, 4, 5}) + 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 ($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, 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} + $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} - assume ({x: 1, y: 1} & {y: 10, z: 10}) == {y: 1} - assume ({x: 1, y: 1} ~ {y: 10, z: 10}) == {x: 1, z: 10} + 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} + assume ({.x = 1, .y = 1} & {.y = 10, .z = 10}) == {.y = 1} + assume ({.x = 1, .y = 1} ~ {.y = 10, .z = 10}) == {.x = 1, .z = 10} test: assume (([[1, 2], [3, 4]] flattened) == [1, 2, 3, 4]) @@ -55,34 +56,39 @@ externally ($lists flattened) means: for $ in $item: recurse $item on $ ..else: - $flat|add $item + $flat, add $item return $flat test: - assume ((entries in {x: 1}) == [{key: "x", value: 1}]) + 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"]) + assume ((keys in {.x = 1}) == ["x"]) + [keys in $dict, keys of $dict] all parse as [: for $k = $v in $dict: add $k] test: - assume ((values in {x: 1}) == [1]) + assume ((values in {.x = 1}) == [1]) [values in $dict, values of $dict] all parse as [: for $k = $v in $dict: add $v] # Metatable stuff test: $t = {} - set $t's metatable to {__tostring: $ -> "XXX"} + set $t's metatable to {.__tostring = ($ -> "XXX")} assume ("\$t" == "XXX") -(set $dict's metatable to $metatable) compiles to \ +(set $dict's metatable to $metatable) compiles to .."setmetatable(\($dict as lua expr), \($metatable as lua expr));" [$'s metatable, $'metatable] all compile to "getmetatable(\($ as lua expr))" + test: assume (({} with fallback $ -> ($ + 1)).10 == 11) -($dict with fallback $key -> $value) compiles to " +($dict with fallback $key -> $value) compiles to (" (function(d) local mt = {} for k,v in pairs(getmetatable(d) or {}) do mt[k] = v end @@ -92,7 +98,8 @@ test: return value end return setmetatable(d, mt) - end)(\($dict as lua expr))" + end)(\($dict as lua expr)) +") # Sorting test: @@ -101,12 +108,12 @@ test: assume ($x == [1, 2, 3]) sort $x by $ = (- $) assume ($x == [3, 2, 1]) - $keys = {1: 999, 2: 0, 3: 50} + $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 (..) +[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)" @@ -121,7 +128,7 @@ externally [$items sorted, sorted $items] all mean: 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 @@ -135,6 +142,6 @@ externally (unique $items) means: $seen = {} for $ in $items: unless $seen.$: - $unique|add $ + $unique, add $ $seen.$ = (yes) return $unique diff --git a/core/control_flow.nom b/core/control_flow.nom index 03861e3..b2db945 100644 --- a/core/control_flow.nom +++ b/core/control_flow.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file contains compile-time actions that define basic control flow structures like "if" statements and loops. @@ -19,23 +19,25 @@ test: if (no): barf "conditional fail" -(if $condition $if_body) compiles to " +(if $condition $if_body) compiles to (" if \($condition as lua expr) then \($if_body as lua) - end" + 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 $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) - end" + end +") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -46,29 +48,31 @@ test: assume ((1 if (yes) else 2) == 1) 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 -..all compile to: +] 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 " + return + Lua (" ((function() if \($condition as lua expr) then return \($when_true_expr as lua expr) else return \($when_false_expr as lua expr) end - end)())" + end)()) + ") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -86,17 +90,19 @@ test: go to (Loop) assume ($i == 0) -(--- $label ---) compiles to " - ::label_\(..) - ($label.stub|as lua id) if ($label.type == "Action") else (..) +(--- $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 (..) +(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: @@ -131,8 +137,8 @@ test: (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" + $lua, add "\n ::continue::" + $lua, add "\nend --while-loop" return $lua (repeat $body) parses as (repeat while (yes) $body) @@ -143,50 +149,52 @@ test: test: $nums = [] for $x in 1 to 5: - $nums|add $x + $nums, add $x assume ($nums == [1, 2, 3, 4, 5]) $nums = [] for $x in 1 to 5 via 2: - $nums|add $x + $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 + $nums, add -2 do next $inner - $nums|add $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 -..all compile to: +] 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) + $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, add "\n ::continue::" if ($body has subtree \(do next $var)): - $lua|add "\n " (\(---next $var ---) as lua) + $lua, add "\n " (\(---next $var ---) as lua) - $lua|add "\nend -- numeric for " ($var as lua identifier) " loop" + $lua, add "\nend -- numeric for " ($var as lua identifier) " loop" if ($body has subtree \(stop $var)): - $lua = (..) - Lua " + $lua = + Lua (" do -- scope for (stop \($var as lua identifier)) \$lua \(\(---stop $var ---) as lua) - end -- scope for (stop \($var as lua identifier))" + 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 $body) parses as for $var in $start to $stop via 1 $body test: @@ -200,7 +208,7 @@ test: $a = [10, 20, 30, 40, 50] $b = [] for $x in $a: - $b|add $x + $b, add $x assume ($a == $b) $b = [] for $x in $a: @@ -210,37 +218,38 @@ test: if ($x == 50): stop $x - $b|add $x + $b, add $x assume ($b == [20, 30, 40]) # For-each loop (lua's "ipairs()") (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 " + $lua = + Lua (" for \($i as lua identifier),\($var as lua identifier) in ipairs(\($iterable as lua expr)) do - " - $lua|add ($body as lua) + \; + ") + $lua, add ($body as lua) if ($body has subtree \(do next)): - $lua|add "\n ::continue::" + $lua, add "\n ::continue::" if ($body has subtree \(do next $var)): - $lua|add "\n " (\(---next $var ---) as lua) + $lua, add "\n " (\(---next $var ---) as lua) - $lua|add "\nend --for \($var as lua identifier) loop" + $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" + $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 $body) parses as for $var in $iterable at (=lua "__") $body test: - $d = {a: 10, b: 20, c: 30, d: 40, e: 50} + $d = {.a = 10, .b = 20, .c = 30, .d = 40, .e = 50} $result = [] for $k = $v in $d: if ($k == "a"): @@ -249,35 +258,36 @@ test: if ($v == 20): do next $v - $result|add "\$k = \$v" + $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) + $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, add "\n ::continue::" if ($body has subtree \(do next $key)): - $lua|add "\n " (\(---next $key ---) as lua) + $lua, add "\n " (\(---next $key ---) as lua) if ($body has subtree \(do next $value)): - $lua|add "\n " (\(---next $value ---) as lua) + $lua, add "\n " (\(---next $value ---) as lua) - $lua|add "\nend --foreach-loop" + $lua, add "\nend --foreach-loop" $stop_labels = (Lua "") if ($body has subtree \(stop $key)): - $stop_labels|add "\n" (\(---stop $key ---) as lua) + $stop_labels, add "\n" (\(---stop $key ---) as lua) if ($body has subtree \(stop $value)): - $stop_labels|add "\n" (\(---stop $value ---) as lua) + $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" + $lua, add $inner_lua $stop_labels "\nend" return $lua @@ -303,45 +313,58 @@ test: $clause = "if" $else_allowed = (yes) unless ($body.type is "Block"): - compile error at $body "'if' expected a Block, but got a \($body.type)." \ + 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: - unless (..) - (($line.type is "Action") and ((size of $line) >= 2)) and (..) + unless + (($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 \ - ..by a block." + 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." \ + 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. \ - ..Otherwise, make sure the 'else' block comes last." + 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 (" + + else + \; + ") ($action as lua) - $code|add "\nelse\n " ($action as lua) $else_allowed = (no) ..else: - $code|add $clause " " + $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) + $code, add " or " + $code, add ($line.$i as lua expr) + + $code, add (" + then + \; + ") ($action as lua) + $clause = "\nelseif" if ((size of "\$code") == 0): - compile error at $body "'if' block has an empty body." \ + 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 $code test: @@ -365,53 +388,72 @@ test: $else_allowed = (yes) define mangler unless ($body.type is "Block"): - compile error at $body "'if' expected a Block, but got a \($body.type)" \ + 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: - unless (..) - (($line.type is "Action") and ((size of $line) >= 2)) and (..) + unless + (($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" + 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." \ + 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. \ - ..Otherwise, make sure the 'else' block comes last." + 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 (" + + else + \; + ") ($action as lua) - $code|add "\nelse\n " ($action as lua) $else_allowed = (no) ..else: - $code|add $clause " " + $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) + $code, add " or " + $code, add "\(mangle "branch value") == " ($line.$i as lua expr) + + $code, add (" + then + \; + ") ($action as lua) + $clause = "\nelseif" if ((size of "\$code") == 0): - compile error at $body "'if' block has an empty body." \ + 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 (..) - Lua " + $code, add "\nend --when" + + return + Lua (" do --if % is... local \(mangle "branch value") = \($branch_value as lua expr) \$code - end -- if % is..." + end -- if % is... + ") # Do/finally -(do $action) compiles to "do\n \($action as lua)\nend -- do" +(do $action) compiles to (" + do + \($action as lua) + end -- do +") + test: $d = {} try: @@ -424,8 +466,8 @@ test: (do $action then always $final_action) compiles to: define mangler - return (..) - Lua " + return + Lua (" do local \(mangle "fell_through") = false local \(mangle "ok"), \(mangle "ret") = pcall(function() @@ -435,7 +477,8 @@ test: \($final_action as lua) if not \(mangle "ok") then error(ret, 0) end if not \(mangle "fell_through") then return ret end - end" + end + ") test: assume ((result of: return 99) == 99) @@ -450,32 +493,33 @@ test: for $2 in $: recurse $ on $2 ..else: - $flat|add $ + $flat, add $ assume (sorted $flat) == [1, 2, 3, 4, 5, 6] # Recurion control flow (for $var in recursive $structure $body) compiles to: with local compile actions: define mangler - (recurse $v on $x) compiles to (..) + (recurse $v on $x) compiles to Lua "table.insert(\(mangle "stack \($v.1)"), \($x as lua expr))" - $lua = (..) - 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)" + \($body as lua) + ") if ($body has subtree \(do next)): - $lua|add "\n ::continue::" + $lua, add "\n ::continue::" if ($body has subtree \(do next $var)): - $lua|add "\n \(\(---next $var ---) as lua)" + $lua, add "\n \(\(---next $var ---) as lua)" - $lua|add "\n end -- Recursive loop" + $lua, add "\n end -- Recursive loop" if ($body has subtree \(stop $var)): - $lua|add "\n \(\(---stop $var ---) as lua)" - $lua|add "\nend -- Recursive scope" + $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 9f6f6f4..c1dd21d 100644 --- a/core/coroutines.nom +++ b/core/coroutines.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file defines the code that creates and manipulates coroutines @@ -9,17 +9,18 @@ use "core/control_flow.nom" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test: - $co = (..) + $co = ->: yield 4 yield 5 repeat 3 times: yield 6 $nums = [] - for $ in coroutine $co: $nums|add $ + for $ in coroutine $co: + $nums, add $ assume ($nums == [4, 5, 6, 6, 6]) or barf "Coroutine iteration failed" - $d = {x: 0} - $co2 = (..) + $d = {.x = 0} + $co2 = coroutine: $d.x += 1 yield 1 @@ -29,7 +30,8 @@ test: 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 $ in coroutine $co $body) compiles to (" for \($ as lua expr) in coroutine_wrap(\($co as lua expr)) do \($body as lua) - end" + end +") diff --git a/core/errors.nom b/core/errors.nom index 07b743c..9cf7a23 100644 --- a/core/errors.nom +++ b/core/errors.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file contains basic error reporting code @@ -6,33 +6,39 @@ use "core/metaprogramming.nom" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -(barf $msg) compiles to \ +(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())" - return (..) - Lua " + + return + Lua (" if not \($condition as lua expr) then error(\(quote "\$assumption"), 0) - end" + end + ") (assume $a == $b) compiles to: lua> "local \$assumption = 'Assumption failed: '..tostring(\(\($a == $b) as nomsu))" + define mangler - return (..) - Lua " + + return + 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) end - end" + end + ") -(assume $condition or barf $message) compiles to " +(assume $condition or barf $message) compiles to (" if not \($condition as lua expr) then error(\($message as lua expr), 0) - end" + end +") test: try (barf) and if it succeeds: @@ -50,10 +56,10 @@ test: 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 " +] all compile to (" do local fell_through = false local err, erred = nil, false @@ -74,7 +80,8 @@ test: elseif erred then error(err, 0) end - end" + end +") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -87,14 +94,14 @@ test: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -(try $action) parses as (..) +(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 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) 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 6512bf5..bc9a96c 100644 --- a/core/id.nom +++ b/core/id.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # A simple UUID function based on RFC 4122: http://www.ietf.org/rfc/rfc4122.txt @@ -13,32 +13,36 @@ use "core/control_flow.nom" $NaN_surrogate = {} $nil_surrogate = {} $obj_by_id = {} -set $obj_by_id's metatable to {__mode: "v"} +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 - - --- (retry) --- - $id = (uuid) - if ($obj_by_id.$id != (nil)): go to (retry) - $self.$key = $id - $obj_by_id.$id = $key - return $id +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 + + --- (retry) --- + $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 randint (2 ^ (1 * 8 - 2)), randint (2 ^ (1 * 8)), randint (2 ^ (3 * 8)) # node randint (2 ^ (3 * 8)) + ] # Set the four most significant bits (bits 12 through 15) of the # time_hi_and_version field to the 4-bit version number from diff --git a/core/io.nom b/core/io.nom index 4bf2028..1d8bac4 100644 --- a/core/io.nom +++ b/core/io.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file contains basic input/output code @@ -7,25 +7,28 @@ use "core/metaprogramming.nom" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (say $message) compiles to: - lua> " + lua> (" if \$message.type == "Text" then return LuaCode("say(", \($message as lua expr), ");"); else return LuaCode("say(tostring(", \($message as lua expr), "));"); - end" + end + ") (say $message inline) compiles to: - lua> " + lua> (" if \$message.type == "Text" then return LuaCode("io.write(", \($message as lua expr), ")"); else return LuaCode("io.write(tostring(", \($message as lua expr), "))"); - end" + end + ") (ask $prompt) compiles to: - lua> " + 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())"); - end" + end + ") diff --git a/core/math.nom b/core/math.nom index 8ee5d62..d456bff 100644 --- a/core/math.nom +++ b/core/math.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file defines some common math literals and functions @@ -12,9 +12,11 @@ use "core/collections.nom" # Literals: test: - assume (all of [inf, NaN, pi, tau, golden ratio, e]) or barf \ + 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)" @@ -29,38 +31,47 @@ test: (($ as a number)'s meaning) = ((tonumber $)'s meaning) (($ as number)'s meaning) = ((tonumber $)'s meaning) test: - assume (..) - all of [..] + assume + all of [ abs 5, | 5 |, sqrt 5, √ 5, sine 5, cosine 5, tangent 5, arc sine 5, arc cosine 5 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 \ + +[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 \ +[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 \ +[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 (..) +externally ($n to the nearest $rounder) means =lua "(\$rounder)*math.floor((\$n / \$rounder) + .5)" # Any/all @@ -140,7 +151,7 @@ externally [product of $items, product $items] all mean: %lua::add ")" return %lua -externally [avg of $items, average of $items] all mean (..) +externally [avg of $items, average of $items] all mean (sum of $items) / (size of $items) # Min/max @@ -150,9 +161,9 @@ externally [min of $items, smallest of $items, lowest of $items] all mean: if (($best == (nil)) or ($ < $best)): $best = $ return $best -externally [..] +externally [ max of $items, biggest of $items, largest of $items, highest of $items -..all mean: +] all mean: $best = (nil) for $ in $items: if (($best == (nil)) or ($ > $best)): $best = $ @@ -162,7 +173,7 @@ test: 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) @@ -173,7 +184,7 @@ test: $best_key = $key return $best -(max of $items by $item = $value_expr) parses as (..) +(max of $items by $item = $value_expr) parses as result of: $best = (nil) $best_key = (nil) @@ -186,15 +197,18 @@ test: # Random functions externally (seed random with $) means: - lua> "math.randomseed(\$);\nfor i=1,20 do math.random(); end" + lua> (" + math.randomseed(\$); + for 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 \ +[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] \ +[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 [..] +externally [ random choice from $elements, random choice $elements, random $elements -..all mean (=lua "\$elements[math.random(#\$elements)]") +] all mean (=lua "\$elements[math.random(#\$elements)]") diff --git a/core/metaprogramming.nom b/core/metaprogramming.nom index 6d9ced4..6dea00f 100644 --- a/core/metaprogramming.nom +++ b/core/metaprogramming.nom @@ -1,11 +1,11 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.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> " +lua> (" do local mangle_index = 0 function mangler() @@ -18,13 +18,15 @@ lua> " end compile.action["define mangler"] = function(compile) return LuaCode("local mangle = mangler()") - end" + end +") -lua> " +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 + 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() @@ -34,11 +36,13 @@ lua> " if arg_lua == "..." 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*)") + "Extra arguments must come last.", "Try removing any arguments after \ + ..(*extra arguments*)") end elseif not arg_lua:is_lua_id() then compile_error_at(SyntaxTree:is_instance(arg) and arg or nil, - "This does not compile to a Lua identifier, so it can't be used as a function argument.", + "This does not compile to a Lua identifier, so it can't be used as a function \ + ..argument.", "This should probably be a Nomsu variable instead (like $x).") end lua:add(i > 1 and ", " or "", arg_lua) @@ -49,7 +53,8 @@ lua> " return lua end compile.action["->"] = compile.action["1 ->"] - compile.action["for"] = compile.action["1 ->"]" + compile.action["for"] = compile.action["1 ->"] +") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -74,7 +79,7 @@ test: asdf assume ($tmp is (nil)) or barf "compile to is leaking variables" -lua> " +lua> (" compile.action["1 compiles to"] = function(compile, \$action, \$body) local \$args = List{\(\$compile), unpack(\$action:get_args())} if \$body.type == "Text" then @@ -82,12 +87,13 @@ lua> " end return LuaCode("compile.action[", \$action:get_stub():as_lua(), "] = ", \(\($args -> $body) as lua)) - end" + end +") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ($actions all compile to $body) compiles to: - lua> " + lua> (" if \$actions.type ~= "List" then compile_error(\$actions, "This should be a list of actions.") end @@ -108,13 +114,14 @@ lua> " lua:add(") end") end end - return lua" + return lua + ") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test: (foo $x) means "outer" - with {((foo $)'s meaning)}: + with [(foo $)'s meaning]: (foo $x) means: $y = ($x + 1) return $y @@ -124,7 +131,7 @@ test: assume ((foo 1) == "outer") ($action means $body) compiles to: - lua> " + lua> (" local lua = LuaCode() if \$action.type == "MethodCall" then @@ -136,10 +143,11 @@ test: compile_error_at(\$action, "Expected an action or method call here") end lua:add(" = ", \(\($action -> $body) as lua), ";") - return lua" + return lua + ") ($actions all mean $body) compiles to: - lua> " + lua> (" local lua = \(\($actions.1 means $body) as lua) local first_def = (\$actions[1].type == "MethodCall" and LuaCode(compile(\$actions[1][1]), ".", \$actions[1]:get_stub():as_lua_id()) @@ -161,7 +169,8 @@ test: lua:add(" = ", \(\($alias_args -> $actions.1) as lua), ";") end end - return lua" + return lua + ") test: externally (baz1) means: @@ -173,23 +182,25 @@ test: assume ((baz2) == "baz2") (externally $action means $body) compiles to: - lua> " + lua> (" local lua = \(\($action means $body) as lua) lua:remove_free_vars({\$action:get_stub():as_lua_id()}) - return lua" + return lua + ") (externally $actions all mean $body) compiles to: - lua> " + lua> (" local lua = \(\($actions all mean $body) as lua) lua:remove_free_vars(table.map(\$actions, function(a) return a:get_stub():as_lua_id() end)) - return lua" + return lua + ") test: assume (((say $)'s meaning) == (=lua "say")) -($action's meaning) compiles to (Lua (($action|get stub)|as lua id)) +($action's meaning) compiles to (Lua ($action, get stub, as lua id)) test: - (swap $x and $y) parses as (..) + (swap $x and $y) parses as do: $tmp = $x $x = $y @@ -198,15 +209,17 @@ test: test: [$1, $2] = [1, 2] swap $1 and $2 - assume (($1 == 2) and ($2 == 1)) or barf \ + 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 \ + assume (($tmp == 2) and ($tmp2 == 1)) or barf .."'parse % as %' variable mangling failed." ($actions all parse as $body) compiles to: - lua> " + lua> (" local replacements = {} if \$actions.type ~= "List" then compile_error(\$actions, "This should be a list.") @@ -219,8 +232,8 @@ test: if replacements[t[1]] then return replacements[t[1]] else - return "SyntaxTree{mangle("..t[1]:as_lua().."), type="..t.type:as_lua()..", source="..tostring(\ - ..t.source):as_lua().."}" + return "SyntaxTree{mangle("..t[1]:as_lua().."), type="..t.type:as_lua()..", \ + ..source="..tostring(t.source):as_lua().."}" end elseif SyntaxTree:is_instance(t) then local ret = {} @@ -248,7 +261,8 @@ test: "local mangle = mangler()", "\\nreturn ", make_tree(\$body)) local ret = \(\($actions all compile to $new_body) as lua) - return ret" + return ret + ") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -256,25 +270,28 @@ test: #(%tree as lua expr) compiles to "compile(\(=lua "compile(\%tree, true)"), true)" externally ($tree as lua expr) means: - lua> " + 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.", + 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" + return tree_lua + ") externally [$var as lua identifier, $var as lua id] all mean: - lua> " + lua> (" local lua = \($var as lua) if not lua:text():is_a_lua_id() then compile_error(\$var, "This is supposed to be something that compiles to a valid Lua identifier.", "This should probably be a variable.") end - return lua" + return lua + ") test: (num args (*extra arguments*)) means (select "#" (*extra arguments*)) @@ -285,40 +302,46 @@ 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 (..) + +externally ($ is $kind syntax tree) means =lua "SyntaxTree:is_instance(\$) and \$.type == \$kind" -($tree with $t -> $replacement) compiles to " +($tree with $t -> $replacement) compiles to (" \($tree as lua expr):map(function(\($t as lua expr)) \(=lua "\$replacement.type == 'Block' and \($replacement as lua) or 'return '..\($replacement as lua expr)") - end)" + end) +") -externally ($tree with vars $replacements) means (..) - =lua " +externally ($tree with vars $replacements) means + =lua (" \$tree:map(function(\$t) if \$t.type == "Var" then return \$replacements[\$t[1]] end - end)" + end) + ") -(tree $tree with vars $replacements) compiles to " +(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]] end - end)" + end) +") -($tree has subtree $match_tree) compiles to " +($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)()" + end)() +") externally (match $tree with $patt) means: - lua> " + lua> (" if \$patt.type == "Var" then return Dict{[\$patt[1]]=\$tree} end if \$patt.type == "Action" and \$patt:get_stub() ~= \$tree:get_stub() then return nil end if #\$patt ~= #\$tree then return nil end @@ -333,7 +356,8 @@ externally (match $tree with $patt) means: end end end - return matches" + return matches + ") test: assume ((quote "one\n\"two\"") == "\"one\\n\\\"two\\\"\"") @@ -346,21 +370,22 @@ test: 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 (..) +externally [$ is not text, $ isn't text] all mean =lua "\(lua type of $) ~= 'string'" externally (type of $) means: - lua> " + 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(\$) if mt and mt.__type then return mt.__type end end - return lua_type" + 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] \ +[$ isn't a $type, $ isn't an $type, $ is not a $type, $ is not an $type] ..all parse as ((type of $) != $type) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -374,7 +399,7 @@ test: 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, compiled $block, $block compiled] all compile to .."compile(\($block as lua))" test: @@ -385,14 +410,15 @@ 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> " + 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, ...)))) end lua:add(" end") - return lua" + return lua + ") # Literals (yes) compiles to "true" @@ -406,14 +432,15 @@ test: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -(with local compile actions $body) compiles to " +(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) compile.action = old_action - end" + end +") externally (Nomsu version) means: return "\(Nomsu syntax version).\(core version).\(Nomsu compiler version).\(lib version)" diff --git a/core/operators.nom b/core/operators.nom index 1bb9f0b..8dfac09 100644 --- a/core/operators.nom +++ b/core/operators.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file contains definitions of operators like "+" and "and". @@ -16,7 +16,7 @@ test: ($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 isn't $b, $a is not $b, $a not= $b, $a != $b] all compile to .."(\($a as lua expr) ~= \($b as lua expr))" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -34,7 +34,7 @@ test: # Variable assignment operator ($var = $value) compiles to: - lua> " + lua> (" local lua = LuaCode() if \$var.type == "List" then for i, \$assignment in ipairs(\$var) do @@ -50,8 +50,8 @@ test: 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.") + "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 if i > 1 then lua:add(", ") end @@ -70,7 +70,8 @@ test: end lua:add(' = ', \($value as lua expr)) end - return lua" + return lua + ") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -89,7 +90,7 @@ test: $foozle = "inner" $y = "inner" set global x local y - assume (($foozle == "inner") and ($y == "outer")) or barf \ + assume (($foozle == "inner") and ($y == "outer")) or barf .."'with external' failed." (with external $externs $body) compiles to: @@ -99,7 +100,7 @@ test: test: [$x, $y] = [1, 2] - with {$z, $x: 999}: + with [$z, $x = 999]: assume $z == (nil) $z = 999 assume ($z == 999) or barf "'with' failed." @@ -108,35 +109,30 @@ test: 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) - if not target_lua:text():is_lua_id() then - compile_error_at(\$target, "Invalid target for 'with' scope assignment.", - "This should be either a variable or an action's meaning.") + lua> (" + local \$defs = LuaCode() + for i, \$item in ipairs(\$assignments) do + if i > 1 then \$defs:add("\\n") end + local item_lua = \($item as lua) + if \$item.type == 'Action' and \$item.stub == '1 =' then + item_lua:remove_free_vars(item_lua.free_vars) end - local value_lua = \$value and \($value as lua) or "nil" - if i > 1 then - lhs:add(", ") - rhs:add(", ") - end - lhs:add(target_lua) - rhs:add(value_lua) - vars[i] = target_lua:text() + \$defs:add("local ", item_lua, ";") end - \$lua:remove_free_vars(vars) - \$lua:prepend("local ", lhs, " = ", rhs, ";\\n")" - return (Lua "do\n \$lua\nend -- 'with' block") + ") + return + Lua (" + do + \$defs + \($body as lua) + end -- '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 wrapped around $y, $x mod $y] all compile to .."((\($x as lua expr)) % (\($y as lua expr)))" # 3-part chained comparisons @@ -147,9 +143,11 @@ test: external $calls = ($calls + 1) return 1 assume (0 <= (one) <= 2) or barf "Three-way chained comparison failed." - assume ($calls == 1) or barf \ + 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) @@ -184,30 +182,31 @@ test: 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 \ +[$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 \ +[$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 \ +[$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 \ +[$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 \ +[$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 LSHIFT $shift, $x << $shift] all compile to .."(\($x as lua expr) << \($shift as lua expr))" -[$x RSHIFT $shift, $x >> $shift] all compile to \ +[$x RSHIFT $shift, $x >> $shift] all compile to .."(\($x as lua expr) >> \($shift as lua expr))" lua> "end" @@ -220,8 +219,8 @@ test: (not $) compiles to "(not \($ as lua expr))" test: assume ((size of [1, 2, 3]) == 3) - assume ((# [1, 2, 3]) == 3) -[# $list, size of $list] all compile to "(#\($list as lua expr))" + assume ((#[1, 2, 3]) == 3) +[#$list, size of $list] all compile to "(#\($list as lua expr))" ($list is empty) compiles to "(#\($list as lua expr) == 0)" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/core/text.nom b/core/text.nom index 8b500f7..b5b22b3 100644 --- a/core/text.nom +++ b/core/text.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file contains some definitions of text escape sequences, including ANSI console color codes. @@ -12,16 +12,22 @@ use "core/control_flow.nom" test: assume "\[1, 2, 3]" == "[1, 2, 3]" assume "foo = \(1 + 2)!" == "foo = 3!" - assume "one\ntwo" == "one\ntwo" + assume (" + one + two + ") == (" + one + two + ") 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", ""] + 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: @@ -31,15 +37,16 @@ test: ($expr for $match in $text matching $patt) compiles to: define mangler - return (..) - Lua " + return + 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) end return \(mangle "comprehension") - end)()" + end)() + ") test: assume "\n" == (newline) @@ -49,15 +56,16 @@ test: externally ($num as hex) means: if ($num < 0): - return ("-0x%X"|formatted with (- $num)) + return ("-0x%X", formatted with (- $num)) ..else: - return ("0x%X"|formatted with $num) + return ("0x%X", formatted with $num) # Text literals -$escapes = {..} - nl: "\n", newline: "\n", tab: "\t", bell: "\a", cr: "\r", "carriage return": "\r" - backspace: "\b", "form feed": "\f", formfeed: "\f", "vertical tab": "\v" +$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)}: + with [$lua = (Lua (quote $str))]: $compile.action.$name = (-> $lua) diff --git a/examples/how_do_i.nom b/examples/how_do_i.nom index a296849..cc1f699 100644 --- a/examples/how_do_i.nom +++ b/examples/how_do_i.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # How do I... # Write a comment? Put a # and go till the end of the line # How do I write a multi-line comment? @@ -35,7 +35,7 @@ $foobar += 1 # How do I define a multi-line string? # In Nomsu, the name "text" is used, rather than "string", and multi-line text looks like: -$multi_text = " +$multi_text = (" Start with a quotation mark, then put indented lines below it. The indented lines will not include the indentation, except when the lines are indented more than 4 spaces relative to the original quote mark. @@ -43,10 +43,11 @@ $multi_text = " But this line will have no leading spaces. The text will continue until a closing quotation at the end of the text's - indentation level." + indentation level. +") # How do I put values inside text? (AKA string formatting, string interpolation) -say " +say (" Text can contain a backslash followed by a variable, list, dict, or parenthesized expression. This escaped value will be converted to readable text, like so: The value of %foobar is \$foobar, isn't that nice? @@ -59,12 +60,13 @@ say " Or, two backlashes will be treated as a single backslash, no matter what follows, like this: \\%foobar <- won't insert any values - If you need to split a long line without inserting a newline, you can end a line with backslash and \ - ..start the next line with two periods, like that. + If you need to split a long line without inserting a newline, you can end a line with backslash \ + ..and start the next line with two periods, like that. - Similarly, you can put a long interpolated indented value like: \(..) + Similarly, you can put a long interpolated indented value like: \( 1000 + 2000 + 3000 + 4000 + 5000 + 6000 + 7000 + 8000 + 9000 - ..between a backslash and two periods." + ) between a backslash and two periods. +") say "Single-line text can contain escape sequences like \", \\, \000, and \n" # How do I define a list? @@ -72,9 +74,10 @@ $my_list = ["first", "second", "third", 4] # Really long lists can use [..] followed by a bunch of indented values delimited by commas and/or newlines -$my_really_long_list = [..] +$my_really_long_list = [ 10000, 20000, 30000, 40000, 50000, 60000, 70000, 80000, 90000, 100000, 110000 120000, 130000, 140000, 150000, 160000, 170000 +] # How do I use a list? # Lists are 1-indexed because they're implemented as Lua tables, so this prints "first" @@ -84,13 +87,13 @@ say $my_list.1 $my_list.1 = "ONE!!!" # Or appended to/removed from: -$my_list|add "extra item" -$my_list|pop +$my_list, add "extra item" +$my_list, pop # How do I define a dictionary/hash map? One-word text keys don't need quotes, otherwise the key is an expression. If the expression is more complex than a literal, it needs parentheses: -$my_dict = {x: 101, y: 2, "how many bottles": 99, 653: 292, (5 + 6): 11} +$my_dict = {.x = 101, .y = 2, ."my value" = 99, .653 = 292, .(5 + 6) = 11} # How do I use a dict? # Dicts are also implemented as Lua tables, so they're accessed and modified the same way as lists @@ -200,12 +203,12 @@ say both "Hello" and also "world!" say (first fibonacci above 10) # Actions can have aliases, which may or may not have the arguments in different order -[..] +[ I hate $worse_things more than $better_things I think $worse_things are worse than $better_things I like $better_things more than $worse_things -..all mean: - say "\($better_things|capitalized) rule and \$worse_things drool!" +] all mean: + say "\($better_things, capitalized) rule and \$worse_things drool!" I like "dogs" more than "cats" I think "chihuahuas" are worse than "corgis" @@ -244,8 +247,9 @@ say (2 + 3) say (2 + 3) # If you need to keep going after an indented region, you can start the next line with ".." -say both "Very long first argument that needs its own line" and also \ +say both "Very long first argument that needs its own line" and also .."short second arg" + (my favorite number) means (21 + 2) # This can be nested: @@ -313,7 +317,7 @@ say (best of [2, -3, 4, -8] according to (($ squared)'s meaning)) # But nomsu was designed with flexible alternatives that are often better than passing functions. For example, instead of calling a key function on every item, you could instead define a macro that gives you a value based on an inlined expression: -(best of $items where $item has score $key_expr) parses as (..) +(best of $items where $item has score $key_expr) parses as result of: $best = (nil) $best_key = (nil) diff --git a/lib/base64.nom b/lib/base64.nom index 6f22afc..44d68cb 100644 --- a/lib/base64.nom +++ b/lib/base64.nom @@ -1,17 +1,17 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file defines actions for encoding/decoding base 64, as specified in: https://tools.ietf.org/html/rfc4648 $b64_str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" -$b64_chars = [: for $ in 1 to (size of $b64_str): add ($b64_str|character $)] +$b64_chars = [: for $ in 1 to (size of $b64_str): add ($b64_str, character $)] $reverse_b64 = {: for $c in $b64_chars at $i: add $c = ($i - 1)} $reverse_b64."=" = 64 -set $reverse_b64's metatable to {__index: -> 0} +set $reverse_b64's metatable to {.__index = (-> 0)} test: $cases = ["", "Zg==", "Zm8=", "Zm9v", "Zm9vYg==", "Zm9vYmE=", "Zm9vYmFy"] for $len = $encoded in $cases: - $plain = ("foobar"|from 1 to ($len - 1)) + $plain = ("foobar", from 1 to ($len - 1)) assume (base64 $plain) == $encoded assume (base64 decode $encoded) == $plain @@ -19,32 +19,32 @@ externally [base64 $str, base64 encode $str, $str base64] all mean: $chars = [] for $i in 1 to (size of $str) via 3: $bytes = [=lua "\$str:byte(\$i, \($i + 2))"] - $chars|add $b64_chars.((($bytes.1 & 252) >> 2) + 1) + $chars, add $b64_chars.((($bytes.1 & 252) >> 2) + 1) if (size of $bytes) is: 3: - $chars|add $b64_chars.((($bytes.1 & 3) << 4) + (($bytes.2 & 240) >> 4) + 1) - $chars|add $b64_chars.((($bytes.2 & 15) << 2) + (($bytes.3 & 192) >> 6) + 1) - $chars|add $b64_chars.(($bytes.3 & 63) + 1) + $chars, add $b64_chars.((($bytes.1 & 3) << 4) + (($bytes.2 & 240) >> 4) + 1) + $chars, add $b64_chars.((($bytes.2 & 15) << 2) + (($bytes.3 & 192) >> 6) + 1) + $chars, add $b64_chars.(($bytes.3 & 63) + 1) 2: - $chars|add $b64_chars.((($bytes.1 & 3) << 4) + (($bytes.2 & 240) >> 4) + 1) - $chars|add $b64_chars.((($bytes.2 & 15) << 2) + 1) - $chars|add "=" + $chars, add $b64_chars.((($bytes.1 & 3) << 4) + (($bytes.2 & 240) >> 4) + 1) + $chars, add $b64_chars.((($bytes.2 & 15) << 2) + 1) + $chars, add "=" 1: - $chars|add $b64_chars.((($bytes.1 & 3) << 4) + 1) - $chars|add "=" - $chars|add "=" - return ($chars|joined) + $chars, add $b64_chars.((($bytes.1 & 3) << 4) + 1) + $chars, add "=" + $chars, add "=" + return ($chars, joined) externally (chr $) means (=lua "string.char(\$)") externally [decode base64 $str, $str base64 decoded, base64 decode $str] all mean: $chars = [] for $i in 1 to (size of $str) via 4: - $indices = [: for $j in $i to ($i + 3): add $reverse_b64.($str|character $j)] - $chars|add (chr (($indices.1 << 2) + (($indices.2 & 48) >> 4))) - if (($str|character ($i + 2)) == "="): stop - $chars|add (chr ((($indices.2 & 15) << 4) + (($indices.3 & 60) >> 2))) - if (($str|character ($i + 3)) == "="): stop - $chars|add (chr ((($indices.3 & 3) << 6) + $indices.4)) - return ($chars|joined) + $indices = [: for $j in $i to ($i + 3): add $reverse_b64.($str, character $j)] + $chars, add (chr (($indices.1 << 2) + (($indices.2 & 48) >> 4))) + if (($str, character ($i + 2)) == "="): stop + $chars, add (chr ((($indices.2 & 15) << 4) + (($indices.3 & 60) >> 2))) + if (($str, character ($i + 3)) == "="): stop + $chars, add (chr ((($indices.3 & 3) << 6) + $indices.4)) + return ($chars, joined) diff --git a/lib/consolecolor.nom b/lib/consolecolor.nom index 55feade..1f5e926 100644 --- a/lib/consolecolor.nom +++ b/lib/consolecolor.nom @@ -1,22 +1,24 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file defines actions for ANSI console color escape codes. test: $ = (bright "\(green)Color test passed.") -$colors = {..} - normal: 0, "reset color": 0, bright: 1, bold: 1, dim: 2, italic: 3, underscore: 4 - "slow blink": 5, "fast blink": 6, reverse: 7, inverse: 7, inverted: 7 - hidden: 8 +$colors = { + .normal = 0, ."reset color" = 0, .bright = 1, .bold = 1, .dim = 2, .italic = 3 + .underscore = 4, ."slow blink" = 5, ."fast blink" = 6, .reverse = 7, .inverse = 7 + .inverted = 7, .hidden = 8 # There's some other codes, but they're not currently implemented - black: 30, red: 31, green: 32, yellow: 33, blue: 34, magenta: 35, cyan: 36 - white: 37, "on black": 40, "on red": 41, "on green": 42, "on yellow": 43 - "on blue": 44, "on magenta": 45, "on cyan": 46, "on white": 47 + .black = 30, .red = 31, .green = 32, .yellow = 33, .blue = 34, .magenta = 35 + .cyan = 36, .white = 37, ."on black" = 40, ."on red" = 41, ."on green" = 42 + ."on yellow" = 43, ."on blue" = 44, ."on magenta" = 45, ."on cyan" = 46 + ."on white" = 47 +} for $name = $colornum in $colors: $colornum = "\$colornum" - $compile.action.$name = (..) + $compile.action.$name = for ($compile $text): if $text: return (Lua "('\\027[\($colornum)m'..\($text as lua expr)..'\\027[0m')") diff --git a/lib/file_hash.nom b/lib/file_hash.nom index dd3d520..a45b684 100644 --- a/lib/file_hash.nom +++ b/lib/file_hash.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file defines some actions for hashing files and looking up files by hash. @@ -10,19 +10,21 @@ use "lib/base64.nom" lua> "local \$use_sha1, \$hashlib = pcall(require, 'openssl.digest')" test: assume (hash "hello world") == (hash "hello world") - assume ((hash "hello world") != (hash "goodbye")) or barf " + assume ((hash "hello world") != (hash "goodbye")) or barf (" Hash collision: (hash "hello world") = \(hash "hello world") - (hash "goodbye") = \(hash "goodbye")" + (hash "goodbye") = \(hash "goodbye") + ") - assume (..) - (..) - hash " + assume + ( + hash (" This is a really long string meant to stress test the hashing function and - ensure that it's not overflowing with long inputs." - ..!= "inf" + ensure that it's not overflowing with long inputs. + ") + ) != "inf" - assume ((hash "\000") != (hash "\000\000\000\000\000")) or barf \ + assume ((hash "\000") != (hash "\000\000\000\000\000")) or barf .."Incorrect hashing of null strings" if $use_sha1: @@ -34,9 +36,13 @@ if $use_sha1: return (base64 $hash) ..else: # TODO: remove warning? - say "\027[31;1mWARNING: OpenSSL module not found. Defaulting to a non-cryptographically secure hash function.\027[0m" + say (" + \027[31;1mWARNING: OpenSSL module not found. Defaulting to a non-cryptographically secure \ + ..hash function.\027[0m + ") + externally (hash $) means: - $bytes = ($|bytes) + $bytes = ($, bytes) $hash = ($bytes.1 << 7) for $i in 2 to (size of $bytes): $hash = ((1000003 * $hash) ~ $bytes.$i) diff --git a/lib/object.nom b/lib/object.nom index 6f16410..72e1588 100644 --- a/lib/object.nom +++ b/lib/object.nom @@ -1,14 +1,16 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file contains the implementation of an Object-Oriented programming system. -$globals.METAMETHOD_MAP = {..} - "as text": "__tostring", "clean up": "__gc", "+ 1": "__add", "- 1": "__sub" - "* 1": "__mul", "/ 1": "__div", "-": "__unm", "// 1": "__idiv", "mod 1": "__mod" - "^ 1": "__pow", "& 1": "__band", "| 1": "__bor", "~ 1": "__bxor", "~": "__bnot" - "<< 1": "__bshl", ">> 1": "__bshr", "== 1": "__eq", "< 1": "__lt", "<= 1": "__le" - "set 1 = 2": "__newindex", size: "__len", iterate: "__ipairs" - "iterate all": "__pairs" +$globals.METAMETHOD_MAP = { + ."as text" = "__tostring", ."clean up" = "__gc", ."+ 1" = "__add" + ."- 1" = "__sub", ."* 1" = "__mul", ."/ 1" = "__div", ."-" = "__unm" + ."// 1" = "__idiv", ."mod 1" = "__mod", ."^ 1" = "__pow", ."& 1" = "__band" + ."| 1" = "__bor", ."~ 1" = "__bxor", ."~" = "__bnot", ."<< 1" = "__bshl" + .">> 1" = "__bshr", ."== 1" = "__eq", ."< 1" = "__lt", ."<= 1" = "__le" + ."set 1 = 2" = "__newindex", .size = "__len", .iterate = "__ipairs" + ."iterate all" = "__pairs" +} test: object (Dog): @@ -18,45 +20,45 @@ test: my action [bark, woof]: $barks = [: for $ in 1 to $me.barks: add "Bark!"] - return ($barks|joined with " ") + return ($barks, joined with " ") my action [get pissed off]: $me.barks += 1 - $d = (Dog {barks: 2}) + $d = (Dog {.barks = 2}) assume (type of $d) == "Dog" assume ($d is a "Dog") assume $d.barks == 2 - assume (($d|bark) == "Bark! Bark!") - assume (($d|woof) == "Bark! Bark!") - $d|get pissed off + assume (($d, bark) == "Bark! Bark!") + assume (($d, woof) == "Bark! Bark!") + $d, get pissed off assume ($d.barks == 3) - assume (($d|bark) == "Bark! Bark! Bark!") + assume (($d, bark) == "Bark! Bark! Bark!") assume ($d.genus == "Canus") assume ("\($d.class)" == "Dog") assume ($d.genus == "Canus") assume ($d.barks == 3) $d2 = (Dog {}) assume ($d2.barks == 0) or barf "Default initializer failed" - with {$d: Dog {barks: 1}}: - assume (($d|bark) == "Bark!") + with [$d = (Dog {.barks = 1})]: + assume (($d, bark) == "Bark!") object (Corgi) extends (Dog): my action [sploot] "splooted" my action [bark, woof]: $barks = [: for $ in 1 to $me.barks: add "Yip!"] - return ($barks|joined with " ") + return ($barks, joined with " ") $corg = (Corgi {}) assume ($corg.barks == 0) - with {$d: Corgi {barks: 1}}: - assume (($d|sploot) == "splooted") or barf "subclass method failed" - assume (($d|bark) == "Yip!") or barf "inheritance failed" - assume (($d|woof) == "Yip!") + with [$d = (Corgi {.barks = 1})]: + assume (($d, sploot) == "splooted") or barf "subclass method failed" + assume (($d, bark) == "Yip!") or barf "inheritance failed" + assume (($d, woof) == "Yip!") - with {$d: Dog {barks: 2}}: - assume (($d|bark) == "Bark! Bark!") + with [$d = (Dog {.barks = 2})]: + assume (($d, bark) == "Bark! Bark!") (my action $actions $body) compiles to: - lua> " + lua> (" local fn_name = \$actions[1].stub:as_lua_id() local \$args = List(\$actions[1]:get_args()) table.insert(\$args, 1, \(\$me)) @@ -73,19 +75,20 @@ test: lua:add(\(\($alias_args -> $actions.1) as lua)) end end - return lua" + return lua + ") (object $classname extends $parent $class_body) compiles to: unless ($classname.type == "Action"): - compile error at $classname \ + compile error at $classname .."Expected this to be an action, not a \$classname.type" for $ in $classname: unless ($ is text): compile error at $ "Class names should not have arguments." - return (..) - Lua " + return + Lua (" do local class = {name=\(quote $classname.stub)} class.__type = class.name @@ -109,7 +112,8 @@ test: for stub,metamethod in pairs(globals.METAMETHOD_MAP) do class[metamethod] = class[stub:as_lua_id()] end - end" + end + ") -(object $classname $class_body) parses as (..) +(object $classname $class_body) parses as object $classname extends (nil) $class_body @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file defines some actions that interact with the operating system and filesystem. @@ -12,39 +12,44 @@ externally (files for $path) means: return $files externally (nomsu files for $path) means: - for $nomsupath in ($package.nomsupath|all matches of "[^;]+"): + for $nomsupath in ($package.nomsupath, all matches of "[^;]+"): $files = (files for "\($nomsupath)/\$path") if $files: return $files externally (sh> $cmd) means: - lua> " + lua> (" local result = io.popen(\$cmd) local contents = result:read("*a") result:close() - return contents" + return contents + ") test: read file "lib/os.nom" externally (read file $filename) means (=lua "Files.read(\$filename)") -externally [..] +externally [ write to file $filename $text, to file $filename write $text write $text to file $filename -..all mean: +] all mean: assume ($filename != "stdin") or barf "Cannot write to stdin" - lua> "local file = io.open(\$filename, 'w')\nfile:write(\$text)\nfile:close()" + lua> (" + local file = io.open(\$filename, 'w') + file:write(\$text) + file:close() + ") externally (source lines of $tree) means: $source = ($tree.source if ($tree is syntax tree) else $tree) $file = (read file $source.filename) - return (..) - [..] + return + [ : - for $ in ($file|line number at $source.start) to (..) - $file|line number at $source.stop - ..: add ($file|line $) - ..|joined with "\n" + for $ in ($file, line number at $source.start) to + $file, line number at $source.stop + ..: add ($file, line $) + ], joined with "\n" externally (spoof file $text) means ($Files.spoof $text) externally (spoof file $filename = $text) means ($Files.spoof $filename $text) diff --git a/lib/things.nom b/lib/things.nom index de51683..e10b9eb 100644 --- a/lib/things.nom +++ b/lib/things.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # A library for simple object oriented programming. @@ -6,86 +6,91 @@ test: an (Empty) is a thing a (Dog) is a thing: [$it, $its] = [Dog, Dog] - ($its|set up) means: + ($its, set up) means: $its.barks or= 0 - [$its|bark, $its|woof] all mean: + [($its, bark), ($its, woof)] all mean: $barks = [: for $ in 1 to $its.barks: add "Bark!"] - return ($barks|joined with " ") + return ($barks, joined with " ") - ($it|gets pissed off) means: $it.barks += 1 + ($it, gets pissed off) means: $it.barks += 1 (Dog).genus = "Canus" - $d = (a Dog with {barks: 2}) + $d = (a Dog with {.barks = 2}) assume "\$d" == "Dog {barks: 2}" assume (type of $d) == "Dog" assume ($d is a "Dog") assume $d.barks == 2 - assume (($d|bark) == "Bark! Bark!") - assume (($d|woof) == "Bark! Bark!") - $d|gets pissed off + assume (($d, bark) == "Bark! Bark!") + assume (($d, woof) == "Bark! Bark!") + $d, gets pissed off assume ($d.barks == 3) - assume (($d|bark) == "Bark! Bark! Bark!") + assume (($d, bark) == "Bark! Bark! Bark!") assume ($d.genus == "Canus") assume ("\($d.class)" == "Dog") assume ($d.genus == "Canus") assume ($d.barks == 3) $d2 = (a Dog) assume ($d2.barks == 0) or barf "Default initializer failed" - with {$d: a Dog with {barks: 1}}: - assume (($d|bark) == "Bark!") + with [$d = (a Dog with {.barks = 1})]: + assume (($d, bark) == "Bark!") a (Corgi) is a thing: [$it, $its] = [Corgi, Corgi] $it [set up, gets pissed off] like a (Dog) - ($it|as text) means "Dogloaf \{: for $k = $v in $it: add $k = $v}" - ($its|sploot) means "sploooot" - [$its|bark, $its|woof] all mean: + ($it, as text) means "Dogloaf \{: for $k = $v in $it: add $k = $v}" + ($its, sploot) means "sploooot" + [($its, bark), ($its, woof)] all mean: $barks = [: for $ in 1 to $its.barks: add "Yip!"] - return ($barks|joined with " ") + return ($barks, joined with " ") $corg = (a Corgi) assume ($corg.barks == 0) assume "\$corg" == "Dogloaf {barks: 0}" - with {$d: a Corgi with {barks: 1}}: - assume (($d|sploot) == "sploooot") or barf "subclass method failed" - assume (($d|bark) == "Yip!") or barf "inheritance failed" - assume (($d|woof) == "Yip!") + with [$d = (a Corgi with {.barks = 1})]: + assume (($d, sploot) == "sploooot") or barf "subclass method failed" + assume (($d, bark) == "Yip!") or barf "inheritance failed" + assume (($d, woof) == "Yip!") - with {$d: a Dog with {barks: 2}}: - assume (($d|bark) == "Bark! Bark!") + with [$d = (a Dog with {.barks = 2})]: + assume (($d, bark) == "Bark! Bark!") - a (Vec) is a thing with {x, y}: + a (Vec) is a thing with {.x, .y}: $its = (Vec) - ($its|+ $other) means (Vec {x: $its.x + $other.x, y: $its.y + $other.y}) + ($its, + $other) means (Vec {.x = ($its.x + $other.x), .y = ($its.y + $other.y)}) - assume ((Vec {x: 1, y: 2}) + (Vec {x: 10, y: 10})) == (Vec {x: 11, y: 12}) - assume (((Vec {x: 1, y: 2}) + (Vec {x: 10, y: 10})) != (Vec {x: 0, y: 0})) + assume ((Vec {.x = 1, .y = 2}) + (Vec {.x = 10, .y = 10})) == + Vec {.x = 11, .y = 12} + + assume + ((Vec {.x = 1, .y = 2}) + (Vec {.x = 10, .y = 10})) != (Vec {.x = 0, .y = 0}) -[..] +[ $it can $actions like a $class, $it can $actions like an $class $it has $actions like a $class, $it has $actions like an $class $it $actions like a $class, $it $actions like an $class -..all compile to: +] all compile to: $lua = (Lua "") $class_expr = ($class as lua expr) $lines = [] for $a in $actions: - $lines| - add "\($it as lua expr).\($a.stub|as lua id) = \$class_expr.\($a.stub|as lua id)" - $lua|add $lines joined with "\n" + $lines, + add "\($it as lua expr).\($a.stub, as lua id) = \$class_expr.\($a.stub, as lua id)" + $lua, add $lines joined with "\n" return $lua -$METAMETHOD_MAP = {..} - "as text": "__tostring", "clean up": "__gc", "+": "__add", "-": "__sub" - "*": "__mul", "/": "__div", negative: "__unm", "//": "__idiv", mod: "__mod" - "^": "__pow", "&": "__band", "|": "__bor", "~": "__bxor", "~": "__bnot" - "<<": "__bshl", ">>": "__bshr", "==": "__eq", "<": "__lt", "<=": "__le" - "set 1 =": "__newindex", size: "__len", iterate: "__ipairs", "iterate all": "__pairs" +$METAMETHOD_MAP = { + ."as text" = "__tostring", ."clean up" = "__gc", ."+" = "__add", ."-" = "__sub" + ."*" = "__mul", ."/" = "__div", .negative = "__unm", ."//" = "__idiv" + .mod = "__mod", ."^" = "__pow", ."&" = "__band", ."|" = "__bor", ."~" = "__bxor" + ."~" = "__bnot", ."<<" = "__bshl", .">>" = "__bshr", ."==" = "__eq" + ."<" = "__lt", ."<=" = "__le", ."set 1 =" = "__newindex" + .size = "__len", .iterate = "__ipairs", ."iterate all" = "__pairs" +} (($ as text like a dict)'s meaning) = ({}'s metatable).__tostring -externally (a class named $classname with $members ((initialize $it)'s meaning)) \ +externally (a class named $classname with $members ((initialize $it)'s meaning)) ..means: - $class = {__type: $classname} + $class = {.__type = $classname} $class.__index = $class $class.class = $class $class.__tostring = ($ -> "\($.__type) \($ as text like a dict)") @@ -93,45 +98,50 @@ externally (a class named $classname with $members ((initialize $it)'s meaning)) $class.__len = ({}'s metatable).__len if $members: $class.__members = $members - $class.__newindex = (..) + $class.__newindex = for ($its $key = $value): if $members.$key: rawset $its $key $value ..else: barf "Cannot set \$key, it's not one of the allowed member fields." - set $class's metatable to {..} - __tostring: $class -> $class.__type, __call: for ($class with $initial_values): - if ($initial_values == (nil)): return $class - set $initial_values's metatable to $class - if $initial_values.set_up: - $initial_values|set up - return $initial_values + set $class's metatable to { + .__tostring = ($class -> $class.__type), .__call = ( + for ($class with $initial_values): + if ($initial_values == (nil)): return $class + set $initial_values's metatable to $class + if $initial_values.set_up: + $initial_values, set up + return $initial_values + ) + } if ((initialize)'s meaning): initialize $class for $stub = $metamethod in $METAMETHOD_MAP: - if $class.($stub|as lua id): - $class.$metamethod = $class.($stub|as lua id) + if $class.($stub, as lua id): + $class.$metamethod = $class.($stub, as lua id) return $class -[..] +[ a $classname is a thing with $members $class_body an $classname is a thing with $members $class_body -..all compile to: - $class_id = ($classname.stub|as lua id) +] all compile to: + $class_id = ($classname.stub, as lua id) if $class_body: $body_lua = ($class_body as lua) - $body_lua|remove free vars [$class_id] - $body_lua|declare locals + $body_lua, remove free vars [$class_id] + $body_lua, declare locals - return (..) - Lua " + return + Lua (" \$class_id = a_class_named_1_with(\(quote $classname.stub), \($members as lua)\((Lua ", function(\$class_id)\n \$body_lua\nend") if $class_body else "")\ ..) - a_\$class_id = function(initial_values) return \($classname.stub|as lua id)(initial_values or {}) end - an_\$class_id, a_\($class_id)_with, an_\($class_id)_with = a_\$class_id, a_\$class_id, a_\$class_id" + a_\$class_id = function(initial_values) return \($classname.stub, as lua id)(initial_values \ + ..or {}) end + an_\$class_id, a_\($class_id)_with, an_\($class_id)_with = a_\$class_id, a_\$class_id, a_\$class_id + ") -[a $classname is a thing $class_body, an $classname is a thing] all parse as (..) +[a $classname is a thing $class_body, an $classname is a thing] all parse as a $classname is a thing with (nil) $class_body diff --git a/nomsu_decompiler.lua b/nomsu_decompiler.lua index efa7ece..5a7cc02 100644 --- a/nomsu_decompiler.lua +++ b/nomsu_decompiler.lua @@ -238,7 +238,10 @@ local tree_to_nomsu tree_to_nomsu = function(tree) local nomsu = NomsuCode:from(tree.source) local recurse - recurse = function(t) + recurse = function(t, argnum) + if argnum == nil then + argnum = nil + end local space = MAX_LINE - nomsu:trailing_line_len() local try_inline = true for subtree in coroutine.wrap(function() @@ -268,7 +271,13 @@ tree_to_nomsu = function(tree) local indented = tree_to_nomsu(t) if t.type == "Action" or t.type == "MethodCall" then if indented:is_multiline() then - return NomsuCode:from(t.source, "(\n ", indented, "\n)") + if argnum == nil or argnum == 1 then + return NomsuCode:from(t.source, "(\n ", indented, "\n)") + else + return NomsuCode:from(t.source, "\n ", indented) + end + elseif argnum and argnum > 1 then + return NomsuCode:from(t.source, "\n ", indented) else indented:parenthesize() end @@ -287,7 +296,7 @@ tree_to_nomsu = function(tree) end indented_lines = _accum_0 end - if inline_nomsu and #indented_lines == (t.type == 'Block' and 2 or 3) and nomsu:trailing_line_len() <= 8 then + if inline_nomsu and #indented_lines == ((t.type == 'Block' or t.type == 'Action' or t.type == 'MethodCall') and 2 or 3) and nomsu:trailing_line_len() <= 8 then return inline_nomsu elseif inline_nomsu and t.type == "Text" and #indented_lines <= 3 and (#inline_nomsu:text() - 2 < MAX_LINE + 4 or #inline_nomsu:text() <= space or #inline_nomsu:text() <= 8) then return inline_nomsu @@ -342,7 +351,7 @@ tree_to_nomsu = function(tree) next_space = " " end num_args = num_args + 1 - local bit_nomsu = recurse(bit) + local bit_nomsu = recurse(bit, i) if bit.type == "Block" then if not bit_nomsu:is_multiline() and #bit_nomsu:text() > nomsu:trailing_line_len() * GOLDEN_RATIO and #bit_nomsu:text() > 8 then bit_nomsu = tree_to_nomsu(bit) @@ -351,16 +360,16 @@ tree_to_nomsu = function(tree) if next_space == " " and #bit_nomsu:text() < MAX_LINE then next_space = "\n.." elseif bit.type == 'Action' or bit.type == "MethodCall" then - bit_nomsu = NomsuCode:from(bit.source, "(\n ", tree_to_nomsu(bit), "\n)") + bit_nomsu = NomsuCode:from(bit.source, "\n ", tree_to_nomsu(bit)) else bit_nomsu = tree_to_nomsu(bit) end end - if not (next_space == " " and bit_nomsu:text():match("^:")) then + if not (next_space == " " and bit_nomsu:text():match("^[:\n]")) then nomsu:add(next_space) end nomsu:add(bit_nomsu) - next_space = (bit.type == 'Block' and bit_nomsu:is_multiline()) and "\n.." or " " + next_space = (bit.type == 'Block' or (i > 1 and (bit.type == 'Action' or bit.type == 'MethodCall')) and bit_nomsu:is_multiline()) and "\n.." or " " _continue_0 = true until true if not _continue_0 then @@ -531,7 +540,8 @@ tree_to_nomsu = function(tree) end nomsu:add(tree_to_nomsu(key)) if value then - nomsu:add(" = ", recurse(value)) + local value_nomsu = recurse(value) + nomsu:add(" = ", value_nomsu) end return nomsu elseif "Comment" == _exp_0 then diff --git a/nomsu_decompiler.moon b/nomsu_decompiler.moon index 9747aa8..b54553d 100644 --- a/nomsu_decompiler.moon +++ b/nomsu_decompiler.moon @@ -185,7 +185,7 @@ tree_to_nomsu = (tree)-> nomsu = NomsuCode\from(tree.source) -- For concision: - recurse = (t)-> + recurse = (t, argnum=nil)-> space = MAX_LINE - nomsu\trailing_line_len! try_inline = true for subtree in coroutine.wrap(-> (t\map(coroutine.yield) and nil)) @@ -206,11 +206,16 @@ tree_to_nomsu = (tree)-> indented = tree_to_nomsu(t) if t.type == "Action" or t.type == "MethodCall" if indented\is_multiline! - return NomsuCode\from(t.source, "(\n ", indented, "\n)") + if argnum == nil or argnum == 1 + return NomsuCode\from(t.source, "(\n ", indented, "\n)") + else + return NomsuCode\from(t.source, "\n ", indented) + elseif argnum and argnum > 1 + return NomsuCode\from(t.source, "\n ", indented) else indented\parenthesize! indented_lines = [line for line in *indented\text!\lines! when line\match("%S")] - if inline_nomsu and #indented_lines == (t.type == 'Block' and 2 or 3) and nomsu\trailing_line_len! <= 8 + if inline_nomsu and #indented_lines == ((t.type == 'Block' or t.type == 'Action' or t.type == 'MethodCall') and 2 or 3) and nomsu\trailing_line_len! <= 8 return inline_nomsu elseif inline_nomsu and t.type == "Text" and #indented_lines <= 3 and (#inline_nomsu\text! - 2 < MAX_LINE + 4 or #inline_nomsu\text! <= space or #inline_nomsu\text! <= 8) @@ -237,6 +242,7 @@ tree_to_nomsu = (tree)-> word_buffer = {} num_args = 0 for i,bit in ipairs tree + -- TODO: properly wrap super long chains of words if type(bit) == "string" if #word_buffer > 0 and is_operator(bit) == is_operator(word_buffer[#word_buffer]) table.insert word_buffer, " " @@ -255,7 +261,7 @@ tree_to_nomsu = (tree)-> next_space = " " num_args += 1 - bit_nomsu = recurse(bit) + bit_nomsu = recurse(bit, i) if bit.type == "Block" -- Rule of thumb: nontrivial one-liner block arguments should be no more -- than golden ratio * the length of the proceeding part of the line @@ -267,15 +273,15 @@ tree_to_nomsu = (tree)-> if next_space == " " and #bit_nomsu\text! < MAX_LINE next_space = "\n.." elseif bit.type == 'Action' or bit.type == "MethodCall" - bit_nomsu = NomsuCode\from bit.source, "(\n ", tree_to_nomsu(bit), "\n)" + bit_nomsu = NomsuCode\from bit.source, "\n ", tree_to_nomsu(bit) else bit_nomsu = tree_to_nomsu(bit) - unless next_space == " " and bit_nomsu\text!\match("^:") + unless next_space == " " and bit_nomsu\text!\match("^[:\n]") nomsu\add next_space nomsu\add bit_nomsu - next_space = (bit.type == 'Block' and bit_nomsu\is_multiline!) and "\n.." or " " + next_space = (bit.type == 'Block' or (i > 1 and (bit.type == 'Action' or bit.type == 'MethodCall')) and bit_nomsu\is_multiline!) and "\n.." or " " if #word_buffer > 0 words = table.concat(word_buffer) @@ -410,7 +416,8 @@ tree_to_nomsu = (tree)-> key = {type:"Index", source:key.source, key} nomsu\add tree_to_nomsu(key) if value - nomsu\add " = ", recurse(value) + value_nomsu = recurse(value) + nomsu\add " = ", value_nomsu return nomsu when "Comment" diff --git a/tools/find.nom b/tools/find.nom index 4d0c29e..d2678d2 100755 --- a/tools/find.nom +++ b/tools/find.nom @@ -1,20 +1,20 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This is a tool to find syntax trees matching a pattern. "*" is a wildcard that will match any subtree, and "**" is a wildcard that will match any 0 or more subtrees. "**" is greedy, so extra arguments after it will not match. - - nomsu -t find [flags] "* squared" file1 file2... - + + nomsu -t find [flags] "* squared" file1 file2... + Flags: - -l List only the names of the files with matches - --wildcard=<wildcard> Specify a custom wildcard (in case you need to - match an action with a "*" in the name) - + -l List only the names of the files with matches + --wildcard=<wildcard> Specify a custom wildcard (in case you need to + match an action with a "*" in the name) + Output: - <filename>:<line number>: - <matching lines> + <filename>:<line number>: + <matching lines> use "lib/os.nom" use "lib/consolecolor.nom" @@ -25,48 +25,32 @@ $wildcard = ($(COMMAND LINE ARGS)."--wildcard" or "%*") $pattern = $(COMMAND LINE ARGS).extras.1 if (any of [not $pattern, $pattern == "*", $pattern == "**"]): barf "Usage: nomsu -t find [-l] [--wildcard=<wildcard>] <pattern>, where <pattern> is valid Nomsu code" - -$pattern = ($pattern|with "\$wildcard\$wildcard" -> "$multi_wildcard") -$pattern = ($pattern|with $wildcard -> "$wildcard") +$pattern = ($pattern, with "\$wildcard\$wildcard" -> "$multi_wildcard") +$pattern = ($pattern, with $wildcard -> "$wildcard") $pattern_tree = ($pattern parsed) - ($tree matches $patt) means: when: - (not ($tree is syntax tree)): - return (no) - - (($patt.type == "Var") and ($patt.1 == "wildcard")): - return (yes) - - ($tree.type != $patt.type): - return (no) - + (not ($tree is syntax tree)): return (no) + (($patt.type == "Var") and ($patt.1 == "wildcard")): return (yes) + ($tree.type != $patt.type): return (no) ($tree.type == "Action"): - if (($tree|get stub) != ($patt|get stub)): - return (no) - + if (($tree, get stub) != ($patt, get stub)): return (no) + for $ in 1 to (#$patt): if ($patt.$ is syntax tree): - if ($patt.$ == \$multi_wildcard): - return (yes) - - unless ($tree.$ matches $patt.$): - return (no) + if ($patt.$ == \$multi_wildcard): return (yes) + unless ($tree.$ matches $patt.$): return (no) ..else: - unless ($tree.$ == $patt.$): - return (no) - - if ((#$tree) != (#$patt)): - return (no) - + unless ($tree.$ == $patt.$): return (no) + + if ((#$tree) != (#$patt)): return (no) return (yes) - -$filenames = ($(COMMAND LINE ARGS).extras|from 2 to -1) +$filenames = ($(COMMAND LINE ARGS).extras, from 2 to -1) if ((#$filenames) == 0): say "Warning: searching stdin (ctrl-d to abort). To avoid this message, use nomsu -t find -" $filenames = ["stdin"] -for $filename in ($filenames): +for $filename in $filenames: $file = (read file $filename) unless $file: barf "File does not exist: \$filename" @@ -83,15 +67,15 @@ for $filename in ($filenames): $results = [] for $t in recursive $tree: if ($t matches $pattern_tree): - $line_num = ($file|line number at $t.source.start) - $results| - add {line: $line_num, text: "\(blue "\$filename:\$line_num:")\n\(source lines of $t)"} + $line_num = ($file, line number at $t.source.start) + $results, + add {.line = $line_num, .text = "\(blue "\$filename:\$line_num:")\n\(source lines of $t)"} for $sub in $t: if ($sub is syntax tree): recurse $t on $sub - - if ($(COMMAND LINE ARGS)."-l"): + + if $(COMMAND LINE ARGS)."-l": if ((#$results) > 0): say $filename ..else: diff --git a/tools/format.nom b/tools/format.nom index 0f09834..76c4981 100755 --- a/tools/format.nom +++ b/tools/format.nom @@ -1,8 +1,8 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # Auto-format Nomsu code. Usage: - nomsu -t format [-i] file1 file2... - + nomsu -t format [-i] file1 file2... + If the "-i" flag is used, the file will be edited in-place. If no files are passed in, this will read from stdin. @@ -19,7 +19,7 @@ for $filename in $filenames: $file = (read file $filename) unless $file: barf "File does not exist: \$filename" - $leading_indent = ($file|matching "[\n]*([ ]*)") + $leading_indent = ($file, matching "[\n]*([ ]*)") $code = (NomsuCode from ($Source $filename 1 (size of $file)) $file) try: $tree = ($code parsed) @@ -28,10 +28,10 @@ for $filename in $filenames: $formatted = $file ..else: say $msg - + if ($tree and (not $formatted)): - $formatted = " - \$leading_indent\((($tree as nomsu)|text)|with "\n" -> "\n\$leading_indent")" + $formatted = + .."\$leading_indent\($tree as nomsu, text, with "\n" -> "\n\$leading_indent")" if $formatted: if $(COMMAND LINE ARGS)."-i": diff --git a/tools/parse.nom b/tools/parse.nom index 1005983..1f87bab 100755 --- a/tools/parse.nom +++ b/tools/parse.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # Tool to print out a parse tree of files in an easy-to-read format. Usage: nomsu tools/parse.nom file1 file2 directory1 ... diff --git a/tools/repl.nom b/tools/repl.nom index 3f1eff3..49a4d3d 100644 --- a/tools/repl.nom +++ b/tools/repl.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # This file defines a Read-Evaluate-Print-Loop (REPL) for Nomsu @@ -9,16 +9,18 @@ use "lib/os.nom" externally [quit, exit] all mean: lua> "os.exit(0)" externally (help) means: - say " + say (" This is the Nomsu v\(Nomsu version) interactive console. You can type in Nomsu code here and hit 'enter' twice to run it. - To exit, type 'exit' or 'quit' and hit enter twice." + To exit, type 'exit' or 'quit' and hit enter twice. + ") -say " +say (" \(bright)\(underscore)Welcome to the Nomsu v\(Nomsu version) interactive console!\(reset color) press 'enter' twice to run a command - " + +") repeat: say (bright (yellow ">> ")) inline @@ -32,11 +34,13 @@ repeat: # clear the line say "\027[1A\027[2K" inline go to (run buffer) - $buff|add ($line|with "\t" -> " ") + $buff, add ($line, with "\t" -> " ") say (dim (yellow ".. ")) inline + --- (run buffer) --- + if ((size of $buff) == 0): stop - $buff = ($buff|joined) + $buff = ($buff, joined) # TODO: support local variables spoof file $buff @@ -53,7 +57,7 @@ repeat: "table": if $ret.as_nomsu: - say "= \($ret|as nomsu)" + say "= \($ret, as nomsu)" ..else: say "= \$ret" diff --git a/tools/test.nom b/tools/test.nom index 7b5842c..0202675 100755 --- a/tools/test.nom +++ b/tools/test.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # Tool to run all tests in a file (i.e. the code block inside a call to 'test %'). Usage: nomsu tools/test.nom file1 file2 directory1 ... @@ -13,21 +13,26 @@ for $filename in $(COMMAND LINE ARGS).extras: use $filename $tests = {: for $s = $t in $TESTS: add (=lua "Source:from_string(\$s)") = $t} for $filename in $(COMMAND LINE ARGS).extras: $file = (read file $filename) - $version = ($file|matching "#![^\n]* nomsu %-V[ ]*([^\n]*)") + $version = ($file, matching "#![^\n]* nomsu %-V[ ]*([^\n]*)") $file_tests = [] for $src = $test in $tests: if ($src.filename == $filename): if $version: - $test = "#!/usr/bin/env nomsu -V\$version\n\$test" - $file_tests|add {test: $test, source: $src} + $test = (" + #!/usr/bin/env nomsu -V\$version + \$test + ") + $file_tests, add {.test = $test, .source = $src} unless ($file_tests is empty): sort $file_tests by $ -> $.source lua> "io.write('[ .. ] ', \$filename); io.flush()" + if (command line args)."-v": say "" + for $ in $file_tests: if (command line args)."-v": - say " \(yellow ($.test|with "\n" -> "\n "))" + say " \(yellow ($.test, with "\n" -> "\n "))" run $.test if (command line args)."-v": diff --git a/tools/upgrade.nom b/tools/upgrade.nom index 96a1312..f335dc0 100755 --- a/tools/upgrade.nom +++ b/tools/upgrade.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.12.12.8 +#!/usr/bin/env nomsu -V6.12.12.8 # Tool to automatically update code from old versions of Nomsu. Usage: nomsu tools/upgrade.nom [-i] file1 file2 directory1 ... @@ -19,13 +19,15 @@ for $filename in $(COMMAND LINE ARGS).extras: $file = (read file $filename) unless $file: barf "File does not exist: \$filename" - $leading_indent = ($file|matching "[\n]*([ ]*)") + $leading_indent = ($file, matching "[\n]*([ ]*)") $code = (NomsuCode from (Source $filename 1 (size of $file)) $file) $tree = ($code parsed $start_version) - $uptree = (..) - $tree upgraded from ($start_version or ($tree.version or (Nomsu version))) to \ + $uptree = + $tree upgraded from ($start_version or ($tree.version or (Nomsu version))) to ..$version - $text = "\$leading_indent\((($uptree as nomsu)|text)|with "\n" -> "\n\$leading_indent")" + + $text = "\$leading_indent\($uptree as nomsu, text, with "\n" -> "\n\$leading_indent")" + when: $inplace: say "Upgraded \$filename" |
