diff options
Diffstat (limited to 'nomnom/decompile.nom')
| -rw-r--r-- | nomnom/decompile.nom | 187 |
1 files changed, 100 insertions, 87 deletions
diff --git a/nomnom/decompile.nom b/nomnom/decompile.nom index fb64f7c..7db61c8 100644 --- a/nomnom/decompile.nom +++ b/nomnom/decompile.nom @@ -1,9 +1,10 @@ +#!/usr/bin/env nomsu -V4.8.10 # This file contains the code to convert syntax trees to Nomsu code use "nomnom/code_obj.nom" use "nomnom/parser.nom" # TODO: maybe re-implement the fancy coroutine checker that aborts early if nomsu gets too long -action [%tree decompiled inline]: +externally (%tree decompiled inline) means: assume (%tree is a "Syntax Tree") if %tree.type is: "Action": @@ -11,18 +12,18 @@ action [%tree decompiled inline]: if %tree.target: %target_nomsu = (%tree.target decompiled inline) if %tree.target.type is: - ("Action", "Block"): + "Action" "Block": %target_nomsu::parenthesize + %nomsu::add [%target_nomsu, "::"] - + for %bit in %tree at %i: if (%bit is text): unless (..) any of [..] - %i == 1, - %tree.(%i - 1) isn't text, - (%bit is a nomsu operator) == (%tree.(%i - 1) is a nomsu operator) + %i == 1, %tree.(%i - 1) isn't text, (%bit is a nomsu operator) == (%tree.(%i - 1) is a nomsu operator) ..: %nomsu::add " " + %nomsu::add %bit ..else: %arg_nomsu = (%bit decompiled inline) @@ -30,39 +31,40 @@ action [%tree decompiled inline]: %nomsu::add " " if ((%bit.type == "Action") or (%bit.type == "Block")): %arg_nomsu::parenthesize + %nomsu::add %arg_nomsu + return %nomsu - + "EscapedNomsu": %inner_nomsu = (%tree.1 decompiled inline) unless (..) any of [..] - %tree.1.type == "List", %tree.1.type == "Dict", - %tree.1.type == "Var" - ..: %inner_nomsu::parenthesize + %tree.(1).type == "List", %tree.(1).type == "Dict", %tree.(1).type == "Var" + ..: + %inner_nomsu::parenthesize + %nomsu = (Nomsu Code from %tree ["\\", %inner_nomsu]) return %nomsu - + "Block": %nomsu = (Nomsu Code from %tree [":"]) for %line in %tree at %i: - %nomsu::add [..] - " " if (%i == 1) else "; " - %line decompiled inline + %nomsu::add [" " if (%i == 1) else "; ", %line decompiled inline] return %nomsu - + "Text": %nomsu = (Nomsu Code from %tree []) for %text in recursive %tree: for %bit in %text at %i: - if (%bit is text): - %nomsu::add %bit + if (%bit is text): %nomsu::add %bit ..else: if %bit.type is: "Text": recurse %text on %bit "Var": %interp_nomsu = (%bit decompiled inline) + # Make sure "...\(%x)y..." isn't confused with "...\(%xy)..." # TODO: make this more robust against "...\%x\("y").." if (..) @@ -70,32 +72,38 @@ action [%tree decompiled inline]: not (%tree.(%i + 1)::matches "^[ \n\t,.:;#(){}%[%]]") ..: %interp_nomsu::parenthesize %nomsu::add ["\\", %interp_nomsu] - ("List", "Dict"): + + "List" "Dict": %nomsu::add ["\\", %bit decompiled inline] else: %nomsu::add ["\\(", %bit decompiled inline, ")"] + return (Nomsu Code from %tree ["\"", %nomsu, "\""]) - - ("List", "Dict"): + + "List" "Dict": %nomsu = (Nomsu Code from %tree ["[" if (%tree.type == "List") else "{"]) for %item in %tree at %i: if (%i > 1): %nomsu::add ", " %nomsu::add (%item decompiled inline) + %nomsu::add ("]" if (%tree.type == "List") else "}") return %nomsu "DictEntry": set {%key:%tree.1, %value:%tree.2} - if (all of [%key.type == "Text", (size of %key) == 1, %key.1 is a nomsu identifier]): + if (..) + all of [%key.type == "Text", (size of %key) == 1, %key.1 is a nomsu identifier] + ..: %nomsu = (Nomsu Code from %key [%key.1]) ..else: %nomsu = (%key decompiled inline) - + if (%key.type == "Action"): %nomsu::parenthesize if %value: %nomsu::add ":" %nomsu::add (%value decompiled inline) + return %nomsu "IndexChain": @@ -104,46 +112,42 @@ action [%tree decompiled inline]: if (%i > 1): %nomsu::add "." if (..) all of [..] - %i > 1, %bit.type == "Text", (size of %bit) == 1, %bit.1 is text, - %bit.1 is a nomsu identifier - ..:%nomsu::add %bit.1 + %i > 1, %bit.type == "Text", (size of %bit) == 1, %bit.1 is text, %bit.1 is a nomsu identifier + ..: %nomsu::add %bit.1 ..else: %bit_nomsu = (%bit decompiled inline) if (..) any of [..] - %bit.type == "Action" - %bit.type == "Block" - %bit.type == "IndexChain" + %bit.type == "Action", %bit.type == "Block", %bit.type == "IndexChain" (%bit.type == "Number") and (%i < (size of %tree)) - ..: %bit_nomsu::parenthesize + ..: + %bit_nomsu::parenthesize + %nomsu::add %bit_nomsu + return %nomsu "Number": return (Nomsu Code from %tree [(%tree.1 as hex) if %tree.hex else "\(%tree.1)"]) - "Var": return (Nomsu Code from %tree ["%\(%tree.1)"]) - - "Comment": - return (nil) - + "Comment": return (nil) "FileChunks": barf "Can't inline a FileChunks" - "Error": barf "Can't compile errors" - else: barf "Unknown type: \(%tree.type)" %MAX_LINE = 90 -action [%tree decompiled]: +externally (%tree decompiled) means: %nomsu = (Nomsu Code from %tree) + # For concision: - local action [recurse on %t]: + (recurse on %t) means: %space = (%MAX_LINE - (%nomsu::trailing line length)) - if (%space <= 0): go to (Use Indented) + if (%space <= 0): + go to (Use Indented) for %subtree in recursive %tree: if %subtree.type is: "Block": @@ -151,45 +155,50 @@ action [%tree decompiled]: go to (Use Indented) if ((size of "\(%subtree decompiled inline)") > 20): go to (Use Indented) + for %k = %v in %subtree: if (%v is a "Syntax Tree"): recurse %subtree on %v - + %inline_nomsu = (%t decompiled inline) if (%inline_nomsu and ((size of "\%inline_nomsu") <= %space)): return %inline_nomsu - === (Use Indented) === %indented = (%t decompiled) if (%t.type == "Action"): - %indented = (Nomsu Code from %t ["(..)\n ", %indented]) + %indented = (..) + Nomsu Code from %t [..] + "(..)\n ", %indented + return %indented - + if %tree.type is: "FileChunks": - local action [%1 and %2 should clump]: + (%1 and %2 should clump) means: if ((%1.type == "Action") and (%2.type == "Action")): - if (%1.stub == "use 1"): return (%2.stub == "use 1") + if (%1.stub == "use 1"): + return (%2.stub == "use 1") if (%1.stub == "test 1"): return (yes) if (%2.stub == "test 1"): return (no) + return (not ((recurse on %1)::is multi-line)) + for %chunk in %tree at %chunk_no: if (%chunk_no > 1): %nomsu::add "\n\n\("~"::* 80)\n\n" if (%chunk.type == "Block"): for %line in %chunk at %line_no: if (%line_no > 1): - if (%chunk.(%line_no - 1) and %line should clump): - %nomsu::add "\n" - ..else: - %nomsu::add "\n\n" + if (%chunk.(%line_no - 1) and %line should clump): %nomsu::add "\n" + ..else: %nomsu::add "\n\n" + %nomsu::add (%line decompiled) ..else: %nomsu::add (%chunk decompiled) - unless ("\%nomsu"::matches "\n$"): - %nomsu::add "\n" + + unless ("\%nomsu"::matches "\n$"): %nomsu::add "\n" return %nomsu - + "Action": %pos = %tree.source.start %next_space = "" @@ -200,33 +209,32 @@ action [%tree decompiled]: %nomsu::add %target_nomsu %pos = %tree.target.source.stop %next_space = ("\n..::" if (%target_nomsu::is multi-line) else "::") - + for %bit in %tree at %i: if ((%next_space == " ") and ((%nomsu::trailing line length) > %MAX_LINE)): %next_space = " \\\n" - + %nomsu::add %next_space - if (%bit is text): unless (..) all of [..] - %tree.(%i - 1) is text - (%tree.(%i - 1) is a nomsu operator) != (%bit is a nomsu operator) - ..: %nomsu::add %next_space + %tree.(%i - 1) is text, (%tree.(%i - 1) is a nomsu operator) != (%bit is a nomsu operator) + ..: + %nomsu::add %next_space + %nomsu::add %bit %next_space = " " do next %bit - + %bit_nomsu = (recurse on %bit) - if (%bit.type == "Comment"): - %next_space = "\n" + if (%bit.type == "Comment"): %next_space = "\n" ..else: %next_space = (" " if (%bit_nomsu::is one line) else "\n..") if (%bit.type == "Action"): %bit_nomsu::parenthesize - + return %nomsu - + "EscapedNomsu": %nomsu::add "\\" %val_nomsu = (recurse on %tree.1) @@ -234,25 +242,25 @@ action [%tree decompiled]: %val_nomsu::parenthesize %nomsu::add %val_nomsu return %nomsu - + "Block": for %line in %tree at %i: - if ((%i > 1) and (%line.type == "Comment")): - %nomsu::add "\n" + if ((%i > 1) and (%line.type == "Comment")): %nomsu::add "\n" %line_nomsu = (recurse on %line) %nomsu::add if (%i < (size of %tree)): - if ((%line_nomsu::number of lines) > 2): - %nomsu::add "\n\n" - ..else: - %nomsu::add "\n" - return (Nomsu Code from %tree [":\n ", %nomsu]) - + if ((%line_nomsu::number of lines) > 2): %nomsu::add "\n\n" + ..else: %nomsu::add "\n" + + return (..) + Nomsu Code from %tree [..] + ":\n ", %nomsu + "Text": # Multi-line text has more generous wrap margins %max_line = ((1.5 * %MAX_LINE) rounded down) %nomsu = (Nomsu Code from %tree) - local action [add text from %tree]: + (add text from %tree) means: for %bit in %tree at %i: if (%bit is text): # TODO: escape properly? @@ -262,7 +270,7 @@ action [%tree decompiled]: (%j > 1): %nomsu::add "\n" (((size of %line) > 10) and ((%nomsu::trailing line length) > %max_line)): %nomsu::add "\\\n.." - + repeat while ((size of %line) > 0): %space = (%max_line - (%nomsu::trailing line length)) %split = (%line::position of "[%p%s]" after %space) @@ -284,18 +292,23 @@ action [%tree decompiled]: "Var": if ((%tree.(%i+1) is text) and (not (%tree.(%i+1)::matches "^[ \n\t,.:#(){}[%]]"))): %interp_nomsu::parenthesize - ("List", "Dict"): + + "List" "Dict": %interp_nomsu::parenthesize + %nomsu::add %interp_nomsu - if (%interp_nomsu::is multi-line): - %nomsu::add "\n.." + if (%interp_nomsu::is multi-line): %nomsu::add "\n.." + add text from %tree - return (Nomsu Code from %tree ["\"\\\n ..", %nomsu, "\""]) - - ("List", "Dict"): + return (..) + Nomsu Code from %tree [..] + "\"\\\n ..", %nomsu, "\"" + + "List" "Dict": if ((size of %tree) == 0): %nomsu::add ("[]" if (%tree.type == "List") else "{}") return %nomsu + for %item in %tree at %i: %item_nomsu = (%item decompiled inline) if ((not %item_nomsu) or ((size of "\%item_nomsu") > %MAX_LINE)): @@ -303,10 +316,10 @@ action [%tree decompiled]: %nomsu::add %item_nomsu if (%i < (size of %tree)): if any of [..] - %item_nomsu::is multi-line - ((%nomsu::trailing line length) + (size of "\%item_nomsu")) >= %MAX_LINE + %item_nomsu::is multi-line, ((%nomsu::trailing line length) + (size of "\%item_nomsu")) >= %MAX_LINE ..: %nomsu::add "\n" ..else: %nomsu::add ", " + return (..) Nomsu Code from %tree [..] "[..]\n " if (%tree.type == "List") else "{..}\n " @@ -314,10 +327,12 @@ action [%tree decompiled]: "DictEntry": set {%key:%tree.1, %value:%tree.2} - if (all of [%key.type == "Text", (size of %key) == 1, %key.1 is a nomsu identifier]): - %nomsu::add %key.1 + if (..) + all of [%key.type == "Text", (size of %key) == 1, %key.1 is a nomsu identifier] + ..: %nomsu::add %key.1 ..else: %nomsu::add (%key decompiled inline) + if ((%key.type == "Action") or (%key.type == "Block")): %nomsu::parenthesize %nomsu::add [": ", recurse on %value] @@ -327,11 +342,9 @@ action [%tree decompiled]: %nomsu::add ["#", %tree.1::with "\n" -> "\n "] return %nomsu - ("IndexChain", "Number", "Var"): + "IndexChain" "Number" "Var": return (%tree decompiled inline) - "Error": barf "Cannot decompile an error" - else: barf "Unknown type: \(%tree.type)" |
