github/workflows/pycopy-test: Upgrade Pycopy to 3.6.1.
[ScratchABlock.git] / sabl_cfg2pseudoc.py
bloba56dd32554074eef0f234273e7d46d5af126991a
1 #!/usr/bin/env python3
2 import sys
3 import re
4 from collections import defaultdict
6 from graph import Graph
7 from utils import pairwise, natural_sort_key
10 def node_name_strip(s):
11 s = s.strip()
12 if s[0] == '"' and s[-1] == '"':
13 s = s[1:-1]
14 return s
17 def parse_dot(f):
18 cfg = Graph()
20 for l in f:
21 l = l.strip()
22 if l.startswith("digraph"):
23 continue
24 if l == "}":
25 break
26 l = re.sub(r"\[.+\]$", "", l)
27 if "->" not in l:
28 continue
29 nodes = [node_name_strip(n) for n in l.split("->")]
31 for from_n, to_n in pairwise(nodes, trailing=False):
32 cfg.add_edge(from_n, to_n)
34 return cfg
37 def __main__():
38 with open(sys.argv[1]) as f:
39 cfg = parse_dot(f)
41 all_nodes = sorted(cfg.nodes(), key=natural_sort_key)
43 for n, next_n in pairwise(all_nodes):
44 print("%s:" % n)
45 print(" nop()")
46 succ = cfg.succ(n)
47 if len(succ) == 0:
48 print(" return")
49 elif len(succ) == 1:
50 if succ[0] != next_n:
51 print(" goto %s" % succ[0])
52 else:
53 old_len = len(succ)
54 succ = [x for x in succ if x != next_n]
55 else_node = None
56 if len(succ) == old_len:
57 # next_n wasn't in succ
58 else_node = succ[-1]
59 succ = succ[:-1]
60 s = ", ".join(["($cond) goto %s" % x for x in succ])
61 if else_node:
62 s += ", else goto %s" % else_node
63 print(" if " + s)
66 if __name__ == "__main__":
67 __main__()