llparse 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- llparse/C_compiler.py +204 -0
- llparse/__init__.py +2 -0
- llparse/compilator.py +1190 -0
- llparse/constants.py +48 -0
- llparse/cython_builder.py +311 -0
- llparse/debug.py +23 -0
- llparse/dot.py +213 -0
- llparse/enumerator.py +20 -0
- llparse/frontend.py +527 -0
- llparse/header.py +89 -0
- llparse/llparse.py +150 -0
- llparse/pybuilder/__init__.py +2 -0
- llparse/pybuilder/builder.py +318 -0
- llparse/pybuilder/loopchecker.py +246 -0
- llparse/pybuilder/main_code.py +548 -0
- llparse/pybuilder/parsemap.py +37 -0
- llparse/pyfront/containers.py +33 -0
- llparse/pyfront/front.py +189 -0
- llparse/pyfront/implementation.py +98 -0
- llparse/pyfront/namespace.py +1 -0
- llparse/pyfront/nodes.py +243 -0
- llparse/pyfront/peephole.py +45 -0
- llparse/pyfront/transform.py +21 -0
- llparse/settings.py +285 -0
- llparse/spanalloc.py +176 -0
- llparse/test.py +232 -0
- llparse/tire.py +158 -0
- llparse/trie.py +165 -0
- llparse-0.1.0.dist-info/METADATA +129 -0
- llparse-0.1.0.dist-info/RECORD +33 -0
- llparse-0.1.0.dist-info/WHEEL +5 -0
- llparse-0.1.0.dist-info/licenses/LICENSE +21 -0
- llparse-0.1.0.dist-info/top_level.txt +1 -0
llparse/pyfront/front.py
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# NOTE The Difference with typescript llparse is that names already
|
|
2
|
+
# taken by python standard library modules
|
|
3
|
+
# are renamed to something else.... - Vizonex
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass, field
|
|
6
|
+
from typing import Generic, Optional, TypeVar, Union
|
|
7
|
+
|
|
8
|
+
T = TypeVar("T")
|
|
9
|
+
|
|
10
|
+
Signature = TypeVar("Signature", bytes, str)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class IWrap(Generic[T]):
|
|
15
|
+
ref: T
|
|
16
|
+
|
|
17
|
+
def __hash__(self) -> int:
|
|
18
|
+
return hash(self.ref)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def toCacheKey(value: Union[int, bool]) -> str:
|
|
22
|
+
if isinstance(value, int):
|
|
23
|
+
return "m" + (-value) if value < 0 else "%i" % value
|
|
24
|
+
elif isinstance(value, bool):
|
|
25
|
+
return "true" if value else "false"
|
|
26
|
+
else:
|
|
27
|
+
raise ValueError(f"Unsupported value: {value}")
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass
|
|
31
|
+
class Code:
|
|
32
|
+
signature: Signature
|
|
33
|
+
cacheKey: str
|
|
34
|
+
name: str
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class External(Code):
|
|
38
|
+
"""Inherits from the `Code` class as a subclass of `Code`"""
|
|
39
|
+
|
|
40
|
+
def __init__(self, signature: Signature, name: str):
|
|
41
|
+
super().__init__(signature, "external_" + name, name)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@dataclass
|
|
45
|
+
class Field(Code):
|
|
46
|
+
"""Inherits from `Code`"""
|
|
47
|
+
|
|
48
|
+
field: str
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class FieldValueError(Exception):
|
|
52
|
+
"""FieldValue `value` must be integer"""
|
|
53
|
+
|
|
54
|
+
def __init__(self, *args: object) -> None:
|
|
55
|
+
super().__init__(*args)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class FieldValue(Field):
|
|
59
|
+
def __init__(
|
|
60
|
+
self, signature: Signature, cacheKey: str, name: str, field: str, value: int
|
|
61
|
+
):
|
|
62
|
+
self.value = value
|
|
63
|
+
if not isinstance(self.value, int):
|
|
64
|
+
raise FieldValueError(
|
|
65
|
+
f'FieldValue "value" must be integer not {type(self.value)}'
|
|
66
|
+
)
|
|
67
|
+
super().__init__(signature, cacheKey, name, field)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class And(FieldValue):
|
|
71
|
+
"""a Subclass of `FieldValue`"""
|
|
72
|
+
|
|
73
|
+
def __init__(self, name: str, field: str, value: int):
|
|
74
|
+
super().__init__(
|
|
75
|
+
"match", f"and_{field}_{toCacheKey(value)}", name, field, value
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class IsEqual(FieldValue):
|
|
80
|
+
def __init__(self, name: str, field: str, value: int):
|
|
81
|
+
super().__init__(
|
|
82
|
+
"match", f"is_equal_{field}_{toCacheKey(value)}", name, field, value
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class Load(Field):
|
|
87
|
+
"""Subclass of Field"""
|
|
88
|
+
|
|
89
|
+
def __init__(self, name: str, field: str):
|
|
90
|
+
super().__init__("match", f"load_{field}", name, field)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class Match(External):
|
|
94
|
+
def __init__(self, name: str):
|
|
95
|
+
super().__init__("match", name)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@dataclass
|
|
99
|
+
class IMulAddOptions:
|
|
100
|
+
base: int
|
|
101
|
+
max: Optional[int]
|
|
102
|
+
signed: bool
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def toOptionsKey(options: IMulAddOptions) -> str:
|
|
106
|
+
res = f"base_{toCacheKey(options.base)}"
|
|
107
|
+
if options.max:
|
|
108
|
+
res += f"_max_{toCacheKey(options.max)}"
|
|
109
|
+
if options.signed:
|
|
110
|
+
res += f"_signed_{toCacheKey(options.signed)}"
|
|
111
|
+
return res
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class MulAdd(Field):
|
|
115
|
+
def __init__(self, name: str, field: str, options: IMulAddOptions):
|
|
116
|
+
self.options = options
|
|
117
|
+
super().__init__(
|
|
118
|
+
"value", f"mul_add_{field}_{toOptionsKey(options)}", name, field
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class Or(FieldValue):
|
|
123
|
+
def __init__(self, name: str, field: str, value: int):
|
|
124
|
+
super().__init__("match", f"or_{field}_{toCacheKey(value)}", name, field, value)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class Span(External):
|
|
128
|
+
"""A `Span` Class"""
|
|
129
|
+
|
|
130
|
+
def __init__(self, name: str):
|
|
131
|
+
self.name = name
|
|
132
|
+
super().__init__("span", name)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
@dataclass
|
|
136
|
+
class SpanField:
|
|
137
|
+
index: int
|
|
138
|
+
callbacks: list[IWrap[Span]]
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class Store(Field):
|
|
142
|
+
def __init__(self, name: str, field: str):
|
|
143
|
+
super().__init__("value", f"store_{field}", name, field)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
class Test(FieldValue):
|
|
147
|
+
def __init__(self, name: str, field: str, value: int):
|
|
148
|
+
super().__init__(
|
|
149
|
+
"match", f"test_{field}_{toCacheKey(value)}", name, field, value
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
class Update(FieldValue):
|
|
154
|
+
def __init__(self, name: str, field: str, value: int):
|
|
155
|
+
super().__init__(
|
|
156
|
+
"match", f"update_{field}_{toCacheKey(value)}", name, field, value
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
class Value(External):
|
|
161
|
+
def __init__(self, name: str):
|
|
162
|
+
super().__init__("value", name)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
@dataclass
|
|
166
|
+
class IUniqueName:
|
|
167
|
+
name: str
|
|
168
|
+
originalName: str
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
@dataclass
|
|
172
|
+
class Identifier:
|
|
173
|
+
prefix: str
|
|
174
|
+
postfix: str = ""
|
|
175
|
+
ns: set[str] = field(default_factory=set, init=False)
|
|
176
|
+
|
|
177
|
+
def id(self, name: str) -> IUniqueName:
|
|
178
|
+
target = self.prefix + name + self.postfix
|
|
179
|
+
if target in self.ns:
|
|
180
|
+
i = 0
|
|
181
|
+
for i in range(1, len(self.ns)):
|
|
182
|
+
if (target + "_%i" % i) not in self.ns:
|
|
183
|
+
break
|
|
184
|
+
|
|
185
|
+
target += "_%i" % i
|
|
186
|
+
|
|
187
|
+
self.ns.add(target)
|
|
188
|
+
|
|
189
|
+
return IUniqueName(name=target, originalName=name)
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
from ..pyfront import front as code
|
|
2
|
+
from ..pyfront import nodes as node
|
|
3
|
+
from ..pyfront import transform
|
|
4
|
+
from ..pyfront.front import IWrap
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class INodeImplementation:
|
|
8
|
+
def __init__(self) -> None:
|
|
9
|
+
return
|
|
10
|
+
|
|
11
|
+
def Consume(self, n: node.Consume):
|
|
12
|
+
return IWrap(n)
|
|
13
|
+
|
|
14
|
+
def Empty(self, n: node.Empty):
|
|
15
|
+
return IWrap(n)
|
|
16
|
+
|
|
17
|
+
def Error(self, n: node.Error):
|
|
18
|
+
return IWrap(n)
|
|
19
|
+
|
|
20
|
+
def Pause(self, n: node.Pause):
|
|
21
|
+
return IWrap(n)
|
|
22
|
+
|
|
23
|
+
def Invoke(self, n: node.Invoke):
|
|
24
|
+
return IWrap(n)
|
|
25
|
+
|
|
26
|
+
def Sequence(self, n: node.Sequence):
|
|
27
|
+
return IWrap(n)
|
|
28
|
+
|
|
29
|
+
def Single(self, n: node.Single):
|
|
30
|
+
return IWrap(n)
|
|
31
|
+
|
|
32
|
+
def SpanEnd(self, n: node.SpanEnd):
|
|
33
|
+
return IWrap(n)
|
|
34
|
+
|
|
35
|
+
def SpanStart(self, n: node.SpanStart):
|
|
36
|
+
return IWrap(n)
|
|
37
|
+
|
|
38
|
+
def TableLookup(self, n: node.TableLookup):
|
|
39
|
+
return IWrap(n)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class ITransformImplementation:
|
|
43
|
+
def __init__(self) -> None:
|
|
44
|
+
return
|
|
45
|
+
|
|
46
|
+
def ID(self, t: transform.ID):
|
|
47
|
+
return IWrap(t)
|
|
48
|
+
|
|
49
|
+
def ToLower(self, t: transform.ToLower):
|
|
50
|
+
return IWrap(t)
|
|
51
|
+
|
|
52
|
+
def ToLowerUnsafe(self, t: transform.ToLowerUnsafe):
|
|
53
|
+
return IWrap(t)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class ICodeImplementation:
|
|
57
|
+
def __init__(self) -> None:
|
|
58
|
+
return
|
|
59
|
+
|
|
60
|
+
def And(self, c: code.And):
|
|
61
|
+
return IWrap(c)
|
|
62
|
+
|
|
63
|
+
def Load(self, c: code.Load):
|
|
64
|
+
return IWrap(c)
|
|
65
|
+
|
|
66
|
+
def IsEqual(self, c: code.IsEqual):
|
|
67
|
+
return IWrap(c)
|
|
68
|
+
|
|
69
|
+
def Match(self, c: code.Match):
|
|
70
|
+
return IWrap(c)
|
|
71
|
+
|
|
72
|
+
def MulAdd(self, c: code.MulAdd):
|
|
73
|
+
return IWrap(c)
|
|
74
|
+
|
|
75
|
+
def Or(self, c: code.Or):
|
|
76
|
+
return IWrap(c)
|
|
77
|
+
|
|
78
|
+
def Span(self, c: code.Span):
|
|
79
|
+
return IWrap(c)
|
|
80
|
+
|
|
81
|
+
def Store(self, c: code.Store):
|
|
82
|
+
return IWrap(c)
|
|
83
|
+
|
|
84
|
+
def Test(self, c: code.Test):
|
|
85
|
+
return IWrap(c)
|
|
86
|
+
|
|
87
|
+
def Update(self, c: code.Update):
|
|
88
|
+
return IWrap(c)
|
|
89
|
+
|
|
90
|
+
def Value(self, c: code.Value):
|
|
91
|
+
return IWrap(c)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class IImplementation:
|
|
95
|
+
def __init__(self) -> None:
|
|
96
|
+
self.code = ICodeImplementation()
|
|
97
|
+
self.node = INodeImplementation()
|
|
98
|
+
self.transform = ITransformImplementation()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from ..pyfront import transform as transform
|
llparse/pyfront/nodes.py
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
from typing import Any, Optional
|
|
3
|
+
|
|
4
|
+
from ..pyfront.front import Code, IWrap, Span, SpanField
|
|
5
|
+
from ..pyfront.transform import Transform
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Slot:
|
|
9
|
+
# ONLY NODE SHOULD BE ALLOWED TO BE SEEN
|
|
10
|
+
|
|
11
|
+
def __init__(self, node: IWrap["Node"], value: Any) -> None:
|
|
12
|
+
self.privNode = node
|
|
13
|
+
"""Same as calling it from get and setting the value etc..."""
|
|
14
|
+
self.privUpdate = value
|
|
15
|
+
|
|
16
|
+
# TODO Vizonex Figure out how to actually implement
|
|
17
|
+
# Slots -> private readonly privUpdate: (value: IWrap<Node>) => void
|
|
18
|
+
# For Now use this backup by using the unique name to hash the values
|
|
19
|
+
# I spent 4 hours trying to figure this how this could be implemented
|
|
20
|
+
# so this is my only ideal sloution
|
|
21
|
+
def __hash__(self) -> int:
|
|
22
|
+
return hash(self.privUpdate.ref.id.name)
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def node(self):
|
|
26
|
+
return self.privNode
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class IUniqueName:
|
|
31
|
+
name: str
|
|
32
|
+
originalName: str
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@dataclass
|
|
36
|
+
class IOtherwiseEdge:
|
|
37
|
+
node: IWrap["Node"]
|
|
38
|
+
noAdvance: bool
|
|
39
|
+
value: Optional[int]
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@dataclass
|
|
43
|
+
class Identifier:
|
|
44
|
+
prefix: str = ""
|
|
45
|
+
postfix: str = ""
|
|
46
|
+
ns: set[str] = field(default_factory=set, init=False)
|
|
47
|
+
|
|
48
|
+
def id(self, name: str):
|
|
49
|
+
"""Creates a Unique name for the switches"""
|
|
50
|
+
target = self.prefix + name + self.postfix
|
|
51
|
+
|
|
52
|
+
if target in self.ns:
|
|
53
|
+
i = 1
|
|
54
|
+
for i in range(1, len(self.ns)):
|
|
55
|
+
if (target + "_%i" % i) not in self.ns:
|
|
56
|
+
break
|
|
57
|
+
target += "_%i" % i
|
|
58
|
+
|
|
59
|
+
self.ns.add(target)
|
|
60
|
+
return IUniqueName(target, name)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@dataclass
|
|
64
|
+
class Node:
|
|
65
|
+
id: IUniqueName
|
|
66
|
+
otherwise: Optional[IOtherwiseEdge] = field(default=None, init=False)
|
|
67
|
+
Slots: Optional[list[Slot]] = field(default_factory=list, init=False)
|
|
68
|
+
|
|
69
|
+
def setOtherwise(
|
|
70
|
+
self, node: IWrap["Node"], noAdvance: bool, value: Optional[int] = None
|
|
71
|
+
):
|
|
72
|
+
self.otherwise = IOtherwiseEdge(node, noAdvance, value)
|
|
73
|
+
|
|
74
|
+
def getSlots(self):
|
|
75
|
+
if self.Slots == []:
|
|
76
|
+
self.Slots.extend(self.buildSlots())
|
|
77
|
+
yield from self.Slots
|
|
78
|
+
|
|
79
|
+
def buildSlots(self):
|
|
80
|
+
otherwise = self.otherwise
|
|
81
|
+
if otherwise:
|
|
82
|
+
yield Slot(otherwise.node, otherwise.node)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class Consume(Node):
|
|
86
|
+
def __init__(self, id: IUniqueName, field: str) -> None:
|
|
87
|
+
self.field = field
|
|
88
|
+
super().__init__(id)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@dataclass
|
|
92
|
+
class IInvokeEdge:
|
|
93
|
+
code: int
|
|
94
|
+
node: IWrap[Node]
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class Invoke(Node):
|
|
98
|
+
def __init__(self, id: IUniqueName, code: IWrap[Code]) -> None:
|
|
99
|
+
self.Edges: list[IInvokeEdge] = []
|
|
100
|
+
self.code = code
|
|
101
|
+
super().__init__(id)
|
|
102
|
+
|
|
103
|
+
def addEdge(self, code: int, node: IWrap[Node]):
|
|
104
|
+
self.Edges.append(IInvokeEdge(code, node))
|
|
105
|
+
|
|
106
|
+
def edges(self):
|
|
107
|
+
return self.Edges
|
|
108
|
+
|
|
109
|
+
def buildSlots(self):
|
|
110
|
+
for edge in self.Edges:
|
|
111
|
+
yield Slot(edge.node, edge.node)
|
|
112
|
+
|
|
113
|
+
for e in super().buildSlots():
|
|
114
|
+
yield e
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
class Empty(Node):
|
|
118
|
+
def __init__(self, id: IUniqueName) -> None:
|
|
119
|
+
super().__init__(id)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class Error(Node):
|
|
123
|
+
def __init__(self, id: IUniqueName, code: int, reason: str) -> None:
|
|
124
|
+
self.code = code
|
|
125
|
+
self.reason = reason
|
|
126
|
+
super().__init__(id)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class Match(Node):
|
|
130
|
+
def __init__(self, id: IUniqueName) -> None:
|
|
131
|
+
self.transform: Optional[IWrap[Transform]] = None
|
|
132
|
+
super().__init__(id)
|
|
133
|
+
|
|
134
|
+
def setTransform(self, transform: IWrap[Transform]):
|
|
135
|
+
self.transform = transform
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class Pause(Error):
|
|
139
|
+
def __init__(self, id: IUniqueName, code: int, reason: str) -> None:
|
|
140
|
+
super().__init__(id, code, reason)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
@dataclass
|
|
144
|
+
class ISeqEdge:
|
|
145
|
+
node: IWrap[Node]
|
|
146
|
+
value: Optional[int]
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
# TODO Make Sure TypeHinting doesn't overlap with the Real Sequence typehint!
|
|
150
|
+
# So I'll add an extra S to it for now...
|
|
151
|
+
class Sequence(Match):
|
|
152
|
+
def __init__(self, id: IUniqueName, select: str) -> None:
|
|
153
|
+
self.select = select
|
|
154
|
+
self.Edge: Optional[ISeqEdge] = None
|
|
155
|
+
super().__init__(id)
|
|
156
|
+
|
|
157
|
+
def setEdge(self, node: Node, value: Optional[int]):
|
|
158
|
+
assert True if not self.Edge else False
|
|
159
|
+
self.Edge = ISeqEdge(node, value)
|
|
160
|
+
|
|
161
|
+
def buildSlots(self):
|
|
162
|
+
edge = self.Edge
|
|
163
|
+
yield Slot(edge.node, edge.node)
|
|
164
|
+
for e in super().buildSlots():
|
|
165
|
+
yield e
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
class SpanStart(Node):
|
|
169
|
+
def __init__(
|
|
170
|
+
self, id: IUniqueName, field: SpanField, callback: IWrap[Span]
|
|
171
|
+
) -> None:
|
|
172
|
+
self.field = field
|
|
173
|
+
self.callback = callback
|
|
174
|
+
super().__init__(id)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
class SpanEnd(Node):
|
|
178
|
+
def __init__(
|
|
179
|
+
self, id: IUniqueName, field: SpanField, callback: IWrap[Span]
|
|
180
|
+
) -> None:
|
|
181
|
+
self.field = field
|
|
182
|
+
self.callback = callback
|
|
183
|
+
super().__init__(id)
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
@dataclass
|
|
187
|
+
class ISingleEdge:
|
|
188
|
+
key: int
|
|
189
|
+
node: IWrap[Node]
|
|
190
|
+
noAdvance: bool
|
|
191
|
+
value: Optional[int] = None
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
class Single(Match):
|
|
195
|
+
def __init__(self, id: IUniqueName) -> None:
|
|
196
|
+
self.privEdges: list[ISingleEdge] = []
|
|
197
|
+
|
|
198
|
+
super().__init__(id)
|
|
199
|
+
|
|
200
|
+
def addEdge(
|
|
201
|
+
self, key: int, node: IWrap[Node], noAdvance: bool, value: Optional[int] = None
|
|
202
|
+
):
|
|
203
|
+
self.privEdges.append(ISingleEdge(key, node, noAdvance, value))
|
|
204
|
+
|
|
205
|
+
@property
|
|
206
|
+
def edges(self):
|
|
207
|
+
return self.privEdges
|
|
208
|
+
|
|
209
|
+
def buildSlots(self):
|
|
210
|
+
for edge in self.privEdges:
|
|
211
|
+
yield Slot(edge.node, edge.node)
|
|
212
|
+
return super().buildSlots()
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
@dataclass
|
|
216
|
+
class ITableEdge:
|
|
217
|
+
keys: list[int]
|
|
218
|
+
node: IWrap[Node]
|
|
219
|
+
noAdvance: bool
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
class TableLookup(Match):
|
|
223
|
+
def __init__(self, id: IUniqueName) -> None:
|
|
224
|
+
self.privEdges: list[ITableEdge] = []
|
|
225
|
+
super().__init__(id)
|
|
226
|
+
|
|
227
|
+
def addEdge(self, edge: ITableEdge):
|
|
228
|
+
self.privEdges.append(edge)
|
|
229
|
+
|
|
230
|
+
def buildSlots(self):
|
|
231
|
+
edge = self.privEdges
|
|
232
|
+
for e in edge:
|
|
233
|
+
yield Slot(e.node, e.node)
|
|
234
|
+
for e in super().buildSlots():
|
|
235
|
+
yield e
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
# Ident = Identifier("llComment")
|
|
239
|
+
|
|
240
|
+
# node = Node(Ident.id("__On_Pagesum"))
|
|
241
|
+
|
|
242
|
+
# node2 = Invoke(Ident.id("Check_Flag"),IsEqual("Flag","Check_Flag",0))
|
|
243
|
+
# node2.setOtherwise(IWrap(node),True,0)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from ..pyfront.front import IWrap
|
|
2
|
+
from ..pyfront.nodes import Empty, Node
|
|
3
|
+
|
|
4
|
+
WrapNode = IWrap[Node]
|
|
5
|
+
WrapList = list[WrapNode]
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# TODO (Vizonex) Make peephole into 2 seperate functions instead of a class to
|
|
9
|
+
# Optimize everything down further...
|
|
10
|
+
class Peephole:
|
|
11
|
+
def optimize(self, root: WrapNode, nodes: WrapList):
|
|
12
|
+
changed = set(nodes)
|
|
13
|
+
|
|
14
|
+
while len(changed) != 0:
|
|
15
|
+
previous = changed
|
|
16
|
+
changed = set()
|
|
17
|
+
|
|
18
|
+
for node in previous:
|
|
19
|
+
if self.optimizeNode(node):
|
|
20
|
+
changed.add(node)
|
|
21
|
+
|
|
22
|
+
while isinstance(root.ref, Empty):
|
|
23
|
+
if not root.ref.otherwise or not root.ref.otherwise.noAdvance:
|
|
24
|
+
break
|
|
25
|
+
root = root.ref.otherwise.node
|
|
26
|
+
|
|
27
|
+
return root
|
|
28
|
+
|
|
29
|
+
def optimizeNode(self, node: WrapNode):
|
|
30
|
+
changed = False
|
|
31
|
+
for slot in node.ref.getSlots():
|
|
32
|
+
# TODO Find an Actual way to check that a Node maybe empty...
|
|
33
|
+
if not isinstance(slot.node.ref, Empty) or not slot.node.ref.otherwise:
|
|
34
|
+
continue
|
|
35
|
+
|
|
36
|
+
otherwise = slot.node.ref.otherwise
|
|
37
|
+
|
|
38
|
+
# Node skips so we cannot optimize
|
|
39
|
+
if not otherwise.noAdvance:
|
|
40
|
+
continue
|
|
41
|
+
|
|
42
|
+
slot.node.ref = otherwise.node.ref
|
|
43
|
+
|
|
44
|
+
changed = True
|
|
45
|
+
return changed
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
@dataclass
|
|
5
|
+
class Transform:
|
|
6
|
+
name: str
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ID(Transform):
|
|
10
|
+
def __init__(self) -> None:
|
|
11
|
+
super().__init__("id")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ToLowerUnsafe(Transform):
|
|
15
|
+
def __init__(self) -> None:
|
|
16
|
+
super().__init__("to_lower_unsafe")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ToLower(Transform):
|
|
20
|
+
def __init__(self) -> None:
|
|
21
|
+
super().__init__("to_lower")
|