aboutsummaryrefslogtreecommitdiff
path: root/nomnom/decompile.nom
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2018-10-31 15:05:17 -0700
committerBruce Hill <bruce@bruce-hill.com>2018-10-31 15:05:17 -0700
commit7a35e38d8778670fe0662f203e82638355db3bba (patch)
treecc9f813d1350f23d2b81a81b18f4f127668bfec9 /nomnom/decompile.nom
parentf43d8c58f755a7f208d84b43071490ab356c5ac8 (diff)
Renamed (action %) -> (%'s meaning)
Diffstat (limited to 'nomnom/decompile.nom')
-rw-r--r--nomnom/decompile.nom187
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)"