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.
Files changed (34) hide show
  1. Dshell/DISCORD_COMMANDS/__init__.py +7 -0
  2. Dshell/DISCORD_COMMANDS/dshell_channel.py +612 -0
  3. Dshell/DISCORD_COMMANDS/dshell_interaction.py +89 -0
  4. Dshell/DISCORD_COMMANDS/dshell_member.py +274 -0
  5. Dshell/DISCORD_COMMANDS/dshell_message.py +444 -0
  6. Dshell/DISCORD_COMMANDS/dshell_pastbin.py +28 -0
  7. Dshell/DISCORD_COMMANDS/dshell_role.py +128 -0
  8. Dshell/DISCORD_COMMANDS/utils/__init__.py +8 -0
  9. Dshell/DISCORD_COMMANDS/utils/utils_global.py +155 -0
  10. Dshell/DISCORD_COMMANDS/utils/utils_list.py +109 -0
  11. Dshell/DISCORD_COMMANDS/utils/utils_member.py +30 -0
  12. Dshell/DISCORD_COMMANDS/utils/utils_message.py +78 -0
  13. Dshell/DISCORD_COMMANDS/utils/utils_permissions.py +94 -0
  14. Dshell/DISCORD_COMMANDS/utils/utils_string.py +157 -0
  15. Dshell/DISCORD_COMMANDS/utils/utils_thread.py +35 -0
  16. Dshell/_DshellInterpreteur/__init__.py +4 -0
  17. Dshell/_DshellInterpreteur/cached_messages.py +4 -0
  18. Dshell/_DshellInterpreteur/dshell_arguments.py +74 -0
  19. Dshell/_DshellInterpreteur/dshell_interpreter.py +671 -0
  20. Dshell/_DshellInterpreteur/errors.py +8 -0
  21. Dshell/_DshellParser/__init__.py +2 -0
  22. Dshell/_DshellParser/ast_nodes.py +675 -0
  23. Dshell/_DshellParser/dshell_parser.py +408 -0
  24. Dshell/_DshellTokenizer/__init__.py +4 -0
  25. Dshell/_DshellTokenizer/dshell_keywords.py +193 -0
  26. Dshell/_DshellTokenizer/dshell_token_type.py +58 -0
  27. Dshell/_DshellTokenizer/dshell_tokenizer.py +146 -0
  28. Dshell/__init__.py +3 -0
  29. Dshell/_utils.py +1 -0
  30. dshellinterpreter-0.2.21.7.dist-info/METADATA +37 -0
  31. dshellinterpreter-0.2.21.7.dist-info/RECORD +34 -0
  32. dshellinterpreter-0.2.21.7.dist-info/WHEEL +5 -0
  33. dshellinterpreter-0.2.21.7.dist-info/licenses/LICENSE +21 -0
  34. 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}"