dshellInterpreter 0.2.21.7__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.
- Dshell/DISCORD_COMMANDS/__init__.py +7 -0
- Dshell/DISCORD_COMMANDS/dshell_channel.py +612 -0
- Dshell/DISCORD_COMMANDS/dshell_interaction.py +89 -0
- Dshell/DISCORD_COMMANDS/dshell_member.py +274 -0
- Dshell/DISCORD_COMMANDS/dshell_message.py +444 -0
- Dshell/DISCORD_COMMANDS/dshell_pastbin.py +28 -0
- Dshell/DISCORD_COMMANDS/dshell_role.py +128 -0
- Dshell/DISCORD_COMMANDS/utils/__init__.py +8 -0
- Dshell/DISCORD_COMMANDS/utils/utils_global.py +155 -0
- Dshell/DISCORD_COMMANDS/utils/utils_list.py +109 -0
- Dshell/DISCORD_COMMANDS/utils/utils_member.py +30 -0
- Dshell/DISCORD_COMMANDS/utils/utils_message.py +78 -0
- Dshell/DISCORD_COMMANDS/utils/utils_permissions.py +94 -0
- Dshell/DISCORD_COMMANDS/utils/utils_string.py +157 -0
- Dshell/DISCORD_COMMANDS/utils/utils_thread.py +35 -0
- Dshell/_DshellInterpreteur/__init__.py +4 -0
- Dshell/_DshellInterpreteur/cached_messages.py +4 -0
- Dshell/_DshellInterpreteur/dshell_arguments.py +74 -0
- Dshell/_DshellInterpreteur/dshell_interpreter.py +671 -0
- Dshell/_DshellInterpreteur/errors.py +8 -0
- Dshell/_DshellParser/__init__.py +2 -0
- Dshell/_DshellParser/ast_nodes.py +675 -0
- Dshell/_DshellParser/dshell_parser.py +408 -0
- Dshell/_DshellTokenizer/__init__.py +4 -0
- Dshell/_DshellTokenizer/dshell_keywords.py +193 -0
- Dshell/_DshellTokenizer/dshell_token_type.py +58 -0
- Dshell/_DshellTokenizer/dshell_tokenizer.py +146 -0
- Dshell/__init__.py +3 -0
- Dshell/_utils.py +1 -0
- dshellinterpreter-0.2.21.7.dist-info/METADATA +37 -0
- dshellinterpreter-0.2.21.7.dist-info/RECORD +34 -0
- dshellinterpreter-0.2.21.7.dist-info/WHEEL +5 -0
- dshellinterpreter-0.2.21.7.dist-info/licenses/LICENSE +21 -0
- dshellinterpreter-0.2.21.7.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,675 @@
|
|
|
1
|
+
from random import randint
|
|
2
|
+
from typing import Optional, Any, Union
|
|
3
|
+
|
|
4
|
+
from .._DshellTokenizer.dshell_token_type import Token
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
'ASTNode',
|
|
8
|
+
'LengthNode',
|
|
9
|
+
'StartNode',
|
|
10
|
+
'ElseNode',
|
|
11
|
+
'ElifNode',
|
|
12
|
+
'IfNode',
|
|
13
|
+
'LoopNode',
|
|
14
|
+
'ArgsCommandNode',
|
|
15
|
+
'CommandNode',
|
|
16
|
+
'VarNode',
|
|
17
|
+
'EndNode',
|
|
18
|
+
'FieldEmbedNode',
|
|
19
|
+
'EmbedNode',
|
|
20
|
+
'SleepNode',
|
|
21
|
+
'ListNode',
|
|
22
|
+
'PermissionNode',
|
|
23
|
+
'EvalGroupNode',
|
|
24
|
+
'ParamNode',
|
|
25
|
+
'UiNode',
|
|
26
|
+
'UiButtonNode',
|
|
27
|
+
'UiSelectNode'
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class ASTNode:
|
|
32
|
+
"""
|
|
33
|
+
Base class for all AST nodes.
|
|
34
|
+
"""
|
|
35
|
+
pass
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class StartNode(ASTNode):
|
|
39
|
+
"""
|
|
40
|
+
Node representing the start of the AST.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
def __init__(self, body: list):
|
|
44
|
+
self.body = body
|
|
45
|
+
|
|
46
|
+
def __repr__(self):
|
|
47
|
+
return f"<StartNode> - {self.body}"
|
|
48
|
+
|
|
49
|
+
def to_dict(self):
|
|
50
|
+
"""
|
|
51
|
+
Convert the StartNode to a dictionary representation.
|
|
52
|
+
:return: Dictionary representation of the StartNode.
|
|
53
|
+
"""
|
|
54
|
+
return {
|
|
55
|
+
"type": "StartNode",
|
|
56
|
+
"body": [token.to_dict() for token in self.body]
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class ElseNode(ASTNode):
|
|
61
|
+
"""
|
|
62
|
+
Node representing the 'else' part of an if statement.
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
def __init__(self, body: list[Token]):
|
|
66
|
+
"""
|
|
67
|
+
:param body: list of tokens representing the body of the else statement
|
|
68
|
+
"""
|
|
69
|
+
self.body = body
|
|
70
|
+
|
|
71
|
+
def __repr__(self):
|
|
72
|
+
return f"<Else> - {self.body}"
|
|
73
|
+
|
|
74
|
+
def to_dict(self):
|
|
75
|
+
"""
|
|
76
|
+
Convert the ElseNode to a dictionary representation.
|
|
77
|
+
:return: Dictionary representation of the ElseNode.
|
|
78
|
+
"""
|
|
79
|
+
return {
|
|
80
|
+
"type": "ElseNode",
|
|
81
|
+
"body": [token.to_dict() for token in self.body]
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class ElifNode(ASTNode):
|
|
86
|
+
"""
|
|
87
|
+
Node representing an 'elif' part of an if statement.
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
def __init__(self, condition: list[Token], body: list[Token], parent: "IfNode"):
|
|
91
|
+
"""
|
|
92
|
+
:param condition: list of tokens representing the condition for the elif
|
|
93
|
+
:param body: list of tokens representing the body of the elif
|
|
94
|
+
:param parent: the if node that this elif belongs to
|
|
95
|
+
"""
|
|
96
|
+
self.condition = condition
|
|
97
|
+
self.body = body
|
|
98
|
+
self.parent = parent
|
|
99
|
+
|
|
100
|
+
def __repr__(self):
|
|
101
|
+
return f"<Elif> - {self.condition} - {self.body}"
|
|
102
|
+
|
|
103
|
+
def to_dict(self):
|
|
104
|
+
"""
|
|
105
|
+
Convert the ElifNode to a dictionary representation.
|
|
106
|
+
:return: Dictionary representation of the ElifNode.
|
|
107
|
+
"""
|
|
108
|
+
return {
|
|
109
|
+
"type": "ElifNode",
|
|
110
|
+
"condition": [token.to_dict() for token in self.condition],
|
|
111
|
+
"body": [token.to_dict() for token in self.body],
|
|
112
|
+
"parent": self.parent.id # Assuming parent is an IfNode, we store its ID
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class IfNode(ASTNode):
|
|
117
|
+
"""
|
|
118
|
+
Node representing an 'if' statement, which can contain 'elif' and 'else' parts.
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
def __init__(self, condition: list[Token], body: list[Token], elif_nodes: Optional[list[ElifNode]] = None,
|
|
122
|
+
else_body: Optional[ElseNode] = None):
|
|
123
|
+
"""
|
|
124
|
+
:param condition: list of tokens representing the condition for the if statement
|
|
125
|
+
:param body: list of tokens representing the body of the if statement
|
|
126
|
+
:param elif_nodes: optional list of ElifNode instances representing 'elif' parts
|
|
127
|
+
:param else_body: optional ElseNode instance representing the 'else' part
|
|
128
|
+
"""
|
|
129
|
+
self.condition = condition
|
|
130
|
+
self.body = body
|
|
131
|
+
self.elif_nodes = elif_nodes
|
|
132
|
+
self.else_body = else_body
|
|
133
|
+
self.id = randint(0, 1000000) # Unique identifier for the IfNode instance
|
|
134
|
+
|
|
135
|
+
def __repr__(self):
|
|
136
|
+
return f"<If> - {self.condition} - {self.body} *- {self.elif_nodes} **- {self.else_body}"
|
|
137
|
+
|
|
138
|
+
def to_dict(self):
|
|
139
|
+
"""
|
|
140
|
+
Convert the IfNode to a dictionary representation.
|
|
141
|
+
:return: Dictionary representation of the IfNode.
|
|
142
|
+
"""
|
|
143
|
+
return {
|
|
144
|
+
"type": "IfNode",
|
|
145
|
+
"condition": [token.to_dict() for token in self.condition],
|
|
146
|
+
"body": [token.to_dict() for token in self.body],
|
|
147
|
+
"elif_nodes": [elif_node.to_dict() for elif_node in self.elif_nodes] if self.elif_nodes else None,
|
|
148
|
+
"else_body": self.else_body.to_dict() if self.else_body else None,
|
|
149
|
+
"id": self.id
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
class LoopNode(ASTNode):
|
|
154
|
+
"""
|
|
155
|
+
Node representing a loop structure in the AST.
|
|
156
|
+
"""
|
|
157
|
+
|
|
158
|
+
def __init__(self, variable: "VarNode", body: list):
|
|
159
|
+
"""
|
|
160
|
+
:param variable: VarNode representing the loop variable. This variable will be used to iterate over the body. Can contain a ListNode, string or integer.
|
|
161
|
+
:param body: list of tokens representing the body of the loop
|
|
162
|
+
"""
|
|
163
|
+
self.variable = variable
|
|
164
|
+
self.body = body
|
|
165
|
+
|
|
166
|
+
def __repr__(self):
|
|
167
|
+
return f"<Loop> - {self.variable.name} -> {self.variable.body} *- {self.body}"
|
|
168
|
+
|
|
169
|
+
def to_dict(self):
|
|
170
|
+
"""
|
|
171
|
+
Convert the LoopNode to a dictionary representation.
|
|
172
|
+
:return: Dictionary representation of the LoopNode.
|
|
173
|
+
"""
|
|
174
|
+
return {
|
|
175
|
+
"type": "LoopNode",
|
|
176
|
+
"variable": self.variable.to_dict(),
|
|
177
|
+
"body": [token.to_dict() for token in self.body]
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
class ArgsCommandNode(ASTNode):
|
|
182
|
+
"""
|
|
183
|
+
Node representing the arguments of a command in the AST.
|
|
184
|
+
"""
|
|
185
|
+
|
|
186
|
+
def __init__(self, body: list[Token]):
|
|
187
|
+
"""
|
|
188
|
+
:param body: list of tokens representing the arguments of the command
|
|
189
|
+
"""
|
|
190
|
+
self.body: list[Token] = body
|
|
191
|
+
|
|
192
|
+
def __repr__(self):
|
|
193
|
+
return f"<Args Command> - {self.body}"
|
|
194
|
+
|
|
195
|
+
def to_dict(self):
|
|
196
|
+
"""
|
|
197
|
+
Convert the ArgsCommandNode to a dictionary representation.
|
|
198
|
+
:return: Dictionary representation of the ArgsCommandNode.
|
|
199
|
+
"""
|
|
200
|
+
return {
|
|
201
|
+
"type": "ArgsCommandNode",
|
|
202
|
+
"body": [token.to_dict() for token in self.body]
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
class CommandNode(ASTNode):
|
|
207
|
+
"""
|
|
208
|
+
Node representing a command in the AST.
|
|
209
|
+
"""
|
|
210
|
+
|
|
211
|
+
def __init__(self, name: str, body: ArgsCommandNode):
|
|
212
|
+
"""
|
|
213
|
+
:param name: The command name (e.g., "sm", "cc")
|
|
214
|
+
:param body: ArgsCommandNode containing the arguments of the command
|
|
215
|
+
"""
|
|
216
|
+
self.name = name
|
|
217
|
+
self.body = body
|
|
218
|
+
|
|
219
|
+
def __repr__(self):
|
|
220
|
+
return f"<{self.name}> - {self.body}"
|
|
221
|
+
|
|
222
|
+
def to_dict(self):
|
|
223
|
+
"""
|
|
224
|
+
Convert the CommandNode to a dictionary representation.
|
|
225
|
+
:return: Dictionary representation of the CommandNode.
|
|
226
|
+
"""
|
|
227
|
+
return {
|
|
228
|
+
"type": "CommandNode",
|
|
229
|
+
"name": self.name,
|
|
230
|
+
"body": self.body.to_dict()
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
class VarNode(ASTNode):
|
|
235
|
+
"""
|
|
236
|
+
Node representing a variable declaration in the AST.
|
|
237
|
+
"""
|
|
238
|
+
|
|
239
|
+
def __init__(self, name: Token, body: list[Token]):
|
|
240
|
+
"""
|
|
241
|
+
:param name: Token representing the variable name
|
|
242
|
+
:param body: list of tokens representing the body of the variable
|
|
243
|
+
"""
|
|
244
|
+
self.name = name
|
|
245
|
+
self.body = body
|
|
246
|
+
|
|
247
|
+
def __repr__(self):
|
|
248
|
+
return f"<VAR> - {self.name} *- {self.body}"
|
|
249
|
+
|
|
250
|
+
def to_dict(self):
|
|
251
|
+
"""
|
|
252
|
+
Convert the VarNode to a dictionary representation.
|
|
253
|
+
:return: Dictionary representation of the VarNode.
|
|
254
|
+
"""
|
|
255
|
+
return {
|
|
256
|
+
"type": "VarNode",
|
|
257
|
+
"name": self.name.to_dict(),
|
|
258
|
+
"body": [token.to_dict() for token in self.body]
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
class LengthNode(ASTNode):
|
|
262
|
+
"""
|
|
263
|
+
Node representing the length operation in the AST.
|
|
264
|
+
"""
|
|
265
|
+
|
|
266
|
+
def __init__(self, body: Token):
|
|
267
|
+
"""
|
|
268
|
+
:param body: list of tokens representing the body of the length operation
|
|
269
|
+
"""
|
|
270
|
+
self.body = body
|
|
271
|
+
|
|
272
|
+
def __repr__(self):
|
|
273
|
+
return f"<LENGTH> - {self.body}"
|
|
274
|
+
|
|
275
|
+
def to_dict(self):
|
|
276
|
+
"""
|
|
277
|
+
Convert the LengthNode to a dictionary representation.
|
|
278
|
+
:return: Dictionary representation of the LengthNode.
|
|
279
|
+
"""
|
|
280
|
+
return {
|
|
281
|
+
"type": "LengthNode",
|
|
282
|
+
"body": self.body.to_dict()
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
class EndNode(ASTNode):
|
|
286
|
+
"""
|
|
287
|
+
Node representing the end of the AST.
|
|
288
|
+
"""
|
|
289
|
+
|
|
290
|
+
def __init__(self, error_message: Union[Token, bool] = True):
|
|
291
|
+
self.error_message: bool = error_message
|
|
292
|
+
|
|
293
|
+
def __repr__(self):
|
|
294
|
+
return f"<END>"
|
|
295
|
+
|
|
296
|
+
def to_dict(self):
|
|
297
|
+
"""
|
|
298
|
+
Convert the EndNode to a dictionary representation.
|
|
299
|
+
:return: Dictionary representation of the EndNode.
|
|
300
|
+
"""
|
|
301
|
+
return {
|
|
302
|
+
"type": "EndNode",
|
|
303
|
+
"error_message": self.error_message
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
class FieldEmbedNode(ASTNode):
|
|
308
|
+
"""
|
|
309
|
+
Node representing a field in an embed structure.
|
|
310
|
+
"""
|
|
311
|
+
|
|
312
|
+
def __init__(self, body: list[Token]):
|
|
313
|
+
"""
|
|
314
|
+
:param body: list of tokens representing the field content
|
|
315
|
+
"""
|
|
316
|
+
self.body: list[Token] = body
|
|
317
|
+
|
|
318
|
+
def __repr__(self):
|
|
319
|
+
return f"<EMBED_FIELD> - {self.body}"
|
|
320
|
+
|
|
321
|
+
def to_dict(self):
|
|
322
|
+
"""
|
|
323
|
+
Convert the FieldEmbedNode to a dictionary representation.
|
|
324
|
+
:return: Dictionary representation of the FieldEmbedNode.
|
|
325
|
+
"""
|
|
326
|
+
return {
|
|
327
|
+
"type": "FieldEmbedNode",
|
|
328
|
+
"body": [token.to_dict() for token in self.body]
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
class EmbedNode(ASTNode):
|
|
333
|
+
"""
|
|
334
|
+
Node representing an embed structure in the AST.
|
|
335
|
+
"""
|
|
336
|
+
|
|
337
|
+
def __init__(self, body: list[Token], fields: list[FieldEmbedNode]):
|
|
338
|
+
"""
|
|
339
|
+
:param body: list of tokens representing the embed content
|
|
340
|
+
:param fields: list of FieldEmbedNode instances representing the fields of the embed
|
|
341
|
+
"""
|
|
342
|
+
self.body = body
|
|
343
|
+
self.fields = fields
|
|
344
|
+
|
|
345
|
+
def __repr__(self):
|
|
346
|
+
return f"<EMBED> - {self.body}"
|
|
347
|
+
|
|
348
|
+
def to_dict(self):
|
|
349
|
+
"""
|
|
350
|
+
Convert the EmbedNode to a dictionary representation.
|
|
351
|
+
:return: Dictionary representation of the EmbedNode.
|
|
352
|
+
"""
|
|
353
|
+
return {
|
|
354
|
+
"type": "EmbedNode",
|
|
355
|
+
"body": [token.to_dict() for token in self.body],
|
|
356
|
+
"fields": [field.to_dict() for field in self.fields]
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
class PermissionNode(ASTNode):
|
|
361
|
+
"""
|
|
362
|
+
Node representing a permission structure in the AST.
|
|
363
|
+
"""
|
|
364
|
+
|
|
365
|
+
def __init__(self, body: list[Token]):
|
|
366
|
+
"""
|
|
367
|
+
:param body: list of tokens representing the permission content
|
|
368
|
+
"""
|
|
369
|
+
self.body = body
|
|
370
|
+
|
|
371
|
+
def __repr__(self):
|
|
372
|
+
return f"<PERMISSION> - {self.body}"
|
|
373
|
+
|
|
374
|
+
def to_dict(self):
|
|
375
|
+
"""
|
|
376
|
+
Convert the PermissionNode to a dictionary representation.
|
|
377
|
+
:return: Dictionary representation of the PermissionNode.
|
|
378
|
+
"""
|
|
379
|
+
return {
|
|
380
|
+
"type": "PermissionNode",
|
|
381
|
+
"body": [token.to_dict() for token in self.body]
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
class SleepNode(ASTNode):
|
|
386
|
+
"""
|
|
387
|
+
Node representing a sleep command in the AST.
|
|
388
|
+
"""
|
|
389
|
+
|
|
390
|
+
def __init__(self, body: list[Token]):
|
|
391
|
+
"""
|
|
392
|
+
:param body: list of tokens representing the sleep duration
|
|
393
|
+
"""
|
|
394
|
+
self.body = body
|
|
395
|
+
|
|
396
|
+
def __repr__(self):
|
|
397
|
+
return f"<SLEEP> - {self.body}"
|
|
398
|
+
|
|
399
|
+
def to_dict(self):
|
|
400
|
+
"""
|
|
401
|
+
Convert the SleepNode to a dictionary representation.
|
|
402
|
+
:return: Dictionary representation of the SleepNode.
|
|
403
|
+
"""
|
|
404
|
+
return {
|
|
405
|
+
"type": "SleepNode",
|
|
406
|
+
"body": [token.to_dict() for token in self.body]
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
class EvalGroupNode(ASTNode):
|
|
410
|
+
"""
|
|
411
|
+
Node representing a group of evaluations in the AST.
|
|
412
|
+
This is used to group multiple evaluations together.
|
|
413
|
+
"""
|
|
414
|
+
|
|
415
|
+
def __init__(self, body: list[Token]):
|
|
416
|
+
"""
|
|
417
|
+
:param body: list of tokens representing the body of the evaluation group
|
|
418
|
+
"""
|
|
419
|
+
self.body = body
|
|
420
|
+
|
|
421
|
+
def __repr__(self):
|
|
422
|
+
return f"<EVAL GROUP> - {self.body}"
|
|
423
|
+
|
|
424
|
+
def to_dict(self):
|
|
425
|
+
"""
|
|
426
|
+
Convert the EvalGroupNode to a dictionary representation.
|
|
427
|
+
:return: Dictionary representation of the EvalGroupNode.
|
|
428
|
+
"""
|
|
429
|
+
return {
|
|
430
|
+
"type": "EvalGroupNode",
|
|
431
|
+
"body": [token.to_dict() for token in self.body]
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
class ParamNode(ASTNode):
|
|
435
|
+
"""
|
|
436
|
+
Node representing a parameter in the AST.
|
|
437
|
+
This is used to define parameters for variables passed to the dshell interpreter.
|
|
438
|
+
"""
|
|
439
|
+
|
|
440
|
+
def __init__(self, body: list[Token]):
|
|
441
|
+
"""
|
|
442
|
+
:param name: Token representing the parameter name
|
|
443
|
+
:param body: list of tokens representing the body of the parameter
|
|
444
|
+
"""
|
|
445
|
+
self.body = body
|
|
446
|
+
|
|
447
|
+
def __repr__(self):
|
|
448
|
+
return f"<PARAM> - {self.body}"
|
|
449
|
+
|
|
450
|
+
def to_dict(self):
|
|
451
|
+
"""
|
|
452
|
+
Convert the ParamNode to a dictionary representation.
|
|
453
|
+
:return: Dictionary representation of the ParamNode.
|
|
454
|
+
"""
|
|
455
|
+
return {
|
|
456
|
+
"type": "ParamNode",
|
|
457
|
+
"body": [token.to_dict() for token in self.body]
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
class UiButtonNode(ASTNode):
|
|
461
|
+
"""
|
|
462
|
+
Node representing a UI button component in the AST.
|
|
463
|
+
This is used to define button elements for commands in Dshell.
|
|
464
|
+
"""
|
|
465
|
+
|
|
466
|
+
def __init__(self, body: list[Token]):
|
|
467
|
+
"""
|
|
468
|
+
:param body: list of tokens representing the button component
|
|
469
|
+
"""
|
|
470
|
+
self.body = body
|
|
471
|
+
|
|
472
|
+
def __repr__(self):
|
|
473
|
+
return f"<UI BUTTON> - {self.body}"
|
|
474
|
+
|
|
475
|
+
def to_dict(self):
|
|
476
|
+
"""
|
|
477
|
+
Convert the UiButtonNode to a dictionary representation.
|
|
478
|
+
:return: Dictionary representation of the UiButtonNode.
|
|
479
|
+
"""
|
|
480
|
+
return {
|
|
481
|
+
"type": "UiButtonNode",
|
|
482
|
+
"body": [token.to_dict() for token in self.body]
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
class UiSelectNode(ASTNode):
|
|
486
|
+
"""
|
|
487
|
+
Node representing a UI select component in the AST.
|
|
488
|
+
This is used to define select elements for commands in Dshell.
|
|
489
|
+
"""
|
|
490
|
+
|
|
491
|
+
def __init__(self, body: list[Token]):
|
|
492
|
+
"""
|
|
493
|
+
:param body: list of tokens representing the select component
|
|
494
|
+
"""
|
|
495
|
+
self.body = body
|
|
496
|
+
|
|
497
|
+
def __repr__(self):
|
|
498
|
+
return f"<UI SELECT> - {self.body}"
|
|
499
|
+
|
|
500
|
+
def to_dict(self):
|
|
501
|
+
"""
|
|
502
|
+
Convert the UiSelectNode to a dictionary representation.
|
|
503
|
+
:return: Dictionary representation of the UiSelectNode.
|
|
504
|
+
"""
|
|
505
|
+
return {
|
|
506
|
+
"type": "UiSelectNode",
|
|
507
|
+
"body": [token.to_dict() for token in self.body]
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
class UiNode(ASTNode):
|
|
511
|
+
"""
|
|
512
|
+
Node representing a UI component in the AST.
|
|
513
|
+
This is used to define UI elements for commands in Dshell.
|
|
514
|
+
"""
|
|
515
|
+
|
|
516
|
+
def __init__(self, buttons: Optional[list[UiButtonNode]] = None,
|
|
517
|
+
selects: Optional[list[UiSelectNode]] = None):
|
|
518
|
+
"""
|
|
519
|
+
:param body: list of tokens representing the UI component
|
|
520
|
+
"""
|
|
521
|
+
self.buttons = buttons or []
|
|
522
|
+
self.selects = selects or []
|
|
523
|
+
|
|
524
|
+
def __repr__(self):
|
|
525
|
+
return f"<UI> - {self.buttons}\n\n - {self.selects}"
|
|
526
|
+
|
|
527
|
+
def to_dict(self):
|
|
528
|
+
"""
|
|
529
|
+
Convert the UiNode to a dictionary representation.
|
|
530
|
+
:return: Dictionary representation of the UiNode.
|
|
531
|
+
"""
|
|
532
|
+
return {
|
|
533
|
+
"type": "UiNode",
|
|
534
|
+
"buttons": [token.to_dict() for token in self.buttons],
|
|
535
|
+
"selects": [token.to_dict() for token in self.selects],
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
class ListNode(ASTNode):
|
|
539
|
+
"""
|
|
540
|
+
Node representing a list structure in the AST.
|
|
541
|
+
Iterable class for browsing lists created from Dshell code.
|
|
542
|
+
This class also lets you interact with the list via specific methods not built in by python.
|
|
543
|
+
"""
|
|
544
|
+
|
|
545
|
+
def __init__(self, body: list[Any]):
|
|
546
|
+
"""
|
|
547
|
+
:param body: list of elements to initialize the ListNode with
|
|
548
|
+
"""
|
|
549
|
+
self.iterable: list[Any] = body
|
|
550
|
+
self.len_iterable: int = len(body)
|
|
551
|
+
self.iterator_count: int = 0
|
|
552
|
+
|
|
553
|
+
def to_dict(self):
|
|
554
|
+
"""
|
|
555
|
+
Convert the ListNode to a dictionary representation.
|
|
556
|
+
:return: Dictionary representation of the ListNode.
|
|
557
|
+
"""
|
|
558
|
+
return {
|
|
559
|
+
"type": "ListNode",
|
|
560
|
+
"body": [token.to_dict() for token in self.iterable]
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
def add(self, value: Any):
|
|
564
|
+
"""
|
|
565
|
+
Add a value to the list.
|
|
566
|
+
"""
|
|
567
|
+
if self.len_iterable > 1000:
|
|
568
|
+
raise PermissionError('The list is too long, it must not exceed 1000 elements !')
|
|
569
|
+
|
|
570
|
+
self.iterable.append(value)
|
|
571
|
+
self.len_iterable += 1
|
|
572
|
+
|
|
573
|
+
def remove(self, value: Any, number: int = 1):
|
|
574
|
+
"""
|
|
575
|
+
Remove a value from the list.
|
|
576
|
+
"""
|
|
577
|
+
if number < 1:
|
|
578
|
+
raise Exception(f"The number of elements to remove must be at least 1, not {number} !")
|
|
579
|
+
|
|
580
|
+
count = 0
|
|
581
|
+
while number > 0 and count < self.len_iterable:
|
|
582
|
+
if self.iterable[count] == value:
|
|
583
|
+
self.iterable.pop(count)
|
|
584
|
+
self.len_iterable -= 1
|
|
585
|
+
number -= 1
|
|
586
|
+
continue
|
|
587
|
+
count += 1
|
|
588
|
+
|
|
589
|
+
def pop(self, index: int = -1):
|
|
590
|
+
"""
|
|
591
|
+
Remove and return the last element of the list.
|
|
592
|
+
:return: The last element of the list.
|
|
593
|
+
"""
|
|
594
|
+
if self.len_iterable == 0:
|
|
595
|
+
raise IndexError("pop from empty list")
|
|
596
|
+
if 0 > index >= self.len_iterable or -self.len_iterable > index < 0:
|
|
597
|
+
raise IndexError("pop index out of range")
|
|
598
|
+
|
|
599
|
+
self.len_iterable -= 1
|
|
600
|
+
return self.iterable.pop(index)
|
|
601
|
+
|
|
602
|
+
def count(self):
|
|
603
|
+
"""
|
|
604
|
+
Return the number of elements in the list.
|
|
605
|
+
:return: The number of elements in the list.
|
|
606
|
+
"""
|
|
607
|
+
return self.len_iterable
|
|
608
|
+
|
|
609
|
+
def clear(self):
|
|
610
|
+
"""
|
|
611
|
+
Clear the list.
|
|
612
|
+
"""
|
|
613
|
+
self.iterable = []
|
|
614
|
+
self.len_iterable = 0
|
|
615
|
+
self.iterator_count = 0
|
|
616
|
+
|
|
617
|
+
def sort(self, reverse: bool = False):
|
|
618
|
+
"""
|
|
619
|
+
Sort the list.
|
|
620
|
+
:param reverse: Whether to sort the list in reverse order.
|
|
621
|
+
"""
|
|
622
|
+
self.iterable.sort(reverse=reverse)
|
|
623
|
+
|
|
624
|
+
def reverse(self):
|
|
625
|
+
"""
|
|
626
|
+
Reverse the list.
|
|
627
|
+
"""
|
|
628
|
+
self.iterable.reverse()
|
|
629
|
+
|
|
630
|
+
def extend(self, values: "ListNode"):
|
|
631
|
+
"""
|
|
632
|
+
Extend the list with another list.
|
|
633
|
+
:param values: List of values to extend the list with.
|
|
634
|
+
"""
|
|
635
|
+
for v in values:
|
|
636
|
+
self.add(v)
|
|
637
|
+
|
|
638
|
+
def __add__(self, other: "ListNode"):
|
|
639
|
+
"""
|
|
640
|
+
Add another ListNode to this one.
|
|
641
|
+
:param other: Another ListNode to add to this one.
|
|
642
|
+
:return: Instance of ListNode with combined elements.
|
|
643
|
+
"""
|
|
644
|
+
for i in other:
|
|
645
|
+
self.add(i)
|
|
646
|
+
return self
|
|
647
|
+
|
|
648
|
+
def __iter__(self):
|
|
649
|
+
return self
|
|
650
|
+
|
|
651
|
+
def __next__(self):
|
|
652
|
+
"""
|
|
653
|
+
Iterate over the elements of the list.
|
|
654
|
+
:return: an element from the list.
|
|
655
|
+
"""
|
|
656
|
+
|
|
657
|
+
if self.iterator_count >= self.len_iterable:
|
|
658
|
+
self.iterator_count = 0
|
|
659
|
+
raise StopIteration()
|
|
660
|
+
|
|
661
|
+
v = self.iterable[self.iterator_count]
|
|
662
|
+
self.iterator_count += 1
|
|
663
|
+
return v
|
|
664
|
+
|
|
665
|
+
def __len__(self):
|
|
666
|
+
return self.len_iterable
|
|
667
|
+
|
|
668
|
+
def __getitem__(self, item):
|
|
669
|
+
return self.iterable[item]
|
|
670
|
+
|
|
671
|
+
def __bool__(self):
|
|
672
|
+
return bool(self.iterable)
|
|
673
|
+
|
|
674
|
+
def __repr__(self):
|
|
675
|
+
return f"<LIST> - {self.iterable}"
|