-
Notifications
You must be signed in to change notification settings - Fork 0
/
Utils.py
116 lines (100 loc) · 5.07 KB
/
Utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import cmp.visitor as visitor
from AST import ProgramNode,ClassDeclarationNode,AttrDeclarationNode,VarDeclarationNode,AssignNode,FuncDeclarationNode,BinaryNode
from AST import AtomicNode,CallNode,InstantiateNode, IfDeclarationNode, LetDeclarationNode, CaseDeclarationNode, WhileDeclarationNode
from AST import BlockNode
class FormatVisitor(object):
@visitor.on('node')
def visit(self, node, tabs):
pass
@visitor.when(ProgramNode)
def visit(self, node, tabs=0):
ans = '\t' * tabs + f'\\__ProgramNode [<class> ... <class>]'
statements = '\n'.join(self.visit(child, tabs + 1) for child in node.declarations)
return f'{ans}\n{statements}'
@visitor.when(ClassDeclarationNode)
def visit(self, node, tabs=0):
parent = '' if node.parent is None else f": {node.parent}"
ans = '\t' * tabs + f'\\__ClassDeclarationNode: class {node.id} {parent} {{ <feature> ... <feature> }}'
features = '\n'.join(self.visit(child, tabs + 1) for child in node.features)
return f'{ans}\n{features}'
@visitor.when(AttrDeclarationNode)
def visit(self, node, tabs=0):
ans = '\t' * tabs + f'\\__AttrDeclarationNode: {node.id} : {node.type}'
if node.expr != None:
ans += f"\n{self.visit(node.expr, tabs +1)}"
return f'{ans}'
@visitor.when(VarDeclarationNode)
def visit(self, node, tabs=0):
ans = '\t' * tabs + f'\\__VarDeclarationNode: {node.id} : {node.type} = <expr>'
if node.expr != None:
ans += f'\n{self.visit(node.expr, tabs + 1)}'
return f'{ans}'
@visitor.when(BlockNode)
def visit(self, node, tabs=0):
ans = '\t' * tabs + '\\__BlockNode: { <expr>; ... <expr>; }'
body = '\n'.join(self.visit(child, tabs + 1) for child in node.body)
return f'{ans}\n{body}'
@visitor.when(IfDeclarationNode)
def visit(self, node, tabs=0):
ifexpr = self.visit(node.ifexpr, tabs + 1)
thenexpr = self.visit(node.thenexpr, tabs + 1)
elseexpr = self.visit(node.elseexpr,tabs + 1)
ans = '\t' * tabs + f'\\__IfDeclarationNode: if <expr> then <expr> else <expr> \n'
ifs = '\t' * (tabs + 1) + f'if:\n{ifexpr}\n'
ths = '\t' * (tabs + 1) + f'then:\n{thenexpr}\n'
els = '\t' * (tabs + 1) + f'else:\n{elseexpr}\n'
ans = ans + ifs + ths + els
return ans
@visitor.when(CaseDeclarationNode)
def visit(self, node, tabs=0):
header = '\t' * tabs + f'\\__CaseDeclarationNode: case <expr> of ( <var> => <expr> ...)\n'
caseexpr = self.visit(node.expr, tabs + 1)
case = '\t' * (tabs + 1) + f'case:\n{caseexpr}\n'
casevars = '\n'.join(self.visit(child, tabs + 1) for child in node.casevars)
of = '\t' * (tabs + 1) + f'of:\n{casevars}\n'
return header + case + of
@visitor.when(LetDeclarationNode)
def visit(self, node, tabs=0):
header = '\t' * tabs + f'\\__LetDeclarationNode: Let (<var> <- <expr> ...) in <expr>\n'
letvars = '\n'.join(self.visit(child, tabs + 1) for child in node.letvars)
expr = self.visit(node.expr, tabs + 1)
let = '\t' * (tabs + 1) + f'let: \n{letvars}\n'
inx = '\t' * (tabs + 1) + f'in: \n{expr}'
return header + let + inx
@visitor.when(WhileDeclarationNode)
def visit(self, node, tabs=0):
header = '\t' * tabs + f'\\__WhileDeclarationNode: while <expr> loop ( <expr> ... <expr> )\n'
body = self.visit(node.bodyexpr, tabs + 1)
whilex = self.visit(node.whileexpr, tabs + 1) + '\n'
text1 = '\t' * (tabs + 1) + f'while:\n {whilex}'
text2 = '\t' * (tabs + 1) + f'loop:\n {body}'
return header + text1 + text2
@visitor.when(AssignNode)
def visit(self, node, tabs=0):
ans = '\t' * tabs + f'\\__AssignNode: {node.id} = <expr>'
expr = self.visit(node.expr, tabs + 1)
return f'{ans}\n{expr}'
@visitor.when(FuncDeclarationNode)
def visit(self, node, tabs=0):
params = ', '.join(':'.join(param) for param in node.params)
ans = '\t' * tabs + f'\\__FuncDeclarationNode: {node.id}({params}) : {node.type} -> <body>'
body = '\n' + self.visit(node.body, tabs + 1)
return f'{ans}{body}'
@visitor.when(BinaryNode)
def visit(self, node, tabs=0):
ans = '\t' * tabs + f'\\__<expr> {node.__class__.__name__} <expr>'
left = self.visit(node.left, tabs + 1)
right = self.visit(node.right, tabs + 1)
return f'{ans}\n{left}\n{right}'
@visitor.when(AtomicNode)
def visit(self, node, tabs=0):
return '\t' * tabs + f'\\__ {node.__class__.__name__}: {node.lex}'
@visitor.when(CallNode)
def visit(self, node, tabs=0):
obj = self.visit(node.obj, tabs + 1)
ans = '\t' * tabs + f'\\__CallNode: <obj>.{node.id}(<expr>, ..., <expr>)'
args = '\n'.join(self.visit(arg, tabs + 1) for arg in node.args)
return f'{ans}\n{args}'#old f'{ans}\n{obj}\n{args}'
@visitor.when(InstantiateNode)
def visit(self, node, tabs=0):
return '\t' * tabs + f'\\__ InstantiateNode: new {node.lex}()'