-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathvarAnalysis.py
More file actions
160 lines (124 loc) · 4.2 KB
/
varAnalysis.py
File metadata and controls
160 lines (124 loc) · 4.2 KB
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
from compiler.ast import *
from HelperClasses import *
import astpp
#helper to combine the 2-tuple's innards
def combine(first, second):
f1, f2 = first
s1, s2 = second
return (f1 | s1, f2 | s2)
def varsModule(ast):
#need to do disjunct with free and written_to?
return getVars(ast.node)
def varsStmt(ast):
return reduce(lambda acc, n: combine(acc, getVars(n)), ast.nodes, (set(), set()))
def varsPrintnl(ast):
return getVars(ast.nodes[0])
def varsConst(ast):
return set(), set()
def varsUnarySub(ast):
return getVars(ast.expr)
def varsAdd(ast):
return combine(getVars(ast.left), getVars(ast.right))
def varsDiscard(ast):
return getVars(ast.expr)
def varsAssign(ast):
#TODO Find a better way to do this
if isinstance(ast.nodes[0], Subscript):
return combine(getVars(ast.nodes[0]), getVars(ast.expr))
else:
return combine(getVars(ast.nodes[0]), getVars(ast.expr))
def varsName(ast):
return set(), set([ast.name])
def varsAssName(ast):
return set([ast.name]), set()
def varsCallFunc(ast):
return combine(getVars(ast.node), reduce(lambda acc, arg: combine(acc, getVars(arg)), ast.args, (set(),set())))
def varsCallRuntime(ast):
return reduce(lambda acc, arg: combine(acc, getVars(arg)), ast.args, (set(),set()))
def varsCompare(ast):
return combine(getVars(ast.ops[0][1]), getVars(ast.expr))
def varsOr(ast):
return combine(getVars(ast.nodes[0]), getVars(ast.nodes[1]))
def varsAnd(ast):
return combine(getVars(ast.nodes[0]), getVars(ast.nodes[1]))
def varsNot(ast):
return getVars(ast.expr)
def varsList(ast):
return reduce(lambda acc, arg: combine(acc, getVars(arg)), ast.nodes, (set(),set()))
def varsDict(ast):
return reduce(lambda acc, (k,v): combine(combine(acc, getVars(k)), getVars(v)), ast.items, (set(),set()))
def varsSubscript(ast):
return combine(getVars(ast.expr), getVars(ast.subs[0]))
def varsIfExp(ast):
return combine(combine(getVars(ast.test), getVars(ast.then)), getVars(ast.else_))
def varsIf(ast):
return combine(combine(getVars(ast.tests[0][0]), getVars(ast.tests[0][1])), getVars(ast.else_))
def varsFunction(ast):
return set([ast.name]), set()
def varsLambda(ast):
return set(), set()
def varsReturn(ast):
return getVars(ast.value)
def varsWhile(ast):
return combine(getVars(ast.test), getVars(ast.body))
def varsClass(ast):
return set([ast.name]), set()
#Pretty sure this is wrong
def varsAssAttr(ast):
return combine(getVars(ast.expr), (set([ast.attrname]), set()))
def varsGetattr(ast):
return combine(getVars(ast.expr), (set(), set([ast.attrname])))
def varsGetTag(ast):
return getVars(ast.arg)
def varsInjectFrom(ast):
return getVars(ast.arg)
def varsProjectTo(ast):
return getVars(ast.arg)
def varsLet(ast):
if isinstance(ast.var, Subscript):
return combine(getVars(ast.var), combine(getVars(ast.rhs), getVars(ast.body)))
else:
return combine((set([ast.var.name]), set()), combine(getVars(ast.rhs), getVars(ast.body)))
def varsIsType(ast):
return getVars(ast.arg)
def varsThrowError(ast):
return set(), set()
#Returns a tuple of: set of all variables written to, set of all variables read from
#In the current scope only and does not recurse on functions and lambda's
def getVars(ast):
return {
Module: varsModule,
Stmt: varsStmt,
Printnl: varsPrintnl,
Const: varsConst,
UnarySub: varsUnarySub,
Add: varsAdd,
Discard: varsDiscard,
Assign: varsAssign,
Name: varsName,
AssName: varsAssName,
CallFunc: varsCallFunc,
CallRuntime: varsCallRuntime,
Compare: varsCompare,
Or: varsOr,
And: varsAnd,
Not: varsNot,
List: varsList,
Dict: varsDict,
Subscript: varsSubscript,
IfExp: varsIfExp,
If: varsIf,
Function: varsFunction,
Lambda: varsLambda,
Return: varsReturn,
While: varsWhile,
Class: varsClass,
AssAttr: varsAssAttr,
Getattr: varsGetattr,
GetTag: varsGetTag,
InjectFrom: varsInjectFrom,
ProjectTo: varsProjectTo,
Let: varsLet,
IsType: varsIsType,
ThrowError: varsThrowError
}[ast.__class__](ast)