-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstackUtil.py
More file actions
125 lines (117 loc) · 5.07 KB
/
Copy pathstackUtil.py
File metadata and controls
125 lines (117 loc) · 5.07 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
from copy import copy
from varNameManager import VariableNameManager
if __name__ == "__main__":
import main
class StackUtil:
@staticmethod
def follow_index_stack(code, indexStack):
out = code
for k in indexStack:
out = out[k]
return out
@staticmethod
def follow_index_stack_set(code, indexStack, value):
if len(indexStack) == 0:
return value
code[indexStack[0]] = StackUtil.follow_index_stack_set(code[indexStack[0]], indexStack[1:], value)
return code
@staticmethod
def get_code_stack(stack):
"""Shortens the stack to just point to a code line (not a expression, var...)"""
codeStack = []
for k in stack:
if k in ['expression', 'condition', 'args', 'var']:
break
codeStack.append(k)
return codeStack
@staticmethod
def get_path_relative(path1, path2):
"""
If the paths are in the SAME scope it returns 'same'\n
If path1 is in a scope that path2 ends in it returns 'p1 in p2'\n
If path2 is in a scope that path1 ends in it returns 'p2 in p1'\n
If the paths are not connected it returns 'none'
"""
path1 = StackUtil.get_code_stack(path1)
path2 = StackUtil.get_code_stack(path2)
searchLen = len(path1)
if len(path1) > len(path2):
searchLen = len(path2)
searchLen -= 1
i = 0
while i < searchLen:
if path1[i] != path2[i]:
return 'none'
i+=1
if len(path1) > len(path2):
return 'p1 in p2'
elif len(path1) < len(path2):
return 'p2 in p1'
else:
return 'same'
@staticmethod
def remove_command(code:list, stack:list):
codeStack = StackUtil.get_code_stack(stack)
if len(codeStack) == 0:
raise Exception(f"can not remove command at {stack} because it does not goto a command")
listWithLine = StackUtil.follow_index_stack(code, codeStack[:-1])
del listWithLine[codeStack[-1]]
code = StackUtil.follow_index_stack_set(code, codeStack[:-1], listWithLine)
return code
@staticmethod
def get_var_usages(code, usageType:str = 'any'):
def get_var_usages_scan(code:list, indexStack:list, varUsageDict:dict, usageType:str):
block = StackUtil.follow_index_stack(code, indexStack)
if block == None:
return varUsageDict
if type(block) == dict:
i = 0
while i < len(block.keys()):
k = list(block.keys())[i]
if usageType == 'any':
if ('expression' in k) or ('condition' in k) or ('args' in k) or ('var' in k) or ('code' in k) or ('else' in k):
varUsageDict = get_var_usages_scan(code, indexStack + [k], varUsageDict, usageType)
elif usageType == 'set':
if ('var' in k) or ('code' in k) or ('else' in k):
varUsageDict = get_var_usages_scan(code, indexStack + [k], varUsageDict, usageType)
elif usageType == 'get':
if ('expression' in k) or ('condition' in k) or ('args' in k):
varUsageDict = get_var_usages_scan(code, indexStack + [k], varUsageDict, usageType)
i+=1
elif type(block) == list:
i = 0
while i < len(block):
varUsageDict = get_var_usages_scan(code, indexStack + [i], varUsageDict, usageType)
i += 1
else:
if VariableNameManager.isValidVarName(block):
if not block in varUsageDict:
varUsageDict[block] = []
varType = 'get'
if indexStack[len(indexStack)-1] == 'var':
if StackUtil.follow_index_stack(code, indexStack[:-1])['type'] == 'define':
varType = 'define'
else:
varType = 'set'
varUsageDict[block].append({'type': varType, 'stack': copy(indexStack)})
return varUsageDict
return get_var_usages_scan(code, [], {}, usageType)
@staticmethod
def add_line_paths(code):
def add_line_paths_scan(code, indexStack):
block = StackUtil.follow_index_stack(code, indexStack)
if type(block) == dict:
block['line_path'] = copy(indexStack)
i = 0
while i < len(block.keys()):
k = list(block.keys())[i]
if ('code' in k) or ('else' in k):
code = add_line_paths_scan(code, indexStack + [k])
i+=1
elif type(block) == list:
i = 0
while i < len(block):
varUsageDict = add_line_paths_scan(code, indexStack + [i])
i += 1
return code
return add_line_paths_scan(code, [])