aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nomsu.lua75
-rwxr-xr-xnomsu.moon61
-rw-r--r--nomsu.peg47
-rw-r--r--nomsu_tree.lua24
-rw-r--r--nomsu_tree.moon20
5 files changed, 156 insertions, 71 deletions
diff --git a/nomsu.lua b/nomsu.lua
index 742fbea..f5f0481 100644
--- a/nomsu.lua
+++ b/nomsu.lua
@@ -173,21 +173,29 @@ do
return start + #nodent
end
end)
- _with_0.error = function(src, pos, err_msg)
- if src:sub(pos, pos):match("[\r\n]") then
- pos = pos + #src:match("[ \t\n\r]*", pos)
+ _with_0.error = function(src, end_pos, start_pos, err_msg)
+ local seen_errors = lpeg.userdata.errors
+ if seen_errors[start_pos] then
+ return true
end
- local line_no = 1
- local text_loc = lpeg.userdata.source_code.source:sub(pos, pos)
- line_no = text_loc:get_line_number()
+ local err_pos = start_pos
+ local text_loc = lpeg.userdata.source_code.source:sub(err_pos, err_pos)
+ local line_no = text_loc:get_line_number()
src = FILE_CACHE[text_loc.filename]
- local prev_line = src:sub(LINE_STARTS[src][line_no - 1] or 1, LINE_STARTS[src][line_no] - 2)
+ local prev_line = line_no == 1 and "" or src:sub(LINE_STARTS[src][line_no - 1] or 1, LINE_STARTS[src][line_no] - 2)
local err_line = src:sub(LINE_STARTS[src][line_no], (LINE_STARTS[src][line_no + 1] or 0) - 2)
local next_line = src:sub(LINE_STARTS[src][line_no + 1] or -1, (LINE_STARTS[src][line_no + 2] or 0) - 2)
- local pointer = ("-"):rep(pos - LINE_STARTS[src][line_no]) .. "^"
- err_msg = (err_msg or "Parse error") .. " in " .. tostring(lpeg.userdata.source_code.source.filename) .. " on line " .. tostring(line_no) .. ":\n"
- err_msg = err_msg .. "\n" .. tostring(prev_line) .. "\n" .. tostring(err_line) .. "\n" .. tostring(pointer) .. "\n" .. tostring(next_line) .. "\n"
- return error(err_msg)
+ local pointer = ("-"):rep(err_pos - LINE_STARTS[src][line_no]) .. "^"
+ err_msg = (err_msg or "Parse error") .. " at " .. tostring(lpeg.userdata.source_code.source.filename) .. ":" .. tostring(line_no) .. ":\n"
+ if #prev_line > 0 then
+ err_msg = err_msg .. ("\n" .. prev_line)
+ end
+ err_msg = err_msg .. "\n" .. tostring(err_line) .. "\n" .. tostring(pointer)
+ if #next_line > 0 then
+ err_msg = err_msg .. ("\n" .. next_line)
+ end
+ seen_errors[start_pos] = err_msg
+ return true
end
NOMSU_DEFS = _with_0
end
@@ -350,13 +358,30 @@ do
source_code = nomsu_code,
indent_stack = {
""
- }
+ },
+ errors = { }
}
local old_userdata
old_userdata, lpeg.userdata = lpeg.userdata, userdata
local tree = NOMSU_PATTERN:match(tostring(nomsu_code))
lpeg.userdata = old_userdata
assert(tree, "In file " .. tostring(colored.blue(filename)) .. " failed to parse:\n" .. tostring(colored.onyellow(colored.black(nomsu_code))))
+ if next(userdata.errors) then
+ local keys = utils.keys(userdata.errors)
+ table.sort(keys)
+ local errors
+ do
+ local _accum_0 = { }
+ local _len_0 = 1
+ for _index_0 = 1, #keys do
+ local k = keys[_index_0]
+ _accum_0[_len_0] = userdata.errors[k]
+ _len_0 = _len_0 + 1
+ end
+ errors = _accum_0
+ end
+ error(concat(errors, "\n\n"), 0)
+ end
return tree
end,
run = function(self, nomsu_code, compile_fn)
@@ -950,7 +975,7 @@ do
end
if arg and debug_getinfo(2).func ~= require then
colors = require('consolecolors')
- local parser = re.compile([[ args <- {| (flag ";")* {:inputs: {| ({file} ";")* |} :} |} ";"? !.
+ local parser = re.compile([[ args <- {| (flag ";")* {:inputs: {| ({file} ";")* |} :} {:nomsu_args: {| ("--;" ({[^;]*} ";")*)? |} :} ";"? |} !.
flag <-
{:interactive: ("-i" -> true) :}
/ {:verbose: ("-v" -> true) :}
@@ -971,7 +996,7 @@ if arg and debug_getinfo(2).func ~= require then
if not args or args.help then
print([=[Nomsu Compiler
-Usage: (lua nomsu.lua | moon nomsu.moon) [-i] [-O] [-f] [-s] [--help] [-o output] [-p print_file] file1 file2...
+Usage: (lua nomsu.lua | moon nomsu.moon) [-i] [-O] [-f] [-s] [--help] [-o output] [-p print_file] file1 file2... [-- nomsu args...]
OPTIONS
-i Run the compiler in interactive mode (REPL)
@@ -987,6 +1012,7 @@ OPTIONS
os.exit()
end
local nomsu = NomsuCompiler()
+ nomsu.environment.arg = args.nomsu_args
local ok, to_lua = pcall(function()
return require('moonscript.base').to_lua
end)
@@ -1177,16 +1203,20 @@ OPTIONS
return output_file:flush()
end
end
+ local parse_errs = { }
local _list_0 = args.inputs
for _index_0 = 1, #_list_0 do
local input = _list_0[_index_0]
if args.syntax then
for input_file in all_files(input) do
- nomsu:parse(io.open(input_file):read("*a"))
- end
- if print_file then
- print_file:write("All files parsed successfully!\n")
- print_file:flush()
+ local err
+ ok, err = pcall(nomsu.parse, nomsu, Nomsu(input_file, io.open(input_file):read("*a")))
+ if not ok then
+ insert(parse_errs, err)
+ elseif print_file then
+ print_file:write("Parse succeeded: " .. tostring(input_file) .. "\n")
+ print_file:flush()
+ end
end
elseif args.format then
for input_file in all_files(input) do
@@ -1207,6 +1237,13 @@ OPTIONS
nomsu:run_file(input, compile_fn)
end
end
+ if #parse_errs > 0 then
+ io.stderr:write(concat(parse_errs, "\n\n"))
+ io.stderr:flush()
+ os.exit(false, true)
+ elseif args.syntax then
+ os.exit(true, true)
+ end
if args.interactive then
while true do
io.write(colored.bright(colored.yellow(">> ")))
diff --git a/nomsu.moon b/nomsu.moon
index 2dca565..81448aa 100755
--- a/nomsu.moon
+++ b/nomsu.moon
@@ -155,21 +155,27 @@ NOMSU_DEFS = with {}
if @sub(start, start+#nodent-1) == nodent
return start + #nodent
- .error = (src,pos,err_msg)->
- --src = tostring(FILE_CACHE[lpeg.userdata.source_code.source.filename])
- if src\sub(pos,pos)\match("[\r\n]")
- pos += #src\match("[ \t\n\r]*", pos)
- line_no = 1
- text_loc = lpeg.userdata.source_code.source\sub(pos,pos)
+ .error = (src,end_pos,start_pos,err_msg)->
+ seen_errors = lpeg.userdata.errors
+ if seen_errors[start_pos]
+ return true
+ err_pos = start_pos
+ --if src\sub(err_pos,err_pos)\match("[\r\n]")
+ -- err_pos += #src\match("[ \t\n\r]*", err_pos)
+ text_loc = lpeg.userdata.source_code.source\sub(err_pos,err_pos)
line_no = text_loc\get_line_number!
src = FILE_CACHE[text_loc.filename]
- prev_line = src\sub(LINE_STARTS[src][line_no-1] or 1, LINE_STARTS[src][line_no]-2)
+ prev_line = line_no == 1 and "" or src\sub(LINE_STARTS[src][line_no-1] or 1, LINE_STARTS[src][line_no]-2)
err_line = src\sub(LINE_STARTS[src][line_no], (LINE_STARTS[src][line_no+1] or 0)-2)
next_line = src\sub(LINE_STARTS[src][line_no+1] or -1, (LINE_STARTS[src][line_no+2] or 0)-2)
- pointer = ("-")\rep(pos-LINE_STARTS[src][line_no]) .. "^"
- err_msg = (err_msg or "Parse error").." in #{lpeg.userdata.source_code.source.filename} on line #{line_no}:\n"
- err_msg ..="\n#{prev_line}\n#{err_line}\n#{pointer}\n#{next_line}\n"
- error(err_msg)
+ pointer = ("-")\rep(err_pos-LINE_STARTS[src][line_no]) .. "^"
+ err_msg = (err_msg or "Parse error").." at #{lpeg.userdata.source_code.source.filename}:#{line_no}:\n"
+ if #prev_line > 0 then err_msg ..= "\n"..prev_line
+ err_msg ..= "\n#{err_line}\n#{pointer}"
+ if #next_line > 0 then err_msg ..= "\n"..next_line
+ --error(err_msg)
+ seen_errors[start_pos] = err_msg
+ return true
setmetatable(NOMSU_DEFS, {__index:(key)=>
make_node = (start, value, stop)->
@@ -279,7 +285,6 @@ class NomsuCompiler
-- TODO: repair
error("Not currently functional.", 0)
- -- TODO: figure out whether indent/dedent should affect first line
dedent: (code)=>
unless code\find("\n")
return code
@@ -307,7 +312,7 @@ class NomsuCompiler
FILE_CACHE[filename] = nomsu_code
nomsu_code = Nomsu(filename, nomsu_code)
userdata = {
- source_code:nomsu_code, indent_stack: {""}
+ source_code:nomsu_code, indent_stack: {""}, errors: {},
}
old_userdata, lpeg.userdata = lpeg.userdata, userdata
@@ -315,6 +320,13 @@ class NomsuCompiler
lpeg.userdata = old_userdata
assert tree, "In file #{colored.blue filename} failed to parse:\n#{colored.onyellow colored.black nomsu_code}"
+
+ if next(userdata.errors)
+ keys = utils.keys(userdata.errors)
+ table.sort(keys)
+ errors = [userdata.errors[k] for k in *keys]
+ error(concat(errors, "\n\n"), 0)
+
return tree
_nomsu_chunk_counter = 0
@@ -663,7 +675,7 @@ if arg and debug_getinfo(2).func != require
export colors
colors = require 'consolecolors'
parser = re.compile([[
- args <- {| (flag ";")* {:inputs: {| ({file} ";")* |} :} |} ";"? !.
+ args <- {| (flag ";")* {:inputs: {| ({file} ";")* |} :} {:nomsu_args: {| ("--;" ({[^;]*} ";")*)? |} :} ";"? |} !.
flag <-
{:interactive: ("-i" -> true) :}
/ {:verbose: ("-v" -> true) :}
@@ -681,7 +693,7 @@ if arg and debug_getinfo(2).func != require
print [=[
Nomsu Compiler
-Usage: (lua nomsu.lua | moon nomsu.moon) [-i] [-O] [-f] [-s] [--help] [-o output] [-p print_file] file1 file2...
+Usage: (lua nomsu.lua | moon nomsu.moon) [-i] [-O] [-f] [-s] [--help] [-o output] [-p print_file] file1 file2... [-- nomsu args...]
OPTIONS
-i Run the compiler in interactive mode (REPL)
@@ -697,6 +709,7 @@ OPTIONS
os.exit!
nomsu = NomsuCompiler!
+ nomsu.environment.arg = args.nomsu_args
ok, to_lua = pcall -> require('moonscript.base').to_lua
if not ok then to_lua = nil
@@ -820,14 +833,17 @@ OPTIONS
output_file\write("local IMMEDIATE = true;\n"..tostring(code))
output_file\flush!
+ parse_errs = {}
for input in *args.inputs
if args.syntax
-- Check syntax:
for input_file in all_files(input)
- nomsu\parse(io.open(input_file)\read("*a"))
- if print_file
- print_file\write("All files parsed successfully!\n")
- print_file\flush!
+ ok,err = pcall nomsu.parse, nomsu, Nomsu(input_file, io.open(input_file)\read("*a"))
+ if not ok
+ insert parse_errs, err
+ elseif print_file
+ print_file\write("Parse succeeded: #{input_file}\n")
+ print_file\flush!
elseif args.format
-- Auto-format
for input_file in all_files(input)
@@ -844,6 +860,13 @@ OPTIONS
else
nomsu\run_file(input, compile_fn)
+ if #parse_errs > 0
+ io.stderr\write concat(parse_errs, "\n\n")
+ io.stderr\flush!
+ os.exit(false, true)
+ elseif args.syntax
+ os.exit(true, true)
+
if args.interactive
-- REPL
while true
diff --git a/nomsu.peg b/nomsu.peg
index 7f6cbf6..82886d3 100644
--- a/nomsu.peg
+++ b/nomsu.peg
@@ -1,13 +1,15 @@
file (File):
{| shebang?
(ignored_line %nl)*
- statement (nodent statement)*
+ statement ((nodent (statement / (({} ([^%nl]* -> "Error while parsing line")) => error)))
+ / (({} ((%nl %dedent) ->"Indentation error")) => error))*
(%nl ignored_line)*
- (!. / (("" -> "Parse error") => error)?) |} -> Tuple
+ |} -> Tuple
+ (!. / (({} (.* -> "Parse error")) => error))
shebang: "#!" [^%nl]* (!. / %nl)
-statement: action / expression
+statement: (action / expression) (eol / (({} ([^%nl]* -> "Error while parsing line")) => error))
inline_statement: inline_action / inline_expression
inline_block (Block):
@@ -24,16 +26,20 @@ index_chain (IndexChain):
noindex_inline_expression:
number / variable / inline_text / inline_list / inline_dict / inline_nomsu
- / ("(" %ws* (inline_block / inline_action / inline_expression) %ws* ")")
+ / (
+ "(" %ws* (inline_block / inline_action / inline_expression) %ws*
+ (")"
+ / (({} ((!. / &%nl) -> 'Expected to find a ) before the end of the line')) => error)
+ / (({} ([^%nl]* -> 'Error while parsing subexpression')) => error))
+ )
inline_expression:
index_chain / noindex_inline_expression
indented_expression:
indented_text / indented_nomsu / indented_list / indented_dict
/ ("(..)"? indent
- (action dedent
- / expression dedent
- / block (dedent / (("" -> "Error while parsing indented expression") => error)))
+ (block / action / expression)
+ (dedent / (({} (non_dedent_error -> "Error while parsing indented expression")) => error))
)
expression:
inline_expression / (":" %ws* (inline_block / inline_action / inline_expression) eol) / indented_expression
@@ -52,7 +58,8 @@ inline_text (Text):
'"' ({|
({~ (('\"' -> '"') / ('\\' -> '\') / %escaped_char / [^%nl\"])+ ~}
/ inline_text_interpolation)*
- |} -> Tuple) '"'
+ |} -> Tuple) ('"' / (({} ([^%nl]*->'Failed to find a closing " mark on the same line')) => error))
+
-- Have to use "%indent" instead of "indent" etc. to avoid messing up text lines that start with "#"
indented_text (Text):
'".."' eol %nl ({|
@@ -60,11 +67,16 @@ indented_text (Text):
({~
(("\\" -> "\") / (("\" nodent "..") -> "")/ (%nl+ {~ %nodent -> "" ~}) / [^%nl\] / (!text_interpolation "\"))+
~} / text_interpolation)*
- |} -> Tuple) (((!.) &%dedent) / (&(%nl %dedent)) / (("" -> "Error while parsing Text") => error))
+ |} -> Tuple) (((!.) &%dedent) / (&(%nl %dedent)) / (({} (non_dedent_error -> "Error while parsing Text")) => error))
inline_text_interpolation:
"\" (
variable / inline_list / inline_dict / inline_text
- / ("(" %ws* (inline_block / inline_action / inline_expression) %ws* ")")
+ / ("("
+ %ws* (inline_block / inline_action / inline_expression) %ws*
+ (")"
+ / (({} (&%nl -> 'Expected to find a ")" before the end of the line')) => error)
+ / (({} ([^%nl]* -> 'Error while parsing text interpolation')) => error))
+ )
)
text_interpolation:
inline_text_interpolation /
@@ -78,12 +90,13 @@ variable (Var): "%" { plain_word? }
inline_list (List):
!('[..]')
- "[" %ws* ({| (inline_list_item (comma inline_list_item)* comma?)? |} -> Tuple) %ws* "]"
+ "[" %ws* ({| (inline_list_item (comma inline_list_item)* comma?)? |} -> Tuple) %ws*
+ ("]" / (({} ([^%nl]*->"Failed to find a closing ] on the same line")) => error))
indented_list (List):
"[..]" indent ({|
list_line (nodent list_line)*
|} -> Tuple)
- (dedent / (("" -> "Error while parsing list") => error))
+ (dedent / (({} (non_dedent_error -> "Error while parsing list")) => error))
list_line:
((action / expression) !comma)
/ (inline_list_item (comma list_line?)?)
@@ -91,17 +104,20 @@ inline_list_item: inline_block / inline_action / inline_expression
inline_dict (Dict):
!('{..}')
- "{" %ws* ({| (inline_dict_item (comma inline_dict_item)* comma?)? |} -> Tuple) %ws* "}"
+ "{" %ws* ({| (inline_dict_item (comma inline_dict_item)*)? |} -> Tuple) %ws*
+ ("}"
+ / (({} (%ws* comma? (!. / &%nl)->"Failed to find a closing } on the same line")) => error)
+ / (({} ([^%nl]*->"Error while parsing dictionary")) => error))
indented_dict (Dict):
"{..}" indent ({|
dict_line (nodent dict_line)*
|} -> Tuple)
- (dedent / (("" -> "Error while parsing dict") => error))
+ (dedent / (({} (non_dedent_error -> "Error while parsing dict")) => error))
dict_line:
((dict_key %ws* ":" %ws* (action / expression)) -> DictEntry !comma)
/ (inline_dict_item (comma dict_line?)?)
inline_dict_item:
- (dict_key %ws* ":" %ws* (inline_block / inline_action / inline_expression)) -> DictEntry
+ ((dict_key %ws* (":" %ws* (inline_block / inline_action / inline_expression)?)?)-> DictEntry)
dict_key:
(({} ({|{%operator / (!number plain_word)}|} -> Tuple) {}) -> Text) / inline_expression
@@ -113,6 +129,7 @@ ignored_line: (%nodent (block_comment / line_comment)) / (%ws* (!. / &%nl))
indent: eol (%nl ignored_line)* %nl %indent ((block_comment/line_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 ".." %ws*
plain_word: ([a-zA-Z0-9_] / %utf8_char)+
diff --git a/nomsu_tree.lua b/nomsu_tree.lua
index cba4fed..817c325 100644
--- a/nomsu_tree.lua
+++ b/nomsu_tree.lua
@@ -153,7 +153,7 @@ Tree("Block", {
return nomsu
end
})
-local math_expression = re.compile([[ "%" (" " [*/^+-] " %")+ !. ]])
+local math_expression = re.compile([[ ([+-] " ")* "%" (" " [*/^+-] (" " [+-])* " %")+ !. ]])
Tree("Action", {
as_lua = function(self, nomsu)
local stub = self:get_stub()
@@ -502,7 +502,7 @@ Tree("List", {
end
if i < #self.value then
if line_length >= MAX_LINE then
- lua:append(",\n")
+ lua:append(",\n ")
line_length = 0
else
lua:append(", ")
@@ -578,7 +578,7 @@ Tree("Dict", {
local line, src = key.source:get_line(), key.source:get_text()
error(tostring(line) .. ": Cannot use " .. tostring(colored.yellow(src)) .. " as a dict key, since it's not an expression.", 0)
end
- local value_lua = entry.value:as_lua(nomsu)
+ local value_lua = entry.value and entry.value:as_lua(nomsu) or Lua.Value(entry.key.source, "true")
if not (value_lua.is_value) then
local line, src = value.source:get_line(), value.source:get_text()
error(tostring(line) .. ": Cannot use " .. tostring(colored.yellow(src)) .. " as a dict value, since it's not an expression.", 0)
@@ -599,7 +599,7 @@ Tree("Dict", {
end
if i < #self.value then
if line_length >= MAX_LINE then
- lua:append(",\n")
+ lua:append(",\n ")
line_length = 0
else
lua:append(", ")
@@ -624,7 +624,7 @@ Tree("Dict", {
if entry.key.type == "Action" or entry.key.type == "Block" then
key_nomsu:parenthesize()
end
- local value_nomsu = entry.value:as_nomsu(true)
+ local value_nomsu = entry.value and entry.value:as_nomsu(true) or Nomsu(entry.key.source, "")
if not (value_nomsu) then
return nil
end
@@ -652,12 +652,15 @@ Tree("Dict", {
if entry.key.type == "Action" or entry.key.type == "Block" then
key_nomsu:parenthesize()
end
- local value_nomsu = entry.value:as_nomsu(true)
+ local value_nomsu = entry.value and entry.value:as_nomsu(true) or Nomsu(entry.key.source, "")
if value_nomsu and #line + #", " + #key_nomsu + #":" + #value_nomsu <= MAX_LINE then
if #line.bits > 1 then
line:append(", ")
end
- line:append(key_nomsu, ":", value_nomsu)
+ line:append(key_nomsu)
+ if entry.value then
+ line:append(":", value_nomsu)
+ end
else
if not (value_nomsu) then
value_nomsu = entry.value:as_nomsu()
@@ -669,7 +672,10 @@ Tree("Dict", {
nomsu:append(line)
line = Nomsu(bit.source, "\n ")
end
- line:append(key_nomsu, ":", value_nomsu)
+ line:append(key_nomsu)
+ if entry.value then
+ line:append(":", value_nomsu)
+ end
end
end
if #line.bits > 1 then
@@ -694,7 +700,7 @@ Tree("IndexChain", {
local _continue_0 = false
repeat
local key = self.value[i]
- if key.type == 'Text' and #key.value == 1 and type(key.value[1]) == 'string' and key.value[1]:match("^[a-zA-Z_][a-zA-Z0-9_]$") then
+ if key.type == 'Text' and #key.value == 1 and type(key.value[1]) == 'string' and key.value[1]:match("^[a-zA-Z_][a-zA-Z0-9_]*$") then
lua:append("." .. tostring(key.value[1]))
_continue_0 = true
break
diff --git a/nomsu_tree.moon b/nomsu_tree.moon
index 00b21c9..0119490 100644
--- a/nomsu_tree.moon
+++ b/nomsu_tree.moon
@@ -103,7 +103,7 @@ Tree "Block",
nomsu\append "\n"
return nomsu
-math_expression = re.compile [[ "%" (" " [*/^+-] " %")+ !. ]]
+math_expression = re.compile [[ ([+-] " ")* "%" (" " [*/^+-] (" " [+-])* " %")+ !. ]]
Tree "Action",
as_lua: (nomsu)=>
stub = @get_stub!
@@ -313,7 +313,7 @@ Tree "List",
line_length += #last_line
if i < #@value
if line_length >= MAX_LINE
- lua\append ",\n"
+ lua\append ",\n "
line_length = 0
else
lua\append ", "
@@ -365,7 +365,7 @@ Tree "Dict",
unless key_lua.is_value
line, src = key.source\get_line!, key.source\get_text!
error "#{line}: Cannot use #{colored.yellow src} as a dict key, since it's not an expression.", 0
- value_lua = entry.value\as_lua(nomsu)
+ value_lua = entry.value and entry.value\as_lua(nomsu) or Lua.Value(entry.key.source, "true")
unless value_lua.is_value
line, src = value.source\get_line!, value.source\get_text!
error "#{line}: Cannot use #{colored.yellow src} as a dict value, since it's not an expression.", 0
@@ -388,7 +388,7 @@ Tree "Dict",
line_length += #last_line
if i < #@value
if line_length >= MAX_LINE
- lua\append ",\n"
+ lua\append ",\n "
line_length = 0
else
lua\append ", "
@@ -404,7 +404,7 @@ Tree "Dict",
return nil unless key_nomsu
if entry.key.type == "Action" or entry.key.type == "Block"
key_nomsu\parenthesize!
- value_nomsu = entry.value\as_nomsu(true)
+ value_nomsu = entry.value and entry.value\as_nomsu(true) or Nomsu(entry.key.source, "")
return nil unless value_nomsu
if i > 1
nomsu\append ", "
@@ -421,11 +421,12 @@ Tree "Dict",
return nil unless key_nomsu
if entry.key.type == "Action" or entry.key.type == "Block"
key_nomsu\parenthesize!
- value_nomsu = entry.value\as_nomsu(true)
+ value_nomsu = entry.value and entry.value\as_nomsu(true) or Nomsu(entry.key.source, "")
if value_nomsu and #line + #", " + #key_nomsu + #":" + #value_nomsu <= MAX_LINE
if #line.bits > 1
line\append ", "
- line\append key_nomsu,":",value_nomsu
+ line\append key_nomsu
+ if entry.value then line\append ":",value_nomsu
else
unless value_nomsu
value_nomsu = entry.value\as_nomsu!
@@ -433,7 +434,8 @@ Tree "Dict",
if #line.bits > 1
nomsu\append line
line = Nomsu(bit.source, "\n ")
- line\append key_nomsu,":",value_nomsu
+ line\append key_nomsu
+ if entry.value then line\append ":",value_nomsu
if #line.bits > 1
nomsu\append line
return nomsu
@@ -450,7 +452,7 @@ Tree "IndexChain",
for i=2,#@value
key = @value[i]
- if key.type == 'Text' and #key.value == 1 and type(key.value[1]) == 'string' and key.value[1]\match("^[a-zA-Z_][a-zA-Z0-9_]$")
+ if key.type == 'Text' and #key.value == 1 and type(key.value[1]) == 'string' and key.value[1]\match("^[a-zA-Z_][a-zA-Z0-9_]*$")
lua\append ".#{key.value[1]}"
continue
key_lua = key\as_lua(nomsu)