aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/collections.nom11
-rw-r--r--core/control_flow.nom3
-rw-r--r--core/text.nom3
-rw-r--r--lib/consolecolor.nom3
-rw-r--r--nomsu.peg6
-rw-r--r--nomsu_compiler.lua139
-rw-r--r--nomsu_compiler.moon104
7 files changed, 153 insertions, 116 deletions
diff --git a/core/collections.nom b/core/collections.nom
index 367356b..94fc02c 100644
--- a/core/collections.nom
+++ b/core/collections.nom
@@ -182,6 +182,15 @@ compile [%dict with fallback %key -> %value] to
end})
# Sorting
+test
+ %x <- [3,1,2]
+ sort %x
+ assume: %x = [1,2,3]
+ sort %x by % = (-%)
+ assume: %x = [3,2,1]
+ %keys <- {1:999,2:0,3:50}
+ 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
@@ -193,6 +202,7 @@ parse [..]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+test: assume: (sorted [3,1,2]) = [1,2,3]
action [%items sorted, sorted %items]
%copy <- (% for % in %items)
sort %copy
@@ -206,6 +216,7 @@ parse [..]
sort %copy by %item = %key
return %copy
+test: assume: (unique [1,2,1,3,2,3]) = [1,2,3]
action [unique %items]
%unique <- []
%seen <- {}
diff --git a/core/control_flow.nom b/core/control_flow.nom
index 61438d1..4733168 100644
--- a/core/control_flow.nom
+++ b/core/control_flow.nom
@@ -8,14 +8,17 @@ use "core/operators.nom"
use "core/errors.nom"
# No-Op
+test: do nothing
compile [do nothing] to: Lua ""
# Conditionals
+test: if (no): barf "conditional fail"
compile [if %condition %if_body] to
Lua ".."
if \(%condition as lua expr) then
\(%if_body as lua statements)
end
+test: unless (yes): barf "conditional fail"
parse [unless %condition %unless_body] as: if (not %condition) %unless_body
compile [if %condition %if_body else %else_body, unless %condition %else_body else %if_body] to
diff --git a/core/text.nom b/core/text.nom
index 37b8082..d09e6b5 100644
--- a/core/text.nom
+++ b/core/text.nom
@@ -44,6 +44,9 @@ compile [%expr for %match where %text matches %patt] to
return ret
end)()
+compile [%text matches %pattern] to
+ Lua value "(\(%text as lua expr):match(\(%pattern as lua expr)) and true or false)"
+
# Text literals
lua> ".."
do
diff --git a/lib/consolecolor.nom b/lib/consolecolor.nom
index 8184b59..8e3ca2f 100644
--- a/lib/consolecolor.nom
+++ b/lib/consolecolor.nom
@@ -1,5 +1,6 @@
use "core"
+test: bright: "\(green)Color test passed."
%colors <- {..}
normal:0, "reset color":0, bright:1, bold:1, dim:2, italic:3, underscore:4
"slow blink":5, "fast blink": 6, reverse:7, inverse:7, inverted:7, hidden:8
@@ -14,4 +15,4 @@ for %name = %colornum in %colors
compile [\%name] to: Lua value (quote \(quote %escapecode))
compile [\%name %text] to
Lua value ".."
- (\\(quote \(quote %escapecode))..\\(%text as lua expr)..\(quote "\27[0m"))
+ (\\(quote \(quote %escapecode))..\\(%text as lua expr).."\\27[0m")
diff --git a/nomsu.peg b/nomsu.peg
index 8b4d9ec..4598598 100644
--- a/nomsu.peg
+++ b/nomsu.peg
@@ -101,11 +101,11 @@ inline_text_interpolation:
indented_text (Text):
'".."' eol %nl {|
{~ (%nl*) (%indent -> "") ~}
- (indented_plain_text / text_interpolation / {~ ("\" nodent "..") -> "" ~} / {~ %nl+ (%nodent -> "") ~})*
+ (indented_plain_text / text_interpolation / {~ %nl+ (%nodent -> "") ~})*
|} (((!.) %dedent) / (&(%nl %dedent)) / (({} (non_dedent_error -> "Unexpected character while parsing Text") %userdata) => error))
indented_plain_text (Text):
- {| ({~ "\\" -> "\" ~} / {[^%nl\]+} / {!(text_interpolation / "\" nodent "..") "\"})+
- {~ (%nl+ (%nodent -> "")) / (("\" nodent "..") -> "") ~}* |}
+ {| {~ (("\\" -> "\") / (("\" nodent "..") -> "") / (!text_interpolation "\") / [^%nl\]+)+
+ (%nl+ (%nodent -> ""))* ~} |}
text_interpolation:
inline_text_interpolation / ("\" indented_expression nodent "..")
diff --git a/nomsu_compiler.lua b/nomsu_compiler.lua
index 412ffc6..c3e78ef 100644
--- a/nomsu_compiler.lua
+++ b/nomsu_compiler.lua
@@ -786,12 +786,16 @@ do
if not (arg_nomsu) then
return nil
end
+ if bit.type == "Action" or bit.type == "Block" then
+ if bit.type == "Action" and i == #tree then
+ nomsu:append(":")
+ else
+ arg_nomsu:parenthesize()
+ end
+ end
if not (i == 1) then
nomsu:append(" ")
end
- if bit.type == "Action" or bit.type == "Block" then
- arg_nomsu:parenthesize()
- end
nomsu:append(arg_nomsu)
end
end
@@ -904,27 +908,28 @@ do
return nomsu
elseif "Text" == _exp_0 then
if inline then
- local nomsu = NomsuCode(tree.source, '"')
- for _index_0 = 1, #tree do
- local bit = tree[_index_0]
- if type(bit) == 'string' then
- nomsu:append((gsub(gsub(gsub(bit, "\\", "\\\\"), "\n", "\\n"), '"', '\\"')))
- else
- local interp_nomsu = recurse(bit, {
- inline = true
- })
- if interp_nomsu then
+ local make_text
+ make_text = function(tree)
+ local nomsu = NomsuCode(tree.source)
+ for _index_0 = 1, #tree do
+ local bit = tree[_index_0]
+ if type(bit) == 'string' then
+ nomsu:append((gsub(gsub(gsub(bit, "\\", "\\\\"), "\n", "\\n"), '"', '\\"')))
+ elseif bit.type == "Text" then
+ nomsu:append(make_text(bit))
+ else
+ local interp_nomsu = assert(recurse(bit, {
+ inline = true
+ }))
if bit.type ~= "Var" and bit.type ~= "List" and bit.type ~= "Dict" and bit.type ~= "Text" then
interp_nomsu:parenthesize()
end
nomsu:append("\\", interp_nomsu)
- else
- return nil
end
end
+ return nomsu
end
- nomsu:append('"')
- return nomsu
+ return NomsuCode(tree.source, '"', make_text(tree), '"')
else
local inline_version = recurse(tree, {
inline = true
@@ -932,61 +937,67 @@ do
if inline_version and #inline_version <= MAX_LINE then
return inline_version
end
- local nomsu = NomsuCode(tree.source, '".."\n ')
- for i, bit in ipairs(tree) do
- if type(bit) == 'string' then
- local bit_lines = files.get_lines(bit)
- for j, line in ipairs(bit_lines) do
- if j > 1 then
- nomsu:append("\n ")
- end
- if #line > 1.25 * MAX_LINE then
- local remainder = line
- while #remainder > 0 do
- local split = find(remainder, " ", MAX_LINE, true)
- if split then
- local chunk
- chunk, remainder = sub(remainder, 1, split), sub(remainder, split + 1, -1)
- nomsu:append(chunk)
- elseif #remainder > 1.75 * MAX_LINE then
- split = math.floor(1.5 * MAX_LINE)
- local chunk
- chunk, remainder = sub(remainder, 1, split), sub(remainder, split + 1, -1)
- nomsu:append(chunk)
- else
- nomsu:append(remainder)
- break
- end
- if #remainder > 0 then
- nomsu:append("\\\n ..")
+ local make_text
+ make_text = function(tree)
+ local nomsu = NomsuCode(tree.source)
+ for i, bit in ipairs(tree) do
+ if type(bit) == 'string' then
+ local bit_lines = files.get_lines(bit)
+ for j, line in ipairs(bit_lines) do
+ if j > 1 then
+ nomsu:append("\n")
+ end
+ if #line > 1.25 * MAX_LINE then
+ local remainder = line
+ while #remainder > 0 do
+ local split = find(remainder, " ", MAX_LINE, true)
+ if split then
+ local chunk
+ chunk, remainder = sub(remainder, 1, split), sub(remainder, split + 1, -1)
+ nomsu:append(chunk)
+ elseif #remainder > 1.75 * MAX_LINE then
+ split = math.floor(1.5 * MAX_LINE)
+ local chunk
+ chunk, remainder = sub(remainder, 1, split), sub(remainder, split + 1, -1)
+ nomsu:append(chunk)
+ else
+ nomsu:append(remainder)
+ break
+ end
+ if #remainder > 0 then
+ nomsu:append("\\\n..")
+ end
end
+ else
+ nomsu:append(line)
end
- else
- nomsu:append(line)
- end
- end
- else
- local interp_nomsu = recurse(bit, {
- inline = true
- })
- if interp_nomsu then
- if bit.type ~= "Var" and bit.type ~= "List" and bit.type ~= "Dict" and bit.type ~= "Text" then
- interp_nomsu:parenthesize()
end
- nomsu:append("\\", interp_nomsu)
+ elseif bit.type == "Text" then
+ nomsu:append(make_text(bit))
else
- interp_nomsu = assert(recurse(bit))
- if not (interp_nomsu) then
- return nil
- end
- nomsu:append("\\\n ", interp_nomsu)
- if i < #tree then
- nomsu:append("\n ..")
+ local interp_nomsu = recurse(bit, {
+ inline = true
+ })
+ if interp_nomsu then
+ if bit.type ~= "Var" and bit.type ~= "List" and bit.type ~= "Dict" and bit.type ~= "Text" then
+ interp_nomsu:parenthesize()
+ end
+ nomsu:append("\\", interp_nomsu)
+ else
+ interp_nomsu = assert(recurse(bit))
+ if not (interp_nomsu) then
+ return nil
+ end
+ nomsu:append("\\\n ", interp_nomsu)
+ if i < #tree then
+ nomsu:append("\n..")
+ end
end
end
end
+ return nomsu
end
- return nomsu
+ return NomsuCode(tree.source, '".."\n ', make_text(tree))
end
elseif "List" == _exp_0 then
if inline then
diff --git a/nomsu_compiler.moon b/nomsu_compiler.moon
index e75fefa..cd35fa4 100644
--- a/nomsu_compiler.moon
+++ b/nomsu_compiler.moon
@@ -522,10 +522,13 @@ with NomsuCompiler
else
arg_nomsu = recurse(bit,inline:true)
return nil unless arg_nomsu
+ if bit.type == "Action" or bit.type == "Block"
+ if bit.type == "Action" and i == #tree
+ nomsu\append ":"
+ else
+ arg_nomsu\parenthesize!
unless i == 1
nomsu\append " "
- if bit.type == "Action" or bit.type == "Block"
- arg_nomsu\parenthesize!
nomsu\append arg_nomsu
return nomsu
else
@@ -607,60 +610,65 @@ with NomsuCompiler
when "Text"
if inline
- nomsu = NomsuCode(tree.source, '"')
- for bit in *tree
- if type(bit) == 'string'
- -- TODO: unescape better?
- nomsu\append (gsub(gsub(gsub(bit,"\\","\\\\"),"\n","\\n"),'"','\\"'))
- else
- interp_nomsu = recurse(bit, inline:true)
- if interp_nomsu
+ make_text = (tree)->
+ nomsu = NomsuCode(tree.source)
+ for bit in *tree
+ if type(bit) == 'string'
+ -- TODO: unescape better?
+ nomsu\append (gsub(gsub(gsub(bit,"\\","\\\\"),"\n","\\n"),'"','\\"'))
+ elseif bit.type == "Text"
+ nomsu\append(make_text(bit))
+ else
+ interp_nomsu = assert recurse(bit, inline:true)
if bit.type != "Var" and bit.type != "List" and bit.type != "Dict" and bit.type != "Text"
interp_nomsu\parenthesize!
nomsu\append "\\", interp_nomsu
- else return nil
- nomsu\append '"'
- return nomsu
+ return nomsu
+ return NomsuCode(tree.source, '"', make_text(tree), '"')
else
inline_version = recurse(tree, inline:true)
if inline_version and #inline_version <= MAX_LINE
return inline_version
- nomsu = NomsuCode(tree.source, '".."\n ')
- for i, bit in ipairs tree
- if type(bit) == 'string'
- bit_lines = files.get_lines(bit)
- for j, line in ipairs bit_lines
- if j > 1 then nomsu\append "\n "
- if #line > 1.25*MAX_LINE
- remainder = line
- while #remainder > 0
- split = find(remainder, " ", MAX_LINE, true)
- if split
- chunk, remainder = sub(remainder, 1, split), sub(remainder, split+1, -1)
- nomsu\append chunk
- elseif #remainder > 1.75*MAX_LINE
- split = math.floor(1.5*MAX_LINE)
- chunk, remainder = sub(remainder, 1, split), sub(remainder, split+1, -1)
- nomsu\append chunk
- else
- nomsu\append remainder
- break
- if #remainder > 0 then nomsu\append "\\\n .."
- else
- nomsu\append line
- else
- interp_nomsu = recurse(bit, inline:true)
- if interp_nomsu
- if bit.type != "Var" and bit.type != "List" and bit.type != "Dict" and bit.type != "Text"
- interp_nomsu\parenthesize!
- nomsu\append "\\", interp_nomsu
+ make_text = (tree)->
+ nomsu = NomsuCode(tree.source)
+ for i, bit in ipairs tree
+ if type(bit) == 'string'
+ bit_lines = files.get_lines(bit)
+ for j, line in ipairs bit_lines
+ if j > 1 then nomsu\append "\n"
+ if #line > 1.25*MAX_LINE
+ remainder = line
+ while #remainder > 0
+ split = find(remainder, " ", MAX_LINE, true)
+ if split
+ chunk, remainder = sub(remainder, 1, split), sub(remainder, split+1, -1)
+ nomsu\append chunk
+ elseif #remainder > 1.75*MAX_LINE
+ split = math.floor(1.5*MAX_LINE)
+ chunk, remainder = sub(remainder, 1, split), sub(remainder, split+1, -1)
+ nomsu\append chunk
+ else
+ nomsu\append remainder
+ break
+ if #remainder > 0 then nomsu\append "\\\n.."
+ else
+ nomsu\append line
+ elseif bit.type == "Text"
+ nomsu\append make_text(bit)
else
- interp_nomsu = assert(recurse(bit))
- return nil unless interp_nomsu
- nomsu\append "\\\n ", interp_nomsu
- if i < #tree
- nomsu\append "\n .."
- return nomsu
+ interp_nomsu = recurse(bit, inline:true)
+ if interp_nomsu
+ if bit.type != "Var" and bit.type != "List" and bit.type != "Dict" and bit.type != "Text"
+ interp_nomsu\parenthesize!
+ nomsu\append "\\", interp_nomsu
+ else
+ interp_nomsu = assert(recurse(bit))
+ return nil unless interp_nomsu
+ nomsu\append "\\\n ", interp_nomsu
+ if i < #tree
+ nomsu\append "\n.."
+ return nomsu
+ return NomsuCode(tree.source, '".."\n ', make_text(tree))
when "List"
if inline