Switched from Node(Tuple(values...), source) to Node(source, values...),

thanks to support from immutable-tables for mixed tables.
This commit is contained in:
Bruce Hill 2018-06-04 17:56:09 -07:00
parent e7bdc35aa8
commit 563e415e07
8 changed files with 196 additions and 207 deletions

View File

@ -188,14 +188,14 @@ immediately
%body has subtree % where
(%.type = "Action") and
(%.stub is "do next %") and
%.value.3.value = %var.value
%.3.value = %var.value
..: to %lua write (Lua "\n ::continue_\(%var as lua identifier)::")
to %lua write "\nend --foreach-loop"
if
%body has subtree % where
(%.type = "Action") and
(%.stub is "stop %") and
%.value.2.value = %var.value
%.2.value = %var.value
..
%lua <-
Lua ".."
@ -222,14 +222,14 @@ immediately
%body has subtree % where
(%.type = "Action") and
(%.stub is "do next %") and
%.value.3.value = %key.value
%.3.value = %key.value
..: to %lua write (Lua "\n ::continue_\(%key as lua identifier)::")
if
%body has subtree % where
(%.type = "Action") and
(%.stub is "do next %") and
%.value.3.value = %value.value
%.3.value = %value.value
..: to %lua write (Lua "\n ::continue_\(%value as lua identifier)::")
to %lua write "\nend --foreach-loop"
@ -238,14 +238,14 @@ immediately
%body has subtree % where
(%.type = "Action") and
(%.stub is "stop %") and
%.value.2.value = %key.value
%.2.value = %key.value
..: to %stop_labels write "\n::stop_\(%key as lua identifier)::"
if
%body has subtree % where
(%.type = "Action") and
(%.stub is "stop %") and
%.value.2.value = %value.value
%.2.value = %value.value
..: to %stop_labels write "\n::stop_\(%value as lua identifier)::"
if: (length of %stop_labels) > 0
@ -265,14 +265,14 @@ immediately
%is_first <- (yes)
%seen_else <- (no)
%branches <-
%body.value if (%body.type = "Block") else [%body]
%body if (%body.type = "Block") else [%body]
for %func_call in %branches
assume (%func_call.type is "Action") or barf ".."
Invalid format for 'when' statement. Only '*' blocks are allowed.
with {..}
%star: %func_call.value.1
%condition: %func_call.value.2
%action: %func_call.value.3
%star: %func_call.1
%condition: %func_call.2
%action: %func_call.3
..
assume (%star = "*") or barf ".."
Invalid format for 'when' statement. Lines must begin with '*'
@ -313,11 +313,11 @@ immediately
%is_first <- (yes)
%seen_else <- (no)
%branches <-
%body.value if (%body.type = "Block") else [%body]
%body if (%body.type = "Block") else [%body]
for %func_call in %branches
assume (%func_call.type is "Action") or barf ".."
Invalid format for 'when' statement. Only '*' blocks are allowed.
with {%star:%func_call.value.1, %condition:%func_call.value.2, %action:%func_call.value.3}
with {%star:%func_call.1, %condition:%func_call.2, %action:%func_call.3}
assume (%star = "*") or barf ".."
Invalid format for 'when' statement. Lines must begin with '*'
assume %condition or barf ".."

View File

@ -42,7 +42,7 @@ compile [all of %items, all %items] to
unless: (%items' "type") is "List"
return: Lua value "utils.all(\(%items as lua expr))"
%clauses <- []
for % in %items.value
for % in %items
lua> "table.insert(\%clauses, \(% as lua expr));"
return: Lua value "(\(%clauses joined with " and "))"
parse [not all of %items, not all %items] as: not (all of %items)
@ -50,7 +50,7 @@ compile [any of %items, any %items] to
unless: (%items' "type") is "List"
return: Lua value "utils.any(\(%items as lua expr))"
%clauses <- []
for % in %items.value
for % in %items
lua> "table.insert(\%clauses, \(% as lua expr));"
return: Lua value "(\(%clauses joined with " or "))"
parse [none of %items, none %items] as: not (any of %items)
@ -58,14 +58,14 @@ compile [sum of %items, sum %items] to
unless: (%items' "type") is "List"
return: Lua value "utils.sum(\(%items as lua expr))"
%clauses <- []
for % in %items.value
for % in %items
lua> "table.insert(\%clauses, \(% as lua expr));"
return: Lua value "(\(%clauses joined with " + "))"
compile [product of %items, product %items] to
unless: (%items' "type") is "List"
return: Lua value "utils.product(\(%items as lua expr))"
%clauses <- []
for % in %items.value
for % in %items
lua> "table.insert(\%clauses, \(% as lua expr));"
return: Lua value "(\(%clauses joined with " * "))"
action [avg of %items, average of %items]

View File

@ -8,7 +8,7 @@ immediately
nomsu:define_compile_action("compile %actions to %lua", function(tree, \%actions, \%lua)
local lua = Lua(tree.source, "nomsu:define_compile_action(")
local specs = {}
for i, action in ipairs(\%actions.value) do
for i, action in ipairs(\%actions) do
specs[i] = action:get_spec()
end
specs = repr(specs)
@ -19,7 +19,7 @@ immediately
end
lua:append("function(tree")
local args = {}
for i,tok in ipairs(\%actions.value[1].value) do
for i,tok in ipairs(\%actions[1]) do
if tok.type == "Var" then args[#args+1] = tok end
end
for i, arg in ipairs(args) do
@ -38,7 +38,7 @@ immediately
lua> ".."
local lua = Lua(tree.source, "nomsu:define_action(")
local specs = {}
for i, action in ipairs(\%actions.value) do
for i, action in ipairs(\%actions) do
specs[i] = action:get_spec()
end
specs = repr(specs)
@ -49,7 +49,7 @@ immediately
end
lua:append("function(")
local args = {}
for i,tok in ipairs(\%actions.value[1].value) do
for i,tok in ipairs(\%actions[1]) do
if tok.type == "Var" then args[#args+1] = tok end
end
for i, arg in ipairs(args) do
@ -68,7 +68,7 @@ immediately
lua> ".."
local lua = Lua(tree.source, "nomsu:define_compile_action(")
local specs = {}
for i, action in ipairs(\%shorthand.value) do
for i, action in ipairs(\%shorthand) do
specs[i] = action:get_spec()
end
specs = repr(specs)
@ -79,7 +79,7 @@ immediately
end
lua:append("function(tree")
local replacements = {}
for i,tok in ipairs(\%shorthand.value[1].value) do
for i,tok in ipairs(\%shorthand[1]) do
if tok.type == "Var" then
local lua_var = tostring(nomsu:tree_to_lua(tok))
replacements[tok.value] = lua_var
@ -93,15 +93,15 @@ immediately
elseif t.type == 'Var' and replacements[t.value] then
return replacements[t.value]
elseif t.type == 'Var' then
return t.type.."("..repr(t.value.."#"..tostring(MANGLE_INDEX))..", "..repr(tostring(t.source))..")"
return t.type.."("..repr(tostring(t.source))..", "..repr(t.value.."#"..tostring(MANGLE_INDEX))..")"
elseif t.is_multi then
local bits = {}
for i, entry in ipairs(t.value) do
bits[i] = make_tree(entry)
local bits = {repr(tostring(t.source))}
for i, entry in ipairs(t) do
bits[#bits+1] = make_tree(entry)
end
return t.type.."(Tuple("..table.concat(bits, ", ").."), "..repr(tostring(t.source))..")"
return t.type.."("..table.concat(bits, ", ")..")"
else
return t.type.."("..repr(t.value)..", "..repr(tostring(t.source))..")"
return t.type.."("..repr(tostring(t.source))..", "..repr(t.value)..")"
end
end
lua:append(")\n local tree = ", make_tree(\%longhand), "\n return nomsu:tree_to_lua(tree)\nend);")

View File

@ -72,8 +72,8 @@ immediately
Expected a Dict for the assignments part of '<- %' statement, not \%assignments
lua> ".."
local lhs, rhs = Lua(tree.source), Lua(tree.source)
for i, item in ipairs(\%assignments.value) do
local \%target, \%value = item.value[1], item.value[2]
for i, item in ipairs(\%assignments) do
local \%target, \%value = item[1], item[2]
\%value = \%value:map(function(t)
if Action:is_instance(t) and t.stub == "?" then
return \%target
@ -105,7 +105,7 @@ immediately
compile [with external %externs %body] to
%body_lua <- (%body as lua statements)
lua> "\%body_lua:remove_free_vars(\%externs.value);"
lua> "\%body_lua:remove_free_vars(\%externs);"
return %body_lua
compile [with %assignments %body] to
@ -113,8 +113,8 @@ immediately
lua> ".."
local lhs, rhs = Lua(tree.source), Lua(tree.source)
local vars = {}
for i, item in ipairs(\%assignments.value) do
local \%target, \%value = item.value[1], item.value[2]
for i, item in ipairs(\%assignments) do
local \%target, \%value = item[1], item[2]
if not \%target.type == "Var" then
error("Invalid target for 'with' assignment: "..tostring(\%target))
end

View File

@ -233,9 +233,9 @@ setmetatable(NOMSU_DEFS, {
local source = userdata.source:sub(start, stop - 1)
local tree
if Types[key].is_multi then
tree = Types[key](Tuple(unpack(value)), source)
tree = Types[key](source, unpack(value))
else
tree = Types[key](value, source)
tree = Types[key](source, value)
end
return tree
end
@ -495,9 +495,8 @@ do
do
local _accum_0 = { }
local _len_0 = 1
local _list_0 = tree.value
for _index_0 = 1, #_list_0 do
local arg = _list_0[_index_0]
for _index_0 = 1, #tree do
local arg = tree[_index_0]
if type(arg) ~= "string" then
_accum_0[_len_0] = arg
_len_0 = _len_0 + 1
@ -525,7 +524,7 @@ do
local action = rawget(self.environment.ACTIONS, stub)
local lua = Lua.Value(tree.source)
if not action and math_expression:match(stub) then
for i, tok in ipairs(tree.value) do
for i, tok in ipairs(tree) do
if type(tok) == 'string' then
lua:append(tok)
else
@ -538,14 +537,14 @@ do
end
lua:append(tok_lua)
end
if i < #tree.value then
if i < #tree then
lua:append(" ")
end
end
return lua
end
local args = { }
for i, tok in ipairs(tree.value) do
for i, tok in ipairs(tree) do
local _continue_0 = false
repeat
if type(tok) == "string" then
@ -596,23 +595,22 @@ do
do
local _accum_0 = { }
local _len_0 = 1
local _list_0 = t.value
for _index_0 = 1, #_list_0 do
local bit = _list_0[_index_0]
for _index_0 = 1, #t do
local bit = t[_index_0]
_accum_0[_len_0] = make_tree(bit)
_len_0 = _len_0 + 1
end
bits = _accum_0
end
return t.type .. "(Tuple(" .. table.concat(bits, ", ") .. "), " .. repr(tostring(t.source)) .. ")"
return t.type .. "(" .. repr(tostring(t.source)) .. ", " .. table.concat(bits, ", ") .. ")"
else
return t.type .. "(" .. repr(t.value) .. ", " .. repr(tostring(t.source)) .. ")"
return t.type .. "(" .. repr(tostring(t.source)) .. ", " .. repr(t.value) .. ")"
end
end
return Lua.Value(tree.source, make_tree(tree.value[1]))
return Lua.Value(tree.source, make_tree(tree[1]))
elseif "Block" == _exp_0 then
local lua = Lua(tree.source)
for i, line in ipairs(tree.value) do
for i, line in ipairs(tree) do
local line_lua = self:tree_to_lua(line)
if i > 1 then
lua:append("\n")
@ -623,7 +621,7 @@ do
elseif "Text" == _exp_0 then
local lua = Lua.Value(tree.source)
local string_buffer = ""
for i, bit in ipairs(tree.value) do
for i, bit in ipairs(tree) do
local _continue_0 = false
repeat
if type(bit) == "string" then
@ -668,7 +666,7 @@ do
elseif "List" == _exp_0 then
local lua = Lua.Value(tree.source, "{")
local line_length = 0
for i, item in ipairs(tree.value) do
for i, item in ipairs(tree) do
local item_lua = self:tree_to_lua(item)
if not (item_lua.is_value) then
error("Cannot use " .. tostring(colored.yellow(repr(item))) .. " as a list item, since it's not an expression.", 0)
@ -681,7 +679,7 @@ do
else
line_length = line_length + #last_line
end
if i < #tree.value then
if i < #tree then
if line_length >= MAX_LINE then
lua:append(",\n ")
line_length = 0
@ -696,7 +694,7 @@ do
elseif "Dict" == _exp_0 then
local lua = Lua.Value(tree.source, "{")
local line_length = 0
for i, entry in ipairs(tree.value) do
for i, entry in ipairs(tree) do
local entry_lua = self:tree_to_lua(entry)
lua:append(entry_lua)
local entry_lua_str = tostring(entry_lua)
@ -706,7 +704,7 @@ do
else
line_length = line_length + #entry_lua_str
end
if i < #tree.value then
if i < #tree then
if line_length >= MAX_LINE then
lua:append(",\n ")
line_length = 0
@ -719,7 +717,7 @@ do
lua:append("}")
return lua
elseif "DictEntry" == _exp_0 then
local key, value = tree.value[1], tree.value[2]
local key, value = tree[1], tree[2]
local key_lua = self:tree_to_lua(key)
if not (key_lua.is_value) then
error("Cannot use " .. tostring(colored.yellow(repr(key))) .. " as a dict key, since it's not an expression.", 0)
@ -737,16 +735,16 @@ do
return Lua(tree.source, "[", key_lua, "]=", value_lua)
end
elseif "IndexChain" == _exp_0 then
local lua = self:tree_to_lua(tree.value[1])
local lua = self:tree_to_lua(tree[1])
if not (lua.is_value) then
error("Cannot index " .. tostring(colored.yellow(repr(tree.value[1]))) .. ", since it's not an expression.", 0)
error("Cannot index " .. tostring(colored.yellow(repr(tree[1]))) .. ", since it's not an expression.", 0)
end
local first_char = tostring(lua):sub(1, 1)
if first_char == "{" or first_char == '"' or first_char == "[" then
lua:parenthesize()
end
for i = 2, #tree.value do
local key = tree.value[i]
for i = 2, #tree do
local key = tree[i]
local key_lua = self:tree_to_lua(key)
if not (key_lua.is_value) then
error("Cannot use " .. tostring(colored.yellow(repr(key))) .. " as an index, since it's not an expression.", 0)
@ -783,7 +781,7 @@ do
if "Action" == _exp_0 then
if inline then
local nomsu = Nomsu(tree.source)
for i, bit in ipairs(tree.value) do
for i, bit in ipairs(tree) do
if type(bit) == "string" then
if i > 1 then
nomsu:append(" ")
@ -808,7 +806,7 @@ do
local nomsu = Nomsu(tree.source)
local next_space = ""
local last_colon = nil
for i, bit in ipairs(tree.value) do
for i, bit in ipairs(tree) do
if type(bit) == "string" then
nomsu:append(next_space, bit)
next_space = " "
@ -861,16 +859,16 @@ do
return nomsu
end
elseif "EscapedNomsu" == _exp_0 then
local nomsu = self:tree_to_nomsu(tree.value, true)
local nomsu = self:tree_to_nomsu(tree[1], true)
if nomsu == nil and not inline then
nomsu = self:tree_to_nomsu(tree.value[1])
nomsu = self:tree_to_nomsu(tree[1])
return nomsu and Nomsu(tree.source, "\\:\n ", nomsu)
end
return nomsu and Nomsu(tree.source, "\\(", nomsu, ")")
elseif "Block" == _exp_0 then
if inline then
local nomsu = Nomsu(tree.source)
for i, line in ipairs(tree.value) do
for i, line in ipairs(tree) do
if i > 1 then
nomsu:append("; ")
end
@ -897,9 +895,8 @@ do
elseif "Text" == _exp_0 then
if inline then
local nomsu = Nomsu(tree.source, '"')
local _list_0 = tree.value
for _index_0 = 1, #_list_0 do
local bit = _list_0[_index_0]
for _index_0 = 1, #tree do
local bit = tree[_index_0]
if type(bit) == 'string' then
nomsu:append((bit:gsub("\\", "\\\\"):gsub("\n", "\\n")))
else
@ -949,7 +946,7 @@ do
elseif "List" == _exp_0 then
if inline then
local nomsu = Nomsu(tree.source, "[")
for i, item in ipairs(tree.value) do
for i, item in ipairs(tree) do
local item_nomsu = self:tree_to_nomsu(item, true)
if not (item_nomsu) then
return nil
@ -968,9 +965,8 @@ do
end
local nomsu = Nomsu(tree.source, "[..]")
local line = Nomsu(tree.source, "\n ")
local _list_0 = tree.value
for _index_0 = 1, #_list_0 do
local item = _list_0[_index_0]
for _index_0 = 1, #tree do
local item = tree[_index_0]
local item_nomsu = self:tree_to_nomsu(item, true)
if item_nomsu and #line + #", " + #item_nomsu <= MAX_LINE then
if #line.bits > 1 then
@ -999,7 +995,7 @@ do
elseif "Dict" == _exp_0 then
if inline then
local nomsu = Nomsu(tree.source, "{")
for i, entry in ipairs(tree.value) do
for i, entry in ipairs(tree) do
local entry_nomsu = self:tree_to_nomsu(entry, true)
if not (entry_nomsu) then
return nil
@ -1018,9 +1014,8 @@ do
end
local nomsu = Nomsu(tree.source, "{..}")
local line = Nomsu(tree.source, "\n ")
local _list_0 = tree.value
for _index_0 = 1, #_list_0 do
local entry = _list_0[_index_0]
for _index_0 = 1, #tree do
local entry = tree[_index_0]
local entry_nomsu = self:tree_to_nomsu(entry)
if not (entry_nomsu) then
return nil
@ -1044,7 +1039,7 @@ do
return nomsu
end
elseif "DictEntry" == _exp_0 then
local key, value = tree.value[1], tree.value[2]
local key, value = tree[1], tree[2]
local key_nomsu = self:tree_to_nomsu(key, true)
if not (key_nomsu) then
return nil
@ -1073,7 +1068,7 @@ do
return Nomsu(tree.source, key_nomsu, ":", value_nomsu)
elseif "IndexChain" == _exp_0 then
local nomsu = Nomsu(tree.source)
for i, bit in ipairs(tree.value) do
for i, bit in ipairs(tree) do
if i > 1 then
nomsu:append(".")
end
@ -1091,11 +1086,6 @@ do
return Nomsu(tree.source, tostring(tree.value))
elseif "Var" == _exp_0 then
return Nomsu(tree.source, "%", tree.value)
elseif "Comment" == _exp_0 then
if inline then
return nil
end
return Nomsu(tree.source, "#", tree.value:gsub("\n", "\n "))
else
return error("Unknown type: " .. tostring(tree.type))
end
@ -1114,9 +1104,8 @@ do
lua:append(", ", nomsu:tree_to_lua(code))
return
end
local _list_0 = code.value
for _index_0 = 1, #_list_0 do
local bit = _list_0[_index_0]
for _index_0 = 1, #code do
local bit = code[_index_0]
lua:append(", ")
if type(bit) == "string" then
lua:append(repr(bit))
@ -1143,9 +1132,8 @@ do
end)
local add_lua_bits
add_lua_bits = function(lua, code)
local _list_0 = code.value
for _index_0 = 1, #_list_0 do
local bit = _list_0[_index_0]
for _index_0 = 1, #code do
local bit = code[_index_0]
if type(bit) == "string" then
lua:append(bit)
else

View File

@ -194,8 +194,8 @@ setmetatable(NOMSU_DEFS, {__index:(key)=>
make_node = (start, value, stop, userdata)->
source = userdata.source\sub(start, stop-1)
tree = if Types[key].is_multi
Types[key](Tuple(unpack(value)), source)
else Types[key](value, source)
Types[key](source, unpack(value))
else Types[key](source, value)
return tree
self[key] = make_node
return make_node
@ -446,7 +446,7 @@ class NomsuCompiler
stub = tree.stub
compile_action = @environment.COMPILE_ACTIONS[stub]
if compile_action
args = [arg for arg in *tree.value when type(arg) != "string"]
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]]
-- Force Lua to avoid tail call optimization for debugging purposes
@ -460,7 +460,7 @@ class NomsuCompiler
-- This is a bit of a hack, but this code handles arbitrarily complex
-- math expressions like 2*x + 3^2 without having to define a single
-- action for every possibility.
for i,tok in ipairs tree.value
for i,tok in ipairs tree
if type(tok) == 'string'
lua\append tok
else
@ -470,12 +470,12 @@ class NomsuCompiler
if tok.type == "Action"
tok_lua\parenthesize!
lua\append tok_lua
if i < #tree.value
if i < #tree
lua\append " "
return lua
args = {}
for i, tok in ipairs tree.value
for i, tok in ipairs tree
if type(tok) == "string" then continue
arg_lua = @tree_to_lua(tok)
unless arg_lua.is_value
@ -499,15 +499,15 @@ class NomsuCompiler
if type(t) != 'userdata'
return repr(t)
if t.is_multi
bits = [make_tree(bit) for bit in *t.value]
return t.type.."(Tuple("..table.concat(bits, ", ").."), "..repr(tostring t.source)..")"
bits = [make_tree(bit) for bit in *t]
return t.type.."("..repr(tostring t.source)..", "..table.concat(bits, ", ")..")"
else
return t.type.."("..repr(t.value)..", "..repr(tostring t.source)..")"
Lua.Value tree.source, make_tree(tree.value[1])
return t.type.."("..repr(tostring t.source)..", "..repr(t.value)..")"
Lua.Value tree.source, make_tree(tree[1])
when "Block"
lua = Lua(tree.source)
for i,line in ipairs tree.value
for i,line in ipairs tree
line_lua = @tree_to_lua(line)
if i > 1
lua\append "\n"
@ -517,7 +517,7 @@ class NomsuCompiler
when "Text"
lua = Lua.Value(tree.source)
string_buffer = ""
for i, bit in ipairs tree.value
for i, bit in ipairs tree
if type(bit) == "string"
string_buffer ..= bit
continue
@ -544,7 +544,7 @@ class NomsuCompiler
when "List"
lua = Lua.Value tree.source, "{"
line_length = 0
for i, item in ipairs tree.value
for i, item in ipairs tree
item_lua = @tree_to_lua(item)
unless item_lua.is_value
error "Cannot use #{colored.yellow repr(item)} as a list item, since it's not an expression.", 0
@ -555,7 +555,7 @@ class NomsuCompiler
line_length = #last_line
else
line_length += #last_line
if i < #tree.value
if i < #tree
if line_length >= MAX_LINE
lua\append ",\n "
line_length = 0
@ -568,7 +568,7 @@ class NomsuCompiler
when "Dict"
lua = Lua.Value tree.source, "{"
line_length = 0
for i, entry in ipairs tree.value
for i, entry in ipairs tree
entry_lua = @tree_to_lua(entry)
lua\append entry_lua
entry_lua_str = tostring(entry_lua)
@ -578,7 +578,7 @@ class NomsuCompiler
line_length = #last_line
else
line_length += #entry_lua_str
if i < #tree.value
if i < #tree
if line_length >= MAX_LINE
lua\append ",\n "
line_length = 0
@ -589,7 +589,7 @@ class NomsuCompiler
return lua
when "DictEntry"
key, value = tree.value[1], tree.value[2]
key, value = tree[1], tree[2]
key_lua = @tree_to_lua(key)
unless key_lua.is_value
error "Cannot use #{colored.yellow repr(key)} as a dict key, since it's not an expression.", 0
@ -608,15 +608,15 @@ class NomsuCompiler
Lua tree.source, "[",key_lua,"]=",value_lua
when "IndexChain"
lua = @tree_to_lua(tree.value[1])
lua = @tree_to_lua(tree[1])
unless lua.is_value
error "Cannot index #{colored.yellow repr(tree.value[1])}, since it's not an expression.", 0
error "Cannot index #{colored.yellow repr(tree[1])}, since it's not an expression.", 0
first_char = tostring(lua)\sub(1,1)
if first_char == "{" or first_char == '"' or first_char == "["
lua\parenthesize!
for i=2,#tree.value
key = tree.value[i]
for i=2,#tree
key = tree[i]
key_lua = @tree_to_lua(key)
unless key_lua.is_value
error "Cannot use #{colored.yellow repr(key)} as an index, since it's not an expression.", 0
@ -646,7 +646,7 @@ class NomsuCompiler
when "Action"
if inline
nomsu = Nomsu(tree.source)
for i,bit in ipairs tree.value
for i,bit in ipairs tree
if type(bit) == "string"
if i > 1
nomsu\append " "
@ -665,7 +665,7 @@ class NomsuCompiler
next_space = ""
-- TODO: track line length as we go and use 80-that instead of 80 for wrapping
last_colon = nil
for i,bit in ipairs tree.value
for i,bit in ipairs tree
if type(bit) == "string"
nomsu\append next_space, bit
next_space = " "
@ -706,16 +706,16 @@ class NomsuCompiler
return nomsu
when "EscapedNomsu"
nomsu = @tree_to_nomsu(tree.value, true)
nomsu = @tree_to_nomsu(tree[1], true)
if nomsu == nil and not inline
nomsu = @tree_to_nomsu(tree.value[1])
nomsu = @tree_to_nomsu(tree[1])
return nomsu and Nomsu tree.source, "\\:\n ", nomsu
return nomsu and Nomsu tree.source, "\\(", nomsu, ")"
when "Block"
if inline
nomsu = Nomsu(tree.source)
for i,line in ipairs tree.value
for i,line in ipairs tree
if i > 1
nomsu\append "; "
line_nomsu = @tree_to_nomsu(line,true)
@ -735,7 +735,7 @@ class NomsuCompiler
when "Text"
if inline
nomsu = Nomsu(tree.source, '"')
for bit in *tree.value
for bit in *tree
if type(bit) == 'string'
-- TODO: unescape better?
nomsu\append (bit\gsub("\\","\\\\")\gsub("\n","\\n"))
@ -773,7 +773,7 @@ class NomsuCompiler
when "List"
if inline
nomsu = Nomsu(tree.source, "[")
for i, item in ipairs tree.value
for i, item in ipairs tree
item_nomsu = @tree_to_nomsu(item, true)
return nil unless item_nomsu
if i > 1
@ -787,7 +787,7 @@ class NomsuCompiler
return inline_version
nomsu = Nomsu(tree.source, "[..]")
line = Nomsu(tree.source, "\n ")
for item in *tree.value
for item in *tree
item_nomsu = @tree_to_nomsu(item, true)
if item_nomsu and #line + #", " + #item_nomsu <= MAX_LINE
if #line.bits > 1
@ -808,7 +808,7 @@ class NomsuCompiler
when "Dict"
if inline
nomsu = Nomsu(tree.source, "{")
for i, entry in ipairs tree.value
for i, entry in ipairs tree
entry_nomsu = @tree_to_nomsu(entry, true)
return nil unless entry_nomsu
if i > 1
@ -821,7 +821,7 @@ class NomsuCompiler
if inline_version then return inline_version
nomsu = Nomsu(tree.source, "{..}")
line = Nomsu(tree.source, "\n ")
for entry in *tree.value
for entry in *tree
entry_nomsu = @tree_to_nomsu(entry)
return nil unless entry_nomsu
if #line + #tostring(entry_nomsu) <= MAX_LINE
@ -838,7 +838,7 @@ class NomsuCompiler
return nomsu
when "DictEntry"
key, value = tree.value[1], tree.value[2]
key, value = tree[1], tree[2]
key_nomsu = @tree_to_nomsu(key, true)
return nil unless key_nomsu
if key.type == "Action" or key.type == "Block"
@ -855,7 +855,7 @@ class NomsuCompiler
when "IndexChain"
nomsu = Nomsu(tree.source)
for i, bit in ipairs tree.value
for i, bit in ipairs tree
if i > 1
nomsu\append "."
bit_nomsu = @tree_to_nomsu(bit, true)
@ -871,10 +871,6 @@ class NomsuCompiler
when "Var"
return Nomsu(tree.source, "%", tree.value)
when "Comment"
return nil if inline
return Nomsu(tree.source, "#", tree.value\gsub("\n", "\n "))
else
error("Unknown type: #{tree.type}")
@ -891,7 +887,7 @@ class NomsuCompiler
if code.type != "Text"
lua\append ", ", nomsu\tree_to_lua(code)
return
for bit in *code.value
for bit in *code
lua\append ", "
if type(bit) == "string"
lua\append repr(bit)
@ -914,7 +910,7 @@ class NomsuCompiler
return lua
add_lua_bits = (lua, code)->
for bit in *code.value
for bit in *code
if type(bit) == "string"
lua\append bit
else

View File

@ -18,19 +18,22 @@ Types.is_node = function(n)
return type(n) == 'userdata' and getmetatable(n) and Types[n.type] == getmetatable(n)
end
local Tree
Tree = function(name, kind, methods)
Tree = function(name, fields, methods)
methods = methods or { }
assert((kind == 'single') or (kind == 'multi'))
local is_multi = (kind == 'multi')
local is_multi = true
for _index_0 = 1, #fields do
local f = fields[_index_0]
is_multi = is_multi and (f ~= "value")
end
do
methods.type = name
methods.name = name
methods.__new = methods.__new or function(self, value, source)
methods.__new = methods.__new or function(self, source, ...)
assert(source)
if type(source) == 'string' then
source = Source:from_string(source)
end
return value, source
return source, ...
end
methods.is_multi = is_multi
methods.map = function(self, fn)
@ -50,9 +53,8 @@ Tree = function(name, kind, methods)
return tostring(self.name) .. "(" .. tostring(table.concat((function()
local _accum_0 = { }
local _len_0 = 1
local _list_0 = self.value
for _index_0 = 1, #_list_0 do
local v = _list_0[_index_0]
for _index_0 = 1, #self do
local v = self[_index_0]
_accum_0[_len_0] = repr(v)
_len_0 = _len_0 + 1
end
@ -70,20 +72,16 @@ Tree = function(name, kind, methods)
do
local _accum_0 = { }
local _len_0 = 1
local _list_0 = self.value
for _index_0 = 1, #_list_0 do
local v = _list_0[_index_0]
for _index_0 = 1, #self do
local v = self[_index_0]
_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)(Tuple(unpack(new_vals)), self.source)
local ret = getmetatable(self)(self.source, unpack(new_vals))
return ret
end
methods.__ipairs = function(self)
return error()
end
else
methods.__tostring = function(self)
return tostring(self.name) .. "(" .. tostring(repr(self.value)) .. ")"
@ -93,54 +91,60 @@ Tree = function(name, kind, methods)
end
end
end
if name == "Action" then
Types[name] = immutable({
"value",
Types[name] = immutable(fields, methods)
end
Tree("Block", {
"source"
})
Tree("EscapedNomsu", {
"source"
})
Tree("Text", {
"source"
})
Tree("List", {
"source"
})
Tree("Dict", {
"source"
})
Tree("DictEntry", {
"source"
})
Tree("IndexChain", {
"source"
})
Tree("Number", {
"source",
"value"
})
Tree("Var", {
"source",
"value"
})
Tree("Action", {
"source",
"stub"
}, methods)
else
Types[name] = immutable({
"value",
"source"
}, methods)
end
end
Tree("Block", 'multi')
Tree("EscapedNomsu", 'multi')
Tree("Text", 'multi')
Tree("List", 'multi')
Tree("Dict", 'multi')
Tree("DictEntry", 'multi')
Tree("IndexChain", 'multi')
Tree("Number", 'single')
Tree("Comment", 'single')
Tree("Var", 'single')
Tree("Action", 'multi', {
__new = function(self, value, source)
}, {
__new = function(self, source, ...)
assert(source)
if type(source) == 'string' then
source = Source:from_string(source)
end
local stub = concat((function()
local _accum_0 = { }
local _len_0 = 1
for _index_0 = 1, #value do
local a = value[_index_0]
_accum_0[_len_0] = type(a) == "string" and a or "%"
_len_0 = _len_0 + 1
local stub_bits = { }
for i = 1, select("#", ...) do
local a = select(i, ...)
stub_bits[i] = type(a) == 'string' and a or "%"
end
return _accum_0
end)(), " ")
return value, source, stub
local stub = concat(stub_bits, " ")
return source, stub, ...
end,
get_spec = function(self)
return concat((function()
local _accum_0 = { }
local _len_0 = 1
local _list_0 = self.value
for _index_0 = 1, #_list_0 do
local a = _list_0[_index_0]
for _index_0 = 1, #self do
local a = self[_index_0]
_accum_0[_len_0] = type(a) == "string" and a or "%" .. tostring(a.value)
_len_0 = _len_0 + 1
end

View File

@ -13,18 +13,19 @@ Types.is_node = (n)->
type(n) == 'userdata' and getmetatable(n) and Types[n.type] == getmetatable(n)
-- Helper method:
Tree = (name, kind, methods)->
Tree = (name, fields, methods)->
methods or= {}
assert((kind == 'single') or (kind == 'multi'))
is_multi = (kind == 'multi')
is_multi = true
for f in *fields do is_multi and= (f != "value")
with methods
.type = name
.name = name
.__new or= (value, source)=>
.__new or= (source, ...)=>
assert source
if type(source) == 'string'
source = Source\from_string(source)
return value, source
--assert Source\is_instance(source)
return source, ...
.is_multi = is_multi
.map = (fn)=>
if type(fn) == 'table'
@ -33,43 +34,43 @@ Tree = (name, kind, methods)->
fn = (k)-> _replacements[k]
return @_map(fn)
if is_multi
.__tostring = => "#{@name}(#{table.concat [repr(v) for v in *@value], ', '})"
.__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 *@value]
ret = getmetatable(self)(Tuple(unpack(new_vals)), @source)
new_vals = [v._map and v\_map(fn) or v for v in *@]
ret = getmetatable(self)(@source, unpack(new_vals))
return ret
.__ipairs = => error!
else
.__tostring = => "#{@name}(#{repr(@value)})"
._map = (fn)=>
fn(@) or @
if name == "Action"
Types[name] = immutable {"value", "source", "stub"}, methods
else
Types[name] = immutable {"value", "source"}, methods
Types[name] = immutable fields, methods
Tree "Block", 'multi'
Tree "EscapedNomsu", 'multi'
Tree "Text", 'multi'
Tree "List", 'multi'
Tree "Dict", 'multi'
Tree "DictEntry", 'multi'
Tree "IndexChain", 'multi'
Tree "Number", 'single'
Tree "Comment", 'single'
Tree "Var", 'single'
Tree "Block", {"source"}
Tree "EscapedNomsu", {"source"}
Tree "Text", {"source"}
Tree "List", {"source"}
Tree "Dict", {"source"}
Tree "DictEntry", {"source"}
Tree "IndexChain", {"source"}
Tree "Number", {"source", "value"}
Tree "Var", {"source", "value"}
Tree "Action", 'multi',
__new: (value, source)=>
Tree "Action", {"source", "stub"},
__new: (source, ...)=>
assert source
if type(source) == 'string'
source = Source\from_string(source)
stub = concat [type(a) == "string" and a or "%" for a in *value], " "
return value, source, stub
--assert Source\is_instance(source)
stub_bits = {}
for i=1,select("#",...)
a = select(i, ...)
stub_bits[i] = type(a) == 'string' and a or "%"
stub = concat stub_bits, " "
return source, stub, ...
get_spec: =>
concat [type(a) == "string" and a or "%#{a.value}" for a in *@value], " "
concat [type(a) == "string" and a or "%#{a.value}" for a in *@], " "
return Types