aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/collections.nom151
-rw-r--r--core/control_flow.nom234
-rw-r--r--core/coroutines.nom9
-rw-r--r--core/errors.nom39
-rw-r--r--core/id.nom33
-rw-r--r--core/io.nom8
-rw-r--r--core/math.nom137
-rw-r--r--core/metaprogramming.nom70
-rw-r--r--core/operators.nom59
-rw-r--r--core/scopes.nom26
-rw-r--r--core/text.nom17
11 files changed, 356 insertions, 427 deletions
diff --git a/core/collections.nom b/core/collections.nom
index 9a7dbe4..e9457e6 100644
--- a/core/collections.nom
+++ b/core/collections.nom
@@ -1,8 +1,8 @@
-#!/usr/bin/env nomsu -V4.8.10
+#!/usr/bin/env nomsu -V4.10.12.7
#
This file contains code that supports manipulating and using collections like lists
and dictionaries.
-
+
use "core/metaprogramming.nom"
use "core/control_flow.nom"
use "core/operators.nom"
@@ -15,11 +15,11 @@ test:
%visited = {}
for %i = %x in %list:
%visited.%i = (yes)
- assume (%visited == {1:yes, 2:yes, 3:yes, 4:yes, 5:yes})
+ assume (%visited == {1: yes, 2: yes, 3: yes, 4: yes, 5: yes})
%visited = {}
for %x in %list:
%visited.%x = (yes)
- assume (%visited == {1:yes, 2:yes, 3:yes, 4:yes, 5:yes})
+ assume (%visited == {1: yes, 2: yes, 3: yes, 4: yes, 5: yes})
assume ((%list::2 nd to last) == 4)
assume ((%list::first) == 1)
assume (%list::has 3)
@@ -35,130 +35,53 @@ test:
# Dict functionality
test:
- %dict = {x:1, y:2, z:3}
- assume ((size of %dict) == 3)
- assume ((% for % in {x:1}) == [{key:"x", value:1}])
- assume (({key:%k, value:%v} for %k = %v in {x:1}) == [{key:"x", value:1}])
- assume (({x:1, y:1} + {y:10, z:10}) == {x:1, y:11, z:10})
- assume (({x:1, y:1} | {y:10, z:10}) == {x:1, y:1, z:10})
- assume (({x:1, y:1} & {y:10, z:10}) == {y:1})
- assume (({x:1, y:1} ~ {y:10, z:10}) == {x:1, z:10})
-
-# List Comprehension
-test:
- assume (((% * %) for % in [1, 2, 3]) == [1, 4, 9])
-(%expression for %item in %iterable) parses as (..)
- result of:
- %comprehension = []
- for %item in %iterable:
- %comprehension::add %expression
- return %comprehension
-
-[..]
- %expression for %index in %start to %stop via %step
- %expression for %index in %start to %stop by %step
-..all parse as (..)
- result of:
- %comprehension = []
- for %index in %start to %stop via %step:
- %comprehension::add %expression
- return %comprehension
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-test:
- assume (((% * %) for % in 1 to 3) == [1, 4, 9])
-(%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"])
-[..]
- %expression for %key = %value in %iterable
- %expression for %key %value in %iterable
-..all parse as (..)
- result of:
- %comprehension = []
- for %key = %value in %iterable:
- %comprehension::add %expression
- return %comprehension
-
-# Dict comprehensions
-test:
- assume (((% * %) = % for % in [1, 2, 3]) == {1:1, 4:2, 9:3})
-[..]
- %key = %value for %item in %iterable, %key %value for %item in %iterable
-..all parse as (..)
- result of:
- %comprehension = {}
- for %item in %iterable:
- %comprehension.%key = %value
- return %comprehension
-
-test:
- assume ((%k = (%v * %v) for %k = %v in {x:1, y:2, z:3}) == {x:1, y:4, z:9})
-[..]
- %key = %value for %src_key = %src_value in %iterable
- %key %value for %src_key %src_value in %iterable
-..all parse as (..)
- result of:
- %comprehension = {}
- for %src_key = %src_value in %iterable:
- %comprehension.%key = %value
- return %comprehension
-
-[..]
- %key = %value for %item in %start to %stop via %step
- %key %value for %item in %start to %stop via %step
-..all parse as (..)
- result of:
- %comprehension = {}
- for %item in %start to %stop via %step:
- %comprehension.%key = %value
- return %comprehension
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-test:
- assume (((% * %) = % for % in 1 to 3) == {1:1, 4:2, 9:3})
-[..]
- %key = %value for %item in %start to %stop
- %key %value for %item in %start to %stop
-..all parse as (%key = %value for %item in %start to %stop via 1)
+ %dict = {x: 1, y: 2, z: 3}
+ assume (size of %dict) == 3
+ assume [: for % in {x: 1}: add %] == [{key: "x", value: 1}]
+ assume [: for %k = %v in {x: 1}: add {key: %k, value: %v}] == [..]
+ {key: "x", value: 1}
+ assume ({x: 1, y: 1} + {y: 10, z: 10}) == {x: 1, y: 11, z: 10}
+ assume ({x: 1, y: 1} | {y: 10, z: 10}) == {x: 1, y: 1, z: 10}
+ assume ({x: 1, y: 1} & {y: 10, z: 10}) == {y: 1}
+ assume ({x: 1, y: 1} ~ {y: 10, z: 10}) == {x: 1, z: 10}
test:
assume (([[1, 2], [3, 4]] flattened) == [1, 2, 3, 4])
+
externally (%lists flattened) means:
%flat = []
- for %list in %lists:
- for %item in %list: %flat::add %item
+ for %item in recursive %lists:
+ if (%item is a "List"):
+ for % in %item:
+ recurse %item on %
+ ..else:
+ %flat::add %item
return %flat
test:
- assume ((entries in {x:1}) == [{key:"x", value:1}])
-(entries in %dict) parses as ({key:%k, value:%v} for %k = %v in %dict)
+ assume ((entries in {x: 1}) == [{key: "x", value: 1}])
+(entries in %dict) parses as [: for %k = %v in %dict: add {key: %k, value: %v}]
test:
- assume ((keys in {x:1}) == ["x"])
-[keys in %dict, keys of %dict] all parse as (%k for %k = %v in %dict)
-
+ assume ((keys in {x: 1}) == ["x"])
+[keys in %dict, keys of %dict] all parse as [: for %k = %v in %dict: add %k]
test:
- assume ((values in {x:1}) == [1])
-[values in %dict, values of %dict] all parse as (%v for %k = %v in %dict)
+ assume ((values in {x: 1}) == [1])
+[values in %dict, values of %dict] all parse as [: for %k = %v in %dict: add %v]
# Metatable stuff
test:
%t = {}
- set %t 's metatable to {__tostring:[%] -> "XXX"}
+ set %t's metatable to {__tostring: [%] -> "XXX"}
assume ("\%t" == "XXX")
-(set %dict 's metatable to %metatable) compiles to "\
- ..setmetatable(\(%dict as lua expr), \(%metatable as lua expr));"
-[% 's metatable, % 'metatable] all compile to "\
- ..getmetatable(\(% as lua expr))"
+(set %dict's metatable to %metatable) compiles to "\
+ ..setmetatable(\(%dict as lua expr), \(%metatable as lua expr));"
+[%'s metatable, %'metatable] all compile to "getmetatable(\(% as lua expr))"
test:
assume (({} with fallback % -> (% + 1)).10 == 11)
+
(%dict with fallback %key -> %value) compiles to "\
..(function(d)
local mt = {}
@@ -178,12 +101,11 @@ test:
assume (%x == [1, 2, 3])
sort %x by % = (- %)
assume (%x == [3, 2, 1])
- %keys = {1:999, 2:0, 3:50}
+ %keys = {1: 999, 2: 0, 3: 50}
sort %x by % = %keys.%
assume (%x == [2, 3, 1])
(sort %items) compiles to "table.sort(\(%items as lua expr));"
-[..]
- sort %items by %item = %key_expr, sort %items by %item -> %key_expr
+[sort %items by %item = %key_expr, sort %items by %item -> %key_expr] \
..all parse as (..)
do:
%keys = ({} with fallback %item -> %key_expr)
@@ -193,19 +115,21 @@ test:
test:
assume ((sorted [3, 1, 2]) == [1, 2, 3])
+
externally [%items sorted, sorted %items] all mean:
- %copy = (% for % in %items)
+ %copy = [: for % in %items: add %]
sort %copy
return %copy
[%items sorted by %item = %key, %items sorted by %item -> %key] all parse as (..)
result of:
- %copy = (% for % in %items)
+ %copy = [: for % in %items: add %]
sort %copy by %item = %key
return %copy
test:
assume ((unique [1, 2, 1, 3, 2, 3]) == [1, 2, 3])
+
externally (unique %items) means:
%unique = []
%seen = {}
@@ -213,5 +137,4 @@ externally (unique %items) means:
unless %seen.%:
%unique::add %
%seen.% = (yes)
-
return %unique
diff --git a/core/control_flow.nom b/core/control_flow.nom
index ff1a7c1..d96e916 100644
--- a/core/control_flow.nom
+++ b/core/control_flow.nom
@@ -1,8 +1,8 @@
-#!/usr/bin/env nomsu -V4.8.10
+#!/usr/bin/env nomsu -V4.10.12.7
#
This file contains compile-time actions that define basic control flow structures
like "if" statements and loops.
-
+
use "core/metaprogramming.nom"
use "core/operators.nom"
use "core/errors.nom"
@@ -10,13 +10,15 @@ use "core/errors.nom"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# No-Op
-test: do nothing
+test:
+ do nothing
(do nothing) compiles to ""
# Conditionals
test:
if (no):
barf "conditional fail"
+
(if %condition %if_body) compiles to "\
..if \(%condition as lua expr) then
\(%if_body as lua)
@@ -25,9 +27,9 @@ test:
test:
unless (yes):
barf "conditional fail"
+
(unless %condition %unless_body) parses as (if (not %condition) %unless_body)
-[..]
- if %condition %if_body else %else_body, unless %condition %else_body else %if_body
+[if %condition %if_body else %else_body, unless %condition %else_body else %if_body] \
..all compile to "\
..if \(%condition as lua expr) then
\(%if_body as lua)
@@ -43,6 +45,7 @@ test:
test:
assume ((1 if (yes) else 2) == 1)
assume ((1 if (no) else 2) == 2)
+
[..]
%when_true_expr if %condition else %when_false_expr
%when_true_expr if %condition otherwise %when_false_expr
@@ -51,12 +54,8 @@ test:
..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):
- return (..)
- Lua "\
- ..(\(%condition as lua expr) and \(%when_true_expr as lua expr) or \(..)
- %when_false_expr as lua expr
- ..)"
+ if {Text: yes, List: yes, Dict: yes, Number: yes}.(%when_true_expr.type):
+ return (Lua "(\(%condition as lua expr) and \(%when_true_expr as lua expr) or \(%when_false_expr as lua expr))")
..else:
# Otherwise, need to do an anonymous inline function (yuck, too bad lua
doesn't have a proper ternary operator!)
@@ -78,35 +77,37 @@ test:
%i = 0
=== %loop ===
%i += 1
- unless (%i == 10): go to %loop
+ unless (%i == 10):
+ go to %loop
assume (%i == 10)
=== (Loop) ===
%i -= 1
- unless (%i == 0): go to (Loop)
+ unless (%i == 0):
+ go to (Loop)
assume (%i == 0)
+
[=== %label ===, --- %label ---, *** %label ***] all compile to "\
- ..::label_\(..)
- (%label.stub if (%label.type == "Action") else %label) as lua identifier
- ..::"
+ ..::label_\((%label.stub if (%label.type == "Action") else %label) as lua identifier)::"
(go to %label) compiles to "\
- ..goto label_\(..)
- (%label.stub if (%label.type == "Action") else %label) as lua identifier
- .."
+ ..goto label_\((%label.stub if (%label.type == "Action") else %label) as lua identifier)"
# Basic loop control
(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")
+ 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")
+ 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 "\
..::stop_\((%var.stub if (%var.type == "action") else %var) as lua identifier)::"
+
[===next %var ===, ---next %var ---, ***next %var ***] all compile to "\
..::continue_\((%var.stub if (%var.type == "action") else %var) as lua identifier)::"
@@ -116,32 +117,31 @@ test:
repeat while (%x < 10): %x += 1
assume (%x == 10)
repeat while (%x < 20): stop
- repeat while (%x < 20): stop repeating
+ repeat while (%x < 20):
+ stop repeating
assume (%x == 10)
repeat while (%x < 20):
%x += 1
- if (yes): do next
+ if (yes):
+ do next
barf "Failed to 'do next'"
-
assume (%x == 20)
repeat while (%x < 30):
%x += 1
- if (yes): do next repeat
+ if (yes):
+ do next repeat
barf "Failed to 'do next repeat'"
-
assume (%x == 30)
(do next repeat) compiles to "goto continue_repeat"
(stop repeating) compiles to "goto stop_repeat"
(repeat while %condition %body) compiles to:
- %lua = (..)
- Lua "\
- ..while \(%condition as lua expr) do
- \(%body as lua)"
-
+ %lua = (Lua "while \(%condition as lua expr) do\n \(%body as lua)")
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 --while-loop"
if (%body has subtree \(stop repeating)):
%inner_lua = %lua
@@ -150,25 +150,24 @@ test:
..
::stop_repeat::
end -- end of 'stop repeating' label scope"
-
return %lua
-
(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)
+
(repeat %n times %body) compiles to:
define mangler
- %lua = (..)
- Lua "for \(mangle "i")=1,\(%n as lua expr) do\n "
+ %lua = (Lua "for \(mangle "i")=1,\(%n as lua expr) do\n ")
%lua::append (%body as lua)
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)):
%inner_lua = %lua
@@ -177,17 +176,18 @@ test:
..
::stop_repeat::
end -- end of 'stop repeating' label scope"
-
return %lua
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test:
%nums = []
- for %x in 1 to 5: %nums::add %x
+ for %x in 1 to 5:
+ %nums::add %x
assume (%nums == [1, 2, 3, 4, 5])
%nums = []
- for %x in 1 to 5 via 2: %nums::add %x
+ for %x in 1 to 5 via 2:
+ %nums::add %x
assume (%nums == [1, 3, 5])
%nums = []
for %outer in 1 to 100:
@@ -195,10 +195,9 @@ test:
if (%inner == 2):
%nums::add -2
do next %inner
-
%nums::add %inner
- if (%inner == 5): stop %outer
-
+ if (%inner == 5):
+ stop %outer
assume (%nums == [1, -2, 3, -2, 3, 4, 3, 4, 5])
# Numeric range for loops
@@ -209,15 +208,11 @@ test:
# 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)"
- %lua = (..)
- Lua "\
- ..for \(%var as lua expr)=\(%start as lua expr),\(%stop as lua expr),\(..)
- %step as lua expr
- .. do"
-
+ %lua = (Lua "for \(%var as lua expr)=\(%start as lua expr),\(%stop as lua expr),\(%step as lua expr) do")
%lua::append "\n " (%body as lua)
if (%body has subtree \(do next)):
%lua::append "\n ::continue::"
+
if (%body has subtree \(do next %var)):
%lua::append "\n " (what (===next %var ===) compiles to)
@@ -228,7 +223,6 @@ test:
%lua::append %inner_lua "\n "
%lua::append (what (===stop %var ===) compiles to)
%lua::append "\nend -- end of scope for stopping for-loop"
-
return %lua
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -239,25 +233,33 @@ test:
test:
%a = [10, 20, 30, 40, 50]
%b = []
- for %x in %a: %b::add %x
+ for %x in %a:
+ %b::add %x
assume (%a == %b)
%b = []
for %x in %a:
- if (%x == 10): do next %x
- if (%x == 50): stop %x
+ if (%x == 10):
+ do next %x
+
+ if (%x == 50):
+ stop %x
+
%b::add %x
-
assume (%b == [20, 30, 40])
# For-each loop (lua's "ipairs()")
(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\n "
+ Lua "\
+ ..for \(mangle "i"),\(%var as lua identifier) in ipairs(\(%iterable as lua expr)) do
+ "
%lua::append (%body as lua)
if (%body has subtree \(do next)):
%lua::append "\n ::continue::"
+
if (%body has subtree \(do next %var)):
%lua::append "\n " (what (===next %var ===) compiles to)
@@ -268,17 +270,19 @@ test:
%lua::append %inner_lua "\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 "\
+ ..for \(%i as lua identifier),\(%var as lua identifier) in ipairs(\(%iterable as lua expr)) do
+ "
%lua::append (%body as lua)
if (%body has subtree \(do next)):
%lua::append "\n ::continue::"
+
if (%body has subtree \(do next %var)):
%lua::append "\n " (what (===next %var ===) compiles to)
@@ -289,37 +293,36 @@ test:
%lua::append %inner_lua "\n "
%lua::append (what (===stop %var ===) compiles to)
%lua::append "\nend -- end of scope for stopping for-loop"
-
return %lua
test:
- %d = {a:10, b:20, c:30, d:40, e:50}
+ %d = {a: 10, b: 20, c: 30, d: 40, e: 50}
%result = []
for %k = %v in %d:
- if (%k == "a"): do next %k
- if (%v == 20): do next %v
+ if (%k == "a"):
+ do next %k
+
+ if (%v == 20):
+ do next %v
+
%result::add "\%k = \%v"
-
assume ((%result sorted) == ["c = 30", "d = 40", "e = 50"])
# Dict iteration (lua's "pairs()")
-[..]
- for %key = %value in %iterable %body, for %key %value in %iterable %body
+[for %key = %value in %iterable %body, for %key %value in %iterable %body] \
..all compile to:
# 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)"
+
unless (%value.type is "Var"):
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"
+ %lua = (Lua "for \(%key as lua identifier),\(%value as lua identifier) in pairs(\(%iterable as lua expr)) do")
%lua::append "\n " (%body as lua)
if (%body has subtree \(do next)):
%lua::append "\n ::continue::"
+
if (%body has subtree \(do next %key)):
%lua::append "\n " (what (===next %key ===) compiles to)
@@ -350,8 +353,10 @@ test:
(1 == 0) (1 == 1) %not_a_variable.x: do nothing
(1 == 1):
barf "bad conditional"
+
(1 == 2):
barf "bad conditional"
+
else:
barf "bad conditional"
@@ -361,30 +366,29 @@ test:
%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'?"
+ compile error at %body "'if' expected a Block, but got a \(%body.type)." "\
+ ..Perhaps you forgot to put a ':' after 'if'?"
for %line in %body:
unless (..)
((%line.type is "Action") and ((size of %line) >= 2)) and (..)
%line.(size of %line) is "Block" syntax tree
..:
- compile error at %line "Invalid line for the body of an 'if' block."
- ..hint "Each line should contain one or more conditional expressions \
- ..followed by a block, or "else" followed by a block."
-
+ compile error at %line "Invalid line for the body of an 'if' block." "\
+ ..Each line should contain one or more conditional expressions followed by a block, or "else" followed \
+ ..by a block."
%action = %line.(size of %line)
if ((%line.1 is "else") and ((size of %line) == 2)):
unless %else_allowed:
- compile error at %line "You can't have two 'else' blocks."
- ..hint "Merge all of the 'else' blocks together."
+ compile error at %line "You can't have two 'else' blocks." "\
+ ..Merge all of the 'else' blocks together."
unless ((size of "\%code") > 0):
compile error at %line "\
..You can't have an 'else' block without a preceeding condition"
- ..hint "If you want the code in this block to always execute, you don't \
- ..need a conditional block around it. Otherwise, make sure the 'else' \
- ..block comes last."
+ .."\
+ ..If you want the code in this block to always execute, you don't need a conditional block around it. \
+ ..Otherwise, make sure the 'else' block comes last."
%code::append "\nelse\n " (%action as lua)
%else_allowed = (no)
@@ -394,13 +398,13 @@ test:
if (%i > 1):
%code::append " or "
%code::append (%line.%i as lua expr)
-
%code::append " then\n " (%action as lua)
%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."
+ compile error at %body "'if' block has an empty body." "\
+ ..This means nothing would happen, so the 'if' block should be deleted."
+
%code::append "\nend --when"
return %code
@@ -408,9 +412,13 @@ test:
if 5 is:
1 2 3:
barf "bad switch statement"
- 4 5: do nothing
+
+ 4 5:
+ do nothing
+
5 6:
barf "bad switch statement"
+
else:
barf "bad switch statement"
@@ -421,28 +429,28 @@ test:
%else_allowed = (yes)
define mangler
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 the 'is'?"
+ compile error at %body "'if' expected a Block, but got a \(%body.type)" "\
+ ..Perhaps you forgot to put a ':' after the 'is'?"
+
for %line in %body:
unless (..)
((%line.type is "Action") and ((size of %line) >= 2)) and (..)
%line.(size of %line) is "Block" syntax tree
..:
- compile error at %line "Invalid line for 'if' block."
- ..hint "Each line should contain expressions \
- ..followed by a block, or "else" followed by a block"
-
+ compile error at %line "Invalid line for 'if' block." "\
+ ..Each line should contain expressions followed by a block, or "else" followed by a block"
%action = %line.(size of %line)
if ((%line.1 is "else") and ((size of %line) == 2)):
unless %else_allowed:
- compile error at %line "You can't have two 'else' blocks."
- ..hint "Merge all of the 'else' blocks together."
+ compile error at %line "You can't have two 'else' blocks." "\
+ ..Merge all of the 'else' blocks together."
+
unless ((size of "\%code") > 0):
compile error at %line "\
..You can't have an 'else' block without a preceeding condition"
- ..hint "If you want the code in this block to always execute, you don't \
- ..need a conditional block around it. Otherwise, make sure the 'else' \
- ..block comes last."
+ .."\
+ ..If you want the code in this block to always execute, you don't need a conditional block around it. \
+ ..Otherwise, make sure the 'else' block comes last."
%code::append "\nelse\n " (%action as lua)
%else_allowed = (no)
@@ -452,13 +460,13 @@ test:
if (%i > 1):
%code::append " or "
%code::append "\(mangle "branch value") == " (%line.%i as lua expr)
-
%code::append " then\n " (%action as lua)
%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."
+ compile error at %body "'if' block has an empty body." "\
+ ..This means nothing would happen, so the 'if' block should be deleted."
+
%code::append "\nend --when"
return (..)
Lua "\
@@ -468,19 +476,17 @@ test:
end -- if % is..."
# Do/finally
-(do %action) compiles to "\
- ..do
- \(%action as lua)
- end -- do"
-
+(do %action) compiles to "do\n \(%action as lua)\nend -- do"
test:
%d = {}
try:
do:
%d.x = "bad"
barf
- ..then always: %d.x = "good"
+ ..then always:
+ %d.x = "good"
assume (%d.x == "good")
+
(do %action then always %final_action) compiles to:
define mangler
return (..)
@@ -497,19 +503,19 @@ test:
end"
test:
- assume ((result of (: return 99)) == 99)
+ assume ((result of: return 99) == 99)
# Inline thunk:
(result of %body) compiles to "\(what ([] -> %body) compiles to)()"
-
test:
%t = [1, [2, [[3], 4], 5, [[[6]]]]]
%flat = []
for % in recursive %t:
if ((lua type of %) is "table"):
- for %2 in %: recurse % on %2
- ..else: %flat::add %
-
+ for %2 in %:
+ recurse % on %2
+ ..else:
+ %flat::add %
assume (sorted %flat) == [1, 2, 3, 4, 5, 6]
# Recurion control flow
@@ -518,6 +524,7 @@ test:
define mangler
(recurse %v on %x) compiles to (..)
Lua "table.insert(\(mangle "stack \(%v.1)"), \(%x as lua expr))"
+
%lua = (..)
Lua "\
..do
@@ -525,10 +532,13 @@ test:
while #\(mangle "stack \(%var.1)") > 0 do
\(%var as lua expr) = table.remove(\(mangle "stack \(%var.1)"), 1)
\(%body as lua)"
+
if (%body has subtree \(do next)):
%lua::append "\n ::continue::"
+
if (%body has subtree \(do 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 \(what (===stop %var ===) compiles to)"
diff --git a/core/coroutines.nom b/core/coroutines.nom
index 27797fa..7d17d63 100644
--- a/core/coroutines.nom
+++ b/core/coroutines.nom
@@ -1,7 +1,7 @@
-#!/usr/bin/env nomsu -V4.8.10
+#!/usr/bin/env nomsu -V4.10.12.7
#
This file defines the code that creates and manipulates coroutines
-
+
use "core/metaprogramming.nom"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -14,8 +14,11 @@ test:
-> 5
repeat 3 times: -> 6
- for % in coroutine %co: %nums::add %
+ for % in coroutine %co:
+ %nums::add %
+
assume (%nums == [4, 5, 6, 6, 6]) or barf "Coroutine iteration failed"
+
[coroutine %body, generator %body] all compile to "\
..(function()
\(%body as lua)
diff --git a/core/errors.nom b/core/errors.nom
index e254209..12a5b29 100644
--- a/core/errors.nom
+++ b/core/errors.nom
@@ -1,16 +1,16 @@
-#!/usr/bin/env nomsu -V4.8.10
+#!/usr/bin/env nomsu -V4.10.12.7
#
This file contains basic error reporting code
-
+
use "core/metaprogramming.nom"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-(barf %msg) compiles to "error(\(=lua "\%msg and \(%msg as lua expr) or 'nil'"), 0);"
+(barf %msg) compiles to "\
+ ..error(\(=lua "\%msg and \(%msg as lua expr) or 'nil'"), 0);"
(assume %condition) compiles to:
- lua> "\
- ..local \%assumption = 'Assumption failed: '..tostring((\%condition):get_source_code())"
+ lua> "local \%assumption = 'Assumption failed: '..tostring((\%condition):get_source_code())"
return (..)
Lua "\
..if not \(%condition as lua expr) then
@@ -18,17 +18,14 @@ use "core/metaprogramming.nom"
end"
(assume %a == %b) compiles to:
- lua> "\
- ..local \%assumption = 'Assumption failed: '..tostring(\(\(%a == %b) as nomsu))"
+ lua> "local \%assumption = 'Assumption failed: '..tostring(\(\(%a == %b) as nomsu))"
define mangler
return (..)
Lua "\
..do
local \(mangle "a"), \(mangle "b") = \(%a as lua expr), \(%b as lua expr)
if \(mangle "a") ~= \(mangle "b") then
- error(\(quote "\%assumption").."\\n"..tostring(\(mangle "a")).." != "..tostring(\(..)
- mangle "b"
- ..), 0)
+ error(\(quote "\%assumption").."\\n"..tostring(\(mangle "a")).." != "..tostring(\(mangle "b")), 0)
end
end"
@@ -38,16 +35,18 @@ use "core/metaprogramming.nom"
end"
test:
- try (barf) and if it succeeds: barf "try failed."
+ try (barf) and if it succeeds:
+ barf "try failed."
%worked = (no)
- try (barf) and if it barfs: %worked = (yes)
+ try (barf) and if it barfs:
+ %worked = (yes)
assume %worked or barf "try/catch failed"
%x = 1
try:
%x = 2
do (barf) then always: %x = 3
- ..and if it barfs: do nothing
-
+ ..and if it barfs:
+ do nothing
assume (%x == 3) or barf "do/then always failed"
# Try/except
@@ -81,19 +80,19 @@ test:
#
[..]
- try %action and if it succeeds %success or if it barfs %fallback
- try %action and if it barfs %fallback or if it succeeds %success
+ 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
-
+ try %action and if it succeeds %success or if it barfs (=lua "") %fallback
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+
(try %action) parses as (..)
try %action and if it succeeds (do nothing) or if it barfs (do nothing)
#(try %action and if it barfs %fallback) parses as (..)
try %action and if it succeeds (do nothing) or if it barfs %fallback
-
+
(try %action and if it barfs %msg %fallback) parses as (..)
try %action and if it succeeds (do nothing) or if it barfs %msg %fallback
diff --git a/core/id.nom b/core/id.nom
index 8875696..9cf5820 100644
--- a/core/id.nom
+++ b/core/id.nom
@@ -1,7 +1,7 @@
-#!/usr/bin/env nomsu -V4.8.10
+#!/usr/bin/env nomsu -V4.10.12.7
#
A simple UUID function based on RFC 4122: http://www.ietf.org/rfc/rfc4122.txt
-
+
use "core/metaprogramming.nom"
use "core/operators.nom"
use "core/math.nom"
@@ -13,21 +13,22 @@ use "core/control_flow.nom"
%NaN_surrogate = {}
%nil_surrogate = {}
%obj_by_id = {}
-set %obj_by_id's metatable to {__mode:"v"}
+set %obj_by_id's metatable to {__mode: "v"}
%id_by_obj = {}
-set %id_by_obj 's metatable to {..}
- __mode:"k", __index: (..)
- [%self, %key] ->:
- if (%key == (nil)):
- return %self.%nil_surrogate
- if (%key != %key):
- return %self.%NaN_surrogate
- --- (retry) ---
- %id = (uuid)
- if (%obj_by_id.%id != (nil)): go to (retry)
- %self.%key = %id
- %obj_by_id.%id = %key
- return %id
+set %id_by_obj's metatable to {..}
+ __mode: "k", __index: [%self, %key] ->:
+ if (%key == (nil)):
+ return %self.%nil_surrogate
+
+ if (%key != %key):
+ return %self.%NaN_surrogate
+
+ --- (retry) ---
+ %id = (uuid)
+ if (%obj_by_id.%id != (nil)): go to (retry)
+ %self.%key = %id
+ %obj_by_id.%id = %key
+ return %id
externally (uuid) means:
# Set all the other bits to randomly (or pseudo-randomly) chosen values.
diff --git a/core/io.nom b/core/io.nom
index 2df0999..d9dbdd3 100644
--- a/core/io.nom
+++ b/core/io.nom
@@ -1,7 +1,7 @@
-#!/usr/bin/env nomsu -V4.8.10
+#!/usr/bin/env nomsu -V4.10.12.7
#
This file contains basic input/output code
-
+
use "core/metaprogramming.nom"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -19,7 +19,5 @@ use "core/metaprogramming.nom"
..if \%prompt.type == "Text" then
return LuaCode("(io.write(", \(%prompt as lua expr), ") and io.read())");
else
- return LuaCode("(io.write(tostring(", \(..)
- %prompt as lua expr
- .., ")) and io.read())");
+ return LuaCode("(io.write(tostring(", \(%prompt as lua expr), ")) and io.read())");
end"
diff --git a/core/math.nom b/core/math.nom
index 8951721..583cc8c 100644
--- a/core/math.nom
+++ b/core/math.nom
@@ -1,7 +1,7 @@
-#!/usr/bin/env nomsu -V4.8.10
+#!/usr/bin/env nomsu -V4.10.12.7
#
This file defines some common math literals and functions
-
+
use "core/metaprogramming.nom"
use "core/text.nom"
use "core/operators.nom"
@@ -28,7 +28,6 @@ test:
assume (("5" as a number) == 5)
((% as a number)'s meaning) = ((tonumber %)'s meaning)
((% as number)'s meaning) = ((tonumber %)'s meaning)
-
test:
assume (..)
all of [..]
@@ -36,101 +35,108 @@ 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"
-[absolute value %, | % |, abs %] all compile to (..)
- "math.abs(\(% as lua expr))"
-
-[square root %, square root of %, √ %, sqrt %] all compile to (..)
- "math.sqrt(\(% as lua expr))"
-
+[absolute value %, | % |, abs %] all compile to "math.abs(\(% as lua expr))"
+[square root %, square root of %, √ %, sqrt %] all compile to "\
+ ..math.sqrt(\(% as lua expr))"
[sine %, sin %] all compile to "math.sin(\(% as lua expr))"
[cosine %, cos %] all compile to "math.cos(\(% as lua expr))"
[tangent %, tan %] all compile to "math.tan(\(% as lua expr))"
[arc sine %, asin %] all compile to "math.asin(\(% as lua expr))"
[arc cosine %, acos %] all compile to "math.acos(\(% as lua expr))"
[arc tangent %, atan %] all compile to "math.atan(\(% as lua expr))"
-[arc tangent %y / %x, atan2 %y %x] all compile to (..)
- "math.atan2(\(%y as lua expr), \(%x as lua expr))"
-
-[hyperbolic sine %, sinh %] all compile to (..)
- "math.sinh(\(% as lua expr))"
-
-[hyperbolic cosine %, cosh %] all compile to (..)
- "math.cosh(\(% as lua expr))"
-
-[hyperbolic tangent %, tanh %] all compile to (..)
- "math.tanh(\(% as lua expr))"
-
+[arc tangent %y / %x, atan2 %y %x] all compile to "\
+ ..math.atan2(\(%y as lua expr), \(%x as lua expr))"
+[hyperbolic sine %, sinh %] all compile to "math.sinh(\(% as lua expr))"
+[hyperbolic cosine %, cosh %] all compile to "math.cosh(\(% as lua expr))"
+[hyperbolic tangent %, tanh %] all compile to "math.tanh(\(% as lua expr))"
[e^ %, exp %] all compile to "math.exp(\(% as lua expr))"
-[natural log %, ln %, log %] all compile to (..)
- "math.log(\(% as lua expr))"
-
-[log % base %base, log base %base of %] all compile to (..)
- "math.log(\(% as lua expr), \(%base as lua expr))"
-
+[natural log %, ln %, log %] all compile to "math.log(\(% as lua expr))"
+[log % base %base, log base %base of %] all compile to "\
+ ..math.log(\(% as lua expr), \(%base as lua expr))"
(floor %) compiles to "math.floor(\(% as lua expr))"
[ceiling %, ceil %] all compile to "math.ceil(\(% as lua expr))"
-[round %, % rounded] all compile to (..)
- "math.floor(\(% as lua expr) + .5)"
-
+[round %, % rounded] all compile to "math.floor(\(% as lua expr) + .5)"
test:
assume ((463 to the nearest 100) == 500) or barf "rounding failed"
assume ((2.6 to the nearest 0.25) == 2.5) or barf "rounding failed"
+
externally (%n to the nearest %rounder) means (..)
=lua "(\%rounder)*math.floor((\%n / \%rounder) + .5)"
# Any/all
externally [all of %items, all %items] all mean:
for % in %items:
- unless %: return (no)
+ unless %:
+ return (no)
return (yes)
+
[all of %items, all %items] all compile to:
unless (%items.type is "List"):
return \(all of %items)
- if ((size of %items) == 0): return (Lua "true")
+
+ if ((size of %items) == 0):
+ return (Lua "true")
+
%lua = (Lua "(")
- %lua::add ((% as lua expr) for % in %items) joined with " and "
+ %lua::add [: for % in %items: add (% as lua expr)] joined with " and "
%lua::append ")"
return %lua
-[not all of %items, not all %items] all parse as (not (all of %items))
+[not all of %items, not all %items] all parse as (not (all of %items))
externally [any of %items, any %items] all mean:
for % in %items:
- if %: return (yes)
+ if %:
+ return (yes)
return (no)
+
[any of %items, any %items] all compile to:
unless (%items.type is "List"):
return \(any of %items)
- if ((size of %items) == 0): return (Lua "false")
+
+ if ((size of %items) == 0):
+ return (Lua "false")
+
%lua = (Lua "(")
- %lua::add ((% as lua expr) for % in %items) joined with " or "
+ %lua::add [: for % in %items: add (% as lua expr)] joined with " or "
%lua::append ")"
return %lua
+
[none of %items, none %items] all parse as (not (any of %items))
# Sum/product
externally [sum of %items, sum %items] all mean:
%total = 0
- for % in %items: %total += %
+ for % in %items:
+ %total += %
return %total
+
[sum of %items, sum %items] all compile to:
unless (%items.type is "List"):
return \(sum of %items)
- if ((size of %items) == 0): return (Lua "0")
+
+ if ((size of %items) == 0):
+ return (Lua "0")
+
%lua = (Lua "(")
- %lua::add ((% as lua expr) for % in %items) joined with " + "
+ %lua::add [: for % in %items: add (% as lua expr)] joined with " + "
%lua::append ")"
return %lua
externally [product of %items, product %items] all mean:
%prod = 1
- for % in %items: %prod *= %
+ for % in %items:
+ %prod *= %
return %prod
+
[product of %items, product %items] all compile to:
unless (%items.type is "List"):
return \(product of %items)
- if ((size of %items) == 0): return (Lua "1")
+
+ if ((size of %items) == 0):
+ return (Lua "1")
+
%lua = (Lua "(")
- %lua::add ((% as lua expr) for % in %items) joined with " * "
+ %lua::add [: for % in %items: add (% as lua expr)] joined with " * "
%lua::append ")"
return %lua
@@ -156,45 +162,43 @@ externally [avg of %items, average of %items] all mean (..)
[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)
+[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
+[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)
+[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
+[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)
+[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
+[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)
# Min/max
externally [min of %items, smallest of %items, lowest of %items] all mean:
%best = (nil)
for % in %items:
- if ((%best == (nil)) or (% < %best)):
- %best = %
+ if ((%best == (nil)) or (% < %best)): %best = %
return %best
-externally [max of %items, biggest of %items, largest of %items, highest of %items] all mean:
+externally [..]
+ max of %items, biggest of %items, largest of %items, highest of %items
+..all mean:
%best = (nil)
for % in %items:
- if ((%best == (nil)) or (% > %best)):
- %best = %
+ if ((%best == (nil)) or (% > %best)): %best = %
return %best
test:
assume ((min of [3, -4, 1, 2] by % = (% * %)) == 1)
assume ((max of [3, -4, 1, 2] by % = (% * %)) == -4)
+
(min of %items by %item = %value_expr) parses as (..)
result of:
%best = (nil)
@@ -219,17 +223,14 @@ test:
# Random functions
externally (seed random with %) means:
- lua> "\
- ..math.randomseed(\%);
- for i=1,20 do math.random(); end"
-
+ lua> "math.randomseed(\%);\nfor i=1,20 do math.random(); end"
(seed random) parses as (seed random with (=lua "os.time()"))
[random number, random, rand] all compile to "math.random()"
-[random int %n, random integer %n, randint %n] all compile to (..)
- "math.random(\(%n as lua expr))"
+[random int %n, random integer %n, randint %n] all compile to "\
+ ..math.random(\(%n as lua expr))"
-[random from %low to %high, random number from %low to %high, rand %low %high] all \
-..compile to "math.random(\(%low as lua expr), \(%high as lua expr))"
+[random from %low to %high, random number from %low to %high, rand %low %high] \
+..all compile to "math.random(\(%low as lua expr), \(%high as lua expr))"
externally [..]
random choice from %elements, random choice %elements, random %elements
diff --git a/core/metaprogramming.nom b/core/metaprogramming.nom
index b27147d..944dc34 100644
--- a/core/metaprogramming.nom
+++ b/core/metaprogramming.nom
@@ -1,11 +1,9 @@
-#!/usr/bin/env nomsu -V4.8.10
+#!/usr/bin/env nomsu -V4.10.12.7
#
This File contains actions for making actions and compile-time actions and some helper
functions to make that easier.
-
-lua> "\
- ..NOMSU_CORE_VERSION = 10
- NOMSU_LIB_VERSION = 7"
+
+lua> "NOMSU_CORE_VERSION = 10\nNOMSU_LIB_VERSION = 7"
lua> "\
..do
local mangle_index = 0
@@ -25,7 +23,8 @@ lua> "\
..compile.action["1 ->"] = function(compile, \%args, \%body)
local lua = LuaCode("(function(")
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 compile(a):text() or a end)
+ local lua_args = table.map(\%args, function(a) return SyntaxTree:is_instance(a) and compile(a):text(\
+ ..) or a end)
lua:concat_append(lua_args, ", ")
local body_lua = SyntaxTree:is_instance(\%body) and compile(\%body) or \%body
if SyntaxTree:is_instance(\%body) and \%body.type ~= "Block" then body_lua:prepend("return ") end
@@ -49,9 +48,11 @@ lua> "\
test:
(five) compiles to "5"
+
test:
assume ((five) == 5) or barf "Compile to expression failed."
(loc x) compiles to "local x = 99;"
+
test:
lua> "do"
loc x
@@ -61,9 +62,11 @@ test:
(asdf) compiles to:
%tmp = ""
return (Lua %tmp)
+
test:
asdf
assume (%tmp is (nil)) or barf "compile to is leaking variables"
+
lua> "\
..compile.action["1 compiles to"] = function(compile, \%action, \%body)
local \%args = List{\(\%compile), unpack(\%action:get_args())}
@@ -114,11 +117,9 @@ test:
(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."
(baz %) parses as (foo %)
-
assume ((foo 1) == "outer")
(%action means %body) compiles to:
@@ -128,6 +129,7 @@ test:
local lua = LuaCode(fn_name, " = ", \(what (%args -> %body) compiles to))
lua:add_free_vars({fn_name})
return lua"
+
(%actions all mean %body) compiles to:
lua> "\
..local fn_name = \%actions[1].stub:as_lua_id()
@@ -148,16 +150,20 @@ test:
return lua"
test:
- externally (baz1) means: return "baz1"
+ externally (baz1) means:
+ return "baz1"
externally (baz2) means "baz2"
+
test:
assume ((baz1) == "baz1")
assume ((baz2) == "baz2")
+
(externally %action means %body) compiles to:
lua> "\
..local lua = \(what (%action means %body) compiles to)
lua:remove_free_vars({\%action.stub:as_lua_id()})
return lua"
+
(externally %actions all mean %body) compiles to:
lua> "\
..local lua = \(what (%actions all mean %body) compiles to)
@@ -166,23 +172,25 @@ test:
test:
assume (((say %)'s meaning) == (=lua "say"))
-(%action's meaning) compiles to (Lua (%action.stub as lua id))
+(%action's meaning) compiles to (Lua (%action.stub as lua id))
test:
(swap %x and %y) parses as (..)
do:
%tmp = %x
%x = %y
%y = %tmp
+
test:
- set {%1:1, %2:2}
+ set {%1: 1, %2: 2}
swap %1 and %2
assume ((%1 == 2) and (%2 == 1)) or barf "\
..'parse % as %' failed on 'swap % and %'"
- set {%tmp:1, %tmp2:2}
+ set {%tmp: 1, %tmp2: 2}
swap %tmp and %tmp2
assume ((%tmp == 2) and (%tmp2 == 1)) or barf "\
..'parse % as %' variable mangling failed."
+
(%actions all parse as %body) compiles to:
lua> "\
..local replacements = {}
@@ -197,7 +205,8 @@ test:
if replacements[t[1]] then
return replacements[t[1]]
else
- return "SyntaxTree{mangle("..t[1]:as_lua().."), type="..t.type:as_lua()..", source="..tostring(t.source):as_lua().."}"
+ return "SyntaxTree{mangle("..t[1]:as_lua().."), type="..t.type:as_lua()..", source="..tostring(\
+ ..t.source):as_lua().."}"
end
elseif SyntaxTree:is_instance(t) then
local ret = {}
@@ -227,12 +236,10 @@ test:
local ret = \(what (%actions all compile to %new_body) compiles to)
return ret"
-~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[%action parses as %body] all parse as ([%action] all parse as %body)
-
-(%tree as lua expr) compiles to "\
- ..compile(\(=lua "compile(\%tree, true)"), true)"
+(%tree as lua expr) compiles to "compile(\(=lua "compile(\%tree, true)"), true)"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -257,7 +264,10 @@ externally (% is %kind syntax tree) means (..)
(%tree with %t -> %replacement) compiles to "\
..\(%tree as lua expr):map(function(\(%t as lua expr))
- \((%replacement as lua) if (%replacement.type == "Block") else ("return \(%replacement as lua expr)"))
+ \(..)
+ (%replacement as lua) if (%replacement.type == "Block") else "\
+ ..return \(%replacement as lua expr)"
+ ..
end)"
externally (%tree with vars %replacements) means (..)
@@ -317,14 +327,9 @@ externally (%tree with %patt ~> %replacement) means:
end)"
test:
- assume (..)
- (..)
- quote "\
- ..one
- "two""
- ..== "\"one\\n\\\"two\\\"\""
-(quote %s) compiles to "tostring(\(%s as lua expr)):as_lua()"
+ assume ((quote "one\n\"two\"") == "\"one\\n\\\"two\\\"\"")
+(quote %s) compiles to "tostring(\(%s as lua expr)):as_lua()"
test:
assume (lua type of {}) == "table"
assume (type of {}) == "Dict"
@@ -346,8 +351,8 @@ externally (type of %) means:
return lua_type"
[% is a %type, % is an %type] all parse as ((type of %) == %type)
-[% isn't a %type, % isn't an %type, % is not a %type, % is not an %type] 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)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -357,18 +362,14 @@ test:
run "external %passed = (yes)"
assume %passed
assume (run \(return \(\(5) + \(5)))) == 10
-(run %nomsu_code) compiles to "\
- ..run_1_in(\(%nomsu_code as lua expr), _ENV)"
-
+(run %nomsu_code) compiles to "run_1_in(\(%nomsu_code as lua expr), _ENV)"
[compile %block, compiled %block, %block compiled] all compile to "\
..compile(\(%block 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.
(return %return_value) compiles to "\
- ..do return \(..)
- =lua "\%return_value and \(%return_value as lua expr) or ''"
- .. end"
+ ..do return \(=lua "\%return_value and \(%return_value as lua expr) or ''") end"
# Literals
(yes) compiles to "true"
@@ -392,5 +393,4 @@ test:
end"
externally (Nomsu version) means:
- return "\
- ..\(Nomsu syntax version).\(core version).\(Nomsu compiler version).\(lib version)"
+ return "\(Nomsu syntax version).\(core version).\(Nomsu compiler version).\(lib version)"
diff --git a/core/operators.nom b/core/operators.nom
index 19a61d7..cc86398 100644
--- a/core/operators.nom
+++ b/core/operators.nom
@@ -1,7 +1,7 @@
-#!/usr/bin/env nomsu -V4.8.10
+#!/usr/bin/env nomsu -V4.10.12.7
#
This file contains definitions of operators like "+" and "and".
-
+
use "core/metaprogramming.nom"
use "core/errors.nom"
@@ -16,7 +16,6 @@ test:
(%x <= %y) compiles to "(\(%x as lua expr) <= \(%y as lua expr))"
(%x >= %y) compiles to "(\(%x as lua expr) >= \(%y as lua expr))"
[%a is %b, %a == %b] all compile to "(\(%a as lua expr) == \(%b as lua expr))"
-
[%a isn't %b, %a is not %b, %a not= %b, %a != %b] all compile to "\
..(\(%a as lua expr) ~= \(%b as lua expr))"
@@ -38,9 +37,9 @@ test:
return lua"
test:
- set {%x:10, %y:20}
+ set {%x: 10, %y: 20}
assume ((%x == 10) and (%y == 20)) or barf "mutli-assignment failed."
- set {%x:%y, %y:%x}
+ set {%x: %y, %y: %x}
assume ((%y == 10) and (%x == 20)) or barf "swapping vars failed."
# Simultaneous mutli-assignments like: x,y,z = 1,x,3;
@@ -48,6 +47,7 @@ test:
(set %assignments) compiles to:
assume (%assignments.type is "Dict") or barf "\
..Expected a Dict for the assignments part of '<- %' statement, not \%assignments"
+
lua> "\
..local lhs, rhs = LuaCode(), LuaCode()
for i, item in ipairs(\%assignments) do
@@ -74,40 +74,37 @@ test:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test:
- set {%foozle:"outer", %y:"outer"}
+ set {%foozle: "outer", %y: "outer"}
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."
(external %var = %value) compiles to "\(%var as lua) = \(%value as lua)"
-
test:
- set {%foozle:"outer", %y:"outer"}
+ set {%foozle: "outer", %y: "outer"}
externally (set global x local y) means:
with external [%foozle]:
%foozle = "inner"
%y = "inner"
-
set global x local y
assume ((%foozle == "inner") and (%y == "outer")) or barf "\
..'with external' failed."
+
(with external %externs %body) compiles to:
%body_lua = (%body as lua)
- lua> "\
- ..\%body_lua:remove_free_vars(table.map(\%externs, function(v) return compile(v):text() end))"
+ lua> "\%body_lua:remove_free_vars(table.map(\%externs, function(v) return compile(v):text() end))"
return %body_lua
test:
- set {%x:1, %y:2}
- with {%z:nil, %x:999}:
+ set {%x: 1, %y: 2}
+ with {%z: nil, %x: 999}:
%z = 999
assume (%z == 999) or barf "'with' failed."
assume (%x == 999) or barf "'with' assignment failed."
-
assume (%x == 1) or barf "'with' scoping failed"
assume (%z == (nil)) or barf "'with' scoping failed"
+
(with %assignments %body) compiles to:
%lua = (%body as lua)
lua> "\
@@ -132,18 +129,14 @@ test:
end
\%lua:remove_free_vars(vars)
\%lua:prepend("local ", lhs, " = ", rhs, ";\\n")"
-
- return (..)
- Lua "\
- ..do
- \%lua
- end -- 'with' block"
+ return (Lua "do\n \%lua\nend -- 'with' block")
# Math Operators
test:
assume ((5 wrapped around 2) == 1) or barf "mod not working"
-[%x wrapped around %y, %x mod %y] all compile to (..)
- "((\(%x as lua expr)) % (\(%y as lua expr)))"
+
+[%x wrapped around %y, %x mod %y] all compile to "\
+ ..((\(%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)
@@ -152,10 +145,10 @@ test:
(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"
+
(%x < %y < %z) parses as (..)
call ([%a, %b, %c] -> ((%a < %b) and (%b < %c))) with [%x, %y, %z]
@@ -206,13 +199,21 @@ test:
fall back to bit.bor(), bit.band(), etc.
lua> "if \((is jit) or ((Lua version) == "Lua 5.2")) then"
[NOT %, ~ %] all compile to "bit.bnot(\(% as lua expr))"
-[%x OR %y, %x | %y] all compile to "bit.bor(\(%x as lua expr), \(%y as lua expr))"
-[%x XOR %y, %x ~ %y] all compile to "bit.bxor(\(%x as lua expr), \(%y as lua expr))"
-[%x AND %y, %x & %y] all compile to "bit.band(\(%x as lua expr), \(%y as lua expr))"
+[%x OR %y, %x | %y] all compile to "\
+ ..bit.bor(\(%x as lua expr), \(%y as lua expr))"
+
+[%x XOR %y, %x ~ %y] all compile to "\
+ ..bit.bxor(\(%x as lua expr), \(%y as lua expr))"
+
+[%x AND %y, %x & %y] all compile to "\
+ ..bit.band(\(%x as lua expr), \(%y as lua expr))"
+
[%x LSHIFT %shift, %x << %shift] all compile to "\
..bit.lshift(\(%x as lua expr), \(%shift as lua expr))"
+
[%x RSHIFT %shift, %x >> %shift] all compile to "\
..bit.rshift(\(%x as lua expr), \(%shift as lua expr))"
+
lua> "else"
[NOT %, ~ %] all compile to "~(\(% as lua expr))"
[%x OR %y, %x | %y] all compile to "(\(%x as lua expr) | \(%y as lua expr))"
@@ -220,8 +221,10 @@ lua> "else"
[%x AND %y, %x & %y] all compile to "(\(%x as lua expr) & \(%y as lua expr))"
[%x LSHIFT %shift, %x << %shift] all compile to "\
..(\(%x as lua expr) << \(%shift as lua expr))"
+
[%x RSHIFT %shift, %x >> %shift] all compile to "\
..(\(%x as lua expr) >> \(%shift as lua expr))"
+
lua> "end"
# Unary operators
@@ -230,11 +233,9 @@ test:
assume ((not (yes)) == (no))
(- %) compiles to "(- \(% as lua expr))"
(not %) compiles to "(not \(% as lua expr))"
-
test:
assume ((size of [1, 2, 3]) == 3)
(size of %list) compiles to "(#\(%list as lua expr))"
-
(%list is empty) compiles to "(#\(%list as lua expr) == 0)"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/core/scopes.nom b/core/scopes.nom
index bd8b8a6..009728b 100644
--- a/core/scopes.nom
+++ b/core/scopes.nom
@@ -1,7 +1,7 @@
-#!/usr/bin/env nomsu -V4.8.10
+#!/usr/bin/env nomsu -V4.10.12.7
#
This file contains definitions pertaining to variable scoping
-
+
use "core/metaprogramming.nom"
use "core/operators.nom"
use "core/collections.nom"
@@ -14,34 +14,26 @@ test:
with local %x:
%x = "inner"
assume (%x == "inner")
-
assume (%x == "outer")
externally (foo) means "outer foo"
with local [(foo)'s meaning]:
externally (foo) means "inner foo"
assume ((foo) == "inner foo")
-
assume ((foo) == "outer foo")
+
[with local %locals %body, with local %locals do %body] all compile to:
%body_lua = (%body as lua)
if %locals.type is:
"Dict":
- %body_lua = (..)
- Lua "\
- ..\(what (<- %locals) compiles to)
- \%body_lua"
-
- %body_lua::declare locals ("\(%.1 as lua)" for % in %locals)
+ %body_lua = (Lua "\(what (<- %locals) compiles to)\n\%body_lua")
+ %body_lua::declare locals [: for % in %locals: add "\(%.1 as lua)"]
"List":
- %body_lua::declare locals ("\(% as lua)" for % in %locals)
+ %body_lua::declare locals [: for % in %locals: add "\(% as lua)"]
+
"Var" "Action":
%body_lua::declare locals ["\(%locals as lua)"]
+
else:
compile error at %locals "Unexpected local value"
-
- return (..)
- Lua "\
- ..do
- \%body_lua
- end"
+ return (Lua "do\n \%body_lua\nend")
diff --git a/core/text.nom b/core/text.nom
index 28944dd..86d8d45 100644
--- a/core/text.nom
+++ b/core/text.nom
@@ -1,8 +1,8 @@
-#!/usr/bin/env nomsu -V4.8.10
+#!/usr/bin/env nomsu -V4.10.12.7
#
This file contains some definitions of text escape sequences, including ANSI console
color codes.
-
+
use "core/metaprogramming.nom"
use "core/operators.nom"
use "core/control_flow.nom"
@@ -27,19 +27,19 @@ test:
assume ("asdf"::with "s" -> "X") == "aXdf"
assume ("one\ntwo\n"::lines) == ["one", "two", ""]
(%spec とは %body) parses as (%spec means %body)
+
test:
%こんにちは = "こんにちは"
(% と言う) とは "\(%)世界"
assume (%こんにちは と言う) == "こんにちは世界"
+
(%expr for %match in %text matching %patt) compiles to:
define mangler
return (..)
Lua "\
..(function()
local \(mangle "comprehension") = List{}
- for \(%match as lua expr) in (\(%text as lua expr)):gmatch(\(..)
- %patt as lua expr
- ..) do
+ for \(%match as lua expr) in (\(%text as lua expr)):gmatch(\(%patt as lua expr)) do
\(mangle "comprehension")[#\(mangle "comprehension")+1] = \(%expr as lua)
end
return \(mangle "comprehension")
@@ -50,8 +50,9 @@ test:
# Text literals
%escapes = {..}
- nl:"\n", newline:"\n", tab:"\t", bell:"\a", cr:"\r", "carriage return":"\r",
- backspace:"\b", "form feed":"\f", formfeed:"\f", "vertical tab":"\v"
+ nl: "\n", newline: "\n", tab: "\t", bell: "\a", cr: "\r", "carriage return": "\r"
+ backspace: "\b", "form feed": "\f", formfeed: "\f", "vertical tab": "\v"
+
for %name = %str in %escapes:
with {%lua: Lua (quote %str)}:
- %compile.action.%name = ([]-> %lua)
+ %compile.action.%name = ([] -> %lua)