aboutsummaryrefslogtreecommitdiff
path: root/nomsu_decompiler.moon
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2018-12-30 23:56:28 -0800
committerBruce Hill <bruce@bruce-hill.com>2018-12-30 23:58:43 -0800
commitec69ee6f62016a2edcc13e3183cbe4cadd75717f (patch)
tree24e04f77c7390d379f2fb372611ac468a67aed03 /nomsu_decompiler.moon
parent435eae7c0ab10577431bb943a6f48873e5ecdf7c (diff)
Fixes for: indented strings ending in ", peeking at code object text
before modifying them, and major upgrades to the nomsu codegen, including support for indented inline arguments (instead of using "\n..") and just generally better line wrapping, including finally good rules for when to use indented text (for almost all cases).
Diffstat (limited to 'nomsu_decompiler.moon')
-rw-r--r--nomsu_decompiler.moon93
1 files changed, 64 insertions, 29 deletions
diff --git a/nomsu_decompiler.moon b/nomsu_decompiler.moon
index 181d73f..3c20f76 100644
--- a/nomsu_decompiler.moon
+++ b/nomsu_decompiler.moon
@@ -133,24 +133,26 @@ tree_to_inline_nomsu = (tree)->
key[1]
else
tree_to_inline_nomsu(key)
- key_nomsu\parenthesize! if key.type == "Block" or key.type == "Action" or key.type == "MethodCall"
+ switch key.type
+ when "Block", "Action", "MethodCall", "IndexChain"
+ key_nomsu\parenthesize!
return NomsuCode\from(key.source, ".", key_nomsu)
when "IndexChain"
nomsu = NomsuCode\from(tree.source)
- for i, bit in ipairs tree
- nomsu\add "." if i > 1 and bit.type != "Index"
- local bit_nomsu
- bit_nomsu = if i > 1 and bit.type == "Text" and #bit == 1 and type(bit[1]) == 'string' and is_identifier(bit[1])
- bit[1]
- else tree_to_inline_nomsu(bit)
- assert bit.type != "Block"
- switch bit.type
- when "Action", "MethodCall", "IndexChain"
- bit_nomsu\parenthesize!
- when "Number"
- bit_nomsu\parenthesize! if bit_nomsu\text!\match("%.")
- nomsu\add bit_nomsu
+ target = tree[1]
+ target_nomsu = tree_to_inline_nomsu(target)
+ switch target.type
+ when "Action", "MethodCall"
+ target_nomsu\parenthesize!
+ when "Number"
+ target_nomsu\parenthesize! if target_nomsu\text!\match("%.")
+ nomsu\add target_nomsu
+ for i=2,#tree
+ -- TODO: remove shim?
+ if tree[i].type != "Index"
+ tree[i] = {type:"Index", source:tree[i].source, tree[i]}
+ nomsu\add tree_to_inline_nomsu(tree[i])
return nomsu
when "Number"
@@ -189,18 +191,27 @@ tree_to_nomsu = (tree)->
space = MAX_LINE - nomsu\trailing_line_len!
try_inline = true
for subtree in coroutine.wrap(-> (t\map(coroutine.yield) and nil))
- if subtree.type == "Comment"
- try_inline = false
- if subtree.type == "Block"
- if #subtree > 1
+ switch subtree.type
+ when "Comment"
try_inline = false
+ when "Block"
+ if #subtree > 1
+ try_inline = false
+ when "Text"
+ indented = tree_to_nomsu(subtree)
+ indented_lines = [line for line in *indented\text!\lines! when line\match("^ +([^ ].*)")]
+ for i=#indented_lines,1,-1
+ if indented_lines[i]\match("^ *\\;$")
+ table.remove(indented_lines, i)
+ if #indented_lines > 1 or (#indented_lines == 1 and #indented_lines[1] > MAX_LINE + 8)
+ try_inline = false
local inline_nomsu
if try_inline
inline_nomsu = tree_to_inline_nomsu(t)
+ if (t.type == "Action" or t.type == "MethodCall")
+ inline_nomsu\parenthesize!
if #inline_nomsu\text! <= space or #inline_nomsu\text! <= 8
- if (t.type == "Action" or t.type == "MethodCall")
- inline_nomsu\parenthesize!
if t.type != "Text"
return inline_nomsu
indented = tree_to_nomsu(t)
@@ -214,11 +225,13 @@ tree_to_nomsu = (tree)->
return NomsuCode\from(t.source, "\n ", indented)
else
indented\parenthesize!
- indented_lines = [line for line in *indented\text!\lines! when line\match("%S")]
- if inline_nomsu and #indented_lines == ((t.type == 'Block' or t.type == 'Action' or t.type == 'MethodCall') and 2 or 3) and nomsu\trailing_line_len! <= 8
- return inline_nomsu
- elseif inline_nomsu and t.type == "Text" and #indented_lines <= 3 and
- (#inline_nomsu\text! - 2 < MAX_LINE + 4 or #inline_nomsu\text! <= space or #inline_nomsu\text! <= 8)
+ indented_lines = [line for line in *indented\text!\lines! when line\match("^ +([^ ].*)")]
+ if t.type == "Text"
+ for i=#indented_lines,1,-1
+ if indented_lines[i]\match("^ *\\;$")
+ table.remove(indented_lines, i)
+ if inline_nomsu and (#inline_nomsu\text! < MAX_LINE or #inline_nomsu\text! <= space) and
+ #indented_lines <= 1
return inline_nomsu
return indented
@@ -265,13 +278,21 @@ tree_to_nomsu = (tree)->
if bit.type == "Block"
-- Rule of thumb: nontrivial one-liner block arguments should be no more
-- than golden ratio * the length of the proceeding part of the line
- if not bit_nomsu\is_multiline! and #bit_nomsu\text! > nomsu\trailing_line_len! * GOLDEN_RATIO and #bit_nomsu\text! > 8
+ if not bit_nomsu\is_multiline! and
+ (#bit_nomsu\text! > nomsu\trailing_line_len! * GOLDEN_RATIO and #bit_nomsu\text! > 8) or
+ #bit_nomsu\text! + nomsu\trailing_line_len! > MAX_LINE
bit_nomsu = tree_to_nomsu(bit)
elseif (not bit_nomsu\is_multiline! and
nomsu\trailing_line_len! + #bit_nomsu\text! > MAX_LINE and
nomsu\trailing_line_len! > 8)
if next_space == " " and #bit_nomsu\text! < MAX_LINE
- next_space = "\n.."
+ if i == #tree
+ bit_nomsu = tree_to_inline_nomsu(bit)
+ next_space = "\n "
+ elseif bit.type == "List" or bit.type == "Dict"
+ bit_nomsu = tree_to_nomsu(bit)
+ else
+ next_space = "\n.."
elseif bit.type == 'Action' or bit.type == "MethodCall"
bit_nomsu = NomsuCode\from bit.source, "\n ", tree_to_nomsu(bit)
else
@@ -281,7 +302,7 @@ tree_to_nomsu = (tree)->
nomsu\add next_space
nomsu\add bit_nomsu
- next_space = (bit.type == 'Block' or (i > 1 and (bit.type == 'Action' or bit.type == 'MethodCall')) and bit_nomsu\is_multiline!) and "\n.." or " "
+ next_space = (bit.type == "Block" or bit_nomsu\text!\matches("\n [^\n]*$")) and "\n.." or " "
if #word_buffer > 0
words = table.concat(word_buffer)
@@ -365,12 +386,25 @@ tree_to_nomsu = (tree)->
nomsu\add "\\"
interp_nomsu = recurse(bit)
unless interp_nomsu\is_multiline!
+ space = max_line - nomsu\trailing_line_len!
if bit.type == "Var"
next_str = tree[i+1]
while type(next_str) == 'table' and next_str.type == 'Text'
next_str = next_str[1]
if type(next_str) == 'string' and not match(next_str, "^[ \n\t,.:;#(){}[%]]")
interp_nomsu\parenthesize!
+ elseif #interp_nomsu\text! > space
+ interp_nomsu2 = if bit.type == "Action" or bit.type == "MethodCall"
+ NomsuCode\from(bit.source, "(\n ", tree_to_nomsu(bit), "\n)")
+ else
+ tree_to_nomsu(bit)
+
+ if #interp_nomsu2\text!\lines! > 3 or #interp_nomsu2\text! >= MAX_LINE*GOLDEN_RATIO
+ interp_nomsu = interp_nomsu2
+ else
+ nomsu\add "\n..\\"
+ if bit.type == "EscapedNomsu" or bit.type == "Block" or bit.type == "IndexChain"
+ interp_nomsu\parenthesize!
elseif bit.type == "EscapedNomsu" or bit.type == "Block" or bit.type == "IndexChain"
interp_nomsu\parenthesize!
nomsu\add interp_nomsu
@@ -396,7 +430,8 @@ tree_to_nomsu = (tree)->
else
item_nomsu = tree_to_inline_nomsu(item)
if #item_nomsu\text! > MAX_LINE
- item_nomsu = recurse(item)
+ sep = '\n' if i > 1
+ item_nomsu = tree_to_nomsu(item)
nomsu\add sep
nomsu\add item_nomsu
if item_nomsu\is_multiline! or item.type == 'Comment' or nomsu\trailing_line_len! + #tostring(item_nomsu) >= MAX_LINE