aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--code_obj.lua4
-rw-r--r--code_obj.moon4
-rw-r--r--core/collections.nom2
-rw-r--r--nomsu.lua35
-rwxr-xr-xnomsu.moon21
-rw-r--r--nomsu.peg22
-rw-r--r--nomsu_compiler.lua87
-rw-r--r--nomsu_compiler.moon77
-rw-r--r--tests/text.nom2
9 files changed, 144 insertions, 110 deletions
diff --git a/code_obj.lua b/code_obj.lua
index 7fa91fc..cc2fb69 100644
--- a/code_obj.lua
+++ b/code_obj.lua
@@ -85,7 +85,7 @@ do
local _continue_0 = false
repeat
local b = select(i, ...)
- assert(b)
+ assert(b, "bit is nil")
if b == '' then
_continue_0 = true
break
@@ -176,7 +176,7 @@ do
if type(self.source) == 'string' then
self.source = Source:from_string(self.source)
end
- assert(self.source and Source:is_instance(self.source))
+ assert(self.source and Source:is_instance(self.source), "Source has the wrong type")
return self:append(...)
end,
__base = _base_0,
diff --git a/code_obj.moon b/code_obj.moon
index 74e9a15..8ac7146 100644
--- a/code_obj.moon
+++ b/code_obj.moon
@@ -48,7 +48,7 @@ class Code
@bits, @indents, @current_indent = {}, {}, 0
if type(@source) == 'string'
@source = Source\from_string(@source)
- assert(@source and Source\is_instance(@source))
+ assert(@source and Source\is_instance(@source), "Source has the wrong type")
@append(...)
append: (...)=>
@@ -57,7 +57,7 @@ class Code
match = string.match
for i=1,n
b = select(i, ...)
- assert(b)
+ assert(b, "bit is nil")
if b == '' then continue
bits[#bits+1] = b
if type(b) == 'string'
diff --git a/core/collections.nom b/core/collections.nom
index 48a4330..367356b 100644
--- a/core/collections.nom
+++ b/core/collections.nom
@@ -181,8 +181,6 @@ compile [%dict with fallback %key -> %value] to
return value
end})
-test: assume: 1 is 2
-
# Sorting
compile [sort %items] to: Lua "table.sort(\(%items as lua expr));"
parse [..]
diff --git a/nomsu.lua b/nomsu.lua
index ad41446..6080637 100644
--- a/nomsu.lua
+++ b/nomsu.lua
@@ -160,7 +160,10 @@ run = function()
local tests = { }
if args.run_tests then
nomsu.COMPILE_ACTIONS["test %"] = function(self, tree, _body)
- table.insert(tests, _body)
+ if not (tests[tree.source.filename]) then
+ tests[tree.source.filename] = { }
+ end
+ table.insert(tests[tree.source.filename], _body)
return LuaCode("")
end
end
@@ -190,7 +193,7 @@ run = function()
end
local file, source = get_file_and_source(filename)
if not (file) then
- return nil
+ return
end
local tree = nomsu:parse(file, source)
if tree then
@@ -199,25 +202,25 @@ run = function()
tree
}
end
- tests = { }
for _index_0 = 1, #tree do
local chunk = tree[_index_0]
local lua = nomsu:compile(chunk):as_statements("return ")
lua:declare_locals()
lua:prepend("-- File: " .. tostring(source.filename:gsub("\n.*", "...")) .. "\n")
- if lua_handler then
+ if lua_handler and input_files[filename] then
lua_handler(tostring(lua))
end
nomsu:run_lua(lua)
end
- if args.run_tests and #tests > 0 then
- for _index_0 = 1, #tests do
- local t = tests[_index_0]
+ if args.run_tests and tests[filename] and input_files[filename] then
+ local _list_0 = tests[filename]
+ for _index_0 = 1, #_list_0 do
+ local t = _list_0[_index_0]
local lua = nomsu:compile(t)
if lua_handler then
lua_handler(tostring(lua))
end
- nomsu:run_lua(lua)
+ nomsu:run_lua(lua, t.source)
end
end
end
@@ -228,6 +231,10 @@ run = function()
for filename in files.walk(f) do
local _continue_0 = false
repeat
+ if not (filename == "stdin" or filename:match("%.nom$")) then
+ _continue_0 = true
+ break
+ end
if args.check_syntax then
local file, source = get_file_and_source(filename)
if not (file) then
@@ -276,7 +283,6 @@ action [help]
say ".."
\(bright)\(underscore)Welcome to the Nomsu v\(Nomsu version) interactive console!\(reset color)
-
press 'enter' twice to run a command
\("")]])
for repl_line = 1, math.huge do
@@ -316,11 +322,18 @@ say ".."
end
end
end
-local debugger = require(args.debugger or 'error_handling')
+local debugger
+if args.debugger == "nil" then
+ debugger = { }
+else
+ debugger = require(args.debugger or 'error_handling')
+end
local guard
if type(debugger) == 'function' then
guard = debugger
else
- guard = debugger.guard or debugger.call or debugger.wrap or debugger.run
+ guard = debugger.guard or debugger.call or debugger.wrap or debugger.run or (function(fn)
+ return fn()
+ end)
end
return guard(run)
diff --git a/nomsu.moon b/nomsu.moon
index 2aaf058..cba9eee 100755
--- a/nomsu.moon
+++ b/nomsu.moon
@@ -106,7 +106,8 @@ run = ->
tests = {}
if args.run_tests
nomsu.COMPILE_ACTIONS["test %"] = (tree, _body)=>
- table.insert tests, _body
+ unless tests[tree.source.filename] then tests[tree.source.filename] = {}
+ table.insert tests[tree.source.filename], _body
return LuaCode ""
get_file_and_source = (filename)->
@@ -126,7 +127,7 @@ run = ->
run_file = (filename, lua_handler=nil)->
file, source = get_file_and_source(filename)
- return nil unless file
+ return unless file
tree = nomsu\parse(file, source)
if tree
if tree.type != "FileChunks"
@@ -134,22 +135,22 @@ run = ->
-- Each chunk's compilation is affected by the code in the previous chunks
-- (typically), so each chunk needs to compile and run before the next one
-- compiles.
- tests = {}
for chunk in *tree
lua = nomsu\compile(chunk)\as_statements("return ")
lua\declare_locals!
lua\prepend "-- File: #{source.filename\gsub("\n.*", "...")}\n"
- if lua_handler then lua_handler(tostring(lua))
+ if lua_handler and input_files[filename] then lua_handler(tostring(lua))
nomsu\run_lua(lua)
- if args.run_tests and #tests > 0
- for t in *tests
+ if args.run_tests and tests[filename] and input_files[filename]
+ for t in *tests[filename]
lua = nomsu\compile(t)
if lua_handler then lua_handler(tostring(lua))
- nomsu\run_lua(lua)
+ nomsu\run_lua(lua, t.source)
parse_errs = {}
for f in *file_queue
for filename in files.walk(f)
+ continue unless filename == "stdin" or filename\match("%.nom$")
if args.check_syntax
-- Check syntax
file, source = get_file_and_source(filename)
@@ -186,7 +187,6 @@ action [help]
say ".."
\(bright)\(underscore)Welcome to the Nomsu v\(Nomsu version) interactive console!\(reset color)
-
press 'enter' twice to run a command
\("")]]
for repl_line=1,math.huge
@@ -217,7 +217,8 @@ say ".."
elseif not ok
Errhand.print_error ret
-debugger = require(args.debugger or 'error_handling')
+debugger = if args.debugger == "nil" then {}
+else require(args.debugger or 'error_handling')
guard = if type(debugger) == 'function' then debugger
-else debugger.guard or debugger.call or debugger.wrap or debugger.run
+else debugger.guard or debugger.call or debugger.wrap or debugger.run or ((fn)->fn())
guard(run)
diff --git a/nomsu.peg b/nomsu.peg
index 2497e7c..8b4d9ec 100644
--- a/nomsu.peg
+++ b/nomsu.peg
@@ -85,15 +85,6 @@ inline_text (Text):
(({} (eol->'Line ended before finding a closing double quotation mark') %userdata) => error)
/(({} ([^%nl]*->'Unexpected character while parsing Text') %userdata) => error)
))
-
--- Have to use "%indent" instead of "indent" etc. to avoid messing up text lines that start with "#"
-indented_text (Text):
- '".."' eol %nl {|
- {~ (%nl*) (%indent -> "") ~}
- ({~
- (("\\" -> "\") / (("\" nodent "..") -> "")/ (%nl+ {~ %nodent -> "" ~}) / [^%nl\] / (!text_interpolation "\"))+
- ~} / text_interpolation)*
- |} (((!.) %dedent) / (&(%nl %dedent)) / (({} (non_dedent_error -> "Unexpected character while parsing Text") %userdata) => error))
inline_text_interpolation:
"\" (
variable / inline_list / inline_dict / inline_text
@@ -105,9 +96,18 @@ inline_text_interpolation:
/ (({} ([^%nl]* -> 'Unexpected character while parsing Text interpolation') %userdata) => error))
)
)
+
+-- Have to use "%indent" instead of "indent" etc. to avoid messing up text lines that start with "#"
+indented_text (Text):
+ '".."' eol %nl {|
+ {~ (%nl*) (%indent -> "") ~}
+ (indented_plain_text / text_interpolation / {~ ("\" nodent "..") -> "" ~} / {~ %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 "..") -> "") ~}* |}
text_interpolation:
- inline_text_interpolation /
- ("\" indented_expression nodent "..")
+ inline_text_interpolation / ("\" indented_expression nodent "..")
number (Number): {| (("-"? (([0-9]+ "." [0-9]+) / ("." [0-9]+) / ([0-9]+)))-> tonumber) |}
diff --git a/nomsu_compiler.lua b/nomsu_compiler.lua
index b2c034a..ca4b760 100644
--- a/nomsu_compiler.lua
+++ b/nomsu_compiler.lua
@@ -234,40 +234,38 @@ do
end
local math_expression = re.compile([[ ([+-] " ")* "%" (" " [*/^+-] (" " [+-])* " %")+ !. ]])
local add_lua_bits
- add_lua_bits = function(self, lua, code)
- for _index_0 = 1, #code do
- local bit = code[_index_0]
- if type(bit) == "string" then
- lua:append(bit)
- else
- local bit_lua = self:compile(bit)
- if not (bit_lua.is_value) then
- self:compile_error(bit, "Cannot use:\n%s\nas a string interpolation value, since it's not an expression.")
+ add_lua_bits = function(self, val_or_stmt, code)
+ local cls = val_or_stmt == "value" and LuaCode.Value or LuaCode
+ local operate_on_text
+ operate_on_text = function(text)
+ local lua = cls(text.source)
+ for _index_0 = 1, #text do
+ local bit = text[_index_0]
+ if type(bit) == "string" then
+ lua:append(bit)
+ elseif bit.type == "Text" then
+ lua:append(operate_on_text(bit))
+ else
+ local bit_lua = self:compile(bit)
+ if not (bit_lua.is_value) then
+ self:compile_error(bit, "Cannot use:\n%s\nas a string interpolation value, since it's not an expression.")
+ end
+ lua:append(bit_lua)
end
- lua:append(bit_lua)
end
+ return lua
end
- return lua
+ return operate_on_text(code)
end
local add_lua_string_bits
- add_lua_string_bits = function(self, lua, code)
+ add_lua_string_bits = function(self, val_or_stmt, code)
local line_len = 0
+ local cls_str = val_or_stmt == "value" and "LuaCode.Value(" or "LuaCode("
if code.type ~= "Text" then
- lua:append(", ", self:compile(code))
- return
+ return LuaCode(code.source, cls_str, repr(tostring(code.source)), ", ", self:compile(code), ")")
end
- for _index_0 = 1, #code do
- local bit = code[_index_0]
- local bit_lua
- if type(bit) == "string" then
- bit_lua = repr(bit)
- else
- bit_lua = self:compile(bit)
- if not (bit_lua.is_value) then
- self:compile_error(bit, "Cannot use:\n%s\nas a string interpolation value, since it's not an expression.")
- end
- bit_lua = bit_lua
- end
+ local add_bit_lua
+ add_bit_lua = function(lua, bit_lua)
line_len = line_len + #tostring(bit_lua)
if line_len > MAX_LINE then
lua:append(",\n ")
@@ -275,8 +273,29 @@ do
else
lua:append(", ")
end
- lua:append(bit_lua)
+ return lua:append(bit_lua)
end
+ local operate_on_text
+ operate_on_text = function(text)
+ local lua = LuaCode.Value(text.source, cls_str, repr(tostring(text.source)))
+ for _index_0 = 1, #text do
+ local bit = text[_index_0]
+ if type(bit) == "string" then
+ add_bit_lua(lua, repr(bit))
+ elseif bit.type == "Text" then
+ add_bit_lua(lua, operate_on_text(bit))
+ else
+ local bit_lua = self:compile(bit)
+ if not (bit_lua.is_value) then
+ self:compile_error(bit, "Cannot use:\n%s\nas a string interpolation value, since it's not an expression.")
+ end
+ add_bit_lua(lua, bit_lua)
+ end
+ end
+ lua:append(")")
+ return lua
+ end
+ return operate_on_text(code)
end
NomsuCompiler.COMPILE_ACTIONS = setmetatable({
["# compile math expr #"] = function(self, tree, ...)
@@ -301,28 +320,22 @@ do
return lua
end,
["Lua %"] = function(self, tree, _code)
- local lua = LuaCode.Value(tree.source, "LuaCode(", repr(tostring(_code.source)))
- add_lua_string_bits(self, lua, _code)
- lua:append(")")
- return lua
+ return add_lua_string_bits(self, 'statements', _code)
end,
["Lua value %"] = function(self, tree, _code)
- local lua = LuaCode.Value(tree.source, "LuaCode.Value(", repr(tostring(_code.source)))
- add_lua_string_bits(self, lua, _code)
- lua:append(")")
- return lua
+ return add_lua_string_bits(self, 'value', _code)
end,
["lua > %"] = function(self, tree, _code)
if _code.type ~= "Text" then
return LuaCode(tree.source, "nomsu:run_lua(", self:compile(_code), ");")
end
- return add_lua_bits(self, LuaCode(tree.source), _code)
+ return add_lua_bits(self, "statements", _code)
end,
["= lua %"] = function(self, tree, _code)
if _code.type ~= "Text" then
return LuaCode.Value(tree.source, "nomsu:run_lua(", self:compile(_code), ":as_statements('return '))")
end
- return add_lua_bits(self, LuaCode.Value(tree.source), _code)
+ return add_lua_bits(self, "value", _code)
end,
["use %"] = function(self, tree, _path)
if _path.type == 'Text' and #_path == 1 and type(_path[1]) == 'string' then
diff --git a/nomsu_compiler.moon b/nomsu_compiler.moon
index 83c864c..080e3d7 100644
--- a/nomsu_compiler.moon
+++ b/nomsu_compiler.moon
@@ -137,32 +137,31 @@ with NomsuCompiler
-- math expressions like 2*x + 3^2 without having to define a single
-- action for every possibility.
math_expression = re.compile [[ ([+-] " ")* "%" (" " [*/^+-] (" " [+-])* " %")+ !. ]]
- add_lua_bits = (lua, code)=>
- for bit in *code
- if type(bit) == "string"
- lua\append bit
- else
- bit_lua = @compile(bit)
- unless bit_lua.is_value
- @compile_error bit,
- "Cannot use:\n%s\nas a string interpolation value, since it's not an expression."
- lua\append bit_lua
- return lua
-
- add_lua_string_bits = (lua, code)=>
+
+ add_lua_bits = (val_or_stmt, code)=>
+ cls = val_or_stmt == "value" and LuaCode.Value or LuaCode
+ operate_on_text = (text)->
+ lua = cls(text.source)
+ for bit in *text
+ if type(bit) == "string"
+ lua\append bit
+ elseif bit.type == "Text"
+ lua\append(operate_on_text(bit))
+ else
+ bit_lua = @compile(bit)
+ unless bit_lua.is_value
+ @compile_error bit,
+ "Cannot use:\n%s\nas a string interpolation value, since it's not an expression."
+ lua\append bit_lua
+ return lua
+ return operate_on_text code
+
+ add_lua_string_bits = (val_or_stmt, code)=>
line_len = 0
+ cls_str = val_or_stmt == "value" and "LuaCode.Value(" or "LuaCode("
if code.type != "Text"
- lua\append ", ", @compile(code)
- return
- for bit in *code
- bit_lua = if type(bit) == "string"
- repr(bit)
- else
- bit_lua = @compile(bit)
- unless bit_lua.is_value
- @compile_error bit,
- "Cannot use:\n%s\nas a string interpolation value, since it's not an expression."
- bit_lua
+ return LuaCode(code.source, cls_str, repr(tostring(code.source)), ", ", @compile(code), ")")
+ add_bit_lua = (lua, bit_lua)->
line_len += #tostring(bit_lua)
if line_len > MAX_LINE
lua\append ",\n "
@@ -170,6 +169,22 @@ with NomsuCompiler
else
lua\append ", "
lua\append bit_lua
+ operate_on_text = (text)->
+ lua = LuaCode.Value(text.source, cls_str, repr(tostring(text.source)))
+ for bit in *text
+ if type(bit) == "string"
+ add_bit_lua(lua, repr(bit))
+ elseif bit.type == "Text"
+ add_bit_lua(lua, operate_on_text(bit))
+ else
+ bit_lua = @compile(bit)
+ unless bit_lua.is_value
+ @compile_error bit,
+ "Cannot use:\n%s\nas a string interpolation value, since it's not an expression."
+ add_bit_lua(lua, bit_lua)
+ lua\append ")"
+ return lua
+ return operate_on_text code
.COMPILE_ACTIONS = setmetatable {
["# compile math expr #"]: (tree, ...)=>
@@ -189,26 +204,20 @@ with NomsuCompiler
return lua
["Lua %"]: (tree, _code)=>
- lua = LuaCode.Value(tree.source, "LuaCode(", repr(tostring _code.source))
- add_lua_string_bits(@, lua, _code)
- lua\append ")"
- return lua
+ return add_lua_string_bits(@, 'statements', _code)
["Lua value %"]: (tree, _code)=>
- lua = LuaCode.Value(tree.source, "LuaCode.Value(", repr(tostring _code.source))
- add_lua_string_bits(@, lua, _code)
- lua\append ")"
- return lua
+ return add_lua_string_bits(@, 'value', _code)
["lua > %"]: (tree, _code)=>
if _code.type != "Text"
return LuaCode tree.source, "nomsu:run_lua(", @compile(_code), ");"
- return add_lua_bits(@, LuaCode(tree.source), _code)
+ return add_lua_bits(@, "statements", _code)
["= lua %"]: (tree, _code)=>
if _code.type != "Text"
return LuaCode.Value tree.source, "nomsu:run_lua(", @compile(_code), ":as_statements('return '))"
- return add_lua_bits(@, LuaCode.Value(tree.source), _code)
+ return add_lua_bits(@, "value", _code)
["use %"]: (tree, _path)=>
if _path.type == 'Text' and #_path == 1 and type(_path[1]) == 'string'
diff --git a/tests/text.nom b/tests/text.nom
index 4b7f952..39ee496 100644
--- a/tests/text.nom
+++ b/tests/text.nom
@@ -24,7 +24,7 @@ assume ((%こんにちは と言う) = "こんにちは世界") or barf "Unicode
%s <- ".."
one two\nthree\
..four
-assume (%s = "one two\\nthreefour")
+assume (%s = "one two\\nthreefour") or barf "%s = \(quote %s), not \(quote "one two\\nthreefour")"
%s <- ".."
list:\[..]
1,2,3