aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bitbucket@bruce-hill.com>2018-07-18 17:55:29 -0700
committerBruce Hill <bitbucket@bruce-hill.com>2018-07-18 17:56:15 -0700
commitbf67a610135c0803187cf6ed896638962f142d14 (patch)
treea0b126c954168282c8c69ea728d4abbae712ac33
parentacb86f78c3f79479ac3a73f0e5862f8f5d8f31f5 (diff)
Updating to version 2.4.4.3, with new syntax for multi-statement 'if'
and switch statements.
-rw-r--r--code_obj.lua6
-rw-r--r--code_obj.moon6
-rw-r--r--compatibility/2.nom4
-rw-r--r--compatibility/compatibility.nom10
-rw-r--r--core/collections.nom2
-rw-r--r--core/control_flow.nom164
-rw-r--r--core/coroutines.nom2
-rw-r--r--core/errors.nom5
-rw-r--r--core/io.nom2
-rw-r--r--core/math.nom2
-rw-r--r--core/metaprogramming.nom16
-rw-r--r--core/operators.nom12
-rw-r--r--core/scopes.nom13
-rw-r--r--core/text.nom2
-rw-r--r--lib/consolecolor.nom2
-rw-r--r--lib/file_hash.nom2
-rw-r--r--lib/object.nom2
-rw-r--r--lib/os.nom2
-rw-r--r--lib/training_wheels.nom4
-rw-r--r--lib/version.nom2
-rw-r--r--nomsu_compiler.lua43
-rw-r--r--nomsu_compiler.moon43
-rw-r--r--tests/collections.nom2
-rw-r--r--tests/colors.nom2
-rw-r--r--tests/control_flow.nom45
-rw-r--r--tests/coroutines.nom2
-rw-r--r--tests/errors.nom2
-rw-r--r--tests/inner/inner.nom4
-rw-r--r--tests/math.nom2
-rw-r--r--tests/metaprogramming.nom4
-rw-r--r--tests/object.nom2
-rw-r--r--tests/operators.nom4
-rw-r--r--tests/os.nom2
-rw-r--r--tests/scopes.nom2
-rw-r--r--tests/text.nom5
-rw-r--r--tools/upgrade.nom25
36 files changed, 225 insertions, 224 deletions
diff --git a/code_obj.lua b/code_obj.lua
index 37ac55a..b67e78d 100644
--- a/code_obj.lua
+++ b/code_obj.lua
@@ -312,12 +312,6 @@ do
end
return statements
end,
- as_expr = function(self)
- if self.is_value then
- return self
- end
- return error("Cannot convert to expression: " .. tostring(tostring(self)))
- end,
__tostring = function(self)
if self.__str == nil then
local buff, indent = { }, 0
diff --git a/code_obj.moon b/code_obj.moon
index e1cf226..9bfa9a5 100644
--- a/code_obj.moon
+++ b/code_obj.moon
@@ -4,7 +4,6 @@
{:insert, :remove, :concat} = table
{:repr} = require 'utils'
local LuaCode, NomsuCode, Source
-export LINE_STARTS
class Source
new: (@filename, @start, @stop)=>
@@ -185,11 +184,6 @@ class LuaCode extends Code
if suffix != ""
statements\append suffix
return statements
-
- as_expr: =>
- if @is_value
- return self
- error("Cannot convert to expression: #{tostring self}")
__tostring: =>
if @__str == nil
diff --git a/compatibility/2.nom b/compatibility/2.nom
index 35ed1a0..a93730c 100644
--- a/compatibility/2.nom
+++ b/compatibility/2.nom
@@ -4,7 +4,7 @@ use "compatibility/compatibility.nom"
upgrade %tree to "2" as:
unless (%tree is "Action" syntax tree): return
- if (all[%tree.stub is "if % % else %", not (%tree.3 is "Var" syntax tree), not (%tree.5 is "Var" syntax tree)]):
+ if (%tree.stub is "if % % else %"):
%true_body = (%tree.3 upgraded)
unless (%true_body is "Block" syntax tree):
%true_body = (=lua "Block(\%true_body.source, \%true_body)")
@@ -22,7 +22,7 @@ upgrade %tree to "2" as:
"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) and (not ((last in %tree) is "Var" syntax tree))):
+ 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)
diff --git a/compatibility/compatibility.nom b/compatibility/compatibility.nom
index 9482e32..c5ac55f 100644
--- a/compatibility/compatibility.nom
+++ b/compatibility/compatibility.nom
@@ -21,16 +21,16 @@ compile [upgrade action %action to %version as %body] to:
%replacements.(%action.%i.1) = "\(\%tree as lua id)[\%i]"
local action [make tree %t]:
when:
- * (%t is "Var" syntax tree):
+ (%t is "Var" syntax tree):
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)")"))"
- * (%t is syntax tree):
+ (%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))
@@ -66,9 +66,9 @@ parse [%tree upgraded from %start_version] as (..)
%tree upgraded from %start_version to (Nomsu version)
parse [%tree upgraded to %end_version] as (..)
- %tree upgraded from %tree.version to %end_version
+ %tree upgraded from (%tree.version or "0") to %end_version
-parse [%tree upgraded] as (%tree upgraded from %tree.version to (Nomsu version))
+parse [%tree upgraded] as (%tree upgraded from (%tree.version or "0") to (Nomsu version))
action [use %path from version %version] (..)
for file %filename in %path:
if (=lua "LOADED[\%filename]"): do next %filename
diff --git a/core/collections.nom b/core/collections.nom
index 45ca74c..428ed4d 100644
--- a/core/collections.nom
+++ b/core/collections.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V2.3.4.3
+#!/usr/bin/env nomsu -V2.4.4.3
#
This file contains code that supports manipulating and using collections like lists
and dictionaries.
diff --git a/core/control_flow.nom b/core/control_flow.nom
index b3f0978..5719d72 100644
--- a/core/control_flow.nom
+++ b/core/control_flow.nom
@@ -154,7 +154,7 @@ compile [..]
..to:
# This uses Lua's approach of only allowing loop-scoped variables in a loop
- assume (%var.type is "Var") or barf "Loop expected variable, not: \%var"
+ 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
@@ -185,12 +185,11 @@ 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
- assume (%var.type is "Var") or barf "Loop expected variable, not: \%var"
+ 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
@@ -223,8 +222,8 @@ compile [for %key = %value in %iterable %body, for %key %value in %iterable %bod
..to:
# This uses Lua's approach of only allowing loop-scoped variables in a loop
- assume (%key.type is "Var") or barf "Loop expected variable, not: \%key"
- assume (%value.type is "Var") or barf "Loop expected variable, not: \%value"
+ 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
@@ -266,101 +265,88 @@ compile [for %key = %value in %iterable %body, for %key %value in %iterable %bod
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# Switch statement/multi-branch if
-compile [when %body] to:
+# Multi-branch conditional (if..elseif..else)
+compile [if %body, when %body] to:
%code = (Lua "")
- %fallthroughs = []
- %is_first = (yes)
- %seen_else = (no)
- %branches = (%body if (%body.type == "Block") else [%body])
- for %func_call in %branches:
- assume (%func_call.type is "Action") or barf "Invalid format for 'when' statement. Only '*' blocks are allowed."
- with {%star: %func_call.1, %condition: %func_call.2, %action: %func_call.3}:
- assume (%star == "*") or barf "Invalid format for 'when' statement. Lines must begin with '*'"
- assume %condition or barf ".."
- Invalid format for 'when' statement. Lines must begin with '*' and have a condition \
- ..or the word "else"
-
- if (%action is (nil)):
- lua> "table.insert(\%fallthroughs, \(%condition as lua expr))"
- do next %func_call
-
- if (%condition == "else"):
- assume (not %is_first) or barf "'else' clause cannot be first in 'when % = ?' block"
- to %code write "\nelse\n "
- to %code write (%action as lua statements)
- %seen_else = (yes)
- ..else:
- assume (not %seen_else) or barf "'else' clause needs to be last in 'when' block"
- lua> "table.insert(\%fallthroughs, \(%condition as lua expr))"
- to %code write "\("if" if %is_first else "\nelseif") "
- for %i = %condition in %fallthroughs:
- if (%i > 1): to %code write " or "
- to %code write %condition
-
- to %code write " then\n "
- to %code write (%action as lua statements)
-
- %fallthroughs = []
- %is_first = (no)
+ %clause = "if"
+ %else_allowed = (yes)
+ 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)
+ ..:
+ 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:
+ %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 ((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)"
+ %else_allowed = (no)
+ ..else:
+ to %code write "\%clause "
+ for %i in 1 to ((length of %line) - 1):
+ unless (%line.%i is syntax tree):
+ compile error at %line.source ".."
+ Invalid condition for 'if' statement:
+ %s
+ if (%i > 1): to %code write " or "
+ to %code write (%line.%i as lua expr)
+ to %code write " then\n \(%action as lua statements)"
+ %clause = "\nelseif"
- assume (%fallthroughs == []) or barf "Unfinished fallthrough conditions in 'when' block"
- assume ((length of "\%code") > 0) or barf "Empty body for 'when' block"
+ 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 [when %branch_value = ? %body, when %branch_value is? %body] to:
+compile [if %branch_value is %body, when %branch_value is %body] to:
%code = (Lua "")
- %fallthroughs = []
- %is_first = (yes)
- %seen_else = (no)
- %branches = (%body if (%body.type == "Block") else [%body])
- for %func_call in %branches:
- assume (%func_call.type is "Action") or barf "Invalid format for 'when' statement. Only '*' blocks are allowed."
- with {%star: %func_call.1, %condition: %func_call.2, %action: %func_call.3}:
- assume (%star == "*") or barf "Invalid format for 'when' statement. Lines must begin with '*'"
- assume %condition or barf ".."
- Invalid format for 'when' statement. Lines must begin with '*' and have a condition \
- ..or the word "else"
-
- if (%action is (nil)):
- lua> "table.insert(\%fallthroughs, \(%condition as lua expr))"
- do next %func_call
-
- if (%condition == "else"):
- assume (not %is_first) or barf "'else' clause cannot be first in 'when % = ?' block"
- to %code write "\nelse\n "
- to %code write (%action as lua statements)
- ..else:
- assume (not %seen_else) or barf "'else' clause needs to be last in 'when % = ?' block"
- to %code write "\("if" if %is_first else "\nelseif") "
- lua> "table.insert(\%fallthroughs, \(%condition as lua expr))"
- for %i = % in %fallthroughs:
- if (%i > 1): to %code write " or "
- if ((%.type is "Text") or (%.type is "Number")):
- to %code write "branch_value == \%"
- ..else: to %code write "utils.equivalent(branch_value, \%)"
-
- to %code write "then\n "
- to %code write (%action as lua statements)
-
- %fallthroughs = []
- %is_first = (no)
+ %clause = "if"
+ %else_allowed = (yes)
+ 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)
+ ..:
+ 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:
+ %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 ((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)"
+ %else_allowed = (no)
+ ..else:
+ to %code write "\%clause "
+ for %i in 1 to ((length of %line) - 1):
+ unless (%line.%i is syntax tree):
+ compile error at %line.source ".."
+ Invalid condition for 'if' statement:
+ %s
+ 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)"
+ %clause = "\nelseif"
- assume (%fallthroughs == []) or barf "Unfinished fallthrough conditions in 'when' block"
- assume ((length of "\%code") > 0) or barf "No body for 'when % = ?' block!"
- to %code write "\nend"
- %code = (..)
+ if ((length of "\%code") == 0):
+ compile error at %body.source "'if % is % %' block has an empty body"
+ to %code write "\nend --when"
+ return (..)
Lua ".."
- do --when % = ?
+ do --if % is
local branch_value = \(%branch_value as lua expr)
\%code
- end --when % = ?
-
- return %code
-
+ end --if % is
# Do/finally
compile [do %action] to (..)
diff --git a/core/coroutines.nom b/core/coroutines.nom
index 54889d4..bff115d 100644
--- a/core/coroutines.nom
+++ b/core/coroutines.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V2.3.4.3
+#!/usr/bin/env nomsu -V2.4.4.3
#
This file defines the code that creates and manipulates coroutines
diff --git a/core/errors.nom b/core/errors.nom
index efa69a8..5dfed1e 100644
--- a/core/errors.nom
+++ b/core/errors.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V2.3.4.3
+#!/usr/bin/env nomsu -V2.4.4.3
#
This file contains basic error reporting code
@@ -7,6 +7,9 @@ compile [traceback] to (Lua value "debug.traceback()")
compile [traceback %] to (Lua value "debug.traceback('', \(% as lua expr))")
compile [barf] to (Lua "error(nil, 0);")
compile [barf %msg] to (Lua "error(\(%msg as lua expr), 0);")
+compile [compile error at %source %msg] to (..)
+ Lua "nomsu:compile_error(\(%source as lua expr), \(%msg as lua expr))"
+
compile [assume %condition] to:
lua> ".."
local \%assumption = 'Assumption failed: '..tostring(nomsu:tree_to_nomsu(\%condition))
diff --git a/core/io.nom b/core/io.nom
index 2659b3b..b06ebb3 100644
--- a/core/io.nom
+++ b/core/io.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V2.3.4.3
+#!/usr/bin/env nomsu -V2.4.4.3
#
This file contains basic input/output code
diff --git a/core/math.nom b/core/math.nom
index d8952f6..e0c58a3 100644
--- a/core/math.nom
+++ b/core/math.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V2.3.4.3
+#!/usr/bin/env nomsu -V2.4.4.3
#
This file defines some common math literals and functions
diff --git a/core/metaprogramming.nom b/core/metaprogramming.nom
index 8328d26..028a914 100644
--- a/core/metaprogramming.nom
+++ b/core/metaprogramming.nom
@@ -1,9 +1,9 @@
-#!/usr/bin/env nomsu -V2.3.4.3
+#!/usr/bin/env nomsu -V2.4.4.3
#
This File contains actions for making actions and compile-time actions and some helper
functions to make that easier.
-lua> "NOMSU_CORE_VERSION = 3"
+lua> "NOMSU_CORE_VERSION = 4"
lua> ".."
nomsu.COMPILE_ACTIONS["% -> %"] = function(nomsu, tree, \%args, \%body)
local lua = LuaCode.Value(tree.source, "function(")
@@ -119,8 +119,16 @@ compile [parse %actions as %body] to (..)
local ret = \(compile as (compile %actions to %new_body))
return ret
-compile [%tree as lua expr] to (..)
- Lua value "nomsu:compile(\(=lua "nomsu:compile(\%tree):as_expr()")):as_expr()"
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+action [%tree as lua expr]:
+ lua> ".."
+ \%tree_lua = nomsu:compile(\%tree)
+ if not \%tree_lua.is_value then
+ nomsu:compile_error(\%tree.source, "Could not convert %s to a Lua expression",
+ nomsu:tree_to_nomsu(\%tree))
+ end
+ return \%tree_lua
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/core/operators.nom b/core/operators.nom
index 70b0207..bce91c4 100644
--- a/core/operators.nom
+++ b/core/operators.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V2.3.4.3
+#!/usr/bin/env nomsu -V2.4.4.3
#
This file contains definitions of operators like "+" and "and".
@@ -147,21 +147,29 @@ compile [%x wrapped around %y, %x mod %y] to (..)
# (uses a lambda to avoid re-evaluating middle value, while still being an expression)
parse [%x < %y < %z] as (..)
=lua "(function(x,y,z) return x < y and y < z; end)(\%x,\%y,\%z)"
+
parse [%x <= %y < %z] as (..)
=lua "(function(x,y,z) return x <= y and y < z; end)(\%x,\%y,\%z)"
+
parse [%x < %y <= %z] as (..)
=lua "(function(x,y,z) return x < y and y <= z; end)(\%x,\%y,\%z)"
+
parse [%x <= %y <= %z] as (..)
=lua "(function(x,y,z) return x <= y and y <= z; end)(\%x,\%y,\%z)"
+
parse [%x > %y > %z] as (..)
=lua "(function(x,y,z) return x > y and y > z; end)(\%x,\%y,\%z)"
+
parse [%x >= %y > %z] as (..)
=lua "(function(x,y,z) return x >= y and y > z; end)(\%x,\%y,\%z)"
+
parse [%x > %y >= %z] as (..)
=lua "(function(x,y,z) return x > y and y >= z; end)(\%x,\%y,\%z)"
+
parse [%x >= %y >= %z] as (..)
=lua "(function(x,y,z) return x >= y and y >= z; end)(\%x,\%y,\%z)"
+
# TODO: optimize for common case where x,y,z are all either variables or number literals
# Boolean Operators
compile [%x and %y] to (Lua value "(\(%x as lua expr) and \(%y as lua expr))")
@@ -204,4 +212,4 @@ parse [%var /= %] as (%var = (%var / %))
parse [%var ^= %] as (%var = (%var ^ %))
parse [%var and= %] as (%var = (%var and %))
parse [%var or= %] as (%var = (%var or %))
-parse [wrap %var around %] as (%var = (%var wrapped around %))
+parse [wrap %var around %] as (%var = (%var wrapped around %)) \ No newline at end of file
diff --git a/core/scopes.nom b/core/scopes.nom
index 2be24e6..30bdea0 100644
--- a/core/scopes.nom
+++ b/core/scopes.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V2.3.4.3
+#!/usr/bin/env nomsu -V2.4.4.3
#
This file contains definitions pertaining to variable scoping
@@ -8,17 +8,16 @@ 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)
- when %locals.type = ?:
- * "Dict":
+ if %locals.type is:
+ "Dict":
%body_lua = (..)
Lua "\(compile as (<- %locals))\n\%body_lua"
declare locals ("\(%.1 as lua)" for % in %locals) in %body_lua
- * "List": declare locals ("\(% as lua)" for % in %locals) in %body_lua
- * "Var"
- * "Action": declare locals ["\(%locals as lua)"] in %body_lua
- *else (barf "Unexpected local: \(%locals as nomsu)")
+ "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" \ No newline at end of file
diff --git a/core/text.nom b/core/text.nom
index 62ec056..30eab50 100644
--- a/core/text.nom
+++ b/core/text.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V2.3.4.3
+#!/usr/bin/env nomsu -V2.4.4.3
#
This file contains some definitions of text escape sequences, including ANSI console
color codes.
diff --git a/lib/consolecolor.nom b/lib/consolecolor.nom
index 39bae68..6e327ff 100644
--- a/lib/consolecolor.nom
+++ b/lib/consolecolor.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V2.3.4.3
+#!/usr/bin/env nomsu -V2.4.4.3
#
This file defines actions for ANSI console color escape codes.
diff --git a/lib/file_hash.nom b/lib/file_hash.nom
index 283c5b4..49c768f 100644
--- a/lib/file_hash.nom
+++ b/lib/file_hash.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V2.3.4.3
+#!/usr/bin/env nomsu -V2.4.4.3
#
This file defines some actions for hashing files and looking up files by hash.
diff --git a/lib/object.nom b/lib/object.nom
index cb5cd3c..ae52d99 100644
--- a/lib/object.nom
+++ b/lib/object.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V2.3.4.3
+#!/usr/bin/env nomsu -V2.4.4.3
#
This file contains the implementation of an Object-Oriented programming system.
diff --git a/lib/os.nom b/lib/os.nom
index 57dac26..e29b5d1 100644
--- a/lib/os.nom
+++ b/lib/os.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V2.3.4.3
+#!/usr/bin/env nomsu -V2.4.4.3
#
This file defines some actions that interact with the operating system and filesystem.
diff --git a/lib/training_wheels.nom b/lib/training_wheels.nom
index 4c0b166..2845768 100644
--- a/lib/training_wheels.nom
+++ b/lib/training_wheels.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V2.3.4.3
+#!/usr/bin/env nomsu -V2.4.4.3
#
This file contains a set of definitions that bring some familiar language features
from other languages into nomsu (e.g. "==" and "continue")
@@ -11,7 +11,7 @@ parse [%a === %b] as ((%a 's id) is (%b 's id))
parse [%a !== %b] as ((%a 's id) is not (%b 's id))
parse [%a mod %b] as (%a wrapped around %b)
parse [function %names %body, def %names %body] as (action %names %body)
-parse [switch %branch_value %body] as (when %branch_value = ? %body)
+parse [switch %branch_value %body] as (if %branch_value is: %body)
parse [None, Null] as (nil)
parse [True, true] as (yes)
parse [False, false] as (no)
diff --git a/lib/version.nom b/lib/version.nom
index 952d940..3380301 100644
--- a/lib/version.nom
+++ b/lib/version.nom
@@ -1,3 +1,3 @@
-#!/usr/bin/env nomsu -V2.3.4.3
+#!/usr/bin/env nomsu -V2.4.4.3
# This file sets the current library version.
lua> "NOMSU_LIB_VERSION = 3" \ No newline at end of file
diff --git a/nomsu_compiler.lua b/nomsu_compiler.lua
index da4a155..b4702ed 100644
--- a/nomsu_compiler.lua
+++ b/nomsu_compiler.lua
@@ -227,18 +227,19 @@ do
})
NomsuCompiler.LOADED = { }
NomsuCompiler.AST = AST
- NomsuCompiler.compile_error = function(self, tok, err_format_string, ...)
- local file = files.read(tok.source.filename)
+ NomsuCompiler.compile_error = function(self, source, err_format_string, ...)
+ err_format_string = err_format_string:gsub("%%[^s]", "%%%1")
+ local file = files.read(source.filename)
local line_starts = files.get_line_starts(file)
- local line_no = files.get_line_number(file, tok.source.start)
+ local line_no = files.get_line_number(file, source.start)
local line_start = line_starts[line_no]
- local src = colored.dim(file:sub(line_start, tok.source.start - 1))
- src = src .. colored.underscore(colored.bright(colored.red(file:sub(tok.source.start, tok.source.stop - 1))))
- local end_of_line = (line_starts[files.get_line_number(file, tok.source.stop) + 1] or 0) - 1
- src = src .. colored.dim(file:sub(tok.source.stop, end_of_line - 1))
+ local src = colored.dim(file:sub(line_start, source.start - 1))
+ src = src .. colored.underscore(colored.bright(colored.red(file:sub(source.start, source.stop - 1))))
+ local end_of_line = (line_starts[files.get_line_number(file, source.stop) + 1] or 0) - 1
+ src = src .. colored.dim(file:sub(source.stop, end_of_line - 1))
src = ' ' .. src:gsub('\n', '\n ')
local err_msg = err_format_string:format(src, ...)
- return error(tostring(tok.source.filename) .. ":" .. tostring(line_no) .. ": " .. err_msg, 0)
+ return error(tostring(source.filename) .. ":" .. tostring(line_no) .. ": " .. err_msg, 0)
end
local math_expression = re.compile([[ ([+-] " ")* "%" (" " [*/^+-] (" " [+-])* " %")+ !. ]])
local add_lua_bits
@@ -256,7 +257,7 @@ do
else
local bit_lua = self:compile(bit)
if not (bit_lua.is_value) then
- self:compile_error(bit, "Cannot use:\n%s\nas a string interpolation value, since it's not an expression.")
+ self:compile_error(bit.source, "Cannot use:\n%s\nas a string interpolation value, since it's not an expression.")
end
lua:append(bit_lua)
end
@@ -289,7 +290,7 @@ do
else
local bit_lua = self:compile(bit)
if not (bit_lua.is_value) then
- self:compile_error(bit, "Cannot use:\n%s\nas a string interpolation value, since it's not an expression.")
+ self:compile_error(bit.source, "Cannot use:\n%s\nas a string interpolation value, since it's not an expression.")
end
add_bit_lua(lua, bit_lua)
end
@@ -308,7 +309,7 @@ do
else
local tok_lua = self:compile(tok)
if not (tok_lua.is_value) then
- self:compile_error(tok, "Non-expression value inside math expression:\n%s")
+ self:compile_error(tok.source, "Non-expression value inside math expression:\n%s")
end
if tok.type == "Action" then
tok_lua:parenthesize()
@@ -456,7 +457,7 @@ do
source = nil
end
local lua_string = tostring(lua)
- local run_lua_fn, err = load(lua_string, tostring(source or lua.source), "t", self)
+ local run_lua_fn, err = load(lua_string, nil and tostring(source or lua.source), "t", self)
if not run_lua_fn then
local line_numbered_lua = concat((function()
local _accum_0 = { }
@@ -540,7 +541,7 @@ do
end
local ret = compile_action(self, tree, unpack(args))
if not ret then
- self:compile_error(tree, "Compile-time action:\n%s\nfailed to produce any Lua")
+ self:compile_error(tree.source, "Compile-time action:\n%s\nfailed to produce any Lua")
end
return ret
end
@@ -556,7 +557,7 @@ do
end
local arg_lua = self:compile(tok)
if not (arg_lua.is_value) then
- self:compile_error(tok, "Cannot use:\n%s\nas an argument to %s, since it's not an expression, it produces: %s", stub, repr(arg_lua))
+ self:compile_error(tok.source, "Cannot use:\n%s\nas an argument to %s, since it's not an expression, it produces: %s", stub, repr(arg_lua))
end
insert(args, arg_lua)
_continue_0 = true
@@ -624,7 +625,7 @@ do
if not (bit_lua.is_value) then
local src = ' ' .. gsub(tostring(recurse(bit)), '\n', '\n ')
local line = tostring(bit.source.filename) .. ":" .. tostring(files.get_line_number(files.read(bit.source.filename), bit.source.start))
- self:compile_error(bit, "Cannot use:\n%s\nas a string interpolation value, since it's not an expression.")
+ self:compile_error(bit.source, "Cannot use:\n%s\nas a string interpolation value, since it's not an expression.")
end
if #lua.bits > 0 then
lua:append("..")
@@ -655,7 +656,7 @@ do
for i, item in ipairs(tree) do
local item_lua = self:compile(item)
if not (item_lua.is_value) then
- self:compile_error(item, "Cannot use:\n%s\nas a list item, since it's not an expression.")
+ self:compile_error(item.source, "Cannot use:\n%s\nas a list item, since it's not an expression.")
end
items[i] = item_lua
end
@@ -680,11 +681,11 @@ do
local key, value = tree[1], tree[2]
local key_lua = self:compile(key)
if not (key_lua.is_value) then
- self:compile_error(tree[1], "Cannot use:\n%s\nas a dict key, since it's not an expression.")
+ self:compile_error(tree[1].source, "Cannot use:\n%s\nas a dict key, since it's not an expression.")
end
local value_lua = value and self:compile(value) or LuaCode.Value(key.source, "true")
if not (value_lua.is_value) then
- self:compile_error(tree[2], "Cannot use:\n%s\nas a dict value, since it's not an expression.")
+ self:compile_error(tree[2].source, "Cannot use:\n%s\nas a dict value, since it's not an expression.")
end
local key_str = match(tostring(key_lua), [=[["']([a-zA-Z_][a-zA-Z0-9_]*)['"]]=])
if key_str then
@@ -697,7 +698,7 @@ do
elseif "IndexChain" == _exp_0 then
local lua = self:compile(tree[1])
if not (lua.is_value) then
- self:compile_error(tree[1], "Cannot index:\n%s\nsince it's not an expression.")
+ self:compile_error(tree[1].source, "Cannot index:\n%s\nsince it's not an expression.")
end
local first_char = sub(tostring(lua), 1, 1)
if first_char == "{" or first_char == '"' or first_char == "[" then
@@ -707,7 +708,7 @@ do
local key = tree[i]
local key_lua = self:compile(key)
if not (key_lua.is_value) then
- self:compile_error(key, "Cannot use:\n%s\nas an index, since it's not an expression.")
+ self:compile_error(key.source, "Cannot use:\n%s\nas an index, since it's not an expression.")
end
local key_lua_str = tostring(key_lua)
do
@@ -833,7 +834,7 @@ do
return nomsu
else
local pos = tree.source.start
- local nomsu = NomsuCode(tree.source, pop_comments(pos, '\n'))
+ local nomsu = NomsuCode(tree.source, pop_comments(pos))
local next_space = ""
for i, bit in ipairs(tree) do
if match(next_space, '\n') then
diff --git a/nomsu_compiler.moon b/nomsu_compiler.moon
index dd08994..5b9b3f6 100644
--- a/nomsu_compiler.moon
+++ b/nomsu_compiler.moon
@@ -124,18 +124,19 @@ with NomsuCompiler
.LOADED = {}
.AST = AST
- .compile_error = (tok, err_format_string, ...)=>
- file = files.read(tok.source.filename)
+ .compile_error = (source, err_format_string, ...)=>
+ err_format_string = err_format_string\gsub("%%[^s]", "%%%1")
+ file = files.read(source.filename)
line_starts = files.get_line_starts(file)
- line_no = files.get_line_number(file, tok.source.start)
+ line_no = files.get_line_number(file, source.start)
line_start = line_starts[line_no]
- src = colored.dim(file\sub(line_start, tok.source.start-1))
- src ..= colored.underscore colored.bright colored.red(file\sub(tok.source.start, tok.source.stop-1))
- end_of_line = (line_starts[files.get_line_number(file, tok.source.stop) + 1] or 0) - 1
- src ..= colored.dim(file\sub(tok.source.stop, end_of_line-1))
+ src = colored.dim(file\sub(line_start, source.start-1))
+ src ..= colored.underscore colored.bright colored.red(file\sub(source.start, source.stop-1))
+ end_of_line = (line_starts[files.get_line_number(file, source.stop) + 1] or 0) - 1
+ src ..= colored.dim(file\sub(source.stop, end_of_line-1))
src = ' '..src\gsub('\n', '\n ')
err_msg = err_format_string\format(src, ...)
- error("#{tok.source.filename}:#{line_no}: "..err_msg, 0)
+ error("#{source.filename}:#{line_no}: "..err_msg, 0)
-- This is a bit of a hack, but this code handles arbitrarily complex
-- math expressions like 2*x + 3^2 without having to define a single
@@ -154,7 +155,7 @@ with NomsuCompiler
else
bit_lua = @compile(bit)
unless bit_lua.is_value
- @compile_error bit,
+ @compile_error bit.source,
"Cannot use:\n%s\nas a string interpolation value, since it's not an expression."
lua\append bit_lua
return lua
@@ -178,7 +179,7 @@ with NomsuCompiler
else
bit_lua = @compile(bit)
unless bit_lua.is_value
- @compile_error bit,
+ @compile_error bit.source,
"Cannot use:\n%s\nas a string interpolation value, since it's not an expression."
add_bit_lua(lua, bit_lua)
lua\append ")"
@@ -194,7 +195,7 @@ with NomsuCompiler
else
tok_lua = @compile(tok)
unless tok_lua.is_value
- @compile_error tok, "Non-expression value inside math expression:\n%s"
+ @compile_error tok.source, "Non-expression value inside math expression:\n%s"
if tok.type == "Action"
tok_lua\parenthesize!
lua\append tok_lua
@@ -293,7 +294,7 @@ with NomsuCompiler
.run_lua = (lua, source=nil)=>
lua_string = tostring(lua)
- run_lua_fn, err = load(lua_string, tostring(source or lua.source), "t", self)
+ run_lua_fn, err = load(lua_string, nil and tostring(source or lua.source), "t", self)
if not run_lua_fn
line_numbered_lua = concat(
[format("%3d|%s",i,line) for i, line in ipairs files.get_lines(lua_string)],
@@ -340,7 +341,7 @@ with NomsuCompiler
-- TODO: use tail call?
ret = compile_action(@, tree, unpack(args))
if not ret
- @compile_error tree,
+ @compile_error tree.source,
"Compile-time action:\n%s\nfailed to produce any Lua"
return ret
@@ -350,7 +351,7 @@ with NomsuCompiler
if type(tok) == "string" then continue
arg_lua = @compile(tok)
unless arg_lua.is_value
- @compile_error tok,
+ @compile_error tok.source,
"Cannot use:\n%s\nas an argument to %s, since it's not an expression, it produces: %s",
stub, repr arg_lua
insert args, arg_lua
@@ -387,7 +388,7 @@ with NomsuCompiler
unless bit_lua.is_value
src = ' '..gsub(tostring(recurse(bit)), '\n','\n ')
line = "#{bit.source.filename}:#{files.get_line_number(files.read(bit.source.filename), bit.source.start)}"
- @compile_error bit,
+ @compile_error bit.source,
"Cannot use:\n%s\nas a string interpolation value, since it's not an expression."
if #lua.bits > 0 then lua\append ".."
if bit.type != "Text"
@@ -408,7 +409,7 @@ with NomsuCompiler
for i, item in ipairs tree
item_lua = @compile(item)
unless item_lua.is_value
- @compile_error item,
+ @compile_error item.source,
"Cannot use:\n%s\nas a list item, since it's not an expression."
items[i] = item_lua
lua\concat_append(items, ", ", ",\n ")
@@ -425,11 +426,11 @@ with NomsuCompiler
key, value = tree[1], tree[2]
key_lua = @compile(key)
unless key_lua.is_value
- @compile_error tree[1],
+ @compile_error tree[1].source,
"Cannot use:\n%s\nas a dict key, since it's not an expression."
value_lua = value and @compile(value) or LuaCode.Value(key.source, "true")
unless value_lua.is_value
- @compile_error tree[2],
+ @compile_error tree[2].source,
"Cannot use:\n%s\nas a dict value, since it's not an expression."
-- TODO: support arbitrary words here, like operators and unicode
key_str = match(tostring(key_lua), [=[["']([a-zA-Z_][a-zA-Z0-9_]*)['"]]=])
@@ -446,7 +447,7 @@ with NomsuCompiler
when "IndexChain"
lua = @compile(tree[1])
unless lua.is_value
- @compile_error tree[1],
+ @compile_error tree[1].source,
"Cannot index:\n%s\nsince it's not an expression."
first_char = sub(tostring(lua),1,1)
if first_char == "{" or first_char == '"' or first_char == "["
@@ -456,7 +457,7 @@ with NomsuCompiler
key = tree[i]
key_lua = @compile(key)
unless key_lua.is_value
- @compile_error key,
+ @compile_error key.source,
"Cannot use:\n%s\nas an index, since it's not an expression."
key_lua_str = tostring(key_lua)
if lua_id = match(key_lua_str, "^['\"]([a-zA-Z_][a-zA-Z0-9_]*)['\"]$")
@@ -539,7 +540,7 @@ with NomsuCompiler
return nomsu
else
pos = tree.source.start
- nomsu = NomsuCode(tree.source, pop_comments(pos, '\n'))
+ nomsu = NomsuCode(tree.source, pop_comments(pos))
next_space = ""
for i,bit in ipairs tree
if match(next_space, '\n')
diff --git a/tests/collections.nom b/tests/collections.nom
index cf60ebe..f8b813f 100644
--- a/tests/collections.nom
+++ b/tests/collections.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V2.3.4.3
+#!/usr/bin/env nomsu -V2.4.4.3
#..
Tests for the stuff defined in core/control_flow.nom
use "core"
diff --git a/tests/colors.nom b/tests/colors.nom
index d4d5ac5..da1b2e3 100644
--- a/tests/colors.nom
+++ b/tests/colors.nom
@@ -1,3 +1,3 @@
-#!/usr/bin/env nomsu -V2.3.4.3
+#!/usr/bin/env nomsu -V2.4.4.3
use "lib/consolecolor.nom"
say (bright (green "Color test passed.")) \ No newline at end of file
diff --git a/tests/control_flow.nom b/tests/control_flow.nom
index 1d223a4..6312d77 100644
--- a/tests/control_flow.nom
+++ b/tests/control_flow.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V2.3.4.3
+#!/usr/bin/env nomsu -V2.4.4.3
#
Tests for the stuff defined in core/control_flow.nom
@@ -107,37 +107,35 @@ for %key = %value in {x: 1, y: 2}:
do next %value
barf "skipping value failed"
-action [barfer] (barf "this should never be reached")
-when:
- * (no) (barf "'when' fail")
- * (no)
- * (3 > 4) (barf "'when' fail 2")
- * (yes)
- * (barfer) (do nothing)
- * (99 > 1) (barf "Fell through incorrectly")
+action [barfer]: barf "this should never be reached"
+if:
+ (no): barf "'when' fail"
+ (no) (3 > 4): barf "'when' fail 2"
+ (yes) (barfer): do nothing
+ (99 > 1): barf "Fell through incorrectly"
%else_worked = (no)
-when:
- * (no) (barf)
- *else (%else_worked = (yes))
+if:
+ (no): barf
+ else: %else_worked = (yes)
+
+
assume %else_worked or barf "when..else failed"
-action [test when scope] (when (* (yes) (%leaked = (yes))))
+action [test when scope]:
+ if (yes): %leaked = (yes)
test when scope
assume (not %leaked) or barf "'when' is leaking locals"
%when_worked = (no)
-when 4 = ?:
- * 1
- * 2 (barf "'when = ?' fail")
- * 3
- * 4
- * (barfer) (%when_worked = (yes))
+if 4 is:
+ 1 2: barf "'when = ?' fail"
+ 3 4 (barfer): %when_worked = (yes)
assume %when_worked
%when_worked = (no)
-when 5 = ?:
- * 6 (barf)
- *else (%when_worked = (yes))
+if 5 is:
+ 6: barf
+ else: %when_worked = (yes)
assume %when_worked
%x = 1
@@ -149,8 +147,7 @@ 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:
diff --git a/tests/coroutines.nom b/tests/coroutines.nom
index 54b233e..a67e1c8 100644
--- a/tests/coroutines.nom
+++ b/tests/coroutines.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V2.3.4.3
+#!/usr/bin/env nomsu -V2.4.4.3
#
Tests for the stuff defined in core/control_flow.nom
diff --git a/tests/errors.nom b/tests/errors.nom
index 7f91c88..af918a6 100644
--- a/tests/errors.nom
+++ b/tests/errors.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V2.3.4.3
+#!/usr/bin/env nomsu -V2.4.4.3
#
Tests for the stuff defined in core/errors.nom
diff --git a/tests/inner/inner.nom b/tests/inner/inner.nom
index a4341f0..903e0c0 100644
--- a/tests/inner/inner.nom
+++ b/tests/inner/inner.nom
@@ -1,3 +1,3 @@
-#!/usr/bin/env nomsu -V1
+#!/usr/bin/env nomsu -V2.4.4.3
use "core"
-say "Inner directory 'use' test passed."
+say "Inner directory 'use' test passed." \ No newline at end of file
diff --git a/tests/math.nom b/tests/math.nom
index 7ddefba..f740315 100644
--- a/tests/math.nom
+++ b/tests/math.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V2.3.4.3
+#!/usr/bin/env nomsu -V2.4.4.3
#..
Tests for the stuff defined in core/control_flow.nom
use "core"
diff --git a/tests/metaprogramming.nom b/tests/metaprogramming.nom
index d74542c..b8dfde0 100644
--- a/tests/metaprogramming.nom
+++ b/tests/metaprogramming.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V2.3.4.3
+#!/usr/bin/env nomsu -V2.4.4.3
#
Tests for the stuff defined in core/metaprogramming.nom
@@ -68,4 +68,4 @@ lua> %code
assume (=lua "global_x") or barf "Running lua from a variable failed."
%code = (Lua value "global_x")
assume (=lua %code) or barf "Running lua from a variable failed."
-say "Metaprogramming test passed."
+say "Metaprogramming test passed." \ No newline at end of file
diff --git a/tests/object.nom b/tests/object.nom
index 30cf748..186957d 100644
--- a/tests/object.nom
+++ b/tests/object.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V2.3.4.3
+#!/usr/bin/env nomsu -V2.4.4.3
#
Tests for the object model defined in lib/object.nom
diff --git a/tests/operators.nom b/tests/operators.nom
index 0ab44c1..a8f7bfd 100644
--- a/tests/operators.nom
+++ b/tests/operators.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V2.3.4.3
+#!/usr/bin/env nomsu -V2.4.4.3
#..
Tests for the stuff defined in core/operators.nom
use "core"
@@ -69,4 +69,4 @@ assume (%x == 2) or barf "+<- failed"
assume (%x == 4) or barf "*<- failed"
wrap %x around 3
assume (%x == 1) or barf "wrap around failed"
-say "Operator test passed."
+say "Operator test passed." \ No newline at end of file
diff --git a/tests/os.nom b/tests/os.nom
index cbda5b3..c96306b 100644
--- a/tests/os.nom
+++ b/tests/os.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V2.3.4.3
+#!/usr/bin/env nomsu -V2.4.4.3
#
Tests for the stuff defined in lib/os.nom
diff --git a/tests/scopes.nom b/tests/scopes.nom
index a882dcb..4d20dd7 100644
--- a/tests/scopes.nom
+++ b/tests/scopes.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V2.3.4.3
+#!/usr/bin/env nomsu -V2.4.4.3
use "core"
%x = "outer"
with local %x:
diff --git a/tests/text.nom b/tests/text.nom
index 316b343..a002445 100644
--- a/tests/text.nom
+++ b/tests/text.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V2.3.4.3
+#!/usr/bin/env nomsu -V2.4.4.3
#..
Tests for the stuff defined in core/text.nom
use "core"
@@ -40,10 +40,9 @@ assume (..)
..== "one\ntwo"
assume ("nogap" == "nogap")
+
#comment
#
block comment
-
-
say "Text test passed." \ No newline at end of file
diff --git a/tools/upgrade.nom b/tools/upgrade.nom
index 14f7ee0..8f478ac 100644
--- a/tools/upgrade.nom
+++ b/tools/upgrade.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env Nomsu -V2.3.4.3
+#!/usr/bin/env Nomsu -V2.4.4.3
use "core"
use "compatibility"
use "lib/os.nom"
@@ -8,14 +8,25 @@ 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)
- %tree = (%tree upgraded from %tree.version to (Nomsu version))
- %text = "#!/usr/bin/env nomsu -V\(Nomsu version)\n\(%tree as nomsu)"
- if %inplace:
- write %text to file %filename
- ..else:
- say %text
+ %uptree = (%tree upgraded from %tree.version to (Nomsu version))
+ %text = "#!/usr/bin/env nomsu -V\(Nomsu version)\n\(%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