aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/control_flow.nom42
-rw-r--r--core/metaprogramming.nom18
-rw-r--r--core/scopes.nom4
-rw-r--r--nomsu.lua87
-rwxr-xr-xnomsu.moon81
-rw-r--r--nomsu.peg28
-rw-r--r--nomsu_tree.lua27
-rw-r--r--nomsu_tree.moon19
8 files changed, 150 insertions, 156 deletions
diff --git a/core/control_flow.nom b/core/control_flow.nom
index f5c61e3..73a0f43 100644
--- a/core/control_flow.nom
+++ b/core/control_flow.nom
@@ -49,13 +49,13 @@ immediately
To see why this is necessary consider: (random()<.5 and false or 99)
return
Lua value ".."
- (function()
+ ((function()
if \(%condition as lua expr) then
return \(%when_true_expr as lua expr)
else
return \(%when_false_expr as lua expr)
end
- end)()
+ end)())
# GOTOs
immediately
@@ -361,31 +361,46 @@ immediately
# Try/except
immediately
compile [..]
- 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 %msg %fallback
+ try %action and if it barfs %msg %fallback or if it succeeds %success
..to
Lua ".."
do
local fell_through = false
- local ok, ret = pcall(function()
+ local err, erred = nil, false
+ local ok, ret = xpcall(function()
\(%action as lua statements)
fell_through = true
+ end, function(\(%msg as lua expr))
+ local ok, ret = pcall(function()
+ \(%fallback as lua statements)
+ end)
+ if not ok then err, erred = ret, true end
end)
if ok then
\(%success as lua statements)
if not fell_through then
return ret
end
- else
- \(%fallback as lua statements)
+ elseif erred then
+ error(err, 0)
end
end
+immediately
+ 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
+immediately
parse [try %action] 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 succeeds: do nothing
..or if it barfs %fallback
+ parse [try %action and if it barfs %msg %fallback] 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 or if it barfs: do nothing
@@ -406,17 +421,20 @@ immediately
fell_through = true
end)
\(%final_action as lua statements)
- if not ok then error(ret) end
+ if not ok then error(ret, 0) end
if not fell_through then return ret end
end
# Inline thunk:
immediately
compile [result of %body] to
- Lua value ".."
- (function()
- \(%body as lua statements)
- end)()
+ %body <- (%body as lua statements)
+ declare locals in %body
+ return
+ Lua value ".."
+ ((function()
+ \%body
+ end)())
# Coroutines:
immediately
diff --git a/core/metaprogramming.nom b/core/metaprogramming.nom
index 8ad9448..83293c1 100644
--- a/core/metaprogramming.nom
+++ b/core/metaprogramming.nom
@@ -132,15 +132,25 @@ immediately
lua> ".."
local lua = nomsu:tree_to_lua(\%tree)
if not lua.is_value then
- error("Invalid thing to convert to lua expr: "..tostring(\%tree))
+ compile_error(\%tree, "Invalid thing to convert to lua expr:\n%s")
end
return lua
action [%tree as lua statements]
=lua "nomsu:tree_to_lua(\%tree):as_statements()"
+
+ action [%tree as lua return]
+ =lua "nomsu:tree_to_lua(\%tree):as_statements('return ')"
- action [%tree with vars %vars]
- =lua "\%tree:map(\%vars)"
+immediately
+ compile [%tree with vars %vars] to
+ barf "Deprecated"
+
+ compile [%tree with %t -> %replacement] to
+ Lua value ".."
+ \(%tree as lua expr):map(function(\(%t as lua expr))
+ \(%replacement as lua return)
+ end)
compile [declare locals in %code] to
Lua value "\(%code as lua expr):declare_locals()"
@@ -202,6 +212,8 @@ immediately
# Error functions
immediately
+ compile [traceback] to: Lua value "debug.traceback()"
+ compile [traceback %] to: Lua value "debug.traceback('', \(% as lua expr))"
compile [barf] to: Lua "error(nil, 0);"
compile [barf %msg] to: Lua "error(\(%msg as lua expr), 0);"
compile [assume %condition] to
diff --git a/core/scopes.nom b/core/scopes.nom
index 72631c0..02ad73d 100644
--- a/core/scopes.nom
+++ b/core/scopes.nom
@@ -30,7 +30,7 @@ compile [using %definitions %body, using %definitions do %body] to
\%setup_lua
if not ok then
ACTIONS, COMPILE_ACTIONS, ARG_ORDERS = old_actions, old_compile_actions, old_arg_orders
- error(ret)
+ error(ret, 0)
end
if not fell_through then
ACTIONS, COMPILE_ACTIONS, ARG_ORDERS = old_actions, old_compile_actions, old_arg_orders
@@ -42,7 +42,7 @@ compile [using %definitions %body, using %definitions do %body] to
\%body_lua
ACTIONS, COMPILE_ACTIONS, ARG_ORDERS = old_actions, old_compile_actions, old_arg_orders
if not ok then
- error(ret)
+ error(ret, 0)
end
if not fell_through then
return ret
diff --git a/nomsu.lua b/nomsu.lua
index dc1a5d8..646b9af 100644
--- a/nomsu.lua
+++ b/nomsu.lua
@@ -278,7 +278,7 @@ end
local NomsuCompiler
do
local _class_0
- local stub_pattern, var_pattern, _running_files, _report_error, MAX_LINE, math_expression
+ local compile_error, stub_pattern, var_pattern, _running_files, MAX_LINE, math_expression
local _base_0 = {
define_action = function(self, signature, fn, is_compile_action)
if is_compile_action == nil then
@@ -304,12 +304,13 @@ do
end
fn_arg_positions = _tbl_0
end
+ local actions = (is_compile_action and self.environment.COMPILE_ACTIONS or self.environment.ACTIONS)
local arg_orders = { }
for _index_0 = 1, #signature do
local alias = signature[_index_0]
local stub = concat(assert(stub_pattern:match(alias)), ' ')
- local stub_args = assert(var_pattern:match(alias));
- (is_compile_action and self.environment.COMPILE_ACTIONS or self.environment.ACTIONS)[stub] = fn
+ local stub_args = assert(var_pattern:match(alias))
+ actions[stub] = fn
do
local _accum_0 = { }
local _len_0 = 1
@@ -507,10 +508,11 @@ do
end
args = _accum_0
end
+ local arg_orders = self.environment.ARG_ORDERS[compile_action]
do
local _accum_0 = { }
local _len_0 = 1
- local _list_0 = self.environment.ARG_ORDERS[compile_action][stub]
+ local _list_0 = arg_orders[stub]
for _index_0 = 1, #_list_0 do
local p = _list_0[_index_0]
_accum_0[_len_0] = args[p - 1]
@@ -520,9 +522,7 @@ do
end
local ret = compile_action(tree, unpack(args))
if not ret then
- _report_error(tree, function(src)
- return "Compile-time action:\n" .. tostring(src) .. "\nfailed to produce any Lua"
- end)
+ compile_error(tree, "Compile-time action:\n%s\nfailed to produce any Lua")
end
return ret
end
@@ -535,9 +535,7 @@ do
else
local tok_lua = self:tree_to_lua(tok)
if not (tok_lua.is_value) then
- _report_error(tok, function(src)
- return "Non-expression value inside math expression:\n" .. tostring(src)
- end)
+ compile_error(tok, "Non-expression value inside math expression:\n%s")
end
if tok.type == "Action" then
tok_lua:parenthesize()
@@ -560,9 +558,7 @@ do
end
local arg_lua = self:tree_to_lua(tok)
if not (arg_lua.is_value) then
- _report_error(tok, function(src)
- return "Cannot use:\n" .. tostring(src) .. "\nas an argument to " .. tostring(stub) .. ", since it's not an expression, it produces: " .. tostring(repr(arg_lua)), 0
- end)
+ compile_error(tok, "Cannot use:\n%s\nas an argument to %s, since it's not an expression, it produces: %s", stub, repr(arg_lua))
end
insert(args, arg_lua)
_continue_0 = true
@@ -649,9 +645,7 @@ do
if not (bit_lua.is_value) then
local src = ' ' .. tostring(self:tree_to_nomsu(bit)):gsub('\n', '\n ')
local line = tostring(bit.source.filename) .. ":" .. tostring(pos_to_line(FILE_CACHE[bit.source.filename], bit.source.start))
- _report_error(bit, function(src)
- return "Cannot use:\n" .. tostring(src) .. "\nas a string interpolation value, since it's not an expression."
- end)
+ compile_error(bit, "Cannot use:\n%s\nas a string interpolation value, since it's not an expression.")
end
if #lua.bits > 0 then
lua:append("..")
@@ -682,9 +676,7 @@ do
for i, item in ipairs(tree) do
local item_lua = self:tree_to_lua(item)
if not (item_lua.is_value) then
- _report_error(item, function(src)
- return "Cannot use:\n" .. tostring(src) .. "\nas a list item, since it's not an expression."
- end)
+ compile_error(item, "Cannot use:\n%s\nas a list item, since it's not an expression.")
end
lua:append(item_lua)
local item_string = tostring(item_lua)
@@ -735,15 +727,11 @@ do
local key, value = tree[1], tree[2]
local key_lua = self:tree_to_lua(key)
if not (key_lua.is_value) then
- _report_error(tree[1], function(src)
- return "Cannot use:\n" .. tostring(src) .. "\nas a dict key, since it's not an expression."
- end)
+ compile_error(tree[1], "Cannot use:\n%s\nas a dict key, since it's not an expression.")
end
local value_lua = value and self:tree_to_lua(value) or Lua.Value(key.source, "true")
if not (value_lua.is_value) then
- _report_error(tree[2], function(src)
- return "Cannot use:\n" .. tostring(src) .. "\nas a dict value, since it's not an expression."
- end)
+ compile_error(tree[2], "Cannot use:\n%s\nas a dict value, since it's not an expression.")
end
local key_str = tostring(key_lua):match([=[["']([a-zA-Z_][a-zA-Z0-9_]*)['"]]=])
if key_str then
@@ -756,9 +744,7 @@ do
elseif "IndexChain" == _exp_0 then
local lua = self:tree_to_lua(tree[1])
if not (lua.is_value) then
- _report_error(tree[1], function(src)
- return "Cannot index:\n" .. tostring(src) .. "\nsince it's not an expression."
- end)
+ compile_error(tree[1], "Cannot index:\n%s\nsince it's not an expression.")
end
local first_char = tostring(lua):sub(1, 1)
if first_char == "{" or first_char == '"' or first_char == "[" then
@@ -768,9 +754,7 @@ do
local key = tree[i]
local key_lua = self:tree_to_lua(key)
if not (key_lua.is_value) then
- _report_error(key, function(src)
- return "Cannot use:\n" .. tostring(key) .. "\nas an index, since it's not an expression."
- end)
+ compile_error(key, "Cannot use:\n%s\nas an index, since it's not an expression.")
end
local key_lua_str = tostring(key_lua)
do
@@ -1135,9 +1119,7 @@ do
else
local bit_lua = nomsu:tree_to_lua(bit)
if not (bit_lua.is_value) then
- _report_error(bit, function(src)
- return "Cannot use:\n" .. tostring(src) .. "\nas a string interpolation value, since it's not an expression."
- end)
+ compile_error(bit, "Cannot use:\n%s\nas a string interpolation value, since it's not an expression.")
end
lua:append(bit_lua)
end
@@ -1164,9 +1146,7 @@ do
else
local bit_lua = nomsu:tree_to_lua(bit)
if not (bit_lua.is_value) then
- _report_error(bit, function(src)
- return "Cannot use:\n" .. tostring(src) .. "\nas a string interpolation value, since it's not an expression."
- end)
+ compile_error(bit, "Cannot use:\n%s\nas a string interpolation value, since it's not an expression.")
end
lua:append(bit_lua)
end
@@ -1186,12 +1166,10 @@ do
return add_lua_bits(Lua.Value(self.source), _code)
end)
return self:define_compile_action("use %path", function(self, _path)
- local path
- if _path.type == 'Text' and #_path == 1 and type(_path[1]) == 'string' then
- path = _path[1]
- else
- path = nomsu:run_lua(Lua(_path.source, "return ", nomsu:tree_to_lua(_path)))
+ if not (_path.type == 'Text' and #_path == 1 and type(_path[1]) == 'string') then
+ return Lua(_path.source, "nomsu:run_file(" .. tostring(nomsu:tree_to_lua(_path)) .. ");")
end
+ local path = _path[1]
nomsu:run_file(path)
return Lua(_path.source, "nomsu:run_file(" .. tostring(repr(path)) .. ");")
end)
@@ -1260,6 +1238,7 @@ do
utils = utils,
lpeg = lpeg,
re = re,
+ compile_error = compile_error,
next = next,
unpack = unpack,
setmetatable = setmetatable,
@@ -1382,6 +1361,18 @@ do
})
_base_0.__class = _class_0
local self = _class_0
+ compile_error = function(tok, err_format_string, ...)
+ local file = FILE_CACHE[tok.source.filename]
+ local line_no = pos_to_line(file, tok.source.start)
+ local line_start = LINE_STARTS[file][line_no]
+ local src = colored.dim(file:sub(line_start, tok.source.start - 1))
+ src = src .. colored.underscore(colored.bright(colored.red(file:sub(tok.source.start, tok.source.stop - 1))))
+ local end_of_line = (LINE_STARTS[file][pos_to_line(file, tok.source.stop) + 1] or 0) - 1
+ src = src .. colored.dim(file:sub(tok.source.stop, end_of_line - 1))
+ src = ' ' .. src:gsub('\n', '\n ')
+ local err_msg = err_format_string:format(src, ...)
+ return error(tostring(tok.source.filename) .. ":" .. tostring(line_no) .. ": " .. err_msg, 0)
+ end
local stub_defs
do
stub_defs = {
@@ -1394,18 +1385,6 @@ do
]=], stub_defs)
var_pattern = re.compile("{| ((('%' {%varname}) / %word) ([ ])*)+ !. |}", stub_defs)
_running_files = { }
- _report_error = function(tok, fn)
- local file = FILE_CACHE[tok.source.filename]
- local line_no = pos_to_line(file, tok.source.start)
- local line_start = LINE_STARTS[file][line_no]
- local src = colored.dim(file:sub(line_start, tok.source.start - 1))
- src = src .. colored.underscore(colored.bright(colored.red(file:sub(tok.source.start, tok.source.stop - 1))))
- local end_of_line = (LINE_STARTS[file][pos_to_line(file, tok.source.stop) + 1] or 0) - 1
- src = src .. colored.dim(file:sub(tok.source.stop, end_of_line - 1))
- src = ' ' .. src:gsub('\n', '\n ')
- local err_msg = fn(src)
- return error(tostring(tok.source.filename) .. ":" .. tostring(line_no) .. ": " .. err_msg, 0)
- end
MAX_LINE = 80
math_expression = re.compile([[ ([+-] " ")* "%" (" " [*/^+-] (" " [+-])* " %")+ !. ]])
NomsuCompiler = _class_0
diff --git a/nomsu.moon b/nomsu.moon
index b47b32a..1196b37 100755
--- a/nomsu.moon
+++ b/nomsu.moon
@@ -230,6 +230,17 @@ NOMSU_PATTERN = do
re.compile(nomsu_peg, NOMSU_DEFS)
class NomsuCompiler
+ compile_error = (tok, err_format_string, ...)->
+ file = FILE_CACHE[tok.source.filename]
+ line_no = pos_to_line(file, tok.source.start)
+ line_start = LINE_STARTS[file][line_no]
+ src = colored.dim(file\sub(line_start, tok.source.start-1))
+ src ..= colored.underscore colored.bright colored.red(file\sub(tok.source.start, tok.source.stop-1))
+ end_of_line = (LINE_STARTS[file][pos_to_line(file, tok.source.stop) + 1] or 0) - 1
+ src ..= colored.dim(file\sub(tok.source.stop, end_of_line-1))
+ src = ' '..src\gsub('\n', '\n ')
+ err_msg = err_format_string\format(src, ...)
+ error("#{tok.source.filename}:#{line_no}: "..err_msg, 0)
new: =>
-- Weak-key mapping from objects to randomly generated unique IDs
NaN_surrogate = {}
@@ -259,6 +270,7 @@ class NomsuCompiler
@environment = {
-- Discretionary/convenience stuff
nomsu:self, repr:repr, stringify:stringify, utils:utils, lpeg:lpeg, re:re,
+ :compile_error
-- Lua stuff:
:next, :unpack, :setmetatable, :coroutine, :rawequal, :getmetatable, :pcall,
:error, :package, :os, :require, :tonumber, :tostring, :string, :xpcall, :module,
@@ -329,11 +341,12 @@ class NomsuCompiler
fn_info = debug_getinfo(fn, "u")
assert(not fn_info.isvararg, "Vararg functions aren't supported. Sorry, use a list instead.")
fn_arg_positions = {debug.getlocal(fn, i), i for i=1,fn_info.nparams}
+ actions = (is_compile_action and @environment.COMPILE_ACTIONS or @environment.ACTIONS)
arg_orders = {}
for alias in *signature
stub = concat(assert(stub_pattern\match(alias)), ' ')
stub_args = assert(var_pattern\match(alias))
- (is_compile_action and @environment.COMPILE_ACTIONS or @environment.ACTIONS)[stub] = fn
+ actions[stub] = fn
arg_orders[stub] = [fn_arg_positions[string.as_lua_id a] for a in *stub_args]
@environment.ARG_ORDERS[fn] = arg_orders
@@ -411,17 +424,6 @@ class NomsuCompiler
loaded[filename] = ret or true
return ret
- _report_error = (tok, fn)->
- file = FILE_CACHE[tok.source.filename]
- line_no = pos_to_line(file, tok.source.start)
- line_start = LINE_STARTS[file][line_no]
- src = colored.dim(file\sub(line_start, tok.source.start-1))
- src ..= colored.underscore colored.bright colored.red(file\sub(tok.source.start, tok.source.stop-1))
- end_of_line = (LINE_STARTS[file][pos_to_line(file, tok.source.stop) + 1] or 0) - 1
- src ..= colored.dim(file\sub(tok.source.stop, end_of_line-1))
- src = ' '..src\gsub('\n', '\n ')
- err_msg = fn(src)
- error("#{tok.source.filename}:#{line_no}: "..err_msg, 0)
run_lua: (lua)=>
assert(type(lua) != 'string', "Attempt to run lua string instead of Lua (object)")
lua_string = tostring(lua)
@@ -469,13 +471,14 @@ class NomsuCompiler
if compile_action
args = [arg for arg in *tree when type(arg) != "string"]
-- Force all compile-time actions to take a tree location
- args = [args[p-1] for p in *@environment.ARG_ORDERS[compile_action][stub]]
+ arg_orders = @environment.ARG_ORDERS[compile_action]
+ args = [args[p-1] for p in *arg_orders[stub]]
-- Force Lua to avoid tail call optimization for debugging purposes
-- TODO: use tail call
ret = compile_action(tree, unpack(args))
if not ret
- _report_error tree, (src)->
- "Compile-time action:\n#{src}\nfailed to produce any Lua"
+ compile_error tree,
+ "Compile-time action:\n%s\nfailed to produce any Lua"
return ret
action = rawget(@environment.ACTIONS, stub)
lua = Lua.Value(tree.source)
@@ -489,8 +492,8 @@ class NomsuCompiler
else
tok_lua = @tree_to_lua(tok)
unless tok_lua.is_value
- _report_error tok, (src)->
- "Non-expression value inside math expression:\n#{src}"
+ compile_error tok,
+ "Non-expression value inside math expression:\n%s"
if tok.type == "Action"
tok_lua\parenthesize!
lua\append tok_lua
@@ -503,8 +506,9 @@ class NomsuCompiler
if type(tok) == "string" then continue
arg_lua = @tree_to_lua(tok)
unless arg_lua.is_value
- _report_error tok, (src)->
- "Cannot use:\n#{src}\nas an argument to #{stub}, since it's not an expression, it produces: #{repr arg_lua}", 0
+ compile_error tok,
+ "Cannot use:\n%s\nas an argument to %s, since it's not an expression, it produces: %s",
+ stub, repr arg_lua
insert args, arg_lua
if action
@@ -554,8 +558,8 @@ class NomsuCompiler
unless bit_lua.is_value
src = ' '..tostring(@tree_to_nomsu(bit))\gsub('\n','\n ')
line = "#{bit.source.filename}:#{pos_to_line(FILE_CACHE[bit.source.filename], bit.source.start)}"
- _report_error bit, (src)->
- "Cannot use:\n#{src}\nas a string interpolation value, since it's not an expression."
+ compile_error bit,
+ "Cannot use:\n%s\nas a string interpolation value, since it's not an expression."
if #lua.bits > 0 then lua\append ".."
if bit.type != "Text"
bit_lua = Lua.Value(bit.source, "stringify(",bit_lua,")")
@@ -575,8 +579,8 @@ class NomsuCompiler
for i, item in ipairs tree
item_lua = @tree_to_lua(item)
unless item_lua.is_value
- _report_error item, (src)->
- "Cannot use:\n#{src}\nas a list item, since it's not an expression."
+ compile_error item,
+ "Cannot use:\n%s\nas a list item, since it's not an expression."
lua\append item_lua
item_string = tostring(item_lua)
last_line = item_string\match("[^\n]*$")
@@ -621,12 +625,12 @@ class NomsuCompiler
key, value = tree[1], tree[2]
key_lua = @tree_to_lua(key)
unless key_lua.is_value
- _report_error tree[1], (src)->
- "Cannot use:\n#{src}\nas a dict key, since it's not an expression."
+ compile_error tree[1],
+ "Cannot use:\n%s\nas a dict key, since it's not an expression."
value_lua = value and @tree_to_lua(value) or Lua.Value(key.source, "true")
unless value_lua.is_value
- _report_error tree[2], (src)->
- "Cannot use:\n#{src}\nas a dict value, since it's not an expression."
+ compile_error tree[2],
+ "Cannot use:\n%s\nas a dict value, since it's not an expression."
key_str = tostring(key_lua)\match([=[["']([a-zA-Z_][a-zA-Z0-9_]*)['"]]=])
return if key_str
Lua tree.source, key_str,"=",value_lua
@@ -641,8 +645,8 @@ class NomsuCompiler
when "IndexChain"
lua = @tree_to_lua(tree[1])
unless lua.is_value
- _report_error tree[1], (src)->
- "Cannot index:\n#{src}\nsince it's not an expression."
+ compile_error tree[1],
+ "Cannot index:\n%s\nsince it's not an expression."
first_char = tostring(lua)\sub(1,1)
if first_char == "{" or first_char == '"' or first_char == "["
lua\parenthesize!
@@ -651,8 +655,8 @@ class NomsuCompiler
key = tree[i]
key_lua = @tree_to_lua(key)
unless key_lua.is_value
- _report_error key, (src)->
- "Cannot use:\n#{key}\nas an index, since it's not an expression."
+ compile_error key,
+ "Cannot use:\n%s\nas an index, since it's not an expression."
key_lua_str = tostring(key_lua)
if lua_id = key_lua_str\match("^['\"]([a-zA-Z_][a-zA-Z0-9_]*)['\"]$")
lua\append ".#{lua_id}"
@@ -927,8 +931,8 @@ class NomsuCompiler
else
bit_lua = nomsu\tree_to_lua(bit)
unless bit_lua.is_value
- _report_error bit, (src)->
- "Cannot use:\n#{src}\nas a string interpolation value, since it's not an expression."
+ compile_error bit,
+ "Cannot use:\n%s\nas a string interpolation value, since it's not an expression."
lua\append bit_lua
@define_compile_action "Lua %code", (_code)=>
@@ -950,8 +954,8 @@ class NomsuCompiler
else
bit_lua = nomsu\tree_to_lua(bit)
unless bit_lua.is_value
- _report_error bit, (src)->
- "Cannot use:\n#{src}\nas a string interpolation value, since it's not an expression."
+ compile_error bit,
+ "Cannot use:\n%s\nas a string interpolation value, since it's not an expression."
lua\append bit_lua
return lua
@@ -966,10 +970,9 @@ class NomsuCompiler
return add_lua_bits(Lua.Value(@source), _code)
@define_compile_action "use %path", (_path)=>
- path = if _path.type == 'Text' and #_path == 1 and type(_path[1]) == 'string'
- _path[1]
- else
- nomsu\run_lua Lua(_path.source, "return ",nomsu\tree_to_lua(_path))
+ unless _path.type == 'Text' and #_path == 1 and type(_path[1]) == 'string'
+ return Lua(_path.source, "nomsu:run_file(#{nomsu\tree_to_lua(_path)});")
+ path = _path[1]
nomsu\run_file(path)
return Lua(_path.source, "nomsu:run_file(#{repr path});")
diff --git a/nomsu.peg b/nomsu.peg
index cab5dfb..ec40211 100644
--- a/nomsu.peg
+++ b/nomsu.peg
@@ -16,7 +16,7 @@ noindex_inline_expression:
number / variable / inline_text / inline_list / inline_dict / inline_nomsu
/ ( "("
%ws* (inline_block / inline_action / inline_expression) %ws*
- (comma %ws* (inline_block / inline_action / inline_expression) %ws*)*
+ (%ws* ',' %ws* (inline_block / inline_action / inline_expression) %ws*)*
(")"
/ (({} ((!. / &%nl) -> 'Line ended without finding a closing )-parenthesis') %userdata) => error)
/ (({} ([^%nl]* -> 'Unexpected character while parsing subexpression') %userdata) => error)
@@ -47,17 +47,21 @@ indented_nomsu (EscapedNomsu):
index_chain (IndexChain):
{| noindex_inline_expression ("." (text_word / noindex_inline_expression))+ |}
--- Actions need at least one word in them
+-- Actions need either at least 1 word, or at least 2 tokens
inline_action (Action):
{|
- (inline_expression %ws*)* word (%ws* (inline_expression / word))*
+ ( (inline_expression (%ws* (inline_expression / word))+)
+ / (word (%ws* (inline_expression / word))*))
(%ws* ":" %ws* (inline_block / inline_action / inline_expression
/ (({} ('' -> "Missing expression after the ':'") %userdata) => error)))?
|}
action (Action):
- {| (expression (dotdot? %ws*))* word ((dotdot? %ws*) (expression / word))* |}
+ {|
+ (expression ((nodent "..")? %ws* (expression / word))+)
+ / (word ((nodent "..")? %ws* (expression / word))*)
+ |}
-word: { %operator_char+ / (!number %ident_char+) }
+word: !number { %operator_char+ / %ident_char+ }
text_word (Text): {| word |}
@@ -84,7 +88,7 @@ inline_text_interpolation:
variable / inline_list / inline_dict / inline_text
/ ("("
%ws* (inline_block / inline_action / inline_expression) %ws*
- (comma %ws* (inline_block / inline_action / inline_expression) %ws*)*
+ (%ws* ',' %ws* (inline_block / inline_action / inline_expression) %ws*)*
(")"
/ (({} (&%nl -> 'Line ended without finding a closing )-parenthesis') %userdata) => error)
/ (({} ([^%nl]* -> 'Unexpected character while parsing Text interpolation') %userdata) => error))
@@ -103,7 +107,7 @@ variable (Var): "%" { (%ident_char+ ((!"'" %operator_char+) / %ident_char+)*)? }
inline_list (List):
!('[..]')
"[" %ws*
- {| (inline_list_item (comma inline_list_item)* comma?)? |} %ws*
+ {| (inline_list_item (%ws* ',' %ws* inline_list_item)* (%ws* ',')?)? |} %ws*
("]" / (","? (
(({} (eol->"Line ended before finding a closing ]-bracket") %userdata) => error)
/(({} ([^%nl]*->"Unexpected character while parsing List") %userdata) => error)
@@ -113,14 +117,14 @@ indented_list (List):
{| list_line (nodent list_line)* |}
(dedent / ((","? {} (non_dedent_error -> "Unexpected character while parsing List") %userdata) => error))
list_line:
- ((action / expression) !comma)
- / (inline_list_item (comma list_line?)?)
+ ((action / expression) !(%ws* ','))
+ / (inline_list_item ((%ws* ',' %ws*) list_line?)?)
inline_list_item: inline_block / inline_action / inline_expression
inline_dict (Dict):
!('{..}')
"{" %ws*
- {| (inline_dict_entry (comma inline_dict_entry)*)? |} %ws*
+ {| (inline_dict_entry (%ws* ',' %ws* inline_dict_entry)*)? |} %ws*
("}" / (","? (
(({} (%ws* eol->"Line ended before finding a closing }-brace") %userdata) => error)
/ (({} ([^%nl]*->"Unexpected character while parsing Dictionary") %userdata) => error)
@@ -130,7 +134,7 @@ indented_dict (Dict):
{| dict_line (nodent dict_line)* |}
(dedent / ((","? {} (non_dedent_error -> "Unexpected character while parsing Dictionary") %userdata) => error))
dict_line:
- (dict_entry !comma) / (inline_dict_entry (comma dict_line?)?)
+ (dict_entry !(%ws* ',')) / (inline_dict_entry (%ws* ',' %ws dict_line?)?)
dict_entry(DictEntry):
{| dict_key (%ws* ":" %ws* (action / expression))? |}
inline_dict_entry(DictEntry):
@@ -147,5 +151,3 @@ indent: eol (%nl ignored_line)* %nl %indent (comment (%nl ignored_line)* nodent)
nodent: eol (%nl ignored_line)* %nl %nodent
dedent: eol (%nl ignored_line)* (((!.) %dedent) / (&(%nl %dedent)))
non_dedent_error: (!dedent .)* eol (%nl ignored_line)* (!. / &%nl)
-comma: %ws* "," %ws*
-dotdot: nodent ".."
diff --git a/nomsu_tree.lua b/nomsu_tree.lua
index de021eb..f1b6489 100644
--- a/nomsu_tree.lua
+++ b/nomsu_tree.lua
@@ -36,18 +36,6 @@ Tree = function(name, fields, methods)
return source, ...
end
methods.is_multi = is_multi
- methods.map = function(self, fn)
- if type(fn) == 'table' then
- if not (next(fn)) then
- return self
- end
- local _replacements = fn
- fn = function(k)
- return _replacements[k]
- end
- end
- return self:_map(fn)
- end
if is_multi then
methods.__tostring = function(self)
return tostring(self.name) .. "(" .. tostring(table.concat((function()
@@ -61,11 +49,11 @@ Tree = function(name, fields, methods)
return _accum_0
end)(), ', ')) .. ")"
end
- methods._map = function(self, fn)
+ methods.map = function(self, fn)
do
- local ret = fn(self)
- if ret then
- return ret
+ local replacement = fn(self)
+ if replacement then
+ return replacement
end
end
local new_vals
@@ -74,19 +62,18 @@ Tree = function(name, fields, methods)
local _len_0 = 1
for _index_0 = 1, #self do
local v = self[_index_0]
- _accum_0[_len_0] = v._map and v:_map(fn) or v
+ _accum_0[_len_0] = v.map and v:map(fn) or v
_len_0 = _len_0 + 1
end
new_vals = _accum_0
end
- local ret = getmetatable(self)(self.source, unpack(new_vals))
- return ret
+ return getmetatable(self)(self.source, unpack(new_vals))
end
else
methods.__tostring = function(self)
return tostring(self.name) .. "(" .. tostring(repr(self.value)) .. ")"
end
- methods._map = function(self, fn)
+ methods.map = function(self, fn)
return fn(self) or self
end
end
diff --git a/nomsu_tree.moon b/nomsu_tree.moon
index fe365c2..3339606 100644
--- a/nomsu_tree.moon
+++ b/nomsu_tree.moon
@@ -27,23 +27,16 @@ Tree = (name, fields, methods)->
--assert Source\is_instance(source)
return source, ...
.is_multi = is_multi
- .map = (fn)=>
- if type(fn) == 'table'
- return @ unless next(fn)
- _replacements = fn
- fn = (k)-> _replacements[k]
- return @_map(fn)
if is_multi
.__tostring = => "#{@name}(#{table.concat [repr(v) for v in *@], ', '})"
- ._map = (fn)=>
- if ret = fn(@)
- return ret
- new_vals = [v._map and v\_map(fn) or v for v in *@]
- ret = getmetatable(self)(@source, unpack(new_vals))
- return ret
+ .map = (fn)=>
+ if replacement = fn(@)
+ return replacement
+ new_vals = [v.map and v\map(fn) or v for v in *@]
+ return getmetatable(self)(@source, unpack(new_vals))
else
.__tostring = => "#{@name}(#{repr(@value)})"
- ._map = (fn)=>
+ .map = (fn)=>
fn(@) or @
Types[name] = immutable fields, methods