From bf37295faeb9535c56671f4b2050260e1b88cd32 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Tue, 15 Jan 2019 15:53:31 -0800 Subject: [PATCH] Updating to v6.15, which includes "external (...)" instead of separate 'externally' versions of stuff, and some auto-formatting. --- examples/how_do_i.nom | 6 +- ldt.lua | 1 - lib/base64/init.nom | 68 ++--- lib/commandline/init.nom | 19 +- lib/compatibility/2.3.nom | 2 +- lib/compatibility/2.4.nom | 2 +- lib/compatibility/2.5.5.5.nom | 2 +- lib/compatibility/2.5.nom | 2 +- lib/compatibility/2.nom | 6 +- lib/compatibility/3.5.5.6.nom | 2 +- lib/compatibility/3.6.nom | 5 +- lib/compatibility/3.7.nom | 2 +- lib/compatibility/3.8.nom | 6 +- lib/compatibility/3.nom | 2 +- lib/compatibility/4.10.12.7.nom | 4 +- lib/compatibility/4.11.nom | 9 +- lib/compatibility/4.12.nom | 2 +- lib/compatibility/4.8.10.nom | 2 +- lib/compatibility/4.9.nom | 2 +- lib/compatibility/5.13.nom | 14 +- lib/compatibility/6.14.nom | 9 +- lib/compatibility/6.15.nom | 20 ++ lib/compatibility/compatibility.nom | 233 ++++++++--------- lib/compatibility/init.nom | 2 +- lib/consolecolor/init.nom | 2 +- lib/core/collections.nom | 62 ++--- lib/core/control_flow.nom | 3 +- lib/core/coroutines.nom | 2 +- lib/core/errors.nom | 4 +- lib/core/id.nom | 63 ++--- lib/core/init.nom | 2 +- lib/core/io.nom | 45 ++-- lib/core/math.nom | 392 ++++++++++++++-------------- lib/core/metaprogramming.nom | 217 ++++++++------- lib/core/operators.nom | 33 +-- lib/core/text.nom | 19 +- lib/file_hash/init.nom | 40 +-- lib/filesystem/init.nom | 64 ++--- lib/object.nom | 2 +- lib/progressbar/init.nom | 24 +- lib/shell/init.nom | 20 +- lib/things.nom | 129 ++++----- lib/tools/find.nom | 10 +- lib/tools/format.nom | 4 +- lib/tools/parse.nom | 4 +- lib/tools/repl.nom | 19 +- lib/tools/replace.nom | 16 +- lib/tools/test.nom | 14 +- lib/tools/upgrade.nom | 2 +- nomsu.lua | 6 +- nomsu.moon | 5 +- nomsu_decompiler.lua | 8 +- nomsu_decompiler.moon | 8 +- nomsu_environment.lua | 18 +- nomsu_environment.moon | 20 +- parser.lua | 2 +- parser.moon | 2 +- 57 files changed, 838 insertions(+), 845 deletions(-) delete mode 120000 ldt.lua create mode 100644 lib/compatibility/6.15.nom diff --git a/examples/how_do_i.nom b/examples/how_do_i.nom index 906ef74..6e5d4d1 100644 --- a/examples/how_do_i.nom +++ b/examples/how_do_i.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.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? @@ -6,7 +6,7 @@ is considered part of the comment (including any deeper-level indented text) The comment ends when the indentation ends - + # How do I import a libarary? use "consolecolor" @@ -247,7 +247,6 @@ say (2 + 3) # If you need to keep going after an indented region, you can start the next line with ".." say both "Very very very very long first argument that needs its own line" ..and also "short second arg" - (my favorite number) means (21 + 2) # This can be nested: @@ -330,6 +329,7 @@ say (best of [2, -3, 4, -8] according to $($ squared)) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ say (best of [2, -3, 4, -8] where $x has score ($x * $x)) + # The line above expands to: say result of: diff --git a/ldt.lua b/ldt.lua deleted file mode 120000 index b28ba32..0000000 --- a/ldt.lua +++ /dev/null @@ -1 +0,0 @@ -/Users/bruce/Sandbox/lua/ldt/ldt.lua \ No newline at end of file diff --git a/lib/base64/init.nom b/lib/base64/init.nom index 54f785f..a76a49f 100644 --- a/lib/base64/init.nom +++ b/lib/base64/init.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file defines actions for encoding/decoding base 64, as specified in: https://tools.ietf.org/html/rfc4648 @@ -15,36 +15,36 @@ test: assume (base64 $plain) == $encoded assume (base64 decode $encoded) == $plain -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) - 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) - - 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 "=" - - 1: - $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) +external: + [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) + 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) + + 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 "=" + + 1: + $chars, add $b64_chars.((($bytes.1 & 3) << 4) + 1) + $chars, add "=" + $chars, add "=" + return ($chars, joined) + (chr $) means (=lua "string.char(\$)") + [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) diff --git a/lib/commandline/init.nom b/lib/commandline/init.nom index f28e02b..68836fb 100644 --- a/lib/commandline/init.nom +++ b/lib/commandline/init.nom @@ -1,11 +1,12 @@ # A library defining some command line program functionality - -(command line program with $args $body) parses as: - externally (run with $args) means $body - if (this file was run directly): - run with (the command line arguments) - -externally (usage $) means: - say "Usage: \$" - exit 1 + +external: + (command line program with $args $body) parses as: + external ((run with $args) means $body) + if (this file was run directly): + run with (the command line arguments) + + (usage $) means: + say "Usage: \$" + exit 1 diff --git a/lib/compatibility/2.3.nom b/lib/compatibility/2.3.nom index 67870ac..808c859 100644 --- a/lib/compatibility/2.3.nom +++ b/lib/compatibility/2.3.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file defines upgrades from Nomsu <2.3 to Nomsu 2.3 diff --git a/lib/compatibility/2.4.nom b/lib/compatibility/2.4.nom index e0d2e02..a904dd0 100644 --- a/lib/compatibility/2.4.nom +++ b/lib/compatibility/2.4.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file defines upgrades from Nomsu <2.4 to Nomsu 2.4 diff --git a/lib/compatibility/2.5.5.5.nom b/lib/compatibility/2.5.5.5.nom index c026a42..93d3956 100644 --- a/lib/compatibility/2.5.5.5.nom +++ b/lib/compatibility/2.5.5.5.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file defines upgrades from Nomsu <2.5.5.5 to Nomsu 2.5.5.5 diff --git a/lib/compatibility/2.5.nom b/lib/compatibility/2.5.nom index 03b3f61..b5b988a 100644 --- a/lib/compatibility/2.5.nom +++ b/lib/compatibility/2.5.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file defines upgrades from Nomsu <2.5 to Nomsu 2.5 diff --git a/lib/compatibility/2.nom b/lib/compatibility/2.nom index caf7a86..ca3cb6a 100644 --- a/lib/compatibility/2.nom +++ b/lib/compatibility/2.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file defines upgrades from Nomsu 1 to Nomsu 2 @@ -24,8 +24,8 @@ upgrade $tree to "2" as: $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 1 in 2 to", "for 1 2 in", "do", "for 1 in recursive", "test", "with" + "result of", "when" ] for $n in $need_blocks: diff --git a/lib/compatibility/3.5.5.6.nom b/lib/compatibility/3.5.5.6.nom index 6528526..d9bba4f 100644 --- a/lib/compatibility/3.5.5.6.nom +++ b/lib/compatibility/3.5.5.6.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file defines upgrades from Nomsu <3.5.5.6 to Nomsu 3.5.5.6 diff --git a/lib/compatibility/3.6.nom b/lib/compatibility/3.6.nom index 5db2aae..7428158 100644 --- a/lib/compatibility/3.6.nom +++ b/lib/compatibility/3.6.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file defines upgrades from Nomsu <3.6 to 3.6 @@ -7,7 +7,8 @@ use "compatibility/compatibility" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ upgrade action [ - append $item to $list, add $item to $list, to $list add $item, to $list append $item + append $item to $list, add $item to $list, to $list add $item + to $list append $item ] to "3.6" as ($list, add $item) upgrade action [add $item to $list at index $i] to "3.6" as diff --git a/lib/compatibility/3.7.nom b/lib/compatibility/3.7.nom index ed877a6..894c656 100644 --- a/lib/compatibility/3.7.nom +++ b/lib/compatibility/3.7.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file defines upgrades from Nomsu <3.7 to 3.7 diff --git a/lib/compatibility/3.8.nom b/lib/compatibility/3.8.nom index 398e3bb..0c3b3ac 100644 --- a/lib/compatibility/3.8.nom +++ b/lib/compatibility/3.8.nom @@ -1,11 +1,11 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file defines upgrades from Nomsu <3.8 to 3.8 (Text method changes) - + use "compatibility/compatibility" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - + 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) diff --git a/lib/compatibility/3.nom b/lib/compatibility/3.nom index af5c2fd..966dbf9 100644 --- a/lib/compatibility/3.nom +++ b/lib/compatibility/3.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file defines upgrades from Nomsu <=2 to Nomsu 3 diff --git a/lib/compatibility/4.10.12.7.nom b/lib/compatibility/4.10.12.7.nom index c241898..eeff2f2 100644 --- a/lib/compatibility/4.10.12.7.nom +++ b/lib/compatibility/4.10.12.7.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file defines upgrades from Nomsu <4.10.12.7 to 4.10.12.7 use "compatibility/compatibility" @@ -8,9 +8,7 @@ use "compatibility/compatibility" upgrade action ($ as lua statements) to "4.10.12.7" as ($ as lua) 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 [: for $k = $v in $items: add $e] diff --git a/lib/compatibility/4.11.nom b/lib/compatibility/4.11.nom index 24dbbdc..88ea7b3 100644 --- a/lib/compatibility/4.11.nom +++ b/lib/compatibility/4.11.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file defines upgrades from Nomsu <4.11 to Nomsu 4.11 (overhaul of function literals, deleting (if all of ...), etc. shorthand) @@ -25,9 +25,7 @@ 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} $lhs "=" $rhs + return (SyntaxTree {.type = "Action", .source = $tree.source} $lhs "=" $rhs) upgrade action "1 with 2 ~>" to "4.11" via for $tree: @@ -93,5 +91,6 @@ upgrade action [ ] to "4.11" as (if (not (any of $items)) $body else $else) upgrade action [ - unless none of $items $body else $else, unless none of $items then $body else $else + 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) diff --git a/lib/compatibility/4.12.nom b/lib/compatibility/4.12.nom index a76e7df..bb1af0b 100644 --- a/lib/compatibility/4.12.nom +++ b/lib/compatibility/4.12.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file defines upgrades from Nomsu <4.11 to Nomsu 4.11 (overhaul of function literals, deleting (if all of ...), etc. shorthand) diff --git a/lib/compatibility/4.8.10.nom b/lib/compatibility/4.8.10.nom index 250dc4a..15a502b 100644 --- a/lib/compatibility/4.8.10.nom +++ b/lib/compatibility/4.8.10.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file defines upgrades from Nomsu <4.8.10 to 4.8.10 (renaming "action" -> "means") use "compatibility/compatibility" diff --git a/lib/compatibility/4.9.nom b/lib/compatibility/4.9.nom index 14b5dd6..d8260a4 100644 --- a/lib/compatibility/4.9.nom +++ b/lib/compatibility/4.9.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file defines upgrades from Nomsu <4.9 to 4.9 use "compatibility/compatibility" diff --git a/lib/compatibility/5.13.nom b/lib/compatibility/5.13.nom index 1e0db6d..92c8ebe 100644 --- a/lib/compatibility/5.13.nom +++ b/lib/compatibility/5.13.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V5.13 +#!/usr/bin/env nomsu -V6.15.13.8 # This file defines upgrades from Nomsu <5.13 to 5.13 use "compatibility/compatibility" @@ -6,19 +6,15 @@ use "compatibility/compatibility" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ upgrade action (size of $) to "5.13" as (#$) - -upgrade action "with" to "5.13" via (..) +upgrade action "with" to "5.13" via for $tree: $assignments = $tree.2 $body = $tree.3 - if ($assignments.type != "Dict"): - return $tree + if ($assignments.type != "Dict"): return $tree $new_assignments = \[] for $a in $assignments at $i: when: - (($a.type == "DictEntry") and ((#$a) == 1)): - $a = $a.1 - (all of [$a.type == "DictEntry", (#$a) == 2]): - $a = \($a.1 = $a.2) + (($a.type == "DictEntry") and ((#$a) == 1)): $a = $a.1 + (all of [$a.type == "DictEntry", (#$a) == 2]): $a = \($a.1 = $a.2) $new_assignments.$i = $a return \(with $new_assignments $body) diff --git a/lib/compatibility/6.14.nom b/lib/compatibility/6.14.nom index 8443157..0e742d0 100644 --- a/lib/compatibility/6.14.nom +++ b/lib/compatibility/6.14.nom @@ -1,6 +1,7 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file defines upgrades from Nomsu <6.14 to 6.14 + use "compatibility/compatibility" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -26,16 +27,12 @@ upgrade action (assume $assumption or barf $err) to "6.14" as unless $assumption: fail $err upgrade action (barf $msg) to "6.14" as (fail $msg) - upgrade action (\(1's meaning)).stub to "6.14" via $tree -> (SyntaxTree {.source = $tree.source, .type = "Var", $tree.1}) - upgrade action (log base $b of $n) to "6.14" as (log $n base $b) - upgrade action "use" to "6.14" via for $tree: $path = $tree.2.1 $path = ($path, with "%.nom$" -> "") $path = ($path, with "^lib/" -> "") - return \(use (SyntaxTree {.source = $tree.2.source, .type="Text"} $path)) - + return \(use (SyntaxTree {.source = $tree.2.source, .type = "Text"} $path)) diff --git a/lib/compatibility/6.15.nom b/lib/compatibility/6.15.nom new file mode 100644 index 0000000..a911624 --- /dev/null +++ b/lib/compatibility/6.15.nom @@ -0,0 +1,20 @@ +#!/usr/bin/env nomsu -V6.15.13.8 +# + This file defines upgrades from Nomsu <6.15 to 6.15 + +use "compatibility/compatibility" + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +upgrade action (external $x = $y) to "6.15" as (external ($x = $y)) +upgrade action (externally $x means $y) to "6.15" as (external ($x means $y)) +upgrade action (externally $x all mean $y) to "6.15" as + external ($x all mean $y) + +upgrade action ($lists flattened) to "6.15" as [ + : for $ in recursive $lists: + if ($ is a "List"): + for $child in $: + recurse $ on $child + ..else: add $ +] diff --git a/lib/compatibility/compatibility.nom b/lib/compatibility/compatibility.nom index 8e48903..419f589 100644 --- a/lib/compatibility/compatibility.nom +++ b/lib/compatibility/compatibility.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file contains code for defining ways to upgrade code between different versions of Nomsu. @@ -8,126 +8,123 @@ use "filesystem" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $UPGRADES = {} -externally (upgrade to $version via $upgrade_fn) means: - $UPGRADES.$version = $upgrade_fn $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 to $version via (($ $end_version) -> ($ with $tree -> $body)) - -(upgrade action $actions to $version as $body) compiles to: - if ($actions is "Action" syntax tree): - $actions = \[$actions] - $lua = (Lua "") - for $action in $actions: - $replacements = {} - for $i in 1 to (size of $action): - if ($action.$i is "Var" syntax tree): - $replacements.($action.$i.1) = "\(\$tree as lua id)[\$i]" - define mangler - (make tree $t) means: - when: - ($t is "Var" syntax tree): - if $replacements.($t.1): - return $replacements.($t.1) - ..else: - external $needs_mangle = (yes) - return (" - SyntaxTree{type=\(quote $t.type), source=\(quote "\($t.source)"), \(quote (mangle $t.1))} - ") - - ($t is syntax tree): - $args = [] - for $k = $v in $t: - if ((type of $k) == "number"): - $args, add (make tree $v) +external: + (upgrade to $version via $upgrade_fn) means: + $UPGRADES.$version = $upgrade_fn + + (upgrade action $stub to $version via $upgrade_fn) means: + $ACTION_UPGRADES.$version.$stub = $upgrade_fn + + (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: + if ($actions is "Action" syntax tree): + $actions = \[$actions] + $lua = (Lua "") + for $action in $actions: + $replacements = {} + for $i in 1 to (size of $action): + if ($action.$i is "Var" syntax tree): + $replacements.($action.$i.1) = "\(\$tree as lua id)[\$i]" + define mangler + (make tree $t) means: + when: + ($t is "Var" syntax tree): + if $replacements.($t.1): + return $replacements.($t.1) ..else: - $args, add "\($k)=\(make tree $v)" - return "SyntaxTree{\($args, joined with ", ")}" - - else: - return (quote $t) - - unless ("\$lua" == ""): - $lua, add "\n" - - $retval = (make tree $body) - $lua, add - Lua (" - upgrade_action_1_to_2_via(\(quote $action.stub), \($version as lua expr), function(\ - ..\(\$tree as lua id)) - return \$retval - end) - ") - return $lua - -externally [ - $tree upgraded from $start_version to $end_version - $tree upgraded to $end_version from $start_version -] all mean: - unless ($tree is syntax tree): return $tree - - ($ver as list) means (($ as number) for $ in $ver matching "[0-9]+") - - (Ver $) means: - [$lib, $ver] = ($, match "(.*)/([0-9.]+)") - if $lib: - return {.lib = $lib, .version = ($ver as list)} - return {.version = ($ as list)} - - $start = (Ver $start_version) - $end = (Ver $end_version) - $end.lib or= $start.lib - assume $start.lib == $end.lib - - $seen = {} - $versions = {} - for $v = $ in $UPGRADES: $versions.$v = (yes) - for $v = $ in $ACTION_UPGRADES: $versions.$v = (yes) - $versions = [ - :for $v = $ in $versions: - if ((Ver $v).lib == $start.lib): - add $v - ] + external ($needs_mangle = (yes)) + return (" + SyntaxTree{type=\(quote $t.type), source=\(quote "\($t.source)"), \(quote (mangle $t.1))} + ") + + ($t is syntax tree): + $args = [] + for $k = $v in $t: + if ((type of $k) == "number"): + $args, add (make tree $v) + ..else: + $args, add "\($k)=\(make tree $v)" + return "SyntaxTree{\($args, joined with ", ")}" + + else: + return (quote $t) + + unless ("\$lua" == ""): + $lua, add "\n" + + $retval = (make tree $body) + $lua, add + Lua (" + upgrade_action_1_to_2_via(\(quote $action.stub), \($version as lua expr), function(\ + ..\(\$tree as lua id)) + return \$retval + end) + ") + return $lua - sort $versions by $ -> ($ as list) - for $ver in $versions: - if (($ver as list) <= $start.version): do next $ver - if (($ver as list) > $end.version): stop $ver - if $ACTION_UPGRADES.$ver: - $tree = - $tree with $ ->: - if (($ is "Action" syntax tree) and $ACTION_UPGRADES.$ver.($.stub)): - $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) + [ + $tree upgraded from $start_version to $end_version + $tree upgraded to $end_version from $start_version + ] all mean: + unless ($tree is syntax tree): return $tree + ($ver as list) means (($ as number) for $ in $ver matching "[0-9]+") + (Ver $) means: + [$lib, $ver] = ($, match "(.*)/([0-9.]+)") + if $lib: + return {.lib = $lib, .version = ($ver as list)} + return {.version = ($ as list)} + $start = (Ver $start_version) + $end = (Ver $end_version) + $end.lib or= $start.lib + assume $start.lib == $end.lib + $seen = {} + $versions = {} + for $v = $ in $UPGRADES: + $versions.$v = (yes) - if $UPGRADES.$ver: - $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) + for $v = $ in $ACTION_UPGRADES: + $versions.$v = (yes) + + $versions = [: for $v = $ in $versions: if ((Ver $v).lib == $start.lib): add $v] + sort $versions by $ -> ($ as list) + for $ver in $versions: + if (($ver as list) <= $start.version): do next $ver + if (($ver as list) > $end.version): stop $ver + if $ACTION_UPGRADES.$ver: + $tree = + $tree with $ ->: + if (($ is "Action" syntax tree) and $ACTION_UPGRADES.$ver.($.stub)): + $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 = { + : 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) + + if ($tree.version != $end_version): + $tree = (SyntaxTree {: for $k = $v in $tree: add $k = $v}) + $tree.version = $end_version + if $tree.shebang: + $tree.shebang = "#!/usr/bin/env nomsu -V\$end_version\n" + + return $tree - if ($tree.version != $end_version): - $tree = (SyntaxTree {: for $k = $v in $tree: add $k = $v}) - $tree.version = $end_version - if $tree.shebang: - $tree.shebang = "#!/usr/bin/env nomsu -V\$end_version\n" + ($tree upgraded from $start_version) means + $tree upgraded from $start_version to (Nomsu version) - return $tree - -externally ($tree upgraded from $start_version) means - $tree upgraded from $start_version to (Nomsu version) - -externally ($tree upgraded to $end_version) means - $tree upgraded from ($tree.version or (Nomsu version)) to $end_version - -externally ($tree upgraded) means - $tree upgraded from ($tree.version or (Nomsu version)) to (Nomsu version) + ($tree upgraded to $end_version) means + $tree upgraded from ($tree.version or (Nomsu version)) to $end_version + + ($tree upgraded) means + $tree upgraded from ($tree.version or (Nomsu version)) to (Nomsu version) diff --git a/lib/compatibility/init.nom b/lib/compatibility/init.nom index 40cafff..42834bb 100644 --- a/lib/compatibility/init.nom +++ b/lib/compatibility/init.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14.13.8 +#!/usr/bin/env nomsu -V6.15.13.8 export "compatibility/compatibility" export "compatibility/2" export "compatibility/2.3" diff --git a/lib/consolecolor/init.nom b/lib/consolecolor/init.nom index d1da247..19dc5ea 100644 --- a/lib/consolecolor/init.nom +++ b/lib/consolecolor/init.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file defines actions for ANSI console color escape codes. diff --git a/lib/core/collections.nom b/lib/core/collections.nom index 4cf54cd..dbe6900 100644 --- a/lib/core/collections.nom +++ b/lib/core/collections.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file contains code that supports manipulating and using collections like lists and dictionaries. @@ -44,19 +44,6 @@ test: 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]) - -externally ($lists flattened) means: - $flat = [] - for $item in recursive $lists: - if ($item is a "List"): - for $ in $item: - recurse $item on $ - ..else: - $flat, add $item - return $flat - test: assume ((entries in {.x = 1}) == [{.key = "x", .value = 1}]) @@ -118,28 +105,29 @@ test: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -test: - assume ((sorted [3, 1, 2]) == [1, 2, 3]) - -externally [$items sorted, sorted $items] all mean: - $copy = [: for $ in $items: add $] - sort $copy - return $copy - -[$items sorted by $item = $key, $items sorted by $item -> $key] all parse as - result of: +external: + test: + assume ((sorted [3, 1, 2]) == [1, 2, 3]) + + [$items sorted, sorted $items] all mean: $copy = [: for $ in $items: add $] - sort $copy by $item = $key + sort $copy return $copy - -test: - assume ((unique [1, 2, 1, 3, 2, 3]) == [1, 2, 3]) - -externally (unique $items) means: - $unique = [] - $seen = {} - for $ in $items: - unless $seen.$: - $unique, add $ - $seen.$ = (yes) - return $unique + + [$items sorted by $item = $key, $items sorted by $item -> $key] all parse as + result of: + $copy = [: for $ in $items: add $] + sort $copy by $item = $key + return $copy + + test: + assume ((unique [1, 2, 1, 3, 2, 3]) == [1, 2, 3]) + + (unique $items) means: + $unique = [] + $seen = {} + for $ in $items: + unless $seen.$: + $unique, add $ + $seen.$ = (yes) + return $unique diff --git a/lib/core/control_flow.nom b/lib/core/control_flow.nom index b0c4f27..715630b 100644 --- a/lib/core/control_flow.nom +++ b/lib/core/control_flow.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file contains compile-time actions that define basic control flow structures like "if" statements and loops. @@ -466,6 +466,7 @@ test: # Recurion control flow (recurse $v on $x) compiles to Lua "table.insert(_stack_\($v as lua expr), \($x as lua expr))" + (for $var in recursive $structure $body) compiles to: $lua = Lua (" diff --git a/lib/core/coroutines.nom b/lib/core/coroutines.nom index 6a99f7e..3bfb346 100644 --- a/lib/core/coroutines.nom +++ b/lib/core/coroutines.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file defines the code that creates and manipulates coroutines diff --git a/lib/core/errors.nom b/lib/core/errors.nom index 950de49..9a2cc9b 100644 --- a/lib/core/errors.nom +++ b/lib/core/errors.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file contains basic error reporting code @@ -23,9 +23,7 @@ use "core/control_flow" (assume $a == $b) compiles to: lua> "local \$assumption = 'Assumption failed: '..tostring(\(\($a == $b) as nomsu))" - define mangler - return Lua (" do diff --git a/lib/core/id.nom b/lib/core/id.nom index d2427b5..936fd40 100644 --- a/lib/core/id.nom +++ b/lib/core/id.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # A simple UUID function based on RFC 4122: http://www.ietf.org/rfc/rfc4122.txt @@ -33,34 +33,35 @@ set $id_by_obj's metatable to { return $id } -externally (uuid) means: - # Set all the other bits to randomly (or pseudo-randomly) chosen values. - $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)) - ] +external: + (uuid) means: + # Set all the other bits to randomly (or pseudo-randomly) chosen values. + $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 + # Section 4.1.3. + $bytes.3 += 0x4000 + + # Set the two most significant bits (bits 6 and 7) of the + # clock_seq_hi_and_reserved to zero and one, respectively. + $bytes.4 += 0xC0 + return (=lua "('%08x-%04x-%04x-%02x%02x-%6x%6x'):format(unpack(\$bytes))") - # Set the four most significant bits (bits 12 through 15) of the - # time_hi_and_version field to the 4-bit version number from - # Section 4.1.3. - $bytes.3 += 0x4000 - - # Set the two most significant bits (bits 6 and 7) of the - # clock_seq_hi_and_reserved to zero and one, respectively. - $bytes.4 += 0xC0 - return (=lua "('%08x-%04x-%04x-%02x%02x-%6x%6x'):format(unpack(\$bytes))") - -# For strict identity checking, use ($x's id) == ($y's id) -test: - assume (([] == []) and ((id of []) != (id of []))) - seed random with 0 - $x = [] - assume ((id of $x) == (id of $x)) - seed random with 0 - assume ((id of $x) != (id of [])) - seed random -externally [id of $, $'s id, $'id] all mean $id_by_obj.$ + # For strict identity checking, use ($x's id) == ($y's id) + test: + assume (([] == []) and ((id of []) != (id of []))) + seed random with 0 + $x = [] + assume ((id of $x) == (id of $x)) + seed random with 0 + assume ((id of $x) != (id of [])) + seed random + [id of $, $'s id, $'id] all mean $id_by_obj.$ diff --git a/lib/core/init.nom b/lib/core/init.nom index 5b1074f..1319c5f 100644 --- a/lib/core/init.nom +++ b/lib/core/init.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14.13.8 +#!/usr/bin/env nomsu -V6.15.13.8 # Export everything export "core/metaprogramming" export "core/operators" diff --git a/lib/core/io.nom b/lib/core/io.nom index 7afe889..90cfbd4 100644 --- a/lib/core/io.nom +++ b/lib/core/io.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file contains basic input/output code @@ -6,24 +6,25 @@ use "core/metaprogramming" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -(say $message) compiles to: - lua> (" - if \$message.type == "Text" then - return LuaCode("say(", \($message as lua expr), ");"); - else - return LuaCode("say(tostring(", \($message as lua expr), "));"); - end - ") - -(say $message inline) compiles to: - lua> (" - if \$message.type == "Text" then - return LuaCode("io.write(", \($message as lua expr), ")"); - else - return LuaCode("io.write(tostring(", \($message as lua expr), "))"); - end - ") - -externally (ask $prompt) means: - $io.write $prompt - return ($io.read()) +external: + (say $message) compiles to: + lua> (" + if \$message.type == "Text" then + return LuaCode("say(", \($message as lua expr), ");"); + else + return LuaCode("say(tostring(", \($message as lua expr), "));"); + end + ") + + (say $message inline) compiles to: + lua> (" + if \$message.type == "Text" then + return LuaCode("io.write(", \($message as lua expr), ")"); + else + return LuaCode("io.write(tostring(", \($message as lua expr), "))"); + end + ") + + (ask $prompt) means: + $io.write $prompt + return ($io.read()) diff --git a/lib/core/math.nom b/lib/core/math.nom index 685ab1e..e2c759a 100644 --- a/lib/core/math.nom +++ b/lib/core/math.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file defines some common math literals and functions @@ -10,203 +10,201 @@ use "core/collections" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Literals: -test: - unless (all of [inf, NaN, pi, tau, golden ratio, e]): - fail "math constants failed" - $nan = (NaN) - unless ($nan != $nan): - fail "NaN failed" -[infinity, inf] all compile to "math.huge" -[not a number, NaN, nan] all compile to "(0/0)" -[pi, Pi, PI] all compile to "math.pi" -[tau, Tau, TAU] all compile to "(2*math.pi)" -(golden ratio) compiles to "((1+math.sqrt(5))/2)" -(e) compiles to "math.exp(1)" - -# Functions: -test: - assume (("5" as a number) == 5) -external $($ as a number) = $(tonumber $) -external $($ as number) = $(tonumber $) -test: - unless - 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 5 base 2, floor 5, ceiling 5, round 5 - ] - ..: - fail "math functions failed" -external [$(absolute value $), $(absolute value of $), $(| $ |), $(abs $)] = - [$math.abs, $math.abs, $math.abs, $math.abs] -external [$(square root $), $(square root of $), $(√ $), $(sqrt $)] = - [$math.sqrt, $math.sqrt, $math.sqrt, $math.sqrt] -external [$(sine $), $(sin $)] = [$math.sin, $math.sin] -external [$(cosine $), $(cos $)] = [$math.cos, $math.cos] -external [$(tangent $), $(tan $)] = [$math.tan, $math.tan] -external [$(arc sine $), $(asin $)] = [$math.asin, $math.asin] -external [$(arc cosine $), $(acos $)] = [$math.acos, $math.acos] -external [$(arc tangent $), $(atan $)] = [$math.atan, $math.atan] -external [$(arc tangent $y / $x), $(atan2 $y $x)] = [$math.atan2, $math.atan2] -external [$(hyperbolic sine $), $(sinh $)] = [$math.sinh, $math.sinh] -external [$(hyperbolic cosine $), $(cosh $)] = [$math.cosh, $math.cosh] -external [$(hyperbolic tangent $), $(tanh $)] = [$math.tanh, $math.tanh] -external [$(e^ $), $(exp $)] = [$math.exp, $math.exp] -external [$(natural log $), $(ln $), $(log $), $(log $ base $)] = [$math.log, $math.log, $math.log, $math.log] -external $(floor $) = $math.floor -external [$(ceiling $), $(ceil $)] = [$math.ceil, $math.ceil] -externally [round $, $ rounded] all mean - floor ($ + 0.5) -test: - unless ((463 to the nearest 100) == 500): fail "rounding failed" - unless ((2.6 to the nearest 0.25) == 2.5): fail "rounding failed" - -externally ($n to the nearest $rounder) means - $rounder * (floor ($n / $rounder + 0.5)) - -# Any/all -externally [all of $items, all $items] all mean: - for $ in $items: - unless $: - return (no) - return (yes) -[not all of $items, not all $items] all parse as (not (all of $items)) -externally [any of $items, any $items] all mean: - for $ in $items: - if $: - return (yes) - return (no) -[none of $items, none $items] all parse as (not (any of $items)) - -# Sum/product -externally [sum of $items, sum $items] all mean: - $total = 0 - for $ in $items: - $total += $ - return $total - -externally [product of $items, product $items] all mean: - $prod = 1 - for $ in $items: - $prod *= $ - return $prod - -externally [avg of $items, average of $items] all mean - (sum of $items) / (size of $items) - -# Min/max -externally [min of $items, smallest of $items, lowest of $items] all mean: - $best = (nil) - for $ in $items: - if (($best == (nil)) or ($ < $best)): $best = $ - return $best - -externally [ - max of $items, biggest of $items, largest of $items, highest of $items -] all mean: - $best = (nil) - for $ in $items: - if (($best == (nil)) or ($ > $best)): $best = $ - return $best - -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 - result of: +external: + # Literals: + test: + unless (all of [inf, NaN, pi, tau, golden ratio, e]): + fail "math constants failed" + $nan = (NaN) + unless ($nan != $nan): + fail "NaN failed" + [infinity, inf] all compile to "math.huge" + [not a number, NaN, nan] all compile to "(0/0)" + [pi, Pi, PI] all compile to "math.pi" + [tau, Tau, TAU] all compile to "(2*math.pi)" + (golden ratio) compiles to "((1+math.sqrt(5))/2)" + (e) compiles to "math.exp(1)" + + # Functions: + test: + assume (("5" as a number) == 5) + $($ as a number) = $(tonumber $) + $($ as number) = $(tonumber $) + test: + unless + 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 5 base 2, floor 5, ceiling 5, round 5 + ] + ..: + fail "math functions failed" + + [$(absolute value $), $(absolute value of $), $(| $ |), $(abs $)] = + [$math.abs, $math.abs, $math.abs, $math.abs] + + [$(square root $), $(square root of $), $(√ $), $(sqrt $)] = + [$math.sqrt, $math.sqrt, $math.sqrt, $math.sqrt] + + [$(sine $), $(sin $)] = [$math.sin, $math.sin] + [$(cosine $), $(cos $)] = [$math.cos, $math.cos] + [$(tangent $), $(tan $)] = [$math.tan, $math.tan] + [$(arc sine $), $(asin $)] = [$math.asin, $math.asin] + [$(arc cosine $), $(acos $)] = [$math.acos, $math.acos] + [$(arc tangent $), $(atan $)] = [$math.atan, $math.atan] + [$(arc tangent $y / $x), $(atan2 $y $x)] = [$math.atan2, $math.atan2] + [$(hyperbolic sine $), $(sinh $)] = [$math.sinh, $math.sinh] + [$(hyperbolic cosine $), $(cosh $)] = [$math.cosh, $math.cosh] + [$(hyperbolic tangent $), $(tanh $)] = [$math.tanh, $math.tanh] + [$(e^ $), $(exp $)] = [$math.exp, $math.exp] + [$(natural log $), $(ln $), $(log $), $(log $ base $)] = + [$math.log, $math.log, $math.log, $math.log] + $(floor $) = $math.floor + [$(ceiling $), $(ceil $)] = [$math.ceil, $math.ceil] + [round $, $ rounded] all mean (floor ($ + 0.5)) + test: + unless ((463 to the nearest 100) == 500): fail "rounding failed" + unless ((2.6 to the nearest 0.25) == 2.5): fail "rounding failed" + ($n to the nearest $rounder) means ($rounder * (floor ($n / $rounder + 0.5))) + + # Any/all + [all of $items, all $items] all mean: + for $ in $items: + unless $: + return (no) + return (yes) + [not all of $items, not all $items] all parse as (not (all of $items)) + [any of $items, any $items] all mean: + for $ in $items: + if $: + return (yes) + return (no) + [none of $items, none $items] all parse as (not (any of $items)) + + # Sum/product + [sum of $items, sum $items] all mean: + $total = 0 + for $ in $items: + $total += $ + return $total + + [product of $items, product $items] all mean: + $prod = 1 + for $ in $items: + $prod *= $ + return $prod + + [avg of $items, average of $items] all mean ((sum of $items) / (size of $items)) + + # Min/max + [min of $items, smallest of $items, lowest of $items] all mean: $best = (nil) - $best_key = (nil) - for $item in $items: - $key = $value_expr - if (($best == (nil)) or ($key < $best_key)): - $best = $item - $best_key = $key + for $ in $items: + if (($best == (nil)) or ($ < $best)): $best = $ return $best - -(max of $items by $item = $value_expr) parses as - result of: + + [max of $items, biggest of $items, largest of $items, highest of $items] all mean: $best = (nil) - $best_key = (nil) - for $item in $items: - $key = $value_expr - if (($best == (nil)) or ($key > $best_key)): - $best = $item - $best_key = $key + for $ in $items: + if (($best == (nil)) or ($ > $best)): $best = $ return $best - -test: - assume (100 clamped between 0 and 10) == 10 - -externally ($ clamped between $min and $max) means: - when: - ($ < $min): - return $min - - ($ > $max): - return $max - - else: - return $ - -test: - assume (-0.1 smoothed by 2.7) == 0 - assume (0 smoothed by 2.7) == 0 - assume (0.5 smoothed by 2.7) == 0.5 - assume (1 smoothed by 2.7) == 1 - assume (1.1 smoothed by 2.7) == 1 - -externally ($ smoothed by $smoothness) means: - $ = ($ clamped between 0 and 1) - if ($smoothness == 0): return $ - $k = (2 ^ $smoothness) - if ($ < 0.5): - return (0.5 * (2 * $) ^ $k) - ..else: - return (1 - 0.5 * (2 - 2 * $) ^ $k) - -test: - assume (5 to 7 mixed by -1.0) == 5 - assume (5 to 7 mixed by 0.0) == 5 - assume (5 to 7 mixed by 0.5) == 6 - assume (5 to 7 mixed by 1.0) == 7 - assume (5 to 7 mixed by 2.0) == 7 - -externally ($lo to $hi mixed by $amount) means: - $ = ($amount clamped between 0 and 1) - return ((1 - $) * $lo + $ * $hi) - -test: - assume ([0, 1, 11] mixed by 0.0) == 0 - assume ([0, 1, 11] mixed by 0.25) == 0.5 - assume ([0, 1, 11] mixed by 0.5) == 1 - assume ([0, 1, 11] mixed by 0.75) == 6 - assume ([0, 1, 11] mixed by 1.0) == 11 - assume ([99] mixed by 0.5) == 99 - -externally ($nums mixed by $amount) means: - $ = ($amount clamped between 0 and 1) - $i = (1 + ($ * ((#$nums) - 1))) - if ((floor $i) == (#$nums)): - return $nums.(floor $i) - [$lo, $hi] = [$nums.(floor $i), $nums.(floor ($i + 1))] - return ($lo to $hi mixed by ($i mod 1)) - -# Random functions -externally (seed random with $) means: - 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 - "math.random(\($n as lua expr))" - -[random from $low to $high, random number from $low to $high, rand $low $high] -..all compile to "math.random(\($low as lua expr), \($high as lua expr))" - -externally [ - random choice from $elements, random choice $elements, random $elements -] all mean (=lua "\$elements[math.random(#\$elements)]") + + 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 + result of: + $best = (nil) + $best_key = (nil) + for $item in $items: + $key = $value_expr + if (($best == (nil)) or ($key < $best_key)): + $best = $item + $best_key = $key + return $best + + (max of $items by $item = $value_expr) parses as + result of: + $best = (nil) + $best_key = (nil) + for $item in $items: + $key = $value_expr + if (($best == (nil)) or ($key > $best_key)): + $best = $item + $best_key = $key + return $best + + test: + assume (100 clamped between 0 and 10) == 10 + + ($ clamped between $min and $max) means: + when: + ($ < $min): + return $min + + ($ > $max): + return $max + + else: + return $ + + test: + assume (-0.1 smoothed by 2.7) == 0 + assume (0 smoothed by 2.7) == 0 + assume (0.5 smoothed by 2.7) == 0.5 + assume (1 smoothed by 2.7) == 1 + assume (1.1 smoothed by 2.7) == 1 + + ($ smoothed by $smoothness) means: + $ = ($ clamped between 0 and 1) + if ($smoothness == 0): return $ + $k = (2 ^ $smoothness) + if ($ < 0.5): + return (0.5 * (2 * $) ^ $k) + ..else: + return (1 - 0.5 * (2 - 2 * $) ^ $k) + + test: + assume (5 to 7 mixed by -1) == 5 + assume (5 to 7 mixed by 0) == 5 + assume (5 to 7 mixed by 0.5) == 6 + assume (5 to 7 mixed by 1) == 7 + assume (5 to 7 mixed by 2) == 7 + + ($lo to $hi mixed by $amount) means: + $ = ($amount clamped between 0 and 1) + return ((1 - $) * $lo + $ * $hi) + + test: + assume ([0, 1, 11] mixed by 0) == 0 + assume ([0, 1, 11] mixed by 0.25) == 0.5 + assume ([0, 1, 11] mixed by 0.5) == 1 + assume ([0, 1, 11] mixed by 0.75) == 6 + assume ([0, 1, 11] mixed by 1) == 11 + assume ([99] mixed by 0.5) == 99 + + ($nums mixed by $amount) means: + $ = ($amount clamped between 0 and 1) + $i = (1 + ($ * ((#$nums) - 1))) + if ((floor $i) == (#$nums)): + return $nums.(floor $i) + [$lo, $hi] = [$nums.(floor $i), $nums.(floor ($i + 1))] + return ($lo to $hi mixed by ($i mod 1)) + + # Random functions + (seed random with $) means: + 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 + "math.random(\($n as lua expr))" + + [random from $low to $high, random number from $low to $high, rand $low $high] + ..all compile to "math.random(\($low as lua expr), \($high as lua expr))" + + [random choice from $elements, random choice $elements, random $elements] + ..all mean (=lua "\$elements[math.random(#\$elements)]") diff --git a/lib/core/metaprogramming.nom b/lib/core/metaprogramming.nom index 936f9bd..9b3d5c4 100644 --- a/lib/core/metaprogramming.nom +++ b/lib/core/metaprogramming.nom @@ -1,9 +1,9 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This File contains actions for making actions and compile-time actions and some helper functions to make that easier. -lua> "NOMSU_CORE_VERSION = 14" +lua> "NOMSU_CORE_VERSION = 15" lua> "NOMSU_LIB_VERSION = 8" lua> (" do @@ -25,8 +25,7 @@ lua> (" COMPILE_RULES["1 ->"] = function(\(nomsu environment), \$args, \$body) if \$args and not \$body then \$args, \$body = {}, \$args end local body_lua = SyntaxTree:is_instance(\$body) and \(nomsu environment):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() @@ -41,8 +40,7 @@ lua> (" 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) @@ -186,26 +184,40 @@ test: ") test: - externally (baz1) means: - return "baz1" - externally (baz2) means "baz2" + $loc = 99 + external ($glob = 99) test: - assume ((baz1) == "baz1") - assume ((baz2) == "baz2") + assume $loc == (nil) + assume $glob == 99 -(externally $action means $body) compiles to: +(external $body) compiles to: lua> (" - local lua = \(\($action means $body) as lua) - lua:remove_free_vars({\$action:get_stub():as_lua_id()}) + local lua = \($body as lua) + lua:remove_free_vars() return lua ") -(externally $actions all mean $body) compiles to: +test: + [$x, $y] = ["outer", "outer"] + external: + (set external x local y) means: + with external [$x]: + $x = "inner" + $y = "inner" + set external x local y + unless (($x == "inner") and ($y == "outer")): + fail "'with external' failed." + +(with external $externals $body) compiles to: 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 + local body_lua = \($body as lua) + local varnames = {} + for i,\$v in ipairs(\$externals) do + varnames[i] = \($v as lua):text() + end + body_lua:remove_free_vars(varnames) + return body_lua ") test: @@ -239,8 +251,8 @@ test: if replacements[t:as_var()] then return replacements[t:as_var()] else - return "SyntaxTree{mangle("..t:as_var():as_lua().."), type="..t.type:as_lua()..", \ - ..source="..tostring(t.source):as_lua().."}" + return "SyntaxTree{mangle("..t:as_var():as_lua().."), type="..t.type:as_lua(\ + ..)..", source="..tostring(t.source):as_lua().."}" end elseif SyntaxTree:is_instance(t) then local ret = {} @@ -274,34 +286,37 @@ test: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [$action parses as $body] all parse as ([$action] all parse as $body) -externally (in (nomsu environment) $tree as lua expr) means: - lua> (" - local tree_lua = \(nomsu environment):compile(\$tree) - if \$tree.type == 'Block' then - tree_lua = LuaCode:from(\$tree.source, '(function()\\n ', tree_lua, '\\nend)()') - elseif \$tree.type == 'MethodCall' and #\$tree > 2 then - compile_error_at(\$tree, "This must be a single value instead of "..(#\$tree - 1).."\ - .. method calls.", - "Replace this with a single method call.") - end - return tree_lua - ") +external: + (in (nomsu environment) $tree as lua expr) means: + lua> (" + local tree_lua = \(nomsu environment):compile(\$tree) + if \$tree.type == 'Block' then + tree_lua = LuaCode:from(\$tree.source, '(function()\\n ', tree_lua, '\\nend)()') + elseif \$tree.type == 'MethodCall' and #\$tree > 2 then + compile_error_at(\$tree, "This must be a single value instead of "..(#\$tree - 1).."\ + .. method calls.", + "Replace this with a single method call.") + end + return tree_lua + ") # Need to make sure the proper environment is used for compilation (i.e. the caller's environment) -($tree as lua expr) compiles to (\(in \(nomsu environment) $tree as lua expr) as lua) +($tree as lua expr) compiles to + \(in \(nomsu environment) $tree as lua expr) as lua ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -externally [$var as lua identifier, $var as lua id] all mean: - lua> (" - local lua = \($var as lua) - if not lua:text():is_a_lua_id() then - compile_error(\$var, - "This is supposed to be something that compiles to a valid Lua identifier.", - "This should probably be a variable.") - end - return lua - ") +external: + [$var as lua identifier, $var as lua id] all mean: + lua> (" + local lua = \($var as lua) + if not lua:text():is_a_lua_id() then + compile_error(\$var, + "This is supposed to be something that compiles to a valid Lua identifier.", + "This should probably be a variable.") + end + return lua + ") test: (num args (*extra arguments*)) means (select "#" (*extra arguments*)) @@ -312,11 +327,10 @@ test: assume (third arg 5 6 7 8) == 7 (*extra arguments*) compiles to "..." - ($ is syntax tree) compiles to "SyntaxTree:is_instance(\($ as lua expr))" - -externally ($ is $kind syntax tree) means - =lua "SyntaxTree:is_instance(\$) and \$.type == \$kind" +external: + ($ is $kind syntax tree) means + =lua "SyntaxTree:is_instance(\$) and \$.type == \$kind" ($tree with $t -> $replacement) compiles to (" \($tree as lua expr):map(function(\($t as lua expr)) @@ -329,14 +343,15 @@ externally ($ is $kind syntax tree) means end) ") -externally ($tree with vars $replacements) means - =lua (" - \$tree:map(function(\$t) - if \$t.type == "Var" then - return \$replacements[\$t:as_var()] - end - end) - ") +external: + ($tree with vars $replacements) means + =lua (" + \$tree:map(function(\$t) + if \$t.type == "Var" then + return \$replacements[\$t:as_var()] + end + end) + ") (tree $tree with vars $replacements) compiles to (" \(=lua "(\$tree):as_lua()"):map(function(t) @@ -355,24 +370,25 @@ externally ($tree with vars $replacements) means end)() ") -externally (match $tree with $patt) means: - lua> (" - if \$patt.type == "Var" then return Dict{[\$patt:as_var()]=\$tree} end - if \$patt.type == "Action" and \$patt:get_stub() ~= \$tree:get_stub() then return nil end - if #\$patt ~= #\$tree then return nil end - local matches = Dict{} - for \($i)=1,#\$patt do - if SyntaxTree:is_instance(\$tree[\$i]) then - local submatch = \(match $tree.$i with $patt.$i) - if not submatch then return nil end - for k,v in pairs(submatch) do - if matches[k] and matches[k] ~= v then return nil end - matches[k] = v +external: + (match $tree with $patt) means: + lua> (" + if \$patt.type == "Var" then return Dict{[\$patt:as_var()]=\$tree} end + if \$patt.type == "Action" and \$patt:get_stub() ~= \$tree:get_stub() then return nil end + if #\$patt ~= #\$tree then return nil end + local matches = Dict{} + for \($i)=1,#\$patt do + if SyntaxTree:is_instance(\$tree[\$i]) then + local submatch = \(match $tree.$i with $patt.$i) + if not submatch then return nil end + for k,v in pairs(submatch) do + if matches[k] and matches[k] ~= v then return nil end + matches[k] = v + end end end - end - return matches - ") + return matches + ") test: assume @@ -390,20 +406,20 @@ test: assume ({} is a "Dict") assume ("" is text) assume ("" isn't a "Dict") -externally ($ is text) means (=lua "\(lua type of $) == 'string'") -externally [$ is not text, $ isn't text] all mean - =lua "\(lua type of $) ~= 'string'" -externally (type of $) means: - lua> (" - local lua_type = \(lua type of $) - if lua_type == 'string' then return 'Text' - elseif lua_type == 'table' or lua_type == 'userdata' then - local mt = getmetatable(\$) - if mt and mt.__type then return mt.__type end - end - return lua_type - ") +external: + ($ is text) means (=lua "\(lua type of $) == 'string'") + [$ is not text, $ isn't text] all mean (=lua "\(lua type of $) ~= 'string'") + (type of $) means: + lua> (" + local lua_type = \(lua type of $) + if lua_type == 'string' then return 'Text' + elseif lua_type == 'table' or lua_type == 'userdata' then + local mt = getmetatable(\$) + if mt and mt.__type then return mt.__type end + end + return lua_type + ") [$ is a $type, $ is an $type] all parse as ((type of $) == $type) [$ isn't a $type, $ isn't an $type, $ is not a $type, $ is not an $type] @@ -441,19 +457,24 @@ test: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# - (with local compile actions $body) compiles to (" - do - local OLD_RULES = COMPILE_RULES - local OLD_ENV = \(nomsu environment) - local \(nomsu environment) = setmetatable({ - COMPILE_RULES=setmetatable({}, {__index=OLD_RULES}) - }, {__index=OLD_ENV}) - \($body as lua) - end +test: + using compile rules: + (yes) compiles to "3" + assume $(COMPILE RULES).yes + ..do: + assume (yes) == 3 + assume (yes) == (=lua "true") + +(using compile rules $rules do $body) compiles to: + lua> (" + local env = \(new environment) + env:run(\$rules) + local lua = env:compile(\$body) + return lua ") -externally (Nomsu version) means: - return (" - \(Nomsu syntax version).\(core version).\(Nomsu compiler version).\(lib version) - ") +external: + (Nomsu version) means: + return (" + \(Nomsu syntax version).\(core version).\(Nomsu compiler version).\(lib version) + ") diff --git a/lib/core/operators.nom b/lib/core/operators.nom index 912b7c1..b0f37f0 100644 --- a/lib/core/operators.nom +++ b/lib/core/operators.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file contains definitions of operators like "+" and "and". @@ -77,34 +77,6 @@ test: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -test: - [$foozle, $y] = ["outer", "outer"] - externally (set global x local y) means: - external $foozle = "inner" - $y = "inner" - set global x local y - unless (($foozle == "inner") and ($y == "outer")): fail "external failed." -(external $var = $value) compiles to: - $lua = ((SyntaxTree {.type = "Action", .source = $var.source} $var "=" $value) as lua) - $lua, remove free vars - return $lua -test: - [$foozle, $y] = ["outer", "outer"] - externally (set global x local y) means: - with external [$foozle]: - $foozle = "inner" - $y = "inner" - set global x local y - unless (($foozle == "inner") and ($y == "outer")): - fail "'with external' failed." - -(with external $externs $body) compiles to: - $body_lua = ($body as lua) - lua> (" - \$body_lua:remove_free_vars(table.map(\$externs, function(v) return \(nomsu environment):compile(v):text() end)) - ") - return $body_lua - test: [$x, $y] = [1, 2] with [$z, $x = 999]: @@ -156,7 +128,8 @@ test: test: $calls = 0 (one) means: - external $calls = ($calls + 1) + external: + $calls = ($calls + 1) return 1 unless (0 <= (one) <= 2): diff --git a/lib/core/text.nom b/lib/core/text.nom index 1351af6..a1fcaae 100644 --- a/lib/core/text.nom +++ b/lib/core/text.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file contains some definitions of text escape sequences, including ANSI console color codes. @@ -34,7 +34,6 @@ test: "), lines ..== ["one", "two", ""] - ($spec とは $body) parses as ($spec means $body) test: @@ -61,16 +60,18 @@ test: test: assume (0xDEADBEEF as hex) == "0xDEADBEEF" -externally ($num as hex) means: - if ($num < 0): - return ("-0x%X", formatted with (- $num)) - ..else: - return ("0x%X", formatted with $num) +external: + ($num as hex) means: + if ($num < 0): + return ("-0x%X", formatted with (- $num)) + ..else: + 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" + .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: diff --git a/lib/file_hash/init.nom b/lib/file_hash/init.nom index 7b428cd..709c622 100644 --- a/lib/file_hash/init.nom +++ b/lib/file_hash/init.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file defines some actions for hashing files and looking up files by hash. @@ -32,9 +32,10 @@ test: assume ((hash "hello world") == "Kq5sNclPz7QV2+lfQIuc6R7oRu0=") if $use_sha1: - externally (hash $) means: - $hash = (=lua "\$hashlib.new('sha1'):final(\$)") - return (base64 $hash) + external: + (hash $) means: + $hash = (=lua "\$hashlib.new('sha1'):final(\$)") + return (base64 $hash) ..else: # TODO: remove warning? say (" @@ -42,19 +43,20 @@ if $use_sha1: ..hash function.\027[0m ") - externally (hash $) means: - $bytes = ($, bytes) - $hash = ($bytes.1 << 7) - for $i in 2 to (size of $bytes): - $hash = ((1000003 * $hash) ~ $bytes.$i) - $hash = ($hash ~ (size of $bytes)) - return "\$hash" + external: + (hash $) means: + $bytes = ($, bytes) + $hash = ($bytes.1 << 7) + for $i in 2 to (size of $bytes): + $hash = ((1000003 * $hash) ~ $bytes.$i) + $hash = ($hash ~ (size of $bytes)) + return "\$hash" -externally (file with hash $hash) means: - for $filename in (files for "."): - $contents = (read file $filename) - $file_hash = (hash $contents) - if ($file_hash == $hash): - return $filename - -(hash of file $filename) parses as (hash (read file $filename)) +external: + (file with hash $hash) means: + for $filename in (files for "."): + $contents = (read file $filename) + $file_hash = (hash $contents) + if ($file_hash == $hash): + return $filename + (hash of file $filename) parses as (hash (read file $filename)) diff --git a/lib/filesystem/init.nom b/lib/filesystem/init.nom index a228bdc..3e819f8 100644 --- a/lib/filesystem/init.nom +++ b/lib/filesystem/init.nom @@ -1,36 +1,36 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file defines some actions that interact with the filesystem. -externally (files for $path) means: - $files = (=lua "Files.list(\$path)") - if $files: - $files = (List $files) - return $files - -external $(read file $filename) = $Files.read -externally [ - write to file $filename $text, to file $filename write $text - write $text to file $filename -] all mean: - unless ($filename != "stdin"): - fail "Cannot write to stdin" +external: + (files for $path) means: + $files = (=lua "Files.list(\$path)") + if $files: + $files = (List $files) + return $files + $(read file $filename) = $Files.read + [ + write to file $filename $text, to file $filename write $text + write $text to file $filename + ] all mean: + unless ($filename != "stdin"): + fail "Cannot write to stdin" + + lua> (" + local file = io.open(\$filename, 'w') + file:write(\$text) + file: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 - [ - : for $ in ($file, line number at $source.start) to - $file, line number at $source.stop - ..: add ($file, line $) - ], joined with "\n" - -external $(spoof file $text) = $Files.spoof -external $(spoof file $filename = $text) = $Files.spoof + (source lines of $tree) means: + $source = ($tree.source if ($tree is syntax tree) else $tree) + $file = (read file $source.filename) + return + [ + : for $ in ($file, line number at $source.start) to + $file, line number at $source.stop + ..: add ($file, line $) + ], joined with "\n" + + $(spoof file $text) = $Files.spoof + $(spoof file $filename = $text) = $Files.spoof diff --git a/lib/object.nom b/lib/object.nom index a3a8d93..99981a0 100644 --- a/lib/object.nom +++ b/lib/object.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file contains the implementation of an Object-Oriented programming system. diff --git a/lib/progressbar/init.nom b/lib/progressbar/init.nom index a7ff5aa..5da9360 100644 --- a/lib/progressbar/init.nom +++ b/lib/progressbar/init.nom @@ -1,16 +1,12 @@ +#!/usr/bin/env nomsu -V6.15.13.8 # A progress bar - -externally ($x / $w progress bar) means: - $x = ($x clamped between 0 and $w) - $bits = [" ", "▏", "▎", "▍", "▌", "▋", "▊", "▉", "█"] - $middle = - "" if ($x == $w) else - $bits.(1 + (floor ((#$bits) * ($x mod 1)))) - return (" - \027[32;40m\($bits, last, rep (floor $x))\$middle\ - ..\(" ", rep ($w - ((floor $x) + 1)))\027[0m - ") - -externally ($w wide $ progress bar) means - ($ * $w) / $w progress bar +external: + ($x / $w progress bar) means: + $x = ($x clamped between 0 and $w) + $bits = [" ", "▏", "▎", "▍", "▌", "▋", "▊", "▉", "█"] + $middle = ("" if ($x == $w) else $bits.(1 + (floor ((#$bits) * ($x mod 1))))) + return (" + \027[32;40m\($bits, last, rep (floor $x))\$middle\(" ", rep ($w - ((floor $x) + 1)))\027[0m + ") + ($w wide $ progress bar) means (($ * $w) / $w progress bar) diff --git a/lib/shell/init.nom b/lib/shell/init.nom index 6a8970e..d58894e 100644 --- a/lib/shell/init.nom +++ b/lib/shell/init.nom @@ -1,12 +1,12 @@ # This file defines some actions for running shell commands. - -externally (=sh $cmd) means: - lua> (" - local result = io.popen(\$cmd) - local contents = result:read("*a") - result:close() - return contents - ") - -external $(sh> $) = $os.execute + +external: + (=sh $cmd) means: + lua> (" + local result = io.popen(\$cmd) + local contents = result:read("*a") + result:close() + return contents + ") + $(sh> $) = $os.execute diff --git a/lib/things.nom b/lib/things.nom index 95f175d..92cb444 100644 --- a/lib/things.nom +++ b/lib/things.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # A library for simple object oriented programming. @@ -91,67 +91,70 @@ $METAMETHOD_MAP = { } $($ as text like a dict) = ({}'s metatable).__tostring -externally (a class named $classname with $members $(initialize $)) means: - $class = {.__type = $classname} - $class.__index = $class - $class.class = $class - $class.__tostring = ($ -> "\($.__type) \($ as text like a dict)") - $class.__eq = ({}'s metatable).__eq - $class.__len = ({}'s metatable).__len - if $members: - $class.__members = $members - $class.__newindex = - for ($its $key = $value): - if $members.$key: - rawset $its $key $value - ..else: - fail "Cannot set \$key, it's not one of the allowed member fields." +external: + (a class named $classname with $members $(initialize $)) means: + $class = {.__type = $classname} + $class.__index = $class + $class.class = $class + $class.__tostring = ($ -> "\($.__type) \($ as text like a dict)") + $class.__eq = ({}'s metatable).__eq + $class.__len = ({}'s metatable).__len + if $members: + $class.__members = $members + $class.__newindex = + for ($its $key = $value): + if $members.$key: + rawset $its $key $value + ..else: + fail "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 + } + + if $(initialize $): + initialize $class + for $stub = $metamethod in $METAMETHOD_MAP: + if $class.($stub, as lua id): + $class.$metamethod = $class.($stub, as lua id) + + return $class - 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 - } + [ + 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) + if $class_body: + $body_lua = ($class_body as lua) + $body_lua, remove free vars [$class_id] + $body_lua, declare locals + + $lua = + Lua (" + \$class_id = a_class_named_1_with(\(quote $classname.stub), \($members as lua)\( + ( + Lua (" + , function(\$class_id) + local it, its = \$class_id, \$class_id; + \$body_lua + end + ") + ) 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 + ") + + $lua, add free vars [$class_id, "a_\$class_id", "an_\$class_id"] + return $lua - if $(initialize $): - initialize $class - for $stub = $metamethod in $METAMETHOD_MAP: - 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) - if $class_body: - $body_lua = ($class_body as lua) - $body_lua, remove free vars [$class_id] - $body_lua, declare locals - - return - Lua (" - \$class_id = a_class_named_1_with(\(quote $classname.stub), \($members as lua)\( - ( - Lua (" - , function(\$class_id) - local it, its = \$class_id, \$class_id; - \$body_lua - end - ") - ) 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 $classname is a thing $class_body, an $classname is a thing] all parse as - a $classname is a thing with (nil) $class_body + [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/lib/tools/find.nom b/lib/tools/find.nom index a4db987..db7a2c5 100755 --- a/lib/tools/find.nom +++ b/lib/tools/find.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.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 @@ -55,7 +55,7 @@ command line program with $args: Warning: searching stdin (ctrl-d to abort). To avoid this message, use nomsu -t find - ") $filenames = ["stdin"] - + for $filename in $filenames: $file = (read file $filename) unless $file: @@ -79,7 +79,11 @@ command line program with $args: 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 = $line_num + .text = (" + \(blue "\$filename:\$line_num:") + \(source lines of $t) + ") } for $sub in $t: diff --git a/lib/tools/format.nom b/lib/tools/format.nom index 445f35e..eee1316 100755 --- a/lib/tools/format.nom +++ b/lib/tools/format.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # Auto-format Nomsu code. Usage: nomsu -t format [-i] file1 file2... @@ -19,7 +19,7 @@ command line program with $args: Warning: reading from stdin (ctrl-d to abort). To avoid this message, use nomsu -t format - ") $filenames = ["stdin"] - + for $filename in $filenames: $file = (read file $filename) unless $file: diff --git a/lib/tools/parse.nom b/lib/tools/parse.nom index 63cc247..a7e306e 100755 --- a/lib/tools/parse.nom +++ b/lib/tools/parse.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # Tool to print out a parse tree of files in an easy-to-read format. Usage: nomsu tools/parse.nom file1 file2 directory1 ... @@ -8,7 +8,7 @@ use "commandline" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -externally (print tree $t at indent $indent) means: +(print tree $t at indent $indent) means: if $t.type is: "Action": say "\($indent)Action (\($t.stub)):" diff --git a/lib/tools/repl.nom b/lib/tools/repl.nom index 2c0d3df..63d9e30 100755 --- a/lib/tools/repl.nom +++ b/lib/tools/repl.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This file defines a Read-Evaluate-Print-Loop (REPL) for Nomsu @@ -8,12 +8,13 @@ use "commandline" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -externally (help) means: - 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. - ") +external: + (help) means: + 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. + ") command line program with $args: say (" @@ -23,7 +24,7 @@ command line program with $args: press 'enter' twice to run a command ") - + repeat: say (bright (yellow ">> ")) inline $buff = [] @@ -38,9 +39,7 @@ command line program with $args: go to (run buffer) $buff, add ($line, with "\t" -> " ") say (dim (yellow ".. ")) inline - --- (run buffer) --- - if ((size of $buff) == 0): stop $buff = ($buff, joined) spoof file $buff diff --git a/lib/tools/replace.nom b/lib/tools/replace.nom index efc4d09..d9926cf 100755 --- a/lib/tools/replace.nom +++ b/lib/tools/replace.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # This is a tool to replace syntax trees with something new. @@ -34,10 +34,10 @@ command line program with $args: if $args.literal: for $var in ($args.literal, all matches of "$([^ ]*)"): $literal_vars.$var = (yes) - + if (($pattern_tree.type == "Var") and (not $literal_vars.($pattern_tree.1))): fail "Pattern matches every part of the file." - + $pattern_vars = { : for $ in recursive $pattern_tree: if (($.type == "Var") and (not $literal_vars.($.1))): add $.1 @@ -45,7 +45,7 @@ command line program with $args: if ($child is a "Syntax Tree"): recurse $ on $child } - + # TODO: support wildcards and unpacking e.g. nomsu -t replace "test(: $test; *$more_tests)" "*$more_tests; *$test" ($tree matches $patt with $substitution_values) means: @@ -85,7 +85,7 @@ command line program with $args: Warning: searching stdin (ctrl-d to abort). To avoid this message, use nomsu -t find - ") $filenames = ["stdin"] - + for $filename in $filenames: $file = (read file $filename) unless $file: @@ -95,7 +95,8 @@ command line program with $args: $tree = ($code parsed) ..if it fails with $msg: if $args.q: - unless $args.i: say $code + unless $args.i: + say $code ..else: say $msg @@ -124,13 +125,10 @@ command line program with $args: ..\(reset color) ") say "\(bright)..be replaced with:" - say (" \(bright)\(blue)\("\($ret as nomsu)", with "\n" -> "\n ")\(reset color) ") - $user_answers.$t = (ask "\(bright)..? [Y/n]\(reset color) ") - if ($user_answers.$t == "n"): return (nil) $replaced.$t = (yes) return $ret diff --git a/lib/tools/test.nom b/lib/tools/test.nom index 4663bd4..761ec55 100755 --- a/lib/tools/test.nom +++ b/lib/tools/test.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.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 ... @@ -14,7 +14,6 @@ command line program with $args: $file = (read file $filename) unless $file: fail "Couldn't find \$filename" - $(test environment) = (new environment) $(test environment), export $filename $version = @@ -24,7 +23,7 @@ command line program with $args: ]*) ") $file_tests = [] - for $src = $test in $(test environment).TESTS: + for $src = $test in (nomsu environment, Module $filename).TESTS: if $version: $test = (" #!/usr/bin/env nomsu -V\$version @@ -36,20 +35,22 @@ command line program with $args: sort $file_tests by $ -> $.source say "[ .. ] \$filename" inline $io.flush() - if $args.v: say "" - $failures = [] for $ in $file_tests: if $args.v: say " \(yellow ($.test, with "\n" -> "\n "))" + try: $(test environment), run $.test ..if it fails with $msg: $src = ($Source, from string $.source) $l1 = ($file, line number at $src.start) $l2 = ($file, line number at $src.stop) - $failures, add "\(yellow "\($src.filename):\($l1)-\$l2:")\n\(bright (red ($msg, indented)))" + $failures, add (" + \(yellow "\($src.filename):\($l1)-\$l2:") + \(bright (red ($msg, indented))) + ") if ($failures is empty): if $args.v: @@ -62,4 +63,3 @@ command line program with $args: ..else: say "\r[\(red (bright "FAIL"))" say "\($failures, joined with "\n", indented)" - diff --git a/lib/tools/upgrade.nom b/lib/tools/upgrade.nom index 2c63411..30b6cab 100755 --- a/lib/tools/upgrade.nom +++ b/lib/tools/upgrade.nom @@ -1,4 +1,4 @@ -#!/usr/bin/env nomsu -V6.14 +#!/usr/bin/env nomsu -V6.15.13.8 # Tool to automatically update code from old versions of Nomsu. Usage: nomsu tools/upgrade.nom [-i] file1 file2 directory1 ... diff --git a/nomsu.lua b/nomsu.lua index a600e9b..c325387 100644 --- a/nomsu.lua +++ b/nomsu.lua @@ -131,6 +131,7 @@ local NOMSU_PACKAGEPATH = NOMSU_PACKAGEPATH or "/opt/nomsu" add_path(NOMSU_PACKAGEPATH) add_path(".") package.nomsupath = table.concat(nomsupath, ";") +package.nomsuloaded = Dict({ }) local nomsu_environment = require('nomsu_environment') nomsu_environment.COMMAND_LINE_ARGS = nomsu_args nomsu_environment.OPTIMIZATION = optimization @@ -173,6 +174,10 @@ run = function() nomsu_environment._1_parsed(NomsuCode:from(source, code)) print("Parse succeeded: " .. tostring(filename)) elseif args.compile then + local code = Files.read(filename) + if not code then + error("Could not find file '" .. tostring(filename) .. "'") + end if filename:match("%.lua$") then error("Cannot compile a lua file (expected a nomsu file as input)") end @@ -182,7 +187,6 @@ run = function() else output = io.open(filename:gsub("%.nom$", ".lua"), "w") end - local code = Files.read(filename) local source = Source(filename, 1, #code) code = NomsuCode:from(source, code) local env = nomsu_environment.new_environment() diff --git a/nomsu.moon b/nomsu.moon index cfc8500..e45083f 100755 --- a/nomsu.moon +++ b/nomsu.moon @@ -108,6 +108,7 @@ NOMSU_PACKAGEPATH or= "/opt/nomsu" add_path NOMSU_PACKAGEPATH add_path "." package.nomsupath = table.concat(nomsupath, ";") +package.nomsuloaded = Dict{} nomsu_environment = require('nomsu_environment') nomsu_environment.COMMAND_LINE_ARGS = nomsu_args @@ -141,12 +142,14 @@ run = -> nomsu_environment._1_parsed(NomsuCode\from(source, code)) print("Parse succeeded: #{filename}") elseif args.compile + code = Files.read(filename) + if not code + error("Could not find file '#{filename}'") -- Compile .nom files into .lua if filename\match("%.lua$") error("Cannot compile a lua file (expected a nomsu file as input)") output = if filename == 'stdin' then io.output() else io.open(filename\gsub("%.nom$", ".lua"), "w") - code = Files.read(filename) source = Source(filename, 1, #code) code = NomsuCode\from(source, code) env = nomsu_environment.new_environment! diff --git a/nomsu_decompiler.lua b/nomsu_decompiler.lua index 98e93c8..9224f25 100644 --- a/nomsu_decompiler.lua +++ b/nomsu_decompiler.lua @@ -193,7 +193,7 @@ tree_to_inline_nomsu = function(tree) local target = tree[1] local target_nomsu = tree_to_inline_nomsu(target) local _exp_1 = target.type - if "Action" == _exp_1 or "MethodCall" == _exp_1 then + if "Action" == _exp_1 or "MethodCall" == _exp_1 or "EscapedNomsu" == _exp_1 then target_nomsu:parenthesize() elseif "Number" == _exp_1 then if target_nomsu:text():match("%.") then @@ -498,10 +498,10 @@ tree_to_nomsu = function(tree) while #line > 0 do local space = max_line - nomsu:trailing_line_len() local split = find(line, "[%p%s]", space) - if not split or split > space + 10 then - split = space + 10 + if not split or split > space + 16 then + split = space + 16 end - if #line - split < 10 then + if #line - split < 16 then split = #line end local bite diff --git a/nomsu_decompiler.moon b/nomsu_decompiler.moon index 5b35b9a..b88a766 100644 --- a/nomsu_decompiler.moon +++ b/nomsu_decompiler.moon @@ -147,7 +147,7 @@ tree_to_inline_nomsu = (tree)-> target = tree[1] target_nomsu = tree_to_inline_nomsu(target) switch target.type - when "Action", "MethodCall" + when "Action", "MethodCall", "EscapedNomsu" target_nomsu\parenthesize! when "Number" target_nomsu\parenthesize! if target_nomsu\text!\match("%.") @@ -381,9 +381,9 @@ tree_to_nomsu = (tree)-> while #line > 0 space = max_line - nomsu\trailing_line_len! split = find(line, "[%p%s]", space) - if not split or split > space + 10 - split = space + 10 - if #line - split < 10 + if not split or split > space + 16 + split = space + 16 + if #line - split < 16 split = #line bite, line = sub(line, 1, split), sub(line, split+1, -1) nomsu\add bite diff --git a/nomsu_environment.lua b/nomsu_environment.lua index 9952a65..5a055c3 100644 --- a/nomsu_environment.lua +++ b/nomsu_environment.lua @@ -99,7 +99,6 @@ nomsu_environment = Importer({ tostring = tostring, string = string, xpcall = xpcall, - module = module, say = print, loadfile = loadfile, rawset = rawset, @@ -215,7 +214,7 @@ nomsu_environment = Importer({ end return tree end, - load_module = function(self, package_name) + Module = function(self, package_name) local path if package_name:match("%.nom$") or package_name:match("%.lua") then path = package_name @@ -228,7 +227,7 @@ nomsu_environment = Importer({ end path = path:gsub("^%./", "") do - local ret = package.loaded[package_name] or package.loaded[path] + local ret = package.nomsuloaded[package_name] or package.nomsuloaded[path] if ret then return ret end @@ -250,12 +249,12 @@ nomsu_environment = Importer({ _currently_running_files:add(path) mod:run(code) _currently_running_files:pop() - package.loaded[package_name] = mod - package.loaded[path] = mod + package.nomsuloaded[package_name] = mod + package.nomsuloaded[path] = mod return mod end, use = function(self, package_name) - local mod = self:load_module(package_name) + local mod = self:Module(package_name) local imports = assert(_module_imports[self]) for k, v in pairs(mod) do imports[k] = v @@ -267,7 +266,7 @@ nomsu_environment = Importer({ return mod end, export = function(self, package_name) - local mod = self:load_module(package_name) + local mod = self:Module(package_name) local imports = assert(_module_imports[self]) for k, v in pairs(_module_imports[mod]) do if rawget(imports, k) == nil then @@ -290,11 +289,6 @@ nomsu_environment = Importer({ self.COMPILE_RULES[k] = v end end - for k, v in pairs(mod.TESTS) do - if rawget(self.TESTS, k) == nil then - self.TESTS[k] = v - end - end return mod end, run = function(self, to_run) diff --git a/nomsu_environment.moon b/nomsu_environment.moon index 13cf776..2719252 100644 --- a/nomsu_environment.moon +++ b/nomsu_environment.moon @@ -48,7 +48,7 @@ nomsu_environment = Importer{ :next, unpack: unpack or table.unpack, :setmetatable, :rawequal, :getmetatable, :pcall, yield:coroutine.yield, resume:coroutine.resume, coroutine_status_of:coroutine.status, coroutine_wrap:coroutine.wrap, coroutine_from: coroutine.create, - :error, :package, :os, :require, :tonumber, :tostring, :string, :xpcall, :module, + :error, :package, :os, :require, :tonumber, :tostring, :string, :xpcall, say:print, :loadfile, :rawset, :_VERSION, :collectgarbage, :rawget, :rawlen, :table, :assert, :dofile, :loadstring, lua_type_of:type, :select, :math, :io, :load, :pairs, :ipairs, :jit, :_VERSION @@ -105,7 +105,7 @@ nomsu_environment = Importer{ return tree - load_module: (package_name)=> + Module: (package_name)=> local path if package_name\match("%.nom$") or package_name\match("%.lua") path = package_name @@ -114,7 +114,7 @@ nomsu_environment = Importer{ if not path then error(err) path = path\gsub("^%./", "") - if ret = package.loaded[package_name] or package.loaded[path] + if ret = package.nomsuloaded[package_name] or package.nomsuloaded[path] return ret if _currently_running_files\has(path) @@ -132,12 +132,12 @@ nomsu_environment = Importer{ _currently_running_files\add path mod\run(code) _currently_running_files\pop! - package.loaded[package_name] = mod - package.loaded[path] = mod + package.nomsuloaded[package_name] = mod + package.nomsuloaded[path] = mod return mod use: (package_name)=> - mod = @load_module(package_name) + mod = @Module(package_name) imports = assert _module_imports[@] for k,v in pairs(mod) imports[k] = v @@ -147,7 +147,7 @@ nomsu_environment = Importer{ return mod export: (package_name)=> - mod = @load_module(package_name) + mod = @Module(package_name) imports = assert _module_imports[@] for k,v in pairs(_module_imports[mod]) if rawget(imports, k) == nil @@ -163,9 +163,9 @@ nomsu_environment = Importer{ for k,v in pairs(mod.COMPILE_RULES) if rawget(@COMPILE_RULES, k) == nil @COMPILE_RULES[k] = v - for k,v in pairs(mod.TESTS) - if rawget(@TESTS, k) == nil - @TESTS[k] = v + --for k,v in pairs(mod.TESTS) + -- if rawget(@TESTS, k) == nil + -- @TESTS[k] = v return mod run: (to_run)=> diff --git a/parser.lua b/parser.lua index 2ae4aee..4016e9b 100644 --- a/parser.lua +++ b/parser.lua @@ -96,7 +96,7 @@ make_parser = function(peg, make_tree) file = input } local tree = peg:match(input, nil, userdata) - if not tree then + if not tree or type(tree) == 'number' then error("File " .. tostring(filename) .. " failed to parse:\n" .. tostring(input)) end return tree diff --git a/parser.moon b/parser.moon index 637425b..8f75eea 100644 --- a/parser.moon +++ b/parser.moon @@ -74,7 +74,7 @@ make_parser = (peg, make_tree=nil)-> :filename, file:input } tree = peg\match(input, nil, userdata) - if not tree + if not tree or type(tree) == 'number' error "File #{filename} failed to parse:\n#{input}" return tree