aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2018-11-02 15:17:48 -0700
committerBruce Hill <bruce@bruce-hill.com>2018-11-02 15:17:49 -0700
commit0f17c5eb9ac4660f2f969bd1e67af42713e45eac (patch)
tree279ca7da2de0efe2f363684f3c84a540635f11a8 /core
parentacd9c2acd4688f2301b091daad910c04e402bd6a (diff)
parentdc41f30c73c9686685e3a4183c1213fb4ba55c90 (diff)
Merge branch 'master' into working
Diffstat (limited to 'core')
-rw-r--r--core/collections.nom57
-rw-r--r--core/control_flow.nom358
-rw-r--r--core/coroutines.nom10
-rw-r--r--core/errors.nom43
-rw-r--r--core/id.nom6
-rw-r--r--core/io.nom6
-rw-r--r--core/math.nom154
-rw-r--r--core/metaprogramming.nom233
-rw-r--r--core/operators.nom102
-rw-r--r--core/scopes.nom12
-rw-r--r--core/text.nom6
11 files changed, 566 insertions, 421 deletions
diff --git a/core/collections.nom b/core/collections.nom
index 8dbc79d..ae7f5f1 100644
--- a/core/collections.nom
+++ b/core/collections.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V4.8.8.6
+#!/usr/bin/env nomsu -V4.8.10
#
This file contains code that supports manipulating and using collections like lists
and dictionaries.
@@ -45,17 +45,17 @@ test:
# List Comprehension
test:
assume (((% * %) for % in [1, 2, 3]) == [1, 4, 9])
-parse [%expression for %item in %iterable] as (..)
+(%expression for %item in %iterable) parses as (..)
result of:
%comprehension = []
for %item in %iterable:
%comprehension::add %expression
return %comprehension
-parse [..]
+[..]
%expression for %index in %start to %stop via %step
%expression for %index in %start to %stop by %step
-..as (..)
+..all parse as (..)
result of:
%comprehension = []
for %index in %start to %stop via %step:
@@ -66,15 +66,15 @@ parse [..]
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) parses as (..)
%expression for %var in %start to %stop via 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 (..)
+..all parse as (..)
result of:
%comprehension = []
for %key = %value in %iterable:
@@ -84,7 +84,9 @@ parse [..]
# 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 (..)
+[..]
+ %key = %value for %item in %iterable, %key %value for %item in %iterable
+..all parse as (..)
result of:
%comprehension = {}
for %item in %iterable:
@@ -93,20 +95,20 @@ parse [%key = %value for %item in %iterable, %key %value for %item in %iterable]
test:
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
%key %value for %src_key %src_value in %iterable
-..as (..)
+..all parse as (..)
result of:
%comprehension = {}
for %src_key = %src_value in %iterable:
%comprehension.%key = %value
return %comprehension
-parse [..]
+[..]
%key = %value for %item in %start to %stop via %step
%key %value for %item in %start to %stop via %step
-..as (..)
+..all parse as (..)
result of:
%comprehension = {}
for %item in %start to %stop via %step:
@@ -117,14 +119,14 @@ parse [..]
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)
+..all parse as (%key = %value for %item in %start to %stop via 1)
test:
assume (([[1, 2], [3, 4]] flattened) == [1, 2, 3, 4])
-action [%lists flattened]:
+externally (%lists flattened) means:
%flat = []
for %list in %lists:
for %item in %list: %flat::add %item
@@ -132,27 +134,30 @@ action [%lists flattened]:
test:
assume ((entries in {x:1}) == [{key:"x", value:1}])
-parse [entries in %dict] as ({key:%k, value:%v} for %k = %v in %dict)
+(entries in %dict) parses 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)
+[keys in %dict, keys of %dict] all parse as (%k for %k = %v in %dict)
test:
assume ((values in {x:1}) == [1])
-parse [values in %dict, values of %dict] as (%v for %k = %v in %dict)
+[values in %dict, values of %dict] all parse as (%v for %k = %v in %dict)
# Metatable stuff
test:
%t = {}
set %t 's metatable to {__tostring:[%] -> "XXX"}
assume ("\%t" == "XXX")
-compile [set %dict 's metatable to %metatable] to (..)
+(set %dict 's metatable to %metatable) compiles to (..)
Lua "setmetatable(\(%dict as lua expr), \(%metatable as lua expr));"
+[% 's metatable, % 'metatable] all compile to (..)
+ Lua value "getmetatable(\(% as lua expr))"
+
test:
assume (({} with fallback % -> (% + 1)).10 == 11)
-compile [%dict with fallback %key -> %value] to (..)
+(%dict with fallback %key -> %value) compiles to (..)
Lua value "\
..(function(d)
local mt = {}
@@ -175,8 +180,10 @@ test:
%keys = {1:999, 2:0, 3:50}
sort %x by % = %keys.%
assume (%x == [2, 3, 1])
-compile [sort %items] to (Lua "table.sort(\(%items as lua expr));")
-parse [sort %items by %item = %key_expr, sort %items by %item -> %key_expr] as (..)
+(sort %items) compiles to (Lua "table.sort(\(%items as lua expr));")
+[..]
+ sort %items by %item = %key_expr, sort %items by %item -> %key_expr
+..all parse as (..)
do:
%keys = ({} with fallback %item -> %key_expr)
lua> "table.sort(\%items, function(x,y) return \%keys[x] < \%keys[y] end)"
@@ -185,12 +192,12 @@ parse [sort %items by %item = %key_expr, sort %items by %item -> %key_expr] as (
test:
assume ((sorted [3, 1, 2]) == [1, 2, 3])
-action [%items sorted, sorted %items]:
+externally [%items sorted, sorted %items] all mean:
%copy = (% for % in %items)
sort %copy
return %copy
-parse [%items sorted by %item = %key, %items sorted by %item -> %key] as (..)
+[%items sorted by %item = %key, %items sorted by %item -> %key] all parse as (..)
result of:
%copy = (% for % in %items)
sort %copy by %item = %key
@@ -198,7 +205,7 @@ parse [%items sorted by %item = %key, %items sorted by %item -> %key] as (..)
test:
assume ((unique [1, 2, 1, 3, 2, 3]) == [1, 2, 3])
-action [unique %items]:
+externally (unique %items) means:
%unique = []
%seen = {}
for % in %items:
diff --git a/core/control_flow.nom b/core/control_flow.nom
index a9e0ae0..bbc98f1 100644
--- a/core/control_flow.nom
+++ b/core/control_flow.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V4.8.8.6
+#!/usr/bin/env nomsu -V4.8.10
#
This file contains compile-time actions that define basic control flow structures
like "if" statements and loops.
@@ -10,31 +10,35 @@ use "core/errors.nom"
# No-Op
test: do nothing
-compile [do nothing] to (Lua "")
+(do nothing) compiles to (Lua "")
# Conditionals
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"
+(if %condition %if_body) compiles to:
+ %lua = (Lua "if ")
+ %lua::append (%condition as lua expr)
+ %lua::append " then\n "
+ %lua::append (%if_body as lua statements)
+ %lua::append "\nend"
+ return %lua
test:
unless (yes):
barf "conditional fail"
-parse [unless %condition %unless_body] as (if (not %condition) %unless_body)
-compile [..]
+(unless %condition %unless_body) parses as (if (not %condition) %unless_body)
+[..]
if %condition %if_body else %else_body, unless %condition %else_body else %if_body
-..to (..)
- Lua "\
- ..if \(%condition as lua expr) then
- \(%if_body as lua statements)
- else
- \(%else_body as lua statements)
- end"
+..all compile to:
+ %lua = (Lua "if ")
+ %lua::append (%condition as lua expr)
+ %lua::append " then\n "
+ %lua::append (%if_body as lua statements)
+ %lua::append "\nelse\n "
+ %lua::append (%else_body as lua statements)
+ %lua::append "\nend"
+ return %lua
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -44,12 +48,12 @@ compile [..]
test:
assume ((1 if (yes) else 2) == 1)
assume ((1 if (no) else 2) == 2)
-compile [..]
+[..]
%when_true_expr if %condition else %when_false_expr
%when_true_expr if %condition otherwise %when_false_expr
%when_false_expr unless %condition else %when_true_expr
%when_false_expr unless %condition then %when_true_expr
-..to (..)
+..all compile to:
# If %when_true_expr is guaranteed to be truthy, we can use Lua's idiomatic
equivalent of a conditional expression: (cond and if_true or if_false)
if {Text:yes, List:yes, Dict:yes, Number:yes}.(%when_true_expr.type):
@@ -72,6 +76,8 @@ compile [..]
end
end)())"
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
# GOTOs
test:
%i = 0
@@ -79,14 +85,37 @@ test:
%i += 1
unless (%i == 10): go to %loop
assume (%i == 10)
-compile [=== %label ===, --- %label ---, *** %label ***] to (..)
- Lua "::label_\(%label as lua identifier)::"
+ === (Loop) ===
+ %i -= 1
+ unless (%i == 0): go to (Loop)
+ assume (%i == 0)
+[=== %label ===, --- %label ---, *** %label ***] all compile to (..)
+ Lua "\
+ ..::label_\(..)
+ (%label.stub if (%label.type == "Action") else %label) as lua identifier
+ ..::"
-compile [go to %label] to (Lua "goto label_\(%label as lua identifier)")
+(go to %label) compiles to (..)
+ Lua "\
+ ..goto label_\(..)
+ (%label.stub if (%label.type == "Action") else %label) as lua identifier
+ .."
# Basic loop control
-compile [do next] to (Lua "goto continue")
-compile [stop] to (Lua "break")
+(stop %var) compiles to:
+ if %var:
+ return (..)
+ Lua "goto stop_\((%var.stub if (%var.type == "action") else %var) as lua identifier)"
+ ..else: return (Lua "break")
+(do next %var) compiles to:
+ if %var:
+ return (..)
+ Lua "goto continue_\((%var.stub if (%var.type == "action") else %var) as lua identifier)"
+ ..else: return (Lua "goto continue")
+[===stop %var ===, ---stop %var ---, ***stop %var ***] all compile to (..)
+ Lua "::stop_\((%var.stub if (%var.type == "action") else %var) as lua identifier)::"
+[===next %var ===, ---next %var ---, ***next %var ***] all compile to (..)
+ Lua "::continue_\((%var.stub if (%var.type == "action") else %var) as lua identifier)::"
# While loops
test:
@@ -108,9 +137,9 @@ test:
barf "Failed to 'do next repeat'"
assume (%x == 30)
-compile [do next repeat] to (Lua "goto continue_repeat")
-compile [stop repeating] to (Lua "goto stop_repeat")
-compile [repeat while %condition %body] to:
+(do next repeat) compiles to (Lua "goto continue_repeat")
+(stop repeating) compiles to (Lua "goto stop_repeat")
+(repeat while %condition %body) compiles to:
%lua = (..)
Lua "\
..while \(%condition as lua expr) do
@@ -122,53 +151,44 @@ compile [repeat while %condition %body] to:
%lua::append "\n ::continue_repeat::"
%lua::append "\nend --while-loop"
if (%body has subtree \(stop repeating)):
- %lua = (..)
- Lua "\
- ..do -- scope of "stop repeating" label
- \%lua
- ::stop_repeat::
- end -- end of "stop repeating" label scope"
+ %inner_lua = %lua
+ %lua = (Lua "do -- scope of 'stop repeating' label\n ")
+ %lua::append %inner_lua
+ %lua::append "\
+ ..
+ ::stop_repeat::
+ end -- end of 'stop repeating' label scope"
return %lua
-parse [repeat %body] as (repeat while (yes) %body)
-parse [repeat until %condition %body] as (repeat while (not %condition) %body)
+(repeat %body) parses as (repeat while (yes) %body)
+(repeat until %condition %body) parses as (repeat while (not %condition) %body)
test:
%x = 0
repeat 10 times: %x += 1
assume (%x == 10)
-compile [repeat %n times %body] to:
+(repeat %n times %body) compiles to:
define mangler
%lua = (..)
- Lua "\
- ..for \(mangle "i")=1,\(%n as lua expr) do
- \(%body as lua statements)"
-
+ Lua "for \(mangle "i")=1,\(%n as lua expr) do\n "
+ %lua::append (%body as lua statements)
if (%body has subtree \(do next)):
%lua::append "\n ::continue::"
if (%body has subtree \(do next repeat)):
%lua::append "\n ::continue_repeat::"
%lua::append "\nend --numeric for-loop"
if (%body has subtree \(stop repeating)):
- %lua = (..)
- Lua "\
- ..do -- scope of "stop repeating" label
- \%lua
- ::stop_repeat::
- end -- end of "stop repeating" label scope"
+ %inner_lua = %lua
+ %lua = (Lua "do -- scope of 'stop repeating' label\n ")
+ %lua::append %inner_lua
+ %lua::append "\
+ ..
+ ::stop_repeat::
+ end -- end of 'stop repeating' label scope"
return %lua
-# For loop control flow
-compile [stop %var] to (Lua "goto stop_\(%var as lua identifier)")
-compile [do next %var] to (Lua "goto continue_\(%var as lua identifier)")
-compile [===stop %var ===, ---stop %var ---, ***stop %var ***] to (..)
- Lua "::stop_\(%var as lua identifier)::"
-
-compile [===next %var ===, ---next %var ---, ***next %var ***] to (..)
- Lua "::continue_\(%var as lua identifier)::"
-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test:
@@ -191,38 +211,41 @@ test:
assume (%nums == [1, -2, 3, -2, 3, 4, 3, 4, 5])
# Numeric range for loops
-compile [..]
+[..]
for %var in %start to %stop by %step %body
for %var in %start to %stop via %step %body
-..to:
+..all 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 "Expected a variable here, not a \(%var.type)."
+ compile error at %var "Expected a variable here, not a \(%var.type)"
%lua = (..)
Lua "\
..for \(%var as lua expr)=\(%start as lua expr),\(%stop as lua expr),\(..)
%step as lua expr
- .. do
- \(%body as lua statements)"
+ .. do"
+ %lua::append "\n "
+ %lua::append (%body as lua statements)
if (%body has subtree \(do next)):
%lua::append "\n ::continue::"
if (%body has subtree \(do next %var)):
- %lua::append "\n \(compile as (===next %var ===))"
+ %lua::append "\n "
+ %lua::append (what (===next %var ===) compiles to)
+
%lua::append "\nend --numeric for-loop"
if (%body has subtree \(stop %var)):
- %lua = (..)
- Lua "\
- ..do -- scope for stopping for-loop
- \%lua
- \(compile as (===stop %var ===))
- end -- end of scope for stopping for-loop"
+ %inner_lua = %lua
+ %lua = (Lua "do -- scope for stopping for-loop\n ")
+ %lua::append %inner_lua
+ %lua::append "\n "
+ %lua::append (what (===stop %var ===) compiles to)
+ %lua::append "\nend -- end of scope for stopping for-loop"
return %lua
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-parse [for %var in %start to %stop %body] as (..)
+(for %var in %start to %stop %body) parses as (..)
for %var in %start to %stop via 1 %body
test:
@@ -239,28 +262,49 @@ test:
assume (%b == [20, 30, 40])
# 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 "Expected a variable here, not a \(%var.type)."
+(for %var in %iterable %body) compiles to:
define mangler
+ # This uses Lua's approach of only allowing loop-scoped variables in a loop
%lua = (..)
- Lua "\
- ..for \(mangle "i"),\(%var as lua identifier) in ipairs(\(%iterable as lua expr)) do
- \(%body as lua statements)"
+ Lua "for \(mangle "i"),\(%var as lua identifier) in ipairs(\(%iterable as lua expr)) do\n "
+ %lua::append (%body as lua statements)
+ if (%body has subtree \(do next)):
+ %lua::append "\n ::continue::"
+ if (%body has subtree \(do next %var)):
+ %lua::append "\n "
+ %lua::append (what (===next %var ===) compiles to)
+ %lua::append "\nend --foreach-loop"
+ if (%body has subtree \(stop %var)):
+ %inner_lua = %lua
+ %lua = (Lua "do -- scope for stopping for-loop\n ")
+ %lua::append %inner_lua
+ %lua::append "\n "
+ %lua::append (what (===stop %var ===) compiles to)
+ %lua::append "\nend -- end of scope for stopping for-loop"
+
+ return %lua
+
+# TODO: reduce code duplication
+(for %var in %iterable at %i %body) compiles to:
+ # This uses Lua's approach of only allowing loop-scoped variables in a loop
+ %lua = (..)
+ Lua "for \(%i as lua identifier),\(%var as lua identifier) in ipairs(\(%iterable as lua expr)) do\n "
+ %lua::append (%body as lua statements)
if (%body has subtree \(do next)):
%lua::append "\n ::continue::"
if (%body has subtree \(do next %var)):
- %lua::append (Lua "\n\(compile as (===next %var ===))")
+ %lua::append "\n "
+ %lua::append (what (===next %var ===) compiles to)
+
%lua::append "\nend --foreach-loop"
if (%body has subtree \(stop %var)):
- %lua = (..)
- Lua "\
- ..do -- scope for stopping for-loop
- \%lua
- \(compile as (===stop %var ===))
- end -- end of scope for stopping for-loop"
+ %inner_lua = %lua
+ %lua = (Lua "do -- scope for stopping for-loop\n ")
+ %lua::append %inner_lua
+ %lua::append "\n "
+ %lua::append (what (===stop %var ===) compiles to)
+ %lua::append "\nend -- end of scope for stopping for-loop"
return %lua
@@ -275,46 +319,55 @@ test:
assume ((%result sorted) == ["c = 30", "d = 40", "e = 50"])
# Dict iteration (lua's "pairs()")
-compile [..]
+[..]
for %key = %value in %iterable %body, for %key %value in %iterable %body
-..to:
+..all compile to:
# This uses Lua's approach of only allowing loop-scoped variables in a loop
unless (%key.type is "Var"):
- compile error at %key "Expected a variable here, not a \(%key.type)."
+ compile error at %key "Expected a variable here, not a \(%key.type)"
unless (%value.type is "Var"):
- compile error at %value "Expected a variable here, not a \(%value.type)."
+ compile error at %value "Expected a variable here, not a \(%value.type)"
%lua = (..)
Lua "\
..for \(%key as lua identifier),\(%value as lua identifier) in pairs(\(..)
%iterable as lua expr
- ..) do
- \(%body as lua statements)"
+ ..) do"
+ %lua::append "\n "
+ %lua::append (%body as lua statements)
if (%body has subtree \(do next)):
%lua::append "\n ::continue::"
if (%body has subtree \(do next %key)):
- %lua::append (Lua "\n\(compile as (===next %key ===))")
+ %lua::append "\n "
+ %lua::append (what (===next %key ===) compiles to)
+
if (%body has subtree \(do next %value)):
- %lua::append (Lua "\n\(compile as (===next %value ===))")
+ %lua::append "\n "
+ %lua::append (what (===next %value ===) compiles to)
+
%lua::append "\nend --foreach-loop"
%stop_labels = (Lua "")
if (%body has subtree \(stop %key)):
- %stop_labels::append "\n\(compile as (===stop %key ===))"
+ %stop_labels::append "\n"
+ %stop_labels::append (what (===stop %key ===) compiles to)
+
if (%body has subtree \(stop %value)):
- %stop_labels::append "\n\(compile as (===stop %value ===))"
+ %stop_labels::append "\n"
+ %stop_labels::append (what (===stop %value ===) compiles to)
+
if ((size of "\%stop_labels") > 0):
- %lua = (..)
- Lua "\
- ..do -- scope for stopping for % = % loop
- \%lua\%stop_labels
- end"
+ %inner_lua = %lua
+ %lua = (Lua "do -- scope for stopping for % = % loop\n ")
+ %lua::append %inner_lua
+ %lua::append %stop_labels
+ %lua::append "\nend"
return %lua
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test:
- if:
+ when:
(1 == 2) (100 < 0):
barf "bad conditional"
(1 == 0) (1 == 1) %not_a_variable.x: do nothing
@@ -326,13 +379,14 @@ test:
barf "bad conditional"
# Multi-branch conditional (if..elseif..else)
-compile [if %body, when %body] to:
+(when %body) compiles to:
%code = (Lua "")
%clause = "if"
%else_allowed = (yes)
unless (%body.type is "Block"):
compile error at %body "'if' expected a Block, but got a \(%body.type)."
..hint "Perhaps you forgot to put a ':' after 'if'?"
+
for %line in %body:
unless (..)
((%line.type is "Action") and ((size of %line) >= 2)) and (..)
@@ -347,6 +401,7 @@ compile [if %body, when %body] to:
unless %else_allowed:
compile error at %line "You can't have two 'else' blocks."
..hint "Merge all of the 'else' blocks together."
+
unless ((size of "\%code") > 0):
compile error at %line "\
..You can't have an 'else' block without a preceeding condition"
@@ -354,23 +409,19 @@ compile [if %body, when %body] to:
..need a conditional block around it. Otherwise, make sure the 'else' \
..block comes last."
- %code::append "\
- ..
- else
- \(%action as lua statements)"
-
+ %code::append "\nelse\n "
+ %code::append (%action as lua statements)
%else_allowed = (no)
..else:
- %code::append "\%clause "
+ %code::append %clause
+ %code::append " "
for %i in 1 to ((size of %line) - 1):
if (%i > 1):
%code::append " or "
%code::append (%line.%i as lua expr)
- %code::append "\
- .. then
- \(%action as lua statements)"
-
+ %code::append " then\n "
+ %code::append (%action as lua statements)
%clause = "\nelseif"
if ((size of "\%code") == 0):
@@ -390,7 +441,7 @@ test:
barf "bad switch statement"
# Switch statement
-compile [if %branch_value is %body, when %branch_value is %body] to:
+[if %branch_value is %body, when %branch_value is %body] all compile to:
%code = (Lua "")
%clause = "if"
%else_allowed = (yes)
@@ -419,42 +470,42 @@ compile [if %branch_value is %body, when %branch_value is %body] to:
..need a conditional block around it. Otherwise, make sure the 'else' \
..block comes last."
- %code::append "\
- ..
- else
- \(%action as lua statements)"
-
+ %code::append "\nelse\n "
+ %code::append (%action as lua statements)
%else_allowed = (no)
..else:
- %code::append "\%clause "
+ %code::append %clause
+ %code::append " "
for %i in 1 to ((size of %line) - 1):
if (%i > 1):
%code::append " or "
- %code::append "\(mangle "branch value") == \(%line.%i as lua expr)"
-
- %code::append "\
- .. then
- \(%action as lua statements)"
+ %code::append "\(mangle "branch value") == "
+ %code::append (%line.%i as lua expr)
+ %code::append " then\n "
+ %code::append (%action as lua statements)
%clause = "\nelseif"
if ((size of "\%code") == 0):
compile error at %body "'if' block has an empty body."
..hint "This means nothing would happen, so the 'if' block should be deleted."
%code::append "\nend --when"
- return (..)
+ %lua = (..)
Lua "\
- ..do --if % is
- local \(mangle "branch value") = \(%branch_value as lua expr)
- \%code
- end --if % is"
+ ..do --if % is...
+ local \(mangle "branch value") = "
+ %lua::append (%branch_value as lua expr)
+ %lua::append "\n "
+ %lua::append %code
+ %lua::append "\nend --if % is..."
+ return %lua
# Do/finally
-compile [do %action] to (..)
- Lua "\
- ..do
- \(%action as lua statements)
- end --do"
+(do %action) compiles to:
+ %lua = (Lua "do\n ")
+ %lua::append (%action as lua statements)
+ %lua::append "\nend -- do"
+ return %lua
test:
%d = {}
@@ -463,60 +514,63 @@ test:
%d.x = "bad"
barf
..then always: %d.x = "good"
- ..and if it barfs: do nothing
-
assume (%d.x == "good")
-compile [do %action then always %final_action] to:
+(do %action then always %final_action) compiles to:
define mangler
- return (..)
+ %lua = (..)
Lua "\
..do
local \(mangle "fell_through") = false
- local \(mangle "ok"), \(mangle "ret") = pcall(function()
- \(%action as lua statements)
- \(mangle "fell_through") = true
- end)
- \(%final_action as lua statements)
- if not \(mangle "ok") then error(ret, 0) end
- if not \(mangle "fell_through") then return ret end
- end"
+ local \(mangle "ok"), \(mangle "ret") = pcall(function()"
+ %lua::append "\n "
+ %lua::append (%action as lua statements)
+ %lua::append "\
+ .. \(mangle "fell_through") = true
+ end)"
+ %lua::append "\n "
+ %lua::append (%final_action as lua statements)
+ %lua::append "\
+ .. if not \(mangle "ok") then error(ret, 0) end
+ if not \(mangle "fell_through") then return ret end
+ end"
+ return %lua
test:
assume ((result of (: return 99)) == 99)
# Inline thunk:
-compile [result of %body] to (Lua value "\(compile as ([] -> %body))()")
+(result of %body) compiles to (Lua value "\(what ([] -> %body) compiles to)()")
test:
%t = [1, [2, [[3], 4], 5, [[[6]]]]]
%flat = []
for % in recursive %t:
- if ((type of %) is "table"):
+ if ((lua type of %) is "table"):
for %2 in %: recurse % on %2
..else: %flat::add %
- assume ((sorted %flat) == [1, 2, 3, 4, 5, 6])
+ assume (sorted %flat) == [1, 2, 3, 4, 5, 6]
# Recurion control flow
-compile [for %var in recursive %structure %body] to (..)
+(for %var in recursive %structure %body) compiles to:
with local compile actions:
define mangler
- compile [recurse %v on %x] to (..)
+ (recurse %v on %x) compiles to (..)
Lua "table.insert(\(mangle "stack \(%v.1)"), \(%x as lua expr))"
%lua = (..)
Lua "\
..do
local \(mangle "stack \(%var.1)") = _List{\(%structure as lua expr)}
while #\(mangle "stack \(%var.1)") > 0 do
- \(%var as lua expr) = table.remove(\(mangle "stack \(%var.1)"), 1)
- \(%body as lua statements)"
-
+ \(%var as lua expr) = table.remove(\(mangle "stack \(%var.1)"), 1)"
+ %lua::append "\n "
+ %lua::append (%body as lua statements)
if (%body has subtree \(do next)):
%lua::append "\n ::continue::"
if (%body has subtree \(do next %var)):
- %lua::append "\n \(compile as (===next %var ===))"
+ %lua::append "\n \(what (===next %var ===) compiles to)"
%lua::append "\n end -- Recursive loop"
if (%body has subtree \(stop %var)):
- %lua::append "\n \(compile as (===stop %var ===))"
+ %lua::append "\n \(what (===stop %var ===) compiles to)"
%lua::append "\nend -- Recursive scope"
return %lua
diff --git a/core/coroutines.nom b/core/coroutines.nom
index e7ec41e..246a2ef 100644
--- a/core/coroutines.nom
+++ b/core/coroutines.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V4.8.8.6
+#!/usr/bin/env nomsu -V4.8.10
#
This file defines the code that creates and manipulates coroutines
@@ -14,15 +14,15 @@ test:
for % in coroutine %co: %nums::add %
assume (%nums == [4, 5, 6, 6, 6]) or barf "Coroutine iteration failed"
-compile [coroutine %body, generator %body] to (..)
+[coroutine %body, generator %body] all compile to (..)
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))")
-compile [for % in coroutine %co %body] to (..)
+(->) compiles to (Lua value "coroutine.yield(true)")
+(-> %) compiles to (Lua value "coroutine.yield(true, \(% as lua expr))")
+(for % in coroutine %co %body) compiles to (..)
Lua "\
..for junk,\(% as lua expr) in coroutine.wrap(\(%co as lua expr)) do
\(%body as lua statements)
diff --git a/core/errors.nom b/core/errors.nom
index 1157cb1..0b0a6a3 100644
--- a/core/errors.nom
+++ b/core/errors.nom
@@ -1,17 +1,16 @@
-#!/usr/bin/env nomsu -V4.8.8.6
+#!/usr/bin/env nomsu -V4.8.10
#
This file contains basic error reporting code
use "core/metaprogramming.nom"
-compile [barf] to (Lua "error(nil, 0);")
-compile [barf %msg] to (Lua "error(\(%msg as lua expr), 0);")
-compile [compile error at %tree %msg] to (..)
+(barf %msg) compiles to (Lua "error(\(=lua "\%msg and \(%msg as lua expr) or 'nil'"), 0);")
+(compile error at %tree %msg) compiles to (..)
Lua "nomsu:compile_error(\(%tree as lua expr), \(%msg as lua expr))"
-compile [compile error at %tree %msg hint %hint] to (..)
+(compile error at %tree %msg hint %hint) compiles to (..)
Lua "nomsu:compile_error(\(%tree as lua expr), \(%msg as lua expr), \(%hint as lua expr))"
-compile [assume %condition] to:
+(assume %condition) compiles to:
lua> "\
..local \%assumption = 'Assumption failed: '..tostring(nomsu:tree_to_nomsu(\%condition))"
return (..)
@@ -20,7 +19,7 @@ compile [assume %condition] to:
error(\(quote "\%assumption"), 0)
end"
-compile [assume %a == %b] to:
+(assume %a == %b) compiles to:
lua> "\
..local \%assumption = 'Assumption failed: '..tostring(nomsu:tree_to_nomsu(\(\(%a == %b))))"
define mangler
@@ -35,7 +34,7 @@ compile [assume %a == %b] to:
end
end"
-compile [assume %condition or barf %message] to (..)
+(assume %condition or barf %message) compiles to (..)
Lua "\
..if not \(%condition as lua expr) then
error(\(%message as lua expr), 0)
@@ -55,10 +54,10 @@ test:
assume (%x == 3) or barf "do/then always failed"
# Try/except
-compile [..]
+[..]
try %action and if it succeeds %success or if it barfs %msg %fallback
try %action and if it barfs %msg %fallback or if it succeeds %success
-..to (..)
+..all compile to (..)
Lua "\
..do
local fell_through = false
@@ -66,9 +65,9 @@ compile [..]
local ok, ret = xpcall(function()
\(%action as lua statements)
fell_through = true
- end, function(\(%msg as lua expr))
+ end, function(\(=lua "\%fallback and \(%msg as lua expr) or ''"))
local ok, ret = pcall(function()
- \(%fallback as lua statements)
+ \((=lua "\%fallback or \%msg") as lua statements)
end)
if not ok then err, erred = ret, true end
end)
@@ -84,21 +83,23 @@ compile [..]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-parse [..]
- try %action and if it succeeds %success or if it barfs %fallback
- try %action and if it barfs %fallback or if it succeeds %success
-..as (try %action and if it succeeds %success or if it barfs (=lua "") %fallback)
+#
+ [..]
+ try %action and if it succeeds %success or if it barfs %fallback
+ try %action and if it barfs %fallback or if it succeeds %success
+ ..all parse as (..)
+ try %action and if it succeeds %success or if it barfs (=lua "") %fallback
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-parse [try %action] as (..)
+(try %action) parses as (..)
try %action and if it succeeds (do nothing) or if it barfs (do nothing)
-parse [try %action and if it barfs %fallback] as (..)
+#(try %action and if it barfs %fallback) parses as (..)
try %action and if it succeeds (do nothing) or if it barfs %fallback
-parse [try %action and if it barfs %msg %fallback] as (..)
+(try %action and if it barfs %msg %fallback) parses as (..)
try %action and if it succeeds (do nothing) or if it barfs %msg %fallback
-parse [try %action and if it succeeds %success] as (..)
+(try %action and if it succeeds %success) parses as (..)
try %action and if it succeeds %success or if it barfs (do nothing)
diff --git a/core/id.nom b/core/id.nom
index d3b2b71..a9231b9 100644
--- a/core/id.nom
+++ b/core/id.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V4.8.8.6
+#!/usr/bin/env nomsu -V4.8.10
#
A simple UUID function based on RFC 4122: http://www.ietf.org/rfc/rfc4122.txt
@@ -27,7 +27,7 @@ set %id_by_obj 's metatable to {..}
%obj_by_id.%id = %key
return %id
-action [uuid]:
+externally (uuid) means:
# Set all the other bits to randomly (or pseudo-randomly) chosen values.
%bytes = [..]
# time-low, time-mid, time-high-and-version
@@ -56,4 +56,4 @@ test:
seed random with 0
assume ((id of %x) != (id of []))
seed random
-action [id of %, %'s id, %' id] %id_by_obj.%
+externally [id of %, %'s id, %'id] all mean %id_by_obj.%
diff --git a/core/io.nom b/core/io.nom
index 1e87209..6b67b50 100644
--- a/core/io.nom
+++ b/core/io.nom
@@ -1,10 +1,10 @@
-#!/usr/bin/env nomsu -V4.8.8.6
+#!/usr/bin/env nomsu -V4.8.10
#
This file contains basic input/output code
use "core/metaprogramming.nom"
-compile [say %message] to (..)
+(say %message) compiles to (..)
lua> "\
..if \%message.type == "Text" then
return LuaCode(tree.source, "print(", \(%message as lua expr), ");");
@@ -12,7 +12,7 @@ compile [say %message] to (..)
return LuaCode(tree.source, "print(tostring(", \(%message as lua expr), "));");
end"
-compile [ask %prompt] to (..)
+(ask %prompt) compiles to (..)
lua> "\
..if \%prompt.type == "Text" then
return LuaCode.Value(tree.source, "(io.write(", \(%prompt as lua expr), ") and io.read())");
diff --git a/core/math.nom b/core/math.nom
index d6ddbce..66f5aba 100644
--- a/core/math.nom
+++ b/core/math.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V4.8.8.6
+#!/usr/bin/env nomsu -V4.8.10
#
This file defines some common math literals and functions
@@ -14,17 +14,18 @@ test:
..math constants failed"
%nan = (NaN)
assume (%nan != %nan) or barf "NaN failed"
-compile [infinity, inf] to (Lua value "math.huge")
-compile [not a number, NaN, nan] to (Lua value "(0/0)")
-compile [pi, Pi, PI] to (Lua value "math.pi")
-compile [tau, Tau, TAU] to (Lua value "(2*math.pi)")
-compile [golden ratio] to (Lua value "((1+math.sqrt(5))/2)")
-compile [e] to (Lua value "math.exp(1)")
+[infinity, inf] all compile to (Lua value "math.huge")
+[not a number, NaN, nan] all compile to (Lua value "(0/0)")
+[pi, Pi, PI] all compile to (Lua value "math.pi")
+[tau, Tau, TAU] all compile to (Lua value "(2*math.pi)")
+(golden ratio) compiles to (Lua value "((1+math.sqrt(5))/2)")
+(e) compiles to (Lua value "math.exp(1)")
# Functions:
test:
assume (("5" as a number) == 5)
-compile [% as a number, % as number] to (Lua value "tonumber(\(% as lua expr))")
+[% as a number, % as number] all compile to (..)
+ Lua value "tonumber(\(% as lua expr))"
test:
assume (..)
@@ -33,79 +34,127 @@ test:
arc tangent 5, arc tangent 5 / 10, hyperbolic sine 5, hyperbolic cosine 5
hyperbolic tangent 5, e^ 5, ln 5, log base 2 of 5, floor 5, ceiling 5, round 5
..or barf "math functions failed"
-compile [absolute value %, | % |, abs %] to (..)
+[absolute value %, | % |, abs %] all compile to (..)
Lua value "math.abs(\(% as lua expr))"
-compile [square root %, square root of %, √ %, sqrt %] to (..)
+[square root %, square root of %, √ %, sqrt %] all compile to (..)
Lua value "math.sqrt(\(% as lua expr))"
-compile [sine %, sin %] to (Lua value "math.sin(\(% as lua expr))")
-compile [cosine %, cos %] to (Lua value "math.cos(\(% as lua expr))")
-compile [tangent %, tan %] to (Lua value "math.tan(\(% as lua expr))")
-compile [arc sine %, asin %] to (Lua value "math.asin(\(% as lua expr))")
-compile [arc cosine %, acos %] to (Lua value "math.acos(\(% as lua expr))")
-compile [arc tangent %, atan %] to (Lua value "math.atan(\(% as lua expr))")
-compile [arc tangent %y / %x, atan2 %y %x] to (..)
+[sine %, sin %] all compile to (Lua value "math.sin(\(% as lua expr))")
+[cosine %, cos %] all compile to (Lua value "math.cos(\(% as lua expr))")
+[tangent %, tan %] all compile to (Lua value "math.tan(\(% as lua expr))")
+[arc sine %, asin %] all compile to (Lua value "math.asin(\(% as lua expr))")
+[arc cosine %, acos %] all compile to (Lua value "math.acos(\(% as lua expr))")
+[arc tangent %, atan %] all compile to (Lua value "math.atan(\(% as lua expr))")
+[arc tangent %y / %x, atan2 %y %x] all compile 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 tangent %, tanh %] to (..)
+[hyperbolic sine %, sinh %] all compile to (..)
+ Lua value "math.sinh(\(% as lua expr))"
+
+[hyperbolic cosine %, cosh %] all compile to (..)
+ Lua value "math.cosh(\(% as lua expr))"
+
+[hyperbolic tangent %, tanh %] all compile to (..)
Lua value "math.tanh(\(% as lua expr))"
-compile [e^ %, exp %] to (Lua value "math.exp(\(% as lua expr))")
-compile [natural log %, ln %, log %] to (Lua value "math.log(\(% as lua expr))")
-compile [log % base %base, log base %base of %] to (..)
+[e^ %, exp %] all compile to (Lua value "math.exp(\(% as lua expr))")
+[natural log %, ln %, log %] all compile to (..)
+ Lua value "math.log(\(% as lua expr))"
+
+[log % base %base, log base %base of %] all compile to (..)
Lua value "math.log(\(% as lua expr), \(%base as lua expr))"
-compile [floor %] to (Lua value "math.floor(\(% as lua expr))")
-compile [ceiling %, ceil %] to (Lua value "math.ceil(\(% as lua expr))")
-compile [round %, % rounded] to (Lua value "math.floor(\(% as lua expr) + .5)")
+(floor %) compiles to (Lua value "math.floor(\(% as lua expr))")
+[ceiling %, ceil %] all compile to (Lua value "math.ceil(\(% as lua expr))")
+[round %, % rounded] all compile to (..)
+ Lua value "math.floor(\(% as lua expr) + .5)"
test:
assume ((463 to the nearest 100) == 500) or barf "rounding failed"
assume ((2.6 to the nearest 0.25) == 2.5) or barf "rounding failed"
-action [%n to the nearest %rounder] (..)
+externally (%n to the nearest %rounder) means (..)
=lua "(\%rounder)*math.floor((\%n / \%rounder) + .5)"
# Any/all/none
-compile [all of %items, all %items] to:
+[all of %items, all %items] all compile to:
unless (%items.type is "List"):
return (Lua value "utils.all(\(%items as lua expr))")
- %clauses = ((% as lua expr) for % in %items)
+ %clauses = (((% as lua expr)::text) for % in %items)
return (Lua value "(\(%clauses::joined with " and "))")
-parse [not all of %items, not all %items] as (not (all of %items))
-compile [any of %items, any %items] to:
+[not all of %items, not all %items] all parse as (not (all of %items))
+[any of %items, any %items] all compile to:
unless (%items.type is "List"):
return (Lua value "utils.any(\(%items as lua expr))")
- %clauses = ((% as lua expr) for % in %items)
+ %clauses = (((% as lua expr)::text) for % in %items)
return (Lua value "(\(%clauses::joined with " or "))")
-parse [none of %items, none %items] as (not (any of %items))
-compile [sum of %items, sum %items] to:
+[none of %items, none %items] all parse as (not (any of %items))
+[sum of %items, sum %items] all compile to:
unless (%items.type is "List"):
return (Lua value "utils.sum(\(%items as lua expr))")
- %clauses = ((% as lua expr) for % in %items)
+ %clauses = (((% as lua expr)::text) for % in %items)
return (Lua value "(\(%clauses::joined with " + "))")
-compile [product of %items, product %items] to:
+[if all of %items %body, if all of %items then %body] all parse as (..)
+ if (all of %items) %body
+
+[unless all of %items %body, unless all of %items then %body] all parse as (..)
+ if (not (all of %items)) %body
+
+[if any of %items %body, if any of %items then %body] all parse as (..)
+ if (any of %items) %body
+
+[unless any of %items %body, unless any of %items then %body] all parse as (..)
+ if (not (any of %items)) %body
+
+[if none of %items %body, if none of %items then %body] all parse as (..)
+ if (not (any of %items)) %body
+
+[unless none of %items %body, unless none of %items then %body] all parse as (..)
+ if (any of %items) %body
+
+[if all of %items %body else %else, if all of %items then %body else %else] all parse \
+..as (if (all of %items) %body else %else)
+
+[..]
+ unless all of %items %body else %else, unless all of %items then %body else %else
+..all parse as (if (not (all of %items)) %body else %else)
+
+[if any of %items %body else %else, if any of %items then %body else %else] all parse \
+..as (if (any of %items) %body else %else)
+
+[..]
+ unless any of %items %body else %else, unless any of %items then %body else %else
+..all parse as (if (not (any of %items)) %body else %else)
+
+[if none of %items %body else %else, if none of %items then %body else %else] all \
+..parse as (if (not (any of %items)) %body else %else)
+
+[..]
+ unless none of %items %body else %else, unless none of %items then %body else %else
+..all parse as (if (any of %items) %body else %else)
+
+[product of %items, product %items] all compile to:
unless (%items.type is "List"):
return (Lua value "utils.product(\(%items as lua expr))")
- %clauses = ((% as lua expr) for % in %items)
+ %clauses = (((% as lua expr)::text) for % in %items)
return (Lua value "(\(%clauses::joined with " * "))")
-action [avg of %items, average of %items] (=lua "(utils.sum(\%items)/#\%items)")
-compile [min of %items, smallest of %items, lowest of %items] to (..)
+externally [avg of %items, average of %items] all mean (..)
+ =lua "(utils.sum(\%items)/#\%items)"
+
+[min of %items, smallest of %items, lowest of %items] all compile 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))"
+[max of %items, biggest of %items, largest of %items, highest of %items] all compile \
+..to (Lua value "utils.max(\(%items as lua expr))")
test:
assume ((min of [3, -4, 1, 2] by % = (% * %)) == 1)
assume ((max of [3, -4, 1, 2] by % = (% * %)) == -4)
-parse [min of %items by %item = %value_expr] as (..)
+(min of %items by %item = %value_expr) parses as (..)
result of:
set {%best:nil, %best_key:nil}
for %item in %items:
@@ -115,7 +164,7 @@ parse [min of %items by %item = %value_expr] as (..)
return %best
-parse [max of %items by %item = %value_expr] as (..)
+(max of %items by %item = %value_expr) parses as (..)
result of:
set {%best:nil, %best_key:nil}
for %item in %items:
@@ -126,20 +175,19 @@ parse [max of %items by %item = %value_expr] as (..)
return %best
# Random functions
-action [seed random with %] (..)
+externally (seed random with %) means (..)
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 (..)
+(seed random) parses as (seed random with (=lua "os.time()"))
+[random number, random, rand] all compile to (Lua value "math.random()")
+[random int %n, random integer %n, randint %n] all compile to (..)
Lua value "math.random(\(%n as lua expr))"
-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))")
+[random from %low to %high, random number from %low to %high, rand %low %high] all \
+..compile 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)]"
+externally [..]
+ random choice from %elements, random choice %elements, random %elements
+..all mean (=lua "\%elements[math.random(#\%elements)]")
diff --git a/core/metaprogramming.nom b/core/metaprogramming.nom
index c50f783..61c877f 100644
--- a/core/metaprogramming.nom
+++ b/core/metaprogramming.nom
@@ -1,9 +1,9 @@
-#!/usr/bin/env nomsu -V4.8.8.6
+#!/usr/bin/env nomsu -V4.8.10
#
This File contains actions for making actions and compile-time actions and some helper
functions to make that easier.
-lua> "NOMSU_CORE_VERSION = 8"
+lua> "NOMSU_CORE_VERSION = 9"
lua> "\
..do
local mangle_index = 0
@@ -16,16 +16,16 @@ lua> "\
end
end
COMPILE_ACTIONS["define mangler"] = function(nomsu, tree)
- return LuaCode(tree.source, "local mangle_1 = mangler()")
+ return LuaCode(tree.source, "local mangle = mangler()")
end"
lua> "\
- ..COMPILE_ACTIONS["1 -> 2"] = function(nomsu, tree, \%args, \%body)
+ ..COMPILE_ACTIONS["1 ->"] = function(nomsu, tree, \%args, \%body)
local lua = LuaCode.Value(tree.source, "(function(")
- if AST.is_syntax_tree(\%args, "Action") then \%args = \%args:get_args() end
- local lua_args = table.map(\%args, function(a) return AST.is_syntax_tree(a) and tostring(nomsu:compile(a)) or a end)
+ if SyntaxTree:is_instance(\%args) and \%args.type == "Action" then \%args = \%args:get_args() end
+ local lua_args = table.map(\%args, function(a) return SyntaxTree:is_instance(a) and nomsu:compile(a):text() or a end)
lua:concat_append(lua_args, ", ")
- local body_lua = AST.is_syntax_tree(\%body) and nomsu:compile(\%body):as_statements("return ") or \%body
+ local body_lua = SyntaxTree:is_instance(\%body) and nomsu:compile(\%body):as_statements("return ") or \%body
body_lua:remove_free_vars(lua_args)
body_lua:declare_locals()
lua:append(")\\n ", body_lua, "\\nend)")
@@ -33,8 +33,8 @@ lua> "\
end"
lua> "\
- ..COMPILE_ACTIONS["compile as 1"] = function(nomsu, tree, \%action)
- local lua = LuaCode.Value(tree.source, "COMPILE_ACTIONS[", repr(\%action.stub), "](")
+ ..COMPILE_ACTIONS["what 1 compiles to"] = function(nomsu, tree, \%action)
+ local lua = LuaCode.Value(tree.source, "COMPILE_ACTIONS[", \%action.stub:as_lua(), "](")
local lua_args = table.map(\%action:get_args(), function(a) return nomsu:compile(a) end)
table.insert(lua_args, 1, "nomsu")
table.insert(lua_args, 2, "tree")
@@ -46,78 +46,84 @@ lua> "\
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test:
- compile [five] to (Lua value "5")
+ (five) compiles to (Lua value "5")
test:
assume ((five) == 5) or barf "Compile to expression failed."
- compile [loc x] to (Lua "local x = 99;")
+ (loc x) compiles to (Lua "local x = 99;")
test:
lua> "do"
loc x
assume (%x is 99) or barf "Compile to statements with locals failed."
lua> "end"
assume (%x is (nil)) or barf "Failed to properly localize a variable."
- compile [asdf] to:
+ (asdf) compiles to:
%tmp = ""
return (Lua %tmp)
test:
asdf
assume (%tmp is (nil)) or barf "compile to is leaking variables"
lua> "\
- ..COMPILE_ACTIONS["compile 1 to 2"] = 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 lua = LuaCode(tree.source, "COMPILE_ACTIONS[", repr(\%actions[1].stub),
- "] = ", \(compile as (%args -> %body)))
+ ..COMPILE_ACTIONS["1 compiles to"] = function(nomsu, tree, \%actions, \%body)
+ if \%actions.type ~= "List" then \%actions = {\%actions, type="List"} end
+ local \%args = {"nomsu", "tree", unpack(table.map(\%actions[1]:get_args(), function(a) return nomsu:compile(a):text() end))}
+ local lua = LuaCode(tree.source, "COMPILE_ACTIONS[", \%actions[1].stub:as_lua(),
+ "] = ", \(what (%args -> %body) compiles to))
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))}
- lua:append("\\nCOMPILE_ACTIONS[", repr(alias.stub), "] = ")
+ local \%alias_args = {"nomsu", "tree", unpack(table.map(alias:get_args(), function(a) return nomsu:compile(a):text() \
+ ..end))}
+ lua:append("\\nCOMPILE_ACTIONS[", alias.stub:as_lua(), "] = ")
if utils.equivalent(\%args, \%alias_args) then
- lua:append("COMPILE_ACTIONS[", repr(\%actions[1].stub), "]")
+ lua:append("COMPILE_ACTIONS[", \%actions[1].stub:as_lua(), "]")
else
lua:append("function(")
lua:concat_append(\%alias_args, ", ")
- lua:append(")\\n return COMPILE_ACTIONS[", repr(\%actions[1].stub), "](")
+ lua:append(")\\n return COMPILE_ACTIONS[", \%actions[1].stub:as_lua(), "](")
lua:concat_append(\%args, ", ")
lua:append(")\\nend")
end
end
return lua
- end"
+ end
+ COMPILE_ACTIONS["1 all compile to"] = COMPILE_ACTIONS["1 compiles to"]"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-compile [call %fn with %args] to:
+(call %fn with %args) compiles to:
lua> "\
..local lua = LuaCode.Value(tree.source, nomsu:compile(\%fn), "(")
- lua:concat_append(table.map(\%args, function(a) return nomsu:compile(a) end), ", ")
+ if \%args.type == 'List' then
+ lua:concat_append(table.map(\%args, function(a) return nomsu:compile(a) end), ", ")
+ else
+ lua:append('unpack(', nomsu:compile(\%args), ')')
+ end
lua:append(")")
return lua"
test:
- local action [foo %x]: return "outer"
- with local [action (foo %)]:
- local action [foo %x]:
+ (foo %x) means (return "outer")
+ with local [(foo %)'s meaning]:
+ (foo %x) means:
%y = (%x + 1)
return %y
assume ((foo 10) == 11) or barf "Action didn't work."
assume (%y is (nil)) or barf "Action leaked a local into globals."
- parse [baz %] as (foo %)
+ (baz %) parses as (foo %)
assume ((foo 1) == "outer")
-compile [local action %actions %body] to:
+[%actions means %body, %actions all mean %body] all compile to:
lua> "\
- ..local fn_name = \%actions[1].stub:as_lua_id()
- local \%args = table.map(\%actions[1]:get_args(), function(a) return tostring(nomsu:compile(a)) end)
- local lua = LuaCode(tree.source, fn_name, " = ", \(compile as (%args -> %body)))
+ ..if \%actions.type ~= "List" then \%actions = {\%actions, type="List"} end
+ local fn_name = \%actions[1].stub:as_lua_id()
+ local \%args = table.map(\%actions[1]:get_args(), function(a) return nomsu:compile(a):text() end)
+ local lua = LuaCode(tree.source, fn_name, " = ", \(what (%args -> %body) compiles to))
lua:add_free_vars({fn_name})
for i=2,#\%actions do
local alias = \%actions[i]
local alias_name = alias.stub:as_lua_id()
lua:add_free_vars({alias_name})
- local \%alias_args = table.map(alias:get_args(), function(a) return tostring(nomsu:compile(a)) end)
+ local \%alias_args = table.map(alias:get_args(), function(a) return nomsu:compile(a):text() end)
lua:append("\\n", alias_name, " = ")
if utils.equivalent(\%args, \%alias_args) then
lua:append(fn_name)
@@ -132,23 +138,24 @@ compile [local action %actions %body] to:
return lua"
test:
- action [baz1]: return "baz1"
- action [baz2] "baz2"
+ externally (baz1) means: return "baz1"
+ externally (baz2) means "baz2"
test:
assume ((baz1) == "baz1")
assume ((baz2) == "baz2")
-compile [action %actions %body] to (..)
+[externally %actions means %body, externally %actions all mean %body] all compile to:
lua> "\
- ..local lua = \(compile as (local action %actions %body))
+ ..local lua = \(what (%actions means %body) compiles to)
+ if \%actions.type ~= "List" then \%actions = {\%actions, type="List"} end
lua:remove_free_vars(table.map(\%actions, function(a) return a.stub:as_lua_id() end))
return lua"
test:
- assume ((action (say %)) == (=lua "say_1"))
-compile [action %action] to (Lua value (%action as lua id))
+ assume (((say %)'s meaning) == (=lua "say"))
+(%action's meaning) compiles to (Lua value (%action.stub as lua id))
test:
- parse [swap %x and %y] as (..)
+ (swap %x and %y) parses as (..)
do:
%tmp = %x
%x = %y
@@ -162,20 +169,21 @@ test:
swap %tmp and %tmp2
assume ((%tmp == 2) and (%tmp2 == 1)) or barf "\
..'parse % as %' variable mangling failed."
-compile [parse %actions as %body] to (..)
+[%actions parses as %body, %actions all parse as %body] all compile to:
lua> "\
..local replacements = {}
+ if \%actions.type ~= "List" then \%actions = {\%actions, type="List"} end
for i,arg in ipairs(\%actions[1]:get_args()) do
- replacements[arg[1]] = tostring(nomsu:compile(arg))
+ replacements[arg[1]] = nomsu:compile(arg):text()
end
local function make_tree(t)
- if AST.is_syntax_tree(t, "Var") then
+ if SyntaxTree:is_instance(t) and t.type == "Var" then
if replacements[t[1]] then
return replacements[t[1]]
else
- return t.type.."{mangle("..repr(t[1]).."), source="..repr(tostring(t.source)).."}"
+ return "SyntaxTree{mangle("..t[1]:as_lua().."), type="..t.type:as_lua()..", source="..tostring(t.source):as_lua().."}"
end
- elseif AST.is_syntax_tree(t) then
+ elseif SyntaxTree:is_instance(t) then
local ret = {}
local i = 1
for k, v in pairs(t) do
@@ -183,71 +191,76 @@ compile [parse %actions as %body] to (..)
ret[#ret+1] = make_tree(t[i])
i = i + 1
elseif k == "source" then
- ret[#ret+1] = k.."= "..repr(tostring(v))
- elseif type(k) == 'string' and k:match("[_a-zA-Z][_a-zA-Z0-9]*") then
+ ret[#ret+1] = k.."= "..tostring(v):as_lua()
+ elseif lua_type_of(k) == 'string' and k:match("[_a-zA-Z][_a-zA-Z0-9]*") then
ret[#ret+1] = k.."= "..make_tree(v)
else
ret[#ret+1] = "["..make_tree(k).."]= "..make_tree(v)
end
end
- return t.type.."{"..table.concat(ret, ", ").."}"
+ return "SyntaxTree{"..table.concat(ret, ", ").."}"
+ elseif lua_type_of(t) == 'number' then
+ return tostring(t)
else
- return repr(t)
+ return t:as_lua()
end
end
local \%new_body = LuaCode(\%body.source,
"local mangle = mangler()",
"\\nreturn ", make_tree(\%body))
- local ret = \(compile as (compile %actions to %new_body))
+ local ret = \(what (%actions compiles to %new_body) compiles to)
return ret"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# TODO: add check for .is_value
-compile [%tree as lua expr] to (Lua value "nomsu:compile(\(=lua "nomsu:compile(\%tree, nil, true)"), nil, true)")
+(%tree as lua expr) compiles to (..)
+ Lua value "nomsu:compile(\(=lua "nomsu:compile(\%tree, nil, true)"), nil, true)"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-compile [%tree as lua] to (Lua value "nomsu:compile(\(%tree as lua expr))")
-compile [%tree as lua statements] to (..)
+(%tree as lua) compiles to (Lua value "nomsu:compile(\(%tree as lua expr))")
+(%tree as lua statements) compiles to (..)
Lua value "nomsu:compile(\(%tree as lua expr)):as_statements()"
-compile [%tree as lua return] to (..)
+(%tree as lua return) compiles to (..)
Lua value "nomsu:compile(\(%tree as lua expr)):as_statements('return ')"
-compile [remove action %action] to (..)
- Lua "\(=lua "(\(%action.stub)):as_lua_id()") = nil"
-
test:
assume ("\(\(foo \%x) as nomsu)" == "foo %x") or barf "\
..action source code failed."
-compile [%tree as nomsu] to (..)
+(%tree as nomsu) compiles to (..)
Lua value "nomsu:tree_to_nomsu(\(%tree as lua expr))"
-compile [%tree as inline nomsu] to (..)
- Lua value "nomsu:tree_to_nomsu(\(%tree as lua expr), true)"
+(%tree as inline nomsu) compiles to (..)
+ Lua value "nomsu:tree_to_inline_nomsu(\(%tree as lua expr), true)"
-action [%var as lua identifier, %var as lua id] (..)
+externally [%var as lua identifier, %var as lua id] all mean:
lua> "\
- ..if type(\%var) == 'string' then return \%var:as_lua_id()
- elseif AST.is_syntax_tree(\%var, 'Var') then return \%var[1]:as_lua_id()
- elseif AST.is_syntax_tree(\%var, 'Action') then return \%var.stub:as_lua_id()
+ ..if lua_type_of(\%var) == 'string' then return \%var:as_lua_id()
+ elseif SyntaxTree:is_instance(\%var, 'Var') then return \%var[1]:as_lua_id()
+ elseif SyntaxTree:is_instance(\%var) then
+ local lua = \(%var as lua expr)
+ if not lua:text():match("^[_a-zA-Z][_a-zA-Z0-9]*$") then
+ nomsu:compile_error(\%var, "This is not a valid Lua identifier.")
+ end
+ return lua
else error("Unknown type: "..tostring(\%var))
end"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-compile [% is syntax tree] to (Lua value "AST.is_syntax_tree(\(% as lua expr))")
-compile [% is %kind syntax tree] to (..)
- Lua value "AST.is_syntax_tree(\(% as lua expr), \(%kind as lua expr))"
+(% is syntax tree) compiles to (Lua value "SyntaxTree:is_instance(\(% as lua expr))")
+(% is %kind syntax tree) compiles to (..)
+ Lua value "SyntaxTree:is_instance(\(% as lua expr), \(%kind as lua expr))"
-compile [%tree with %t -> %replacement] to (..)
+(%tree with %t -> %replacement) compiles to (..)
Lua value "\
..\(%tree as lua expr):map(function(\(%t as lua expr))
\(%replacement as lua return)
end)"
-action [%tree with vars %replacements] (..)
+externally (%tree with vars %replacements) means (..)
=lua "\
..\%tree:map(function(\%t)
if \%t.type == "Var" then
@@ -255,15 +268,15 @@ action [%tree with vars %replacements] (..)
end
end)"
-compile [tree %tree with vars %replacements] to (..)
+(tree %tree with vars %replacements) compiles to (..)
Lua value "\
- ..\(=lua "repr(\%tree)"):map(function(t)
+ ..\(=lua "(\%tree):as_lua()"):map(function(t)
if t.type == "Var" then
return \(%replacements as lua expr)[t[1]]
end
end)"
-compile [%tree has subtree %match_tree] to (..)
+(%tree has subtree %match_tree) compiles to (..)
Lua value "\
..(function()
local match_tree = \(%match_tree as lua expr)
@@ -272,14 +285,14 @@ compile [%tree has subtree %match_tree] to (..)
end
end)()"
-action [match %tree with %patt]:
+externally (match %tree with %patt) means:
lua> "\
..if \%patt.type == "Var" then return _Dict{[\%patt[1]]=\%tree} end
if \%patt.type == "Action" and \%patt.stub ~= \%tree.stub then return nil end
if #\%patt ~= #\%tree then return nil end
local matches = _Dict{}
for \%i=1,#\%patt do
- if AST.is_syntax_tree(\%tree[\%i]) then
+ if SyntaxTree:is_instance(\%tree[\%i]) then
local submatch = \(match %tree.%i with %patt.%i)
if not submatch then return nil end
for k,v in pairs(submatch) do
@@ -290,7 +303,7 @@ action [match %tree with %patt]:
end
return matches"
-action [%tree with %patt ~> %replacement]:
+externally (%tree with %patt ~> %replacement) means:
lua> "\
..return \%tree:map(function(\%t)
local \%vars = \(match %t with %patt)
@@ -312,11 +325,31 @@ test:
..one
"two""
..== "\"one\\n\\\"two\\\"\""
-compile [quote %s] to (Lua value "repr(\(%s as lua expr))")
+(quote %s) compiles to (Lua value "tostring(\(%s as lua expr)):as_lua()")
test:
- assume ((type of {}) == "table") or barf "type of failed."
-compile [type of %obj] to (Lua value "type(\(%obj as lua expr))")
+ assume (lua type of {}) == "table"
+ assume (type of {}) == "Dict"
+ assume ({} is a "Dict")
+ assume ("" is text)
+ assume ("" isn't a "Dict")
+externally (% is text) means (=lua "\(lua type of %) == 'string'")
+externally [% is not text, % isn't text] all mean (..)
+ =lua "\(lua type of %) ~= 'string'"
+
+externally (type of %) means:
+ lua> "\
+ ..local lua_type = \(lua type of %)
+ if lua_type == 'string' then return 'Text'
+ elseif lua_type == 'table' then
+ local mt = getmetatable(\%)
+ if mt and mt.__type then return mt.__type end
+ return 'Lua table'
+ else return lua_type end"
+
+[% is a %type, % is an %type] all parse as ((type of %) == %type)
+[% isn't a %type, % isn't an %type, % is not a %type, % is not an %type] all parse as (..)
+ (type of %) != %type
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -325,8 +358,8 @@ test:
%a = (parse "\\1")
%b = \(\(1))
assume ((parse "\\1") == \(\(1)))
-compile [parse %text] to (Lua value "nomsu:parse(\(%text as lua expr))")
-compile [parse %text from %filename] to (..)
+(parse %text) compiles to (Lua value "nomsu:parse(\(%text as lua expr))")
+(parse %text from %filename) compiles to (..)
Lua value "\
..nomsu:parse(NomsuCode(Source(\(%filename as lua expr), 1, #\(%text as lua expr)), \(..)
%text as lua expr
@@ -337,37 +370,39 @@ test:
external %passed = (no)
run "external %passed = (yes)"
assume %passed
-compile [run %nomsu_code] to (..)
+(run %nomsu_code) compiles to (..)
Lua value "\
- ..nomsu:run(NomsuCode(\(..)
- =lua "repr(tostring(\(%nomsu_code.source)))"
- .., \(%nomsu_code as lua expr)))"
+ ..nomsu:run(NomsuCode(\(=lua "tostring(\(%nomsu_code.source)):as_lua()"), \(..)
+ %nomsu_code as lua expr
+ ..))"
test:
assume ((\(\(5) + \(5)) as value) == 10) or barf "%tree as value failed."
-compile [run tree %tree, %tree as value] to (Lua value "nomsu:run(\(%tree as lua expr))")
-compile [compile %block, compiled %block, %block compiled] to (..)
+[run tree %tree, %tree as value] all compile to (..)
+ Lua value "nomsu:run(\(%tree as lua expr))"
+
+[compile %block, compiled %block, %block compiled] all compile to (..)
Lua value "nomsu:compile(\(%block as lua))"
# Return statement is wrapped in a do..end block because Lua is unhappy if you
put code after a return statement, unless you wrap it in a block.
-compile [return] to (Lua "do return; end")
-compile [return %return_value] to (..)
+(return) compiles to (Lua "do return; end")
+(return %return_value) compiles to (..)
Lua "do return \(%return_value as lua expr) end"
# Literals
-compile [yes] to (Lua value "true")
-compile [no] to (Lua value "false")
-compile [nothing, nil, null] to (Lua value "nil")
-compile [Nomsu syntax version] to (Lua value "NOMSU_SYNTAX_VERSION")
-compile [Nomsu compiler version] to (Lua value "NOMSU_COMPILER_VERSION")
-compile [core version] to (Lua value "NOMSU_CORE_VERSION")
-compile [lib version] to (Lua value "NOMSU_LIB_VERSION")
-compile [command line args] to (Lua value "arg")
+(yes) compiles to (Lua value "true")
+(no) compiles to (Lua value "false")
+[nothing, nil, null] all compile to (Lua value "nil")
+(Nomsu syntax version) compiles to (Lua value "NOMSU_SYNTAX_VERSION")
+(Nomsu compiler version) compiles to (Lua value "NOMSU_COMPILER_VERSION")
+(core version) compiles to (Lua value "NOMSU_CORE_VERSION")
+(lib version) compiles to (Lua value "NOMSU_LIB_VERSION")
+(command line args) compiles to (Lua value "arg")
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-compile [with local compile actions %body] to (..)
+(with local compile actions %body) compiles to (..)
Lua "\
..do
local nomsu = nomsu:fork()
@@ -375,7 +410,7 @@ compile [with local compile actions %body] to (..)
\(%body as lua statements)
end"
-action [Nomsu version]:
+externally (Nomsu version) means:
use "lib/version.nom"
return "\
..\(Nomsu syntax version).\(core version).\(Nomsu compiler version).\(lib version)"
diff --git a/core/operators.nom b/core/operators.nom
index 3ae7c2f..6d574b7 100644
--- a/core/operators.nom
+++ b/core/operators.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V4.8.8.6
+#!/usr/bin/env nomsu -V4.8.10
#
This file contains definitions of operators like "+" and "and".
@@ -9,14 +9,14 @@ test:
assume (all [1 < 2, 2 > 1, 1 <= 2, 2 >= 1, 1 == 1, 1 != 2])
# Comparison Operators
-compile [%x < %y] to (Lua value "(\(%x as lua expr) < \(%y as lua expr))")
-compile [%x > %y] to (Lua value "(\(%x as lua expr) > \(%y as lua expr))")
-compile [%x <= %y] to (Lua value "(\(%x as lua expr) <= \(%y as lua expr))")
-compile [%x >= %y] to (Lua value "(\(%x as lua expr) >= \(%y as lua expr))")
-compile [%a is %b, %a == %b] to (..)
+(%x < %y) compiles to (Lua value "(\(%x as lua expr) < \(%y as lua expr))")
+(%x > %y) compiles to (Lua value "(\(%x as lua expr) > \(%y as lua expr))")
+(%x <= %y) compiles to (Lua value "(\(%x as lua expr) <= \(%y as lua expr))")
+(%x >= %y) compiles to (Lua value "(\(%x as lua expr) >= \(%y as lua expr))")
+[%a is %b, %a == %b] all compile to (..)
Lua value "(\(%a as lua expr) == \(%b as lua expr))"
-compile [%a isn't %b, %a is not %b, %a not= %b, %a != %b] to (..)
+[%a isn't %b, %a is not %b, %a not= %b, %a != %b] all compile to (..)
Lua value "(\(%a as lua expr) ~= \(%b as lua expr))"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -26,7 +26,7 @@ test:
assume (%x == 10)
# Variable assignment operator
-compile [%var = %value] to:
+(%var = %value) compiles to:
lua> "local \%var_lua = \(%var as lua expr)"
assume %var_lua.is_value or barf "Invalid target for assignment: \%var"
lua> "local \%value_lua = \(%value as lua expr)"
@@ -34,7 +34,7 @@ compile [%var = %value] to:
lua> "\
..local lua = LuaCode(tree.source, \%var_lua, ' = ', \%value_lua, ';')
if \%var.type == 'Var' then
- lua:add_free_vars({tostring(nomsu:compile(\%var))})
+ lua:add_free_vars({nomsu:compile(\%var):text()})
end
return lua"
@@ -45,7 +45,7 @@ test:
assume ((%y == 10) and (%x == 20)) or barf "swapping vars failed."
# Simultaneous mutli-assignments like: x,y,z = 1,x,3;
-compile [set %assignments] to:
+(set %assignments) compiles to:
assume (%assignments.type is "Dict") or barf "\
..Expected a Dict for the assignments part of '<- %' statement, not \%assignments"
lua> "\
@@ -53,7 +53,7 @@ compile [set %assignments] to:
for i, item in ipairs(\%assignments) do
local \%target, \%value = item[1], item[2]
\%value = \%value:map(function(t)
- if Action:is_instance(t) and t.stub == "?" then
+ if SyntaxTree:is_instance(t) and t.type == "Action" and t.stub == "?" then
return \%target
end
end)
@@ -66,7 +66,7 @@ compile [set %assignments] to:
%value as text
..) end
if \%target.type == "Var" then
- lhs:add_free_vars({tostring(target_lua)})
+ lhs:add_free_vars({target_lua:text()})
end
if i > 1 then
lhs:append(", ")
@@ -81,13 +81,13 @@ compile [set %assignments] to:
test:
set {%foozle:"outer", %y:"outer"}
- action [set global x local y]:
+ externally (set global x local y) means:
external %foozle = "inner"
%y = "inner"
set global x local y
assume ((%foozle == "inner") and (%y == "outer")) or barf "external failed."
-compile [external %var = %value] to:
+(external %var = %value) compiles to:
%var_lua = (%var as lua)
assume %var_lua.is_value or barf "Invalid target for assignment: \%var"
%value_lua = (%value as lua)
@@ -96,7 +96,7 @@ compile [external %var = %value] to:
test:
set {%foozle:"outer", %y:"outer"}
- action [set global x local y] (..)
+ externally (set global x local y) means (..)
with external [%foozle]:
%foozle = "inner"
%y = "inner"
@@ -104,10 +104,10 @@ test:
set global x local y
assume ((%foozle == "inner") and (%y == "outer")) or barf "\
..'with external' failed."
-compile [with external %externs %body] to:
+(with external %externs %body) compiles to:
%body_lua = (%body as lua statements)
lua> "\
- ..\%body_lua:remove_free_vars(table.map(\%externs, function(v) return tostring(nomsu:compile(v)) end))"
+ ..\%body_lua:remove_free_vars(table.map(\%externs, function(v) return nomsu:compile(v):text() end))"
return %body_lua
test:
@@ -119,7 +119,7 @@ test:
assume (%x == 1) or barf "'with' scoping failed"
assume (%z == (nil)) or barf "'with' scoping failed"
-compile [with %assignments %body] to:
+(with %assignments %body) compiles to:
%lua = (%body as lua statements)
lua> "\
..local lhs, rhs = LuaCode(tree.source), LuaCode(tree.source)
@@ -141,7 +141,7 @@ compile [with %assignments %body] to:
lhs:append(target_lua)
rhs:append(value_lua)
if \%target.type == "Var" then
- vars[i] = tostring(target_lua)
+ vars[i] = target_lua:text()
end
end
\%lua:remove_free_vars(vars)
@@ -156,53 +156,53 @@ compile [with %assignments %body] to:
# Math Operators
test:
assume ((5 wrapped around 2) == 1) or barf "mod not working"
-compile [%x wrapped around %y, %x mod %y] to (..)
- Lua value "(\(%x as lua expr) % \(%y as lua expr))"
+[%x wrapped around %y, %x mod %y] all compile to (..)
+ Lua value "((\(%x as lua expr)) % (\(%y as lua expr)))"
# 3-part chained comparisons
# (uses a lambda to avoid re-evaluating middle value, while still being an expression)
test:
%calls = 0
- local action [one]:
+ (one) means:
external %calls = (%calls + 1)
return 1
assume (0 <= (one) <= 2) or barf "Three-way chained comparison failed."
assume (%calls == 1) or barf "\
..Three-way comparison evaluated middle value multiple times"
-parse [%x < %y < %z] as (..)
+(%x < %y < %z) parses as (..)
call ([%a, %b, %c] -> ((%a < %b) and (%b < %c))) with [%x, %y, %z]
-parse [%x <= %y < %z] as (..)
+(%x <= %y < %z) parses as (..)
call ([%a, %b, %c] -> ((%a <= %b) and (%b < %c))) with [%x, %y, %z]
-parse [%x < %y <= %z] as (..)
+(%x < %y <= %z) parses as (..)
call ([%a, %b, %c] -> ((%a < %b) and (%b <= %c))) with [%x, %y, %z]
-parse [%x <= %y <= %z] as (..)
+(%x <= %y <= %z) parses as (..)
call ([%a, %b, %c] -> ((%a <= %b) and (%b <= %c))) with [%x, %y, %z]
-parse [%x > %y > %z] as (..)
+(%x > %y > %z) parses as (..)
call ([%a, %b, %c] -> ((%a > %b) and (%b > %c))) with [%x, %y, %z]
-parse [%x >= %y > %z] as (..)
+(%x >= %y > %z) parses as (..)
call ([%a, %b, %c] -> ((%a >= %b) and (%b > %c))) with [%x, %y, %z]
-parse [%x > %y >= %z] as (..)
+(%x > %y >= %z) parses as (..)
call ([%a, %b, %c] -> ((%a > %b) and (%b >= %c))) with [%x, %y, %z]
-parse [%x >= %y >= %z] as (..)
+(%x >= %y >= %z) parses as (..)
call ([%a, %b, %c] -> ((%a >= %b) and (%b >= %c))) with [%x, %y, %z]
# TODO: optimize for common case where x,y,z are all either variables or number literals
# Boolean Operators
test:
- local action [barfer] (barf "short circuiting failed")
+ (barfer) means (barf "short circuiting failed")
assume (((no) and (barfer)) == (no))
assume ((no) or (yes))
assume ((yes) or (barfer))
-compile [%x and %y] to (Lua value "(\(%x as lua expr) and \(%y as lua expr))")
-compile [%x or %y] to (Lua value "(\(%x as lua expr) or \(%y as lua expr))")
+(%x and %y) compiles to (Lua value "(\(%x as lua expr) and \(%y as lua expr))")
+(%x or %y) compiles to (Lua value "(\(%x as lua expr) or \(%y as lua expr))")
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -219,31 +219,31 @@ test:
# Lua 5.3 introduced bit operators like | and &. Use them when possible, otherwise
fall back to bit.bor(), bit.band(), etc.
%use_bitops = ((is jit) or ((Lua version) == "Lua 5.2"))
-compile [NOT %, ~ %] to (..)
+[NOT %, ~ %] all compile to (..)
Lua value (..)
(%use_bitops and "bit.bnot(\(% as lua expr))") or "~(\(% as lua expr))"
-compile [%a OR %b, %a | %b] to (..)
+[%a OR %b, %a | %b] all compile to (..)
Lua value (..)
(%use_bitops and "bit.bor(\(%a as lua expr), \(%b as lua expr))") or "\
..(\(%a as lua expr) | \(%b as lua expr))"
-compile [%a XOR %b, %a ~ %b] to (..)
+[%a XOR %b, %a ~ %b] all compile to (..)
Lua value (..)
(%use_bitops and "bit.bxor(\(%a as lua expr), \(%b as lua expr))") or "\
..(\(%a as lua expr) ~ \(%b as lua expr))"
-compile [%a AND %b, %a & %b] to (..)
+[%a AND %b, %a & %b] all compile to (..)
Lua value (..)
(%use_bitops and "bit.band(\(%a as lua expr), \(%b as lua expr))") or "\
..(\(%a as lua expr) & \(%b as lua expr))"
-compile [%x LSHIFT %shift, %x << %shift] to (..)
+[%x LSHIFT %shift, %x << %shift] all compile to (..)
Lua value (..)
(%use_bitops and "bit.lshift(\(%x as lua expr), \(%shift as lua expr))") or "\
..(\(%x as lua expr) << \(%shift as lua expr))"
-compile [%x RSHIFT %shift, %x >> %shift] to (..)
+[%x RSHIFT %shift, %x >> %shift] all compile to (..)
Lua value (..)
(%use_bitops and "bit.rshift(\(%x as lua expr), \(%shift as lua expr))") or "\
..(\(%x as lua expr) >> \(%shift as lua expr))"
@@ -252,15 +252,15 @@ compile [%x RSHIFT %shift, %x >> %shift] to (..)
test:
assume ((- 5) == -5)
assume ((not (yes)) == (no))
-compile [- %] to (Lua value "(- \(% as lua expr))")
-compile [not %] to (Lua value "(not \(% as lua expr))")
+(- %) compiles to (Lua value "(- \(% as lua expr))")
+(not %) compiles to (Lua value "(not \(% as lua expr))")
test:
assume ((size of [1, 2, 3]) == 3)
-compile [size of %list, size of %list, size of %list, size of %list] to (..)
+[size of %list, size of %list, size of %list, size of %list] all compile to (..)
Lua value "(#\(%list as lua expr))"
-compile [%list is empty] to (Lua value "(#\(%list as lua expr) == 0)")
+(%list is empty) compiles to (Lua value "(#\(%list as lua expr) == 0)")
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -273,11 +273,11 @@ test:
assume (%x == 4) or barf "*= failed"
wrap %x around 3
assume (%x == 1) or barf "wrap around failed"
-parse [%var += %] as (%var = (%var + %))
-parse [%var -= %] as (%var = (%var - %))
-parse [%var *= %] as (%var = (%var * %))
-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 %))
+(%var += %) parses as (%var = (%var + %))
+(%var -= %) parses as (%var = (%var - %))
+(%var *= %) parses as (%var = (%var * %))
+(%var /= %) parses as (%var = (%var / %))
+(%var ^= %) parses as (%var = (%var ^ %))
+(%var and= %) parses as (%var = (%var and %))
+(%var or= %) parses as (%var = (%var or %))
+(wrap %var around %) parses as (%var = (%var wrapped around %))
diff --git a/core/scopes.nom b/core/scopes.nom
index c01a361..2d86ca4 100644
--- a/core/scopes.nom
+++ b/core/scopes.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V4.8.8.6
+#!/usr/bin/env nomsu -V4.8.10
#
This file contains definitions pertaining to variable scoping
@@ -14,19 +14,19 @@ test:
assume (%x == "inner")
assume (%x == "outer")
- action [foo] "outer foo"
- with local [action (foo)]:
- action [foo] "inner foo"
+ externally (foo) means "outer foo"
+ with local [(foo)'s meaning]:
+ externally (foo) means "inner foo"
assume ((foo) == "inner foo")
assume ((foo) == "outer foo")
-compile [with local %locals %body, with local %locals do %body] to:
+[with local %locals %body, with local %locals do %body] all compile to:
%body_lua = (%body as lua statements)
if %locals.type is:
"Dict":
%body_lua = (..)
Lua "\
- ..\(compile as (<- %locals))
+ ..\(what (<- %locals) compiles to)
\%body_lua"
%body_lua::declare locals ("\(%.1 as lua)" for % in %locals)
diff --git a/core/text.nom b/core/text.nom
index 25e9c3c..05ec409 100644
--- a/core/text.nom
+++ b/core/text.nom
@@ -1,4 +1,4 @@
-#!/usr/bin/env nomsu -V4.8.8.6
+#!/usr/bin/env nomsu -V4.8.10
#
This file contains some definitions of text escape sequences, including ANSI console
color codes.
@@ -22,12 +22,12 @@ test:
assume ("asdf"::uppercase) == "ASDF"
assume ("asdf"::with "s" -> "X") == "aXdf"
assume ("one\ntwo\n"::lines) == ["one", "two", ""]
- parse [アクション %spec %body] as (action %spec %body)
+ (アクション %spec %body) parses as (externally %spec means %body)
test:
%こんにちは = "こんにちは"
アクション [% と言う] "\(%)世界"
assume (%こんにちは と言う) == "こんにちは世界"
-compile [%expr for %match in %text matching %patt] to (..)
+(%expr for %match in %text matching %patt) compiles to (..)
Lua value "\
..(function()
local ret = _List{}