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.
@@ -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
@@ -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")