Auto-formatted and auto-upgraded everything!

This commit is contained in:
Bruce Hill 2018-07-20 20:27:15 -07:00
parent c9df1bc3e8
commit 6728587dfc
37 changed files with 623 additions and 309 deletions

View File

@ -1,4 +1,4 @@
#!/usr/bin/env nomsu -V2.3
#!/usr/bin/env nomsu -V2.5.4.3
use "core"
use "compatibility/compatibility.nom"

View File

@ -1,4 +1,4 @@
#!/usr/bin/env nomsu -V2.4
#!/usr/bin/env nomsu -V2.5.4.3
use "core"
use "compatibility/compatibility.nom"
@ -8,49 +8,69 @@ upgrade %tree to "2.4" as:
"when %":
%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:
if:
(not (%line is syntax tree)):
compile error at %tree.source "WUT: %s"
(not (%line is "Action" syntax tree)):
add %line to %new_lines
(%line.stub is "* %"):
add %line.2 to %conditions
(%line.stub == "* else %"):
add (\(else %block) with vars {block:%line.3}) to %new_lines
(%line.stub != "* % %"):
add %line to %new_lines
else:
add %line.2 to %conditions
%action = %line.3
unless (%action is "Block" syntax tree):
%action = (=lua "Block(\%action.source, \%action)")
add %action to %conditions
add (=lua "Action(\%conditions[1].source, unpack(\%conditions))") to %new_lines
%conditions = []
return (\(if %body) with vars {body:=lua "Block(\%tree[2].source, unpack(\%new_lines))"})
return (..)
\(if %body) with vars {body:=lua "Block(\%tree[2].source, unpack(\%new_lines))"}
"when % is ? %" "when % = ? %":
%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:
if:
(not (%line is "Action" syntax tree)):
add %line to %new_lines
(%line.stub is "* %"):
add %line.2 to %values
(%line.stub == "* else %"):
add (\(else %block) with vars {block:%line.3}) to %new_lines
(%line.stub != "* % %"):
add %line to %new_lines
else:
add %line.2 to %values
%action = %line.3
unless (%action is "Block" syntax tree):
%action = (=lua "Block(\%action.source, \%action)")
add %action to %values
add (=lua "Action(\%values[1].source, unpack(\%values))") to %new_lines
%values = []
return (\(if %var is %body) with vars {var: %tree.2 upgraded, body:=lua "Block(\%tree[5].source, unpack(\%new_lines))"})
return (..)
\(if %var is %body) with vars {..}
var:%tree.2 upgraded, body:=lua "Block(\%tree[5].source, unpack(\%new_lines))"

View File

@ -1,6 +1,9 @@
#!/usr/bin/env nomsu -V2.5
#!/usr/bin/env nomsu -V2.5.4.3
use "core"
use "compatibility/compatibility.nom"
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 (%1 for %2 in %3 matching %4)
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 (..)
%1 for %2 in %3 matching %4

View File

@ -1,4 +1,4 @@
#!/usr/bin/env nomsu -V2.3.4.3
#!/usr/bin/env nomsu -V2.5.4.3
use "core"
use "compatibility/compatibility.nom"
@ -8,23 +8,26 @@ upgrade %tree to "2" as:
%true_body = (%tree.3 upgraded)
unless (%true_body is "Block" syntax tree):
%true_body = (=lua "Block(\%true_body.source, \%true_body)")
%false_body = (%tree.5 upgraded)
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 {..}
\(if %cond %true_body else %false_body) with vars {..}
cond:%tree.2 upgraded, true_body:%true_body, false_body:%false_body
%need_blocks = [..]
"if % %", "unless % %", "for % in % %", "for % = % in % %", "repeat while % %"
"repeat % times %", "repeat %", "repeat until % %", "for % in % to % by % %",
"for % in % to % via % %", "for % in % to % %", "for % % in % %", "do %"
"for % in recursive % %", "test %", "with % %", "result of %"
"repeat % times %", "repeat %", "repeat until % %", "for % in % to % by % %"
"for % in % to % via % %", "for % in % to % %", "for % % in % %"
"do %", "for % in recursive % %", "test %", "with % %", "result of %"
for %n in %need_blocks:
if (%tree.stub is %n):
%bits = (((% upgraded) if (% is syntax tree) else %) for % in %tree)
unless ((last in %bits) is "Block" syntax tree):
%body = (last in %bits)
%bits.(length of %bits) = (=lua "Block(\%body.source, \%body)")
return (=lua "Action(\%tree.source, unpack(\%bits))")

View File

@ -1,4 +1,4 @@
#!/usr/bin/env nomsu -V2.5
#!/usr/bin/env nomsu -V2.5.4.3
use "core"
use "lib/os.nom"
@ -8,7 +8,9 @@ action [upgrade to %version via %upgrade_fn]:
%ACTION_UPGRADES = {}
action [upgrade action %stub to %version via %upgrade_fn]:
unless (%ACTION_UPGRADES.%version): %ACTION_UPGRADES.%version = []
unless %ACTION_UPGRADES.%version:
%ACTION_UPGRADES.%version = []
%ACTION_UPGRADES.%version.%stub = %upgrade_fn
parse [upgrade %tree to %version as %body] as (..)
@ -19,21 +21,31 @@ compile [upgrade action %action to %version as %body] to:
for %i in 1 to (length of %action):
if (%action.%i.type is "Var"):
%replacements.(%action.%i.1) = "\(\%tree as lua id)[\%i]"
local action [make tree %t]:
when:
(%t is "Var" syntax tree):
if (%replacements.(%t.1)):
if %replacements.(%t.1):
return %replacements.(%t.1)
..else:
return "\(%t.type)(\(quote "\(%t.source)"), \(quote "\(%t.1) \0\(=lua "string.format('%X', __MANGLE_INDEX)")"))"
return ".."
\(%t.type)(\(quote "\(%t.source)"), \(..)
quote "\(%t.1) \000\(=lua "string.format('%X', __MANGLE_INDEX)")"
..)
(%t is syntax tree):
%args = ((make tree %) for % in %t)
add "\(\%tree as lua id).source" to %args at index 1
return "\(%t.type)(\(%args joined with ", "))"
else: return (quote "\%t")
else:
return (quote "\%t")
return (..)
Lua ".."
A_upgrade_action_1_to_2_via_3(\(quote %action.stub), \(%version as lua expr), function(\(\%tree as lua id))
A_upgrade_action_1_to_2_via_3(\(quote %action.stub), \(%version as lua expr), function(\(..)
\%tree as lua id
..)
__MANGLE_INDEX = (__MANGLE_INDEX or 0) + 1
return \(make tree %body)
end)
@ -44,8 +56,12 @@ action [..]
..:
local action [%ver as list] ((% as number) for % in %ver matching "[0-9]+")
%versions = {}
for %v = % in %UPGRADES: %versions.%v = (yes)
for %v = % in %ACTION_UPGRADES: %versions.%v = (yes)
for %v = % in %UPGRADES:
%versions.%v = (yes)
for %v = % in %ACTION_UPGRADES:
%versions.%v = (yes)
%versions = ((keys in %versions) sorted by % -> (% as list))
for %ver in %versions:
if ((%ver as list) <= (%start_version as list)): do next %ver
@ -55,6 +71,7 @@ action [..]
%tree with % -> (..)
if ((% is "Action" syntax tree) and %ACTION_UPGRADES.%ver.(%.stub)):
return (call %ACTION_UPGRADES.%ver.(%.stub) with [%])
if %UPGRADES.%ver:
%tree = (call %UPGRADES.%ver with [%tree])
@ -68,7 +85,9 @@ parse [%tree upgraded from %start_version] as (..)
parse [%tree upgraded to %end_version] as (..)
%tree upgraded from (%tree.version or (Nomsu version)) to %end_version
parse [%tree upgraded] as (%tree upgraded from (%tree.version or (Nomsu version)) to (Nomsu version))
parse [%tree upgraded] as (..)
%tree upgraded from (%tree.version or (Nomsu version)) to (Nomsu version)
action [use %path from version %version] (..)
for file %filename in %path:
if (=lua "LOADED[\%filename]"): do next %filename

View File

@ -1,4 +1,4 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
#
This file contains code that supports manipulating and using collections like lists
and dictionaries.
@ -9,10 +9,12 @@ use "core/operators.nom"
# List/dict functions:
# Indexing
test: assume ((2 nd to last in [1, 2, 3, 4, 5]) is 4)
test:
assume ((2 nd to last in [1, 2, 3, 4, 5]) is 4)
compile [..]
%index st to last in %list, %index nd to last in %list, %index rd to last in %list
%index th to last in %list
%index st to last in %list, %index nd to last in %list
%index rd to last in %list, %index th to last in %list
..to (Lua value "utils.nth_to_last(\(%list as lua expr), \(%index as lua expr))")
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -21,24 +23,34 @@ parse [last in %list] as (1 st to last in %list)
parse [first in %list] as %list.1
# Membership testing
test: assume (3 is in [1, 2, 3, 4, 5])
test:
assume (3 is in [1, 2, 3, 4, 5])
action [%item is in %list, %list contains %item, %list has %item]:
for %key = %value in %list: if (%key is %item): return (yes)
for %key = %value in %list:
if (%key is %item): return (yes)
return (no)
test: assume (99 isn't in [1, 2, 3])
test:
assume (99 isn't in [1, 2, 3])
action [..]
%item isn't in %list, %item is not in %list, %list doesn't contain %item
%list does not contain %item, %list doesn't have %item, %list does not have %item
..:
for %key = %value in %list: if (%key is %item): return (no)
for %key = %value in %list:
if (%key is %item): return (no)
return (yes)
test: assume ({x: no} has key "x")
test:
assume ({x:no} has key "x")
parse [%list has key %index, %list has index %index] as (%list.%index != (nil))
test:
assume ({x: no} doesn't have key "y")
assume (not ({x: no} doesn't have key "x"))
assume ({x:no} doesn't have key "y")
assume (not ({x:no} doesn't have key "x"))
parse [..]
%list doesn't have key %index, %list does not have key %index
@ -58,12 +70,12 @@ test:
assume ((first in %list) is 2)
compile [..]
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 (Lua "table.insert(\(%list as lua expr), \(%item as lua expr))")
compile [add %item to %list at index %i] to (..)
Lua "table.insert(\(%list as lua expr), \(%i as lua expr), \(%item as lua expr))"
Lua ".."
table.insert(\(%list as lua expr), \(%i as lua expr), \(%item as lua expr))
compile [pop from %list, remove last from %list] to (..)
Lua value "table.remove(\(%list as lua expr))"
@ -74,11 +86,15 @@ compile [remove index %index from %list] to (..)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# List Comprehension
test: assume (((% * %) for % in [1, 2, 3]) == [1, 4, 9])
test:
assume (((% * %) for % in [1, 2, 3]) == [1, 4, 9])
parse [%expression for %item in %iterable] as (..)
result of:
%comprehension = []
for %item in %iterable: add %expression to %comprehension
for %item in %iterable:
add %expression to %comprehension
return %comprehension
parse [..]
@ -87,37 +103,49 @@ parse [..]
..as (..)
result of:
%comprehension = []
for %index in %start to %stop via %step: add %expression to %comprehension
for %index in %start to %stop via %step:
add %expression to %comprehension
return %comprehension
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test: assume (((% * %) for % in 1 to 3) == [1, 4, 9])
test:
assume (((% * %) for % in 1 to 3) == [1, 4, 9])
parse [%expression for %var in %start to %stop] as (..)
%expression for %var in %start to %stop via 1
test: assume (("\%k,\%v" for %k = %v in {x: 1}) == ["x,1"])
test:
assume (("\%k,\%v" for %k = %v in {x:1}) == ["x,1"])
parse [..]
%expression for %key = %value in %iterable
%expression for %key %value in %iterable
..as (..)
result of:
%comprehension = []
for %key = %value in %iterable: add %expression to %comprehension
for %key = %value in %iterable:
add %expression to %comprehension
return %comprehension
# Dict comprehensions
test: assume (((% * %) = % for % in [1, 2, 3]) == {1: 1, 4: 2, 9: 3})
parse [%key = %value for %item in %iterable, %key %value for %item in %iterable]
..as (..)
test:
assume (((% * %) = % for % in [1, 2, 3]) == {1:1, 4:2, 9:3})
parse [%key = %value for %item in %iterable, %key %value for %item in %iterable] as
..(..)
result of:
%comprehension = {}
for %item in %iterable: %comprehension.%key = %value
for %item in %iterable:
%comprehension.%key = %value
return %comprehension
test:
assume ((%k = (%v * %v) for %k = %v in {x: 1, y: 2, z: 3}) == {x: 1, y: 4, z: 9})
assume ((%k = (%v * %v) for %k = %v in {x:1, y:2, z:3}) == {x:1, y:4, z:9})
parse [..]
%key = %value for %src_key = %src_value in %iterable
@ -125,7 +153,9 @@ parse [..]
..as (..)
result of:
%comprehension = {}
for %src_key = %src_value in %iterable: %comprehension.%key = %value
for %src_key = %src_value in %iterable:
%comprehension.%key = %value
return %comprehension
parse [..]
@ -134,40 +164,56 @@ parse [..]
..as (..)
result of:
%comprehension = {}
for %item in %start to %stop via %step: %comprehension.%key = %value
for %item in %start to %stop via %step:
%comprehension.%key = %value
return %comprehension
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test: assume (((% * %) = % for % in 1 to 3) == {1: 1, 4: 2, 9: 3})
test:
assume (((% * %) = % for % in 1 to 3) == {1:1, 4:2, 9:3})
parse [..]
%key = %value for %item in %start to %stop
%key %value for %item in %start to %stop
..as (%key = %value for %item in %start to %stop via 1)
test: assume (([[1, 2], [3, 4]] flattened) == [1, 2, 3, 4])
test:
assume (([[1, 2], [3, 4]] flattened) == [1, 2, 3, 4])
action [%lists flattened]:
%flat = []
for %list in %lists: for %item in %list: add %item to %flat
for %list in %lists:
for %item in %list: add %item to %flat
return %flat
test: assume ((entries in {x: 1}) == [{key: "x", value: 1}])
parse [entries in %dict] as ({key: %k, value: %v} for %k = %v in %dict)
test: assume ((keys in {x: 1}) == ["x"])
test:
assume ((entries in {x:1}) == [{key:"x", value:1}])
parse [entries in %dict] as ({key:%k, value:%v} for %k = %v in %dict)
test:
assume ((keys in {x:1}) == ["x"])
parse [keys in %dict, keys of %dict] as (%k for %k = %v in %dict)
test: assume ((values in {x: 1}) == [1])
test:
assume ((values in {x:1}) == [1])
parse [values in %dict, values of %dict] as (%v for %k = %v in %dict)
# Metatable stuff
test:
%t = {}
set %t 's metatable to {__tostring: [%] -> "XXX"}
set %t 's metatable to {__tostring:[%] -> "XXX"}
assume ("\%t" == "XXX")
compile [set %dict 's metatable to %metatable] to (..)
Lua "setmetatable(\(%dict as lua expr), \(%metatable as lua expr));"
test: assume (({} with fallback % -> (% + 1)).10 == 11)
test:
assume (({} with fallback % -> (% + 1)).10 == 11)
compile [%dict with fallback %key -> %value] to (..)
Lua value ".."
setmetatable(\(%dict as lua expr), {__index=function(self, \(%key as lua expr))
@ -184,7 +230,7 @@ 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])
@ -196,7 +242,9 @@ parse [sort %items by %item = %key_expr, sort %items by %item -> %key_expr] as (
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test: assume ((sorted [3, 1, 2]) == [1, 2, 3])
test:
assume ((sorted [3, 1, 2]) == [1, 2, 3])
action [%items sorted, sorted %items]:
%copy = (% for % in %items)
sort %copy
@ -208,9 +256,15 @@ parse [%items sorted by %item = %key, %items sorted by %item -> %key] as (..)
sort %copy by %item = %key
return %copy
test: assume ((unique [1, 2, 1, 3, 2, 3]) == [1, 2, 3])
test:
assume ((unique [1, 2, 1, 3, 2, 3]) == [1, 2, 3])
action [unique %items]:
%unique = []
%seen = {}
for % in %items: unless %seen.% (: add % to %unique; %seen.% = (yes))
for % in %items:
unless %seen.%:
add % to %unique
%seen.% = (yes)
return %unique

View File

@ -1,4 +1,4 @@
#!/usr/bin/env nomsu -V2.3.4.3
#!/usr/bin/env nomsu -V2.5.4.3
#
This file contains compile-time actions that define basic control flow structures
like "if" statements and loops.
@ -13,11 +13,20 @@ test: do nothing
compile [do nothing] to (Lua "")
# Conditionals
test: if (no): barf "conditional fail"
compile [if %condition %if_body] to (..)
Lua "if \(%condition as lua expr) then\n \(%if_body as lua statements)\nend"
test:
if (no):
barf "conditional fail"
compile [if %condition %if_body] to (..)
Lua ".."
if \(%condition as lua expr) then
\(%if_body as lua statements)
end
test:
unless (yes):
barf "conditional fail"
test: unless (yes): barf "conditional fail"
parse [unless %condition %unless_body] as (if (not %condition) %unless_body)
compile [..]
if %condition %if_body else %else_body, unless %condition %else_body else %if_body
@ -42,10 +51,12 @@ 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: yes, List: yes, Dict: yes, Number: yes}.(%when_true_expr.type):
if {Text:yes, List:yes, Dict:yes, Number:yes}.(%when_true_expr.type):
return (..)
Lua value ".."
(\(%condition as lua expr) and \(%when_true_expr as lua expr) or \(%when_false_expr as lua expr))
(\(%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
@ -61,6 +72,7 @@ compile [..]
end
end)())
# GOTOs
compile [=== %label ===, --- %label ---, *** %label ***] to (..)
Lua "::label_\(%label as lua identifier)::"
@ -91,7 +103,9 @@ compile [do next repeat] to (Lua "goto continue_repeat")
compile [stop repeating] to (Lua "goto stop_repeat")
compile [repeat while %condition %body] to:
%lua = (..)
Lua "while \(%condition as lua expr) do\n \(%body as lua statements)"
Lua ".."
while \(%condition as lua expr) do
\(%body as lua statements)
if (..)
%body has subtree % where ((%.type == "Action") and (%.stub is "do next repeat"))
@ -115,7 +129,9 @@ parse [repeat %body] as (repeat while (yes) %body)
parse [repeat until %condition %body] as (repeat while (not %condition) %body)
compile [repeat %n times %body] to:
%lua = (..)
Lua "for i=1,\(%n as lua expr) do\n \(%body as lua statements)"
Lua ".."
for i=1,\(%n as lua expr) do
\(%body as lua statements)
if (..)
%body has subtree % where ((%.type == "Action") and (%.stub is "do next repeat"))
@ -154,10 +170,14 @@ compile [..]
..to:
# This uses Lua's approach of only allowing loop-scoped variables in a loop
unless (%var.type is "Var"): compile error at %var.source "Loop expected variable, not: %s"
unless (%var.type is "Var"):
compile error at %var.source "Loop expected variable, not: %s"
%lua = (..)
Lua ".."
for \(%var as lua expr)=\(%start as lua expr),\(%stop as lua expr),\(%step as lua expr) do
for \(%var as lua expr)=\(%start as lua expr),\(%stop as lua expr),\(..)
%step as lua expr
.. do
\(%body as lua statements)
if (..)
@ -185,11 +205,14 @@ compile [..]
parse [for %var in %start to %stop %body] as (..)
for %var in %start to %stop via 1 %body
# For-each loop (lua's "ipairs()")
compile [for %var in %iterable %body] to:
# This uses Lua's approach of only allowing loop-scoped variables in a loop
unless (%var.type is "Var"): compile error at %var.source "Loop expected variable, not: %s"
unless (%var.type is "Var"):
compile error at %var.source "Loop expected variable, not: %s"
%lua = (..)
Lua ".."
for i,\(%var as lua identifier) in ipairs(\(%iterable as lua expr)) do
@ -199,8 +222,7 @@ compile [for %var in %iterable %body] to:
%body has subtree % where (..)
(%.type == "Action") and ((%.stub is "do next %") and (%.(3).1 == %var.1))
..:
to %lua write (..)
Lua "\n\(compile as (===next %var ===))"
to %lua write (Lua "\n\(compile as (===next %var ===))")
to %lua write "\nend --foreach-loop"
if (..)
@ -218,30 +240,35 @@ compile [for %var in %iterable %body] to:
# Dict iteration (lua's "pairs()")
compile [for %key = %value in %iterable %body, for %key %value in %iterable %body]
compile [..]
for %key = %value in %iterable %body, for %key %value in %iterable %body
..to:
# This uses Lua's approach of only allowing loop-scoped variables in a loop
unless (%key.type is "Var"): compile error at %key.source "Loop expected variable, not: %s"
unless (%value.type is "Var"): compile error at %value.source "Loop expected variable, not: %s"
unless (%key.type is "Var"):
compile error at %key.source "Loop expected variable, not: %s"
unless (%value.type is "Var"):
compile error at %value.source "Loop expected variable, not: %s"
%lua = (..)
Lua ".."
for \(%key as lua identifier),\(%value as lua identifier) in pairs(\(%iterable as lua expr)) do
for \(%key as lua identifier),\(%value as lua identifier) in pairs(\(..)
%iterable as lua expr
..) do
\(%body as lua statements)
if (..)
%body has subtree % where (..)
(%.type == "Action") and ((%.stub is "do next %") and (%.(3).1 == %key.1))
..:
to %lua write (..)
Lua "\n\(compile as (===next %key ===))"
to %lua write (Lua "\n\(compile as (===next %key ===))")
if (..)
%body has subtree % where (..)
(%.type == "Action") and ((%.stub is "do next %") and (%.(3).1 == %value.1))
..:
to %lua write (..)
Lua "\n\(compile as (===next %value ===))"
to %lua write (Lua "\n\(compile as (===next %value ===))")
to %lua write "\nend --foreach-loop"
%stop_labels = (Lua "")
@ -259,7 +286,10 @@ compile [for %key = %value in %iterable %body, for %key %value in %iterable %bod
if ((length of "\%stop_labels") > 0):
%lua = (..)
Lua "do -- scope for stopping for % = % loop\n \%lua\%stop_labels\nend"
Lua ".."
do -- scope for stopping for % = % loop
\%lua\%stop_labels
end
return %lua
@ -270,22 +300,32 @@ compile [if %body, when %body] to:
%code = (Lua "")
%clause = "if"
%else_allowed = (yes)
unless (%body.type is "Block"): compile error at %body.source "'if' expected a Block, but got: %s"
unless (%body.type is "Block"):
compile error at %body.source "'if' expected a Block, but got: %s"
for %line in %body:
unless (..)
((%line.type is "Action") and ((length of %line) >= 2))
..and (%line.(length of %line) is "Block" syntax tree)
((%line.type is "Action") and ((length of %line) >= 2)) and (..)
%line.(length of %line) is "Block" syntax tree
..:
compile error at %line.source ".."
Invalid line for 'if', each line should contain conditional expressions \
..followed by a block, or "else" followed by a block:
Invalid line for 'if', each line should contain conditional expressions followed by a block, or "else" followed by a block:
%s
%action = %line.(length of %line)
if ((%line.1 is "else") and ((length of %line) == 2)):
unless %else_allowed: compile error at %line.source "Can't have two 'else' blocks"
unless %else_allowed:
compile error at %line.source "Can't have two 'else' blocks"
unless ((length of "\%code") > 0):
compile error at %line.source "Can't have an 'else' block without a preceeding condition"
to %code write "\nelse\n \(%action as lua statements)"
compile error at %line.source ".."
Can't have an 'else' block without a preceeding condition
to %code write ".."
else
\(%action as lua statements)
%else_allowed = (no)
..else:
to %code write "\%clause "
@ -294,37 +334,56 @@ compile [if %body, when %body] to:
compile error at %line.source ".."
Invalid condition for 'if' statement:
%s
if (%i > 1): to %code write " or "
if (%i > 1):
to %code write " or "
to %code write (%line.%i as lua expr)
to %code write " then\n \(%action as lua statements)"
to %code write ".."
then
\(%action as lua statements)
%clause = "\nelseif"
if ((length of "\%code") == 0):
compile error at %body.source "'if' block has an empty body"
to %code write "\nend --when"
return %code
# Switch statement
compile [if %branch_value is %body, when %branch_value is %body] to:
%code = (Lua "")
%clause = "if"
%else_allowed = (yes)
unless (%body.type is "Block"): compile error at %body.source "'if' expected a Block, but got: %s"
unless (%body.type is "Block"):
compile error at %body.source "'if' expected a Block, but got: %s"
for %line in %body:
unless (..)
((%line.type is "Action") and ((length of %line) >= 2))
..and (%line.(length of %line) is "Block" syntax tree)
((%line.type is "Action") and ((length of %line) >= 2)) and (..)
%line.(length of %line) is "Block" syntax tree
..:
compile error at %line.source ".."
Invalid line for 'if % is % %', each line should contain expressions \
..followed by a block, or "else" followed by a block:
Invalid line for 'if % is % %', each line should contain expressions followed by a block, or "else" followed by a block:
%s
%action = %line.(length of %line)
if ((%line.1 is "else") and ((length of %line) == 2)):
unless %else_allowed: compile error at %line.source "Can't have two 'else' blocks"
unless %else_allowed:
compile error at %line.source "Can't have two 'else' blocks"
unless ((length of "\%code") > 0):
compile error at %line.source "Can't have an 'else' block without a preceeding condition"
to %code write "\nelse\n \(%action as lua statements)"
compile error at %line.source ".."
Can't have an 'else' block without a preceeding condition
to %code write ".."
else
\(%action as lua statements)
%else_allowed = (no)
..else:
to %code write "\%clause "
@ -333,13 +392,21 @@ compile [if %branch_value is %body, when %branch_value is %body] to:
compile error at %line.source ".."
Invalid condition for 'if' statement:
%s
if (%i > 1): to %code write " or "
if (%i > 1):
to %code write " or "
to %code write "branch_value == \(%line.%i as lua expr)"
to %code write " then\n \(%action as lua statements)"
to %code write ".."
then
\(%action as lua statements)
%clause = "\nelseif"
if ((length of "\%code") == 0):
compile error at %body.source "'if % is % %' block has an empty body"
to %code write "\nend --when"
return (..)
Lua ".."
@ -348,9 +415,13 @@ compile [if %branch_value is %body, when %branch_value is %body] to:
\%code
end --if % is
# Do/finally
compile [do %action] to (..)
Lua "do\n \(%action as lua statements)\nend --do"
Lua ".."
do
\(%action as lua statements)
end --do
compile [do %action then always %final_action] to (..)
Lua ".."

View File

@ -1,10 +1,14 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
#
This file defines the code that creates and manipulates coroutines
use "core/metaprogramming.nom"
compile [coroutine %body, generator %body] to (..)
Lua value "(function()\n \(%body as lua statements)\nend)"
Lua value ".."
(function()
\(%body as lua statements)
end)
compile [->] to (Lua value "coroutine.yield(true)")
compile [-> %] to (Lua value "coroutine.yield(true, \(% as lua expr))")

View File

@ -1,8 +1,9 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
#
This file contains basic error reporting code
use "core/metaprogramming.nom"
compile [traceback] to (Lua value "debug.traceback()")
compile [traceback %] to (Lua value "debug.traceback('', \(% as lua expr))")
compile [barf] to (Lua "error(nil, 0);")

View File

@ -1,8 +1,9 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
#
This file contains basic input/output code
use "core/metaprogramming.nom"
compile [say %message] to (..)
lua> ".."
if \%message.type == "Text" then
@ -16,5 +17,7 @@ compile [ask %prompt] to (..)
if \%prompt.type == "Text" then
return LuaCode.Value(tree.source, "(io.write(", \(%prompt as lua expr), ") and io.read())");
else
return LuaCode.Value(tree.source, "(io.write(tostring(", \(%prompt as lua expr), ")) and io.read())");
return LuaCode.Value(tree.source, "(io.write(tostring(", \(..)
%prompt as lua expr
.., ")) and io.read())");
end

View File

@ -1,4 +1,4 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
#
This file defines some common math literals and functions
@ -34,9 +34,7 @@ compile [arc tangent %y / %x, atan2 %y %x] to (..)
Lua value "math.atan2(\(%y as lua expr), \(%x as lua expr))"
compile [hyperbolic sine %, sinh %] to (Lua value "math.sinh(\(% as lua expr))")
compile [hyperbolic cosine %, cosh %] to (..)
Lua value "math.cosh(\(% as lua expr))"
compile [hyperbolic cosine %, cosh %] to (Lua value "math.cosh(\(% as lua expr))")
compile [hyperbolic tangent %, tanh %] to (..)
Lua value "math.tanh(\(% as lua expr))"
@ -87,41 +85,45 @@ action [avg of %items, average of %items] (=lua "(utils.sum(\%items)/#\%items)")
compile [min of %items, smallest of %items, lowest of %items] to (..)
Lua value "utils.min(\(%items as lua expr))"
compile [max of %items, biggest of %items, largest of %items, highest of %items]
..to (Lua value "utils.max(\(%items as lua expr))")
compile [max of %items, biggest of %items, largest of %items, highest of %items] to
..(Lua value "utils.max(\(%items as lua expr))")
parse [min of %items by %item = %value_expr] as (..)
result of:
set {%best: nil, %best_key: nil}
set {%best:nil, %best_key:nil}
for %item in %items:
%key = %value_expr
if ((%best == (nil)) or (%key < %best_key)):
set {%best: %item, %best_key: %key}
set {%best:%item, %best_key:%key}
return %best
parse [max of %items by %item = %value_expr] as (..)
result of:
set {%best: nil, %best_key: nil}
set {%best:nil, %best_key:nil}
for %item in %items:
%key = %value_expr
if ((%best == (nil)) or (%key > %best_key)):
set {%best: %item, %best_key: %key}
set {%best:%item, %best_key:%key}
return %best
# Random functions
action [seed random with %] (..)
lua> "math.randomseed(\%);\nfor i=1,20 do math.random(); end"
lua> ".."
math.randomseed(\%);
for i=1,20 do math.random(); end
parse [seed random] as (seed random with (=lua "os.time()"))
compile [random number, random, rand] to (Lua value "math.random()")
compile [random int %n, random integer %n, randint %n] to (..)
Lua value "math.random(\(%n as lua expr))"
compile [random from %low to %high, random number from %low to %high, rand %low %high]
compile [..]
random from %low to %high, random number from %low to %high
rand %low %high
..to (Lua value "math.random(\(%low as lua expr), \(%high as lua expr))")
action [random choice from %elements, random choice %elements, random %elements]
..(=lua "\%elements[math.random(#\%elements)]")
action [random choice from %elements, random choice %elements, random %elements] (..)
=lua "\%elements[math.random(#\%elements)]"

View File

@ -1,4 +1,4 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
#
This File contains actions for making actions and compile-time actions and some helper
functions to make that easier.
@ -32,13 +32,14 @@ lua> ".."
lua> ".."
nomsu.COMPILE_ACTIONS["compile % to %"] = function(nomsu, tree, \%actions, \%body)
local \%args = {"nomsu", "tree", unpack(table.map(\%actions[1]:get_args(), function(a) return tostring(nomsu:compile(a)) end))}
local \%args = {"nomsu", "tree", unpack(table.map(\%actions[1]:get_args(), function(a) return tostring(nomsu:compile(\
..a)) end))}
local lua = LuaCode(tree.source, "nomsu.COMPILE_ACTIONS[", repr(\%actions[1].stub),
"] = ", \(compile as (%args -> %body)))
for i=2,#\%actions do
local alias = \%actions[i]
local \%alias_args = {"nomsu", "tree", unpack(table.map(alias:get_args(), function(a) return tostring(nomsu:compile(a)) \
..end))}
local \%alias_args = {"nomsu", "tree", unpack(table.map(alias:get_args(), function(a) return tostring(nomsu:compile(\
..a)) end))}
lua:append("\\nnomsu.COMPILE_ACTIONS[", repr(alias.stub), "] = ")
if utils.equivalent(\%args, \%alias_args) then
lua:append("nomsu.COMPILE_ACTIONS[", repr(\%actions[1].stub), "]")
@ -108,8 +109,7 @@ compile [parse %actions as %body] to (..)
elseif replacements[t[1]] then
return replacements[t[1]]
else
return t.type.."("..repr(tostring(t.source))..", "..repr(t[1].." \\0").."..string.format('%X', \
..__MANGLE_INDEX))"
return t.type.."("..repr(tostring(t.source))..", "..repr(t[1].." \\0").."..string.format('%X', __MANGLE_INDEX))"
end
end
local \%new_body = LuaCode(\%body.source,
@ -191,7 +191,8 @@ compile [%lua <-write %code, to %lua write %code] to (..)
Lua "\(%lua as lua expr):append(\(%code as lua expr));"
compile [to %lua write %code joined by %glue] to (..)
Lua "\(%lua as lua expr):concat_append(\(%code as lua expr), \(%glue as lua expr));"
Lua ".."
\(%lua as lua expr):concat_append(\(%code as lua expr), \(%glue as lua expr));
compile [quote %s] to (Lua value "repr(\(%s as lua expr))")
compile [type of %obj] to (Lua value "type(\(%obj as lua expr))")
@ -200,11 +201,15 @@ compile [parse %text] to (..)
compile [parse %text from %filename] to (..)
Lua value ".."
nomsu:parse(NomsuCode(Source(\(%filename as lua expr), 1, #\(%text as lua expr)), \(%text as lua expr)))
nomsu:parse(NomsuCode(Source(\(%filename as lua expr), 1, #\(%text as lua expr)), \(..)
%text as lua expr
..))
compile [run %nomsu_code] to (..)
Lua value ".."
nomsu:run(\(%nomsu_code as lua expr), \(=lua "repr(tostring(\(%nomsu_code.source)))"))
nomsu:run(\(%nomsu_code as lua expr), \(..)
=lua "repr(tostring(\(%nomsu_code.source)))"
..)
action [run tree %tree, %tree as value] (lua> "return nomsu:run(\%tree)")
compile [compile %block, compiled %block, %block compiled] to (..)

View File

@ -1,4 +1,4 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
#
This file contains definitions of operators like "+" and "and".
@ -75,9 +75,13 @@ compile [set %assignments] to:
end
end)
local target_lua = \(%target as lua)
if not target_lua.is_value then error("Invalid target for assignment: "..\(%target as text)) end
if not target_lua.is_value then error("Invalid target for assignment: "..\(..)
%target as text
..) end
local value_lua = \(%value as lua)
if not value_lua.is_value then error("Invalid value for assignment: "..\(%value as text)) end
if not value_lua.is_value then error("Invalid value for assignment: "..\(..)
%value as text
..) end
if \%target.type == "Var" then
lhs:add_free_vars({tostring(target_lua)})
end
@ -135,7 +139,10 @@ compile [with %assignments %body] to:
\%lua:prepend("local ", lhs, " = ", rhs, ";\\n")
return (..)
Lua "do\n \%lua\nend -- 'with' block"
Lua ".."
do
\%lua
end -- 'with' block
# Math Operators
@ -199,7 +206,9 @@ compile [%x ARSHIFT %shift, %x >> %shift] to (..)
# Unary operators
compile [- %] to (Lua value "(- \(% as lua expr))")
compile [not %] to (Lua value "(not \(% as lua expr))")
test: assume ((length of [1, 2, 3]) == 3)
test:
assume ((length of [1, 2, 3]) == 3)
compile [length of %list, || %list ||] to (Lua value "(#\(%list as lua expr))")
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -1,4 +1,4 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
#
This file contains definitions pertaining to variable scoping
@ -6,18 +6,29 @@ use "core/metaprogramming.nom"
use "core/operators.nom"
use "core/collections.nom"
use "core/control_flow.nom"
compile [with local %locals %body, with local %locals do %body] to:
%body_lua = (%body as lua statements)
if %locals.type is:
"Dict":
%body_lua = (..)
Lua "\(compile as (<- %locals))\n\%body_lua"
Lua ".."
\(compile as (<- %locals))
\%body_lua
declare locals ("\(%.1 as lua)" for % in %locals) in %body_lua
"List": declare locals ("\(% as lua)" for % in %locals) in %body_lua
"Var" "Action": declare locals ["\(%locals as lua)"] in %body_lua
else: compile error at %locals.source "Unexpected locals: %s"
"List":
declare locals ("\(% as lua)" for % in %locals) in %body_lua
"Var" "Action":
declare locals ["\(%locals as lua)"] in %body_lua
else:
compile error at %locals.source "Unexpected locals: %s"
return (..)
Lua "do\n \%body_lua\nend"
Lua ".."
do
\%body_lua
end

View File

@ -1,4 +1,4 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
#
This file contains some definitions of text escape sequences, including ANSI console
color codes.
@ -20,7 +20,8 @@ compile [..]
%text with %sub instead of %patt, %text with %patt replaced by %sub
%text s/ %patt / %sub
..to (..)
Lua value "((\(%text as lua expr)):gsub(\(%patt as lua expr), \(%sub as lua expr)))"
Lua value ".."
((\(%text as lua expr)):gsub(\(%patt as lua expr), \(%sub as lua expr)))
action [lines in %text, lines of %text] (..)
lua> ".."
@ -49,7 +50,8 @@ compile [%expr for %match in %text matching %patt] to (..)
end)()
compile [%text matches %pattern] to (..)
Lua value "(\(%text as lua expr):match(\(%pattern as lua expr)) and true or false)"
Lua value ".."
(\(%text as lua expr):match(\(%pattern as lua expr)) and true or false)
# Text literals

View File

@ -1,4 +1,4 @@
#!/usr/bin/env nomsu -V2.3.4.3
#!/usr/bin/env nomsu -V2.5.4.3
# How do I...
# Write a comment? Put a # and go till the end of the line
# How do I write a multi-line comment?
@ -56,10 +56,12 @@ 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: \(1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9) between a backslash and two periods.
Similarly, you can put a long interpolated indented value like: \(..)
1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9
.. between a backslash and two periods.
say "Single-line text can contain escape sequences like \", \\, \000, and \n"
@ -81,8 +83,8 @@ say %my_list.1
say (length of %my_list)
# How do I define a dictionary/hash map?
%my_dict = {x: 99, y: 101}
%my_dict = {x: 101, y: 2, "99 bottles": 99, 653: 292}
%my_dict = {x:99, y:101}
%my_dict = {x:101, y:2, "99 bottles":99, 653:292}
# How do I use a dict?
# Dicts are also implemented as Lua tables, so they're accessed and modified the same way as lists
@ -90,41 +92,59 @@ say %my_dict.x
%my_dict.x = 9999
# How do I do conditional branching?
if (1 < 10): say "1 is indeed < 10"
if (1 > 10): say "this won't print"
..else: say "this will print"
if (1 < 10):
say "1 is indeed < 10"
if (1 > 10):
say "this won't print"
..else:
say "this will print"
# There's no "elseif", so for longer conditionals, a "when" branch is the best option
when:
* (3 > 6)
* (3 > 5)
* (3 > 4): say "this won't print"
* (3 > 3): say "this won't print"
* (3 > 2): say "this will print"
*else: say "this is the default case"
if:
(3 > 6) (3 > 5) (3 > 4):
say "this won't print"
(3 > 3):
say "this won't print"
(3 > 2):
say "this will print"
else:
say "this is the default case"
# How do I do a switch statement?
when 3 = ?:
* 0
* 1
* 2: say "this won't print"
* 3: say "this will print"
*else: say "this won't print"
if 3 is:
0 1 2:
say "this won't print"
3:
say "this will print"
else:
say "this won't print"
# How do I loop over a list (a foreach loop)?
%list = [1, 2, 3]
for %x in %list: say "For %x loop #\%x"
for %x in %list:
say "For %x loop #\%x"
# How do I loop over a number range?
# This is inclusive, so it will loop over 1,2, and 3
for %i in 1 to 3: say "For %i in 1 to 3 loop #\%i"
for %i in 1 to 3:
say "For %i in 1 to 3 loop #\%i"
# This will print 0,2, and 4
for %even in 0 to 5 by 2: say "Even #\%even"
for %backwards in 3 to 1 by -1: say "Backwards #\%backwards"
for %backwards in 3 to 1 by -1:
say "Backwards #\%backwards"
# How do I do a 'while' loop?
%x = 1
@ -182,7 +202,8 @@ action [..]
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
..: say "\(%better_things capitalized) rule and \%worse_things drool!"
..:
say "\(%better_things capitalized) rule and \%worse_things drool!"
I like "dogs" more than "cats"
I think "chihuahuas" are worse than "corgis"
@ -208,7 +229,7 @@ action [>> %foo_bar $$$^ --> % @&_~-^-~_~-^ %1 !]:
>> "wow" $$$^ --> "so flexible!" @&_~-^-~_~-^ "even numbers can be variables!" !
# There's also full unicode support
%こんにちは = "\227\129\147\227\130\147\227\129\171\227\129\161\227\129\175"
%こんにちは = "こんにちは"
action [% と言う] "\%世界"
say (%こんにちは と言う)
@ -228,7 +249,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 "short second arg"
say both "Very long first argument that needs its own line" and also ".."
short second arg
action [my favorite number] (21 + 2)
# This can be nested:
@ -236,9 +259,7 @@ say both (my favorite number) and also "foo"
# Macros:
# The "lua> %" and "=lua %" macros can be used to write raw lua code:
action [say the time] (..)
lua> "io.write(\"The OS time is: \", os.time(), \"\\n\");"
action [say the time] (lua> "io.write(\"The OS time is: \", os.time(), \"\\n\");")
say the time
say "Math expression result is: \(=lua "(1 + 2*3 + 3*4)^2")"
@ -251,7 +272,10 @@ parse [if %condition is untrue %body] as (if (not %condition) %body)
# Or to transform nomsu code into custom lua code using "compile % to %"
compile [if %condition on opposite day %body] to (..)
Lua "if not \(%condition as lua expr) then\n \(%body as lua statements)\nend"
Lua ".."
if not \(%condition as lua expr) then
\(%body as lua statements)
end
# Constants can be defined as macros
@ -277,11 +301,11 @@ if (1 > (TWENTY)) on opposite day:
# How do I use an action as a value?
# Well... it's always *possible* to fall back to Lua behavior for something like this:
action [best of %items according to %key_fn]:
set {%best: nil, %best_key: nil}
set {%best:nil, %best_key:nil}
for %item in %items:
%key = (=lua "\%key_fn(\%item)")
if ((%best is (nil)) or (%key > %best_key)):
set {%best: %item, %best_key: %key}
set {%best:%item, %best_key:%key}
return %best
@ -293,11 +317,11 @@ say (best of [2, -3, 4, -8] according to ([%x] -> (%x * %x)))
want to use:
parse [best of %items where %item_var has score %key_expr] as (..)
result of:
set {%best: nil, %best_key: nil}
set {%best:nil, %best_key:nil}
for %item_var in %items:
%key = %key_expr
if ((%best is (nil)) or (%key > %best_key)):
set {%best: %item_var, %best_key: %key}
set {%best:%item_var, %best_key:%key}
return %best

View File

@ -1,19 +1,22 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
#
This file defines actions for ANSI console color escape codes.
use "core"
test: bright "\(green)Color test passed."
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
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:
with {%escapecode: "\27[\(%colornum)m"}:
with {%escapecode:"\027[\(%colornum)m"}:
run ".."
#!/usr/bin/env nomsu -V1
compile [\%name] to: Lua value (quote \(quote %escapecode))

View File

@ -1,8 +1,9 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
#
This file defines some actions for hashing files and looking up files by hash.
use "core"
action [file with hash %hash]:
lua> ".."
local Hash = require("openssl.digest")
@ -21,6 +22,7 @@ action [hash %, sha1 %]:
%hashlib = (=lua "require('openssl.digest')")
%hash = (=lua "\%hashlib.new('sha1'):final(\%)")
return (..)
=lua "\%hash:gsub('.', function(c) return string.format('%02x', string.byte(c)) end)"
=lua ".."
\%hash:gsub('.', function(c) return string.format('%02x', string.byte(c)) end)
parse [hash of file %filename] as (sha1 (=lua "io.open(\%filename):read('*a')"))

View File

@ -1,8 +1,9 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
#
This file contains the implementation of an Object-Oriented programming system.
use "core"
compile [@, me] to (Lua value "self")
compile [method %actions %body] to:
%lua = (compile as (action %actions %body))
@ -12,7 +13,10 @@ compile [method %actions %body] to:
to %lua write "\nclass.\(% as lua id) = \(% as lua id)"
return (..)
Lua "do -- Method: \(%actions.(1).stub)\n \%lua\nend"
Lua ".."
do -- Method: \(%actions.(1).stub)
\%lua
end
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -1,8 +1,9 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
#
This file defines some actions that interact with the operating system and filesystem.
use "core"
action [path of Nomsu file %filename]:
lua> "for i,f in files.walk(\%filename) do return f end"
barf "Could not find file: \%filename"
@ -37,7 +38,10 @@ action [..]
write to file %filename %text, to file %filename write %text
write %text to file %filename
..:
lua> "local file = io.open(\%filename, 'w')\nfile:write(\%text)\nfile:close()"
lua> ".."
local file = io.open(\%filename, 'w')
file:write(\%text)
file:close()
action [line number of %pos in %str] (=lua "files.get_line_number(\%str, \%pos)")
action [line %line_num in %str] (=lua "files.get_line(\%str, \%line_num)")

View File

@ -1,9 +1,10 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
#
This file contains a set of definitions that bring some familiar language features
from other languages into nomsu (e.g. "==" and "continue")
use "core"
parse [%a == %b] as (%a = %b)
parse [%a == %b] as (%a is %b)
parse [%a ~= %b, %a != %b, %a <> %b] as (%a is not %b)
@ -35,7 +36,9 @@ compile [function %args %body, lambda %args %body] to:
to %lua write ")\n "
%body = (%body as lua)
lua> "\%body:convert_to_statements('return ');"
for % in %args.value: lua> "\%body:remove_free_vars(\%);"
for % in %args.value:
lua> "\%body:remove_free_vars(\%);"
to %lua write %body
to %lua write "\nend)"
return %lua

View File

@ -1,3 +1,3 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
# This file sets the current library version.
lua> "NOMSU_LIB_VERSION = 3"

View File

@ -1,13 +1,14 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
#..
Tests for the stuff defined in core/control_flow.nom
use "core"
assume ((2 nd to last in [1, 2, 3, 4, 5]) == 4)
assume (3 is in [1, 2, 3, 4, 5])
assume (99 isn't in [1, 2, 3])
assume ({x: no} has key "x")
assume ({x: no} doesn't have key "y")
assume (not ({x: no} doesn't have key "x"))
assume ({x:no} has key "x")
assume ({x:no} doesn't have key "y")
assume (not ({x:no} doesn't have key "x"))
assume ((length of [1, 2, 3]) == 3)
%list = [1, 2, 3, 4, 5]
append 6 to %list
@ -17,20 +18,20 @@ assume ((last in %list) == 5)
remove index 1 from %list
assume ((first in %list) == 2)
assume (((% * %) for % in [1, 2, 3]) == [1, 4, 9])
assume ((%k = (%v * %v) for %k = %v in {x: 1, y: 2, z: 3}) == {x: 1, y: 4, z: 9})
assume ((%k for %k = %v in {x: 1}) == ["x"])
assume ((% = (% * %) for % in [1, 2, 3]) == {1: 1, 2: 4, 3: 9})
assume ((%k = (%v * %v) for %k = %v in {x:1, y:2, z:3}) == {x:1, y:4, z:9})
assume ((%k for %k = %v in {x:1}) == ["x"])
assume ((% = (% * %) for % in [1, 2, 3]) == {1:1, 2:4, 3:9})
assume (([[1, 2], [3, 4]] flattened) == [1, 2, 3, 4])
assume ((entries in {x: 1}) == [{key: "x", value: 1}])
assume ((keys in {x: 1}) == ["x"])
assume ((values in {x: 1}) == [1])
assume ((entries in {x:1}) == [{key:"x", value:1}])
assume ((keys in {x:1}) == ["x"])
assume ((values in {x:1}) == [1])
assume ((sorted [3, 1, 2]) == [1, 2, 3])
%x = [3, 1, 2]
sort %x
assume (%x == [1, 2, 3])
sort %x by % = (- %)
assume (%x == [3, 2, 1])
%keys = {1: 999, 2: 0, 3: 50}
%keys = {1:999, 2:0, 3:50}
sort %x by % = %keys.%
assume (%x == [2, 3, 1])
assume ((unique [1, 2, 1, 3, 2, 3]) == [1, 2, 3])

View File

@ -1,3 +1,4 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
use "lib/consolecolor.nom"
say (bright (green "Color test passed."))

View File

@ -1,19 +1,27 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
#
Tests for the stuff defined in core/control_flow.nom
use "core"
do nothing
action [test conditionals]:
if (yes): %loc1 = (yes)
if (no): barf "entered if 'no' conditional"
unless (yes): barf "entered unless 'yes' conditional"
if (no):
barf "entered if 'no' conditional"
unless (yes):
barf "entered unless 'yes' conditional"
if (yes): %loc2 = (yes)
..else: barf "entered if 'yes' else conditional"
..else:
barf "entered if 'yes' else conditional"
unless (no) (%loc3 = (yes)) else (barf "entered unless 'no' else conditional")
assume (all of [%loc1 == (nil), %loc2 == (nil), %loc3 == (nil)]) or barf "conditionals leaking locals"
assume (all of [%loc1 == (nil), %loc2 == (nil), %loc3 == (nil)]) or barf ".."
conditionals leaking locals
assume ((5 if (yes) else 1) == 5)
assume ((5 if (no) else 1) == 1)
action [return nil] (return (nil))
@ -28,13 +36,14 @@ assume (%tot == 6) or barf "for-loop failed"
repeat:
%x += 1
if (%x == 3): stop repeating
if (%x > 3): barf "Failed to stop repeat loop"
if (%x > 3):
barf "Failed to stop repeat loop"
assume (%x == 3) or barf "Failed to repeat"
%x = 0
repeat 5 times: %x += 1
assume (%x == 5) or barf "Failed to repeat 5 times"
set {%x: 0, %y: 0}
set {%x:0, %y:0}
for % in [1, 2, 3]:
repeat 5 times:
do next repeat
@ -43,7 +52,7 @@ for % in [1, 2, 3]:
%y += 1
assume ([%x, %y] == [0, 3]) or barf "Failed to continue repeat"
set {%x: 0, %y: 0}
set {%x:0, %y:0}
for % in [1, 2, 3]:
repeat 5 times:
do next %
@ -52,7 +61,7 @@ for % in [1, 2, 3]:
%y += 1
assume ([%x, %y] == [0, 0]) or barf "Failed to continue for"
set {%x: 0, %y: 0}
set {%x:0, %y:0}
for % in [1, 2, 3]:
repeat 5 times:
stop repeating
@ -61,7 +70,7 @@ for % in [1, 2, 3]:
%y += 1
assume ([%x, %y] == [0, 3]) or barf "Failed to stop repeat"
set {%x: 0, %y: 0}
set {%x:0, %y:0}
for % in [1, 2, 3]:
repeat 5 times:
stop %
@ -83,59 +92,70 @@ assume (%x == 6) or barf "Numeric for range failed"
for %i in 3 to 1 via -1: %x += %i
assume (%x == 6) or barf "backwards numeric for range failed"
%result = {}
for %key = %value in {x: 1, y: 2}: %result."\%key\%key" = (%value * 11)
assume (%result == {xx: 11, yy: 22}) or barf "key/value iteration failed"
for %key = %value in {x: 1, y: 2}:
for %key = %value in {x:1, y:2}:
%result."\%key\%key" = (%value * 11)
assume (%result == {xx:11, yy:22}) or barf "key/value iteration failed"
for %key = %value in {x:1, y:2}:
stop %key
barf "stopping key failed"
for %key = %value in {x: 1, y: 2}:
for %key = %value in {x:1, y:2}:
stop %value
barf "stopping value failed"
for %key = %value in {x: 1}:
for %key = %value in {x:1}:
stop %key
stop %value
do next %key
do next %value
for %key = %value in {x: 1, y: 2}:
for %key = %value in {x:1, y:2}:
do next %key
barf "skipping key failed"
for %key = %value in {x: 1, y: 2}:
for %key = %value in {x:1, y:2}:
do next %value
barf "skipping value failed"
action [barfer]: barf "this should never be reached"
action [barfer]:
barf "this should never be reached"
if:
(no): barf "'when' fail"
(no) (3 > 4): barf "'when' fail 2"
(no) (3 > 4):
barf "'when' fail 2"
(yes) (barfer): do nothing
(99 > 1): barf "Fell through incorrectly"
(99 > 1):
barf "Fell through incorrectly"
%else_worked = (no)
if:
(no): barf
else: %else_worked = (yes)
else:
%else_worked = (yes)
assume %else_worked or barf "when..else failed"
action [test when scope]:
if (yes): %leaked = (yes)
test when scope
assume (not %leaked) or barf "'when' is leaking locals"
%when_worked = (no)
if 4 is:
1 2: barf "'when = ?' fail"
3 4 (barfer): %when_worked = (yes)
1 2:
barf "'when = ?' fail"
3 4 (barfer):
%when_worked = (yes)
assume %when_worked
%when_worked = (no)
if 5 is:
6: barf
else: %when_worked = (yes)
else:
%when_worked = (yes)
assume %when_worked
%x = 1
@ -147,11 +167,13 @@ assume (..)
%n = 0
for % in [1, 2, 3]: %n += %
return %n
.. == 6
..== 6
%t = [1, [2, [[3], 4], 5, [[[6]]]]]
%flat = []
for % in recursive %t:
if ((type of %) is "table"): for %2 in %: recurse % on %2
if ((type of %) is "table"):
for %2 in %: recurse % on %2
..else: add % to %flat
assume ((sorted %flat) == [1, 2, 3, 4, 5, 6])

View File

@ -1,10 +1,16 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
#
Tests for the stuff defined in core/control_flow.nom
use "core"
%nums = []
%co = (coroutine (: -> 4; -> 5; repeat 3 times: -> 6))
%co = (..)
coroutine:
-> 4
-> 5
repeat 3 times: -> 6
for % in coroutine %co (add % to %nums)
assume (%nums == [4, 5, 6, 6, 6]) or barf "Coroutine iteration failed"
say "Coroutines test passed."

View File

@ -1,4 +1,4 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
#
Tests for the stuff defined in core/errors.nom

View File

@ -1,3 +1,4 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
use "core"
say "Inner directory 'use' test passed."

View File

@ -1,7 +1,8 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
#..
Tests for the stuff defined in core/control_flow.nom
use "core"
assume (all of [inf, pi, tau, golden ratio, e]) or barf "math constants failed"
%nan = (NaN)
assume (%nan != %nan) or barf "NaN failed"

View File

@ -1,8 +1,9 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
#
Tests for the stuff defined in core/metaprogramming.nom
use "core"
compile [five] to (Lua value "5")
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -41,16 +42,24 @@ parse [V] as (five)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
assume ((V) == 5) or barf "Parse as compile action failed."
parse [swap %x and %y] as (do (: %tmp = %x; %x = %y; %y = %tmp))
parse [swap %x and %y] as (..)
do:
%tmp = %x
%x = %y
%y = %tmp
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
set {%1: 1, %2: 2}
set {%1:1, %2:2}
swap %1 and %2
assume ((%1 == 2) and (%2 == 1)) or barf "'parse % as %' failed on 'swap % and %'"
set {%tmp: 1, %tmp2: 2}
assume ((%1 == 2) and (%2 == 1)) or barf ".."
'parse % as %' failed on 'swap % and %'
set {%tmp:1, %tmp2:2}
swap %tmp and %tmp2
assume ((%tmp == 2) and (%tmp2 == 1)) or barf "'parse % as %' variable mangling failed."
assume ((%tmp == 2) and (%tmp2 == 1)) or barf ".."
'parse % as %' variable mangling failed.
#
remove action (foo %)
@ -58,10 +67,14 @@ assume ((%tmp == 2) and (%tmp2 == 1)) or barf "'parse % as %' variable mangling
..and if it succeeds: barf "Failed to delete action"
assume ((\(5 + 5) as value) == 10) or barf "%tree as value failed."
assume ("\(\(foo %x) as nomsu)" == "foo %x") or barf "action source code failed."
assume ("\(\(%x) as nomsu)" == "%x") or barf "var source code failed."
assume ("\(\(foo %x) as nomsu)" == "foo %x") or barf ".."
action source code failed.
assume ("\(\%x as nomsu)" == "%x") or barf "var source code failed."
assume ((type of {}) == "table") or barf "type of failed."
assume ("\(\(%x) as lua identifier)" == "_x") or barf "converting to identifier failed."
assume ("\(\%x as lua identifier)" == "_x") or barf ".."
converting to identifier failed.
assume ((run "return 99") == 99) or barf "run % failed."
%code = (Lua "global_x = true;")
lua> %code

View File

@ -1,9 +1,10 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
#
Tests for the object model defined in lib/object.nom
use "core"
use "lib/object.nom"
object "Dog":
(class Dog).genus = "Canus"
method [initialize %] (%.barks or= 0)
@ -13,7 +14,7 @@ object "Dog":
method [get pissed off] ((me).barks += 1)
%d = (new Dog {barks: 2})
%d = (new Dog {barks:2})
as %d:
assume ((me) == %d)
assume ((me).barks == 2)
@ -28,17 +29,18 @@ assume ("\(%d.class)" == "Dog")
assume (%d.genus == "Canus")
assume (%d.barks == 3)
as (new Dog) (assume ((me).barks == 0) or barf "Default initializer failed")
as (new Dog {barks: 1}) (assume ((bark) == "Bark!"))
action [foo] (as (new Dog {barks: 23}) (return (me).barks))
as (new Dog {barks:1}) (assume ((bark) == "Bark!"))
action [foo] (as (new Dog {barks:23}) (return (me).barks))
assume ((foo) == 23) or barf "Oops, \(foo) != 23"
as (new Dog {barks: 101}):
try (as (new Dog {barks: 8}) (barf)) and if it succeeds (barf)
assume ((me).barks == 101) or barf "Error in nested 'as % %' failed to properly reset 'self'"
as (new Dog {barks:101}):
try (as (new Dog {barks:8}) (barf)) and if it succeeds (barf)
assume ((me).barks == 101) or barf ".."
Error in nested 'as % %' failed to properly reset 'self'
object "Corgi" extends (class Dog) (method [sploot] "splooted")
%corg = (new Corgi)
assume (%corg.barks == 0)
as (new Corgi {barks: 1}):
as (new Corgi {barks:1}):
assume ((sploot) == "splooted") or barf "subclass method failed"
assume ((bark) == "Bark!") or barf "inheritance failed"
assume ((woof) == "Bark!")

View File

@ -1,10 +1,11 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
#..
Tests for the stuff defined in core/operators.nom
use "core"
set {%x: 10, %y: 20}
set {%x:10, %y:20}
assume ((%x == 10) and (%y == 20)) or barf "mutli-assignment failed."
set {%x: %y, %y: %x}
set {%x:%y, %y:%x}
assume ((%y == 10) and (%x == 20)) or barf "swapping vars failed."
% = [..]
%x < %y, %x <= %y, %x > %y, %x >= %y, %x == %y, %x is %y, %x != %y, %x isn't %y
@ -12,30 +13,34 @@ assume ((%y == 10) and (%x == 20)) or barf "swapping vars failed."
assume ({} is {}) or barf "Equality check failed."
assume (({} 's id) is not ({} 's id)) or barf "Identity check failed."
set {%foozle: "outer", %y: "outer"}
set {%foozle:"outer", %y:"outer"}
action [set global x local y]:
external %foozle = "inner"
%y = "inner"
set global x local y
assume ((%foozle == "inner") and (%y == "outer")) or barf "external failed."
set {%foozle: "outer", %y: "outer"}
set {%foozle:"outer", %y:"outer"}
action [set global x local y] (..)
with external [%foozle]:
%foozle = "inner"
%y = "inner"
set global x local y
assume ((%foozle == "inner") and (%y == "outer")) or barf "'with external' failed."
set {%x: 1, %y: 2}
with {%z: nil, %x: 999}:
assume ((%foozle == "inner") and (%y == "outer")) or barf ".."
'with external' failed.
set {%x:1, %y:2}
with {%z:nil, %x:999}:
%z = 999
assume (%z == 999) or barf "'with' failed."
assume (%x == 999) or barf "'with' assignment failed."
assume (%x == 1) or barf "'with' scoping failed"
assume (%z == (nil)) or barf "'with' scoping failed"
assume ((1 + 2 * 3 - 4 / 2 ^ 2) == 6) or barf "math expressions not working properly"
assume ((1 + 2 * 3 - 4 / 2 ^ 2) == 6) or barf ".."
math expressions not working properly
assume ((5 wrapped around 2) == 1) or barf "mod not working"
assume (1 <= 2 < 3) or barf "chained operator fail."
%value = -999
@ -43,7 +48,9 @@ action [flipflop]:
external %value = (- %value)
return %value
assume (not (1 < (flipflop) < 1)) or barf "3-way inequality evaluated middle term twice"
assume (not (1 < (flipflop) < 1)) or barf ".."
3-way inequality evaluated middle term twice
assume (((yes) and (yes)) == (yes))
action [barfer] (barf "short circuiting failed")
assume (((no) and (barfer)) == (no))

View File

@ -1,9 +1,10 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
#
Tests for the stuff defined in lib/os.nom
use "core"
use "lib/os.nom"
%lines = (lines in (read file "tests/os.nom"))
assume (%lines.3 == " Tests for the stuff defined in lib/os.nom")
%n = 0

View File

@ -1,5 +1,6 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
use "core"
%x = "outer"
with local %x:
%x = "inner"

View File

@ -1,43 +1,46 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
#..
Tests for the stuff defined in core/text.nom
use "core"
assume ((["x", "y"] joined with ",") == "x,y") or barf "joined with failed"
assume ((["x", "y"] joined) == "xy") or barf "joined failed"
assume (("asdf" capitalized) == "Asdf") or barf "capitalized failed"
assume (("asdf" with "X" instead of "s") == "aXdf") or barf "substitution failed"
assume (..)
"\n" == (newline)
..or barf "Text literals failed."
assume (("asdf" with "X" instead of "s") == "aXdf") or barf ".."
substitution failed
assume ("\n" == (newline)) or barf "Text literals failed."
assume (("x" + "y") == "xy")
assume (..)
(..)
lines in "one\ntwo"
lines in ".."
one
two
..== ["one", "two"]
parse [アクション %spec %body] as (action %spec %body)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
%こんにちは = "\227\129\147\227\130\147\227\129\171\227\129\161\227\129\175"
アクション [% と言う] "\(%)\228\184\150\231\149\140"
assume (..)
(%こんにちは と言う) == ".."
こんにちは世界
..or barf "Unicode doesn't work"
%こんにちは = "こんにちは"
アクション [% と言う] "\(%)世界"
assume ((%こんにちは と言う) == "こんにちは世界") or barf ".."
Unicode doesn't work
%s = "one two\\nthreefour"
assume (..)
%s == "one two\\nthreefour"
..or barf "%s = \(quote %s), not \(quote "one two\\nthreefour")"
assume (%s == "one two\\nthreefour") or barf ".."
%s = \(quote %s), not \(quote "one two\\nthreefour")
%s = "list:\[1, 2, 3]"
assume (%s == "list:[1, 2, 3]")
assume ("foo = \(1 + 2)!" == "foo = 3!")
assume (..)
"one\ntwo"
..== "one\ntwo"
".."
one
two
..== ".."
one
two
assume ("nogap" == "nogap")

View File

@ -1,6 +1,7 @@
#!/usr/bin/env nomsu -V2.4.4.3
#!/usr/bin/env nomsu -V2.5.4.3
use "core"
use "lib/os.nom"
%args = (command line args)
%inplace = (no)
if (%args.1 is "-i"):
@ -13,5 +14,6 @@ for %path in %args:
#!/usr/bin/env nomsu -V\(Nomsu version)
\((parse (read file %filename) from %filename) as nomsu)
if %inplace: write %formatted to file %filename
if %inplace:
write %formatted to file %filename
..else: say %formatted

View File

@ -1,3 +1,4 @@
#!/usr/bin/env nomsu -V2.5.4.3
#!/usr/bin/env Nomsu -V2.4.4.3
use "core"
use "compatibility"
@ -8,25 +9,30 @@ use "lib/os.nom"
if (%args.1 is "-i"):
%inplace = (yes)
remove index 1 from %args
if (%args.1 is "-t"):
use "lib/consolecolor.nom"
%test = (yes)
remove index 1 from %args
for %path in %args:
if (%path is "-i"): %inplace = (yes)
for file %filename in %path:
%tree = (parse (read file %filename) from %filename)
%uptree = (%tree upgraded)
%text = "#!/usr/bin/env nomsu -V\(Nomsu version)\n\(%uptree as nomsu)"
%text = ".."
#!/usr/bin/env nomsu -V\(Nomsu version)
\(%uptree as nomsu)
if:
%inplace:
say "Upgraded \%filename"
write %text to file %filename
%test:
if (%uptree == %tree):
say (dim "\%filename will not be changed")
..else:
say (bright "\%filename will be changed")
else:
say %text
else: say %text