Skip to content

Commit

Permalink
checkout pp_html.py which was factored out a while ago
Browse files Browse the repository at this point in the history
  • Loading branch information
robertmuth committed May 15, 2024
1 parent 68eedd8 commit 79ca7fc
Showing 1 changed file with 171 additions and 0 deletions.
171 changes: 171 additions & 0 deletions FrontEnd/pp_html.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
#!/usr/bin/python3
"""Pretty printer (PP) for Cwerg AST
"""

import logging

from FrontEnd import cwast
from FrontEnd import pp_sexpr

from FrontEnd import mod_pool

logger = logging.getLogger(__name__)


############################################################
# Pretty Print HTML
############################################################
def _RenderIndent(n):
return ["<span class=indent>", "&emsp;" * 2 * n, "</span>"]


def _CircledLetterEntity(c):
offset = ord(c.upper()) - ord('A')
return f"&#{0x24b6 + offset};"


def _DecorateNode(node_name, node):
problems = []
if node.x_srcloc is None:
problems.append("missing srcloc")
if cwast.NF.TYPE_ANNOTATED in node.FLAGS and node.x_type is None:
problems.append("missing type")

out = ["<span class=name>", node_name, "</span>"]
if cwast.NF.TYPE_ANNOTATED in node.FLAGS:
out += ["<span class=type title='",
node.x_type.name, "'>", _CircledLetterEntity("T"), "</span>"]
if cwast.NF.VALUE_ANNOTATED in node.FLAGS and node.x_value is not None:
out += ["<span class=value title='",
str(node.x_value), "'>", _CircledLetterEntity("V"), "</span>"]
if cwast.NF.FIELD_ANNOTATED in node.FLAGS:
out += ["<span class=value title='",
str(node.x_field.x_offset), "'>", _CircledLetterEntity("F"), "</span>"]
if cwast.NF.CONTROL_FLOW in node.FLAGS:
out += [_CircledLetterEntity("C")]
if problems:
out += ["<span class=problems title='",
"\n".join(problems), "'>", _CircledLetterEntity("X"), "</span>"]
return out


def _RenderRecursivelyHTML(node, out, indent: int):
line = out[-1]
abbrev = pp_sexpr.MaybeSimplifyLeafNode(node)
if abbrev:
abbrev = abbrev.replace("<", "&lt;").replace(">", "&gt;")
if isinstance(node, (cwast.ValNum, cwast.ValString, cwast.Id)):
line.append(abbrev)
else:
line += _DecorateNode(abbrev, node)
return

node_name, fields = pp_sexpr.GetNodeTypeAndFields(node)
line += _DecorateNode("(" + node_name, node)

for field, nfd in node.ATTRS:
field_kind = nfd.kind
val = getattr(node, field)
if field_kind is cwast.NFK.ATTR_BOOL:
if val:
line.append(" " + field)
elif field_kind is cwast.NFK.ATTR_STR:
if val:
pass
# line.append(" " + field)

for field, nfd in fields:
line = out[-1]
field_kind = nfd.kind
val = getattr(node, field)

if cwast.IsFieldWithDefaultValue(field, val):
continue
elif field_kind is cwast.NFK.STR:
line.append(
" " + str(val.replace("<", "&lt;").replace(">", "&gt;")))
elif field_kind is cwast.NFK.KIND:
line.append(" " + val.name)
elif field_kind is cwast.NFK.NODE:
line.append(" ")
_RenderRecursivelyHTML(val, out, indent)
elif field_kind is cwast.NFK.LIST:
extra_indent = pp_sexpr.GetColonIndent(field)
if not val:
line.append(" []")
else:
line.append(" [")
for cc in val:
out.append(_RenderIndent(indent + extra_indent))
_RenderRecursivelyHTML(cc, out, indent + extra_indent)
if field == "body_mod":
out.append(_RenderIndent(indent))
out[-1].append("]")
elif field_kind is cwast.NFK.STR_LIST:
line.append(f" [{' '.join(val)}]")
else:
assert False, f"{node_name} {nfd}"

line = out[-1]
line.append(")")
if cwast.NF.TOP_LEVEL in node.FLAGS:
out.append(["<p></p>"])


def PrettyPrintHTML(mod: cwast.DefMod): # -> list[Tuple[int, str]]:
out = [[
"""<html>
<style>
body { font-family: monospace; }
span.name { font-weight: bold; }
</style>"""]
]
_RenderRecursivelyHTML(mod, out, 0)
out += [["</html>"]]
for a in out:
print("".join(a))
print("<br>")


############################################################
#
############################################################
if __name__ == "__main__":
import os
import argparse
import pathlib

from FrontEnd import type_corpus
from FrontEnd import symbolize
from FrontEnd import typify
from FrontEnd import eval

def main():
parser = argparse.ArgumentParser(description='pretty_printer')
parser.add_argument('files', metavar='F', type=str, nargs='+',
help='an input source file')
args = parser.parse_args()

logging.basicConfig(level=logging.WARN)
logger.setLevel(logging.INFO)
assert len(args.files) == 1
assert args.files[0].endswith(".cw")

cwd = os.getcwd()
mp: mod_pool.ModPool = mod_pool.ModPool(pathlib.Path(cwd) / "Lib")
mp.ReadModulesRecursively(["builtin",
str(pathlib.Path(args.files[0][:-3]).resolve())])

mod_topo_order = mp.ModulesInTopologicalOrder()
symbolize.MacroExpansionDecorateASTWithSymbols(mod_topo_order)
for mod in mod_topo_order:
cwast.StripFromListRecursively(mod, cwast.DefMacro)
tc = type_corpus.TypeCorpus(type_corpus.STD_TARGET_X64)
typify.DecorateASTWithTypes(mod_topo_order, tc)
eval.DecorateASTWithPartialEvaluation(mod_topo_order)

for mod in mod_topo_order:
PrettyPrintHTML(mod)

main()

0 comments on commit 79ca7fc

Please sign in to comment.