-
Notifications
You must be signed in to change notification settings - Fork 38
/
Copy pathInstructions.py
159 lines (120 loc) · 4.21 KB
/
Instructions.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
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
# -*- coding: utf-8 -*-
from Patterns import *
class IfInst(object):
def __init__(self, cond, then, els=None):
self.cond = cond
self.then = then
self.els = els
def check(self, insn, ctx):
if insn.opname == "if" and self.cond.check(insn.cif.expr, ctx):
if self.then.check(insn.cif.ithen, ctx):
if self.els is not None:
if insn.cif.ielse is not None:
return self.els.check(insn.cif.ielse, ctx)
else:
return False
else:
return insn.cif.ielse is None
return False
class SingleInst(object):
def __init__(self, inner):
self.inner = inner
def check(self, insn, ctx):
#TODO: hmmm... isn't it a ExprInst?
#TODO: maybe will be good to rename class and add checking inside conditions
if insn.opname in ['block', 'if', 'for', 'while', 'do']:
return False
return self.inner.check(insn, ctx)
class EmptyInst(object):
def check(self, insn, ctx):
return insn.opname == "empty"
class BlockInst(object):
def __init__(self, nodes, strict=True):
self.nodes = nodes
self.strict = strict
def check_strict(self, inst, ctx):
if len(self.nodes) == len(inst.cblock):
same = True
for i in zip(self.nodes, inst.cblock):
same = same and i[0].check(i[1], ctx)
if not same:
break
return same
return False
def check(self, inst, ctx):
if inst.opname != "block":
return False
if self.strict:
return self.check_strict(inst, ctx)
ln = len(inst.cblock)
lnpat = len(self.nodes)
pos = 0
pospat = 0
flag = True
currpat = self.nodes[pospat]
nodes = [i for i in inst.cblock]
while pos < ln:
i = nodes[pos]
if type(currpat) == GreedyPattern:
if not currpat.check_greedy(i, ctx):
pos += 1
continue
else:
if not currpat.check(i, ctx):
flag = False
break
pospat += 1
if pospat == lnpat:
if pos + 1 == ln:
return True
else:
return False
currpat = self.nodes[pospat]
pos += 1
return flag
class SwitchInst(object):
def __init__(self, expr, cases):
self.expr = expr
self.cases = cases
def check(self, insn, ctx):
if insn.opname == "switch" and self.expr.check(insn.cswitch.expr, ctx):
# TODO: add properly checking of cases
return True
return False
class WhileInst(object):
def __init__(self, cond, body):
self.cond = cond
self.body = body
def check(self, insn, ctx):
if insn.opname == "while" and self.cond.check(insn.cwhile.expr, ctx):
return self.body.check(insn.cwhile.body, ctx)
return False
class DoInst(object):
def __init__(self, cond, body):
self.cond = cond
self.body = body
def check(self, insn, ctx):
if insn.opname == "do" and self.cond.check(insn.cdo.expr, ctx):
return self.body.check(insn.cdo.body, ctx)
return False
class ReturnInst(object):
def __init__(self, exp):
self.expr = exp
def check(self, insn, ctx):
return insn.opname == 'return' and self.expr.check(insn.creturn.expr, ctx)
class ExprInst(object):
def __init__(self, exp):
self.expr = exp
def check(self, expr, ctx):
return expr.opname == "expr" and self.expr.check(expr.cexpr, ctx)
class ForInst(object):
def __init__(self, init, expr, step, body):
self.init = init
self.expr = expr
self.step = step
self.body = body
def check(self, insn, ctx):
if insn.opname == "for" and self.init.check(insn.cfor.init, ctx):
return self.expr.check(insn.cfor.expr, ctx) and self.step.check(insn.cfor.step, ctx) \
and self.body.check(insn.cfor.body, ctx)
return False