dshellInterpreter 0.2.15.2__py3-none-any.whl → 0.2.15.4__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.

Potentially problematic release.


This version of dshellInterpreter might be problematic. Click here for more details.

@@ -0,0 +1,4 @@
1
+ from .utils_thread import *
2
+ from .utils_message import *
3
+ from .utils_list import *
4
+ from .utils_global import *
@@ -0,0 +1,15 @@
1
+ __all__ = [
2
+ "utils_len",
3
+ ]
4
+
5
+ async def utils_len(ctx, value):
6
+ """
7
+ Return the length of a list, or a string
8
+ :param value:
9
+ :return:
10
+ """
11
+ from ..._DshellParser.ast_nodes import ListNode
12
+ if not isinstance(value, (str, ListNode)):
13
+ raise TypeError(f"value must be a list or a string in len command, not {type(value)}")
14
+
15
+ return len(value)
@@ -0,0 +1,91 @@
1
+ __all__ = [
2
+ "utils_list_add",
3
+ "utils_list_remove",
4
+ "utils_list_clear",
5
+ "utils_list_pop",
6
+ "utils_list_sort",
7
+ "utils_list_reverse"
8
+ ]
9
+
10
+ async def utils_list_add(ctx, value: "ListNode", *elements):
11
+ """
12
+ Add an element to a list
13
+ :param value:
14
+ :param elements:
15
+ :return:
16
+ """
17
+ from ..._DshellParser.ast_nodes import ListNode
18
+ if not isinstance(value, ListNode):
19
+ raise TypeError("value must be a list in add command")
20
+
21
+ for elem in elements:
22
+ value.add(elem)
23
+ return value
24
+
25
+ async def utils_list_remove(ctx, value: "ListNode", *elements):
26
+ """
27
+ Remove an element from a list
28
+ :param value:
29
+ :param elements:
30
+ :return:
31
+ """
32
+ from ..._DshellParser.ast_nodes import ListNode
33
+ if not isinstance(value, ListNode):
34
+ raise TypeError("value must be a list in remove command")
35
+
36
+ for elem in elements:
37
+ value.remove(elem)
38
+ return value
39
+
40
+ async def utils_list_clear(ctx, value: "ListNode"):
41
+ """
42
+ Clear a list
43
+ :param value:
44
+ :return:
45
+ """
46
+ from ..._DshellParser.ast_nodes import ListNode
47
+ if not isinstance(value, ListNode):
48
+ raise TypeError("value must be a list in clear command")
49
+ value.clear()
50
+ return value
51
+
52
+ async def utils_list_pop(ctx, value: "ListNode", index: int = -1):
53
+ """
54
+ Pop an element from a list
55
+ :param value:
56
+ :param index:
57
+ :return:
58
+ """
59
+ from ..._DshellParser.ast_nodes import ListNode
60
+ if not isinstance(value, ListNode):
61
+ raise TypeError("value must be a list in pop command")
62
+ if not isinstance(index, int):
63
+ raise TypeError("index must be an integer in pop command")
64
+ return value.pop(index)
65
+
66
+ async def utils_list_sort(ctx, value: "ListNode", reverse: bool = False):
67
+ """
68
+ Sort a list
69
+ :param value:
70
+ :param reverse:
71
+ :return:
72
+ """
73
+ from ..._DshellParser.ast_nodes import ListNode
74
+ if not isinstance(value, ListNode):
75
+ raise TypeError("value must be a list in sort command")
76
+ if not isinstance(reverse, bool):
77
+ raise TypeError("reverse must be a boolean in sort command")
78
+ value.sort(reverse=reverse)
79
+ return value
80
+
81
+ async def utils_list_reverse(ctx, value: "ListNode"):
82
+ """
83
+ Reverse a list
84
+ :param value:
85
+ :return:
86
+ """
87
+ from ..._DshellParser.ast_nodes import ListNode
88
+ if not isinstance(value, ListNode):
89
+ raise TypeError("value must be a list in reverse command")
90
+ value.reverse()
91
+ return value
@@ -17,7 +17,7 @@ from .._DshellTokenizer.dshell_token_type import DshellTokenType as DTT
17
17
  from .._DshellTokenizer.dshell_token_type import Token
18
18
  from .._DshellTokenizer.dshell_tokenizer import DshellTokenizer
19
19
 
20
- All_nodes = TypeVar('All_nodes', IfNode, LoopNode, ElseNode, ElifNode, ArgsCommandNode, VarNode, IdentOperationNode)
20
+ All_nodes = TypeVar('All_nodes', IfNode, LoopNode, ElseNode, ElifNode, ArgsCommandNode, VarNode)
21
21
  context = TypeVar('context', AutoShardedBot, Message, PrivateChannel, Interaction)
22
22
  ButtonStyleValues: tuple = tuple(i.name for i in ButtonStyle)
23
23
 
@@ -74,7 +74,7 @@ class DshellInterpreteur:
74
74
  '__guild_channels__': ListNode([channel.id for channel in message.channel.guild.channels]),
75
75
  '__guild_channels_count__': len(message.channel.guild.channels),
76
76
 
77
- } if message is not None or not debug else {} # {} is used in debug mode, when ctx is None
77
+ } if message is not None and not debug else {} # {} is used in debug mode, when ctx is None
78
78
  self.vars = vars if vars is not None else ''
79
79
  self.ctx: context = ctx
80
80
  if debug:
@@ -162,15 +162,9 @@ class DshellInterpreteur:
162
162
  elif isinstance(first_node, LengthNode):
163
163
  self.env[node.name.value] = length(first_node)
164
164
 
165
- elif isinstance(first_node, IdentOperationNode):
166
- self.env[node.name.value] = self.eval_ident_operation(first_node)
167
-
168
165
  else:
169
166
  self.env[node.name.value] = eval_expression(node.body, self)
170
167
 
171
- elif isinstance(node, IdentOperationNode):
172
- return self.eval_ident_operation(node)
173
-
174
168
  elif isinstance(node, SleepNode):
175
169
  sleep_time = eval_expression(node.body, self)
176
170
  if sleep_time > 3600:
@@ -217,12 +211,6 @@ class DshellInterpreteur:
217
211
  else:
218
212
  return token.value # fallback
219
213
 
220
- def eval_ident_operation(self, node: IdentOperationNode) -> Optional[Any]:
221
- function = self.eval_data_token(node.function)
222
- listNode = self.eval_data_token(node.ident)
223
- if hasattr(listNode, function):
224
- return getattr(listNode, function)(self.eval_data_token(node.args))
225
- return None
226
214
 
227
215
  def get_params(node: ParamNode, interpreter: DshellInterpreteur) -> dict[str, Any]:
228
216
  """
@@ -18,7 +18,6 @@ __all__ = [
18
18
  'FieldEmbedNode',
19
19
  'EmbedNode',
20
20
  'SleepNode',
21
- 'IdentOperationNode',
22
21
  'ListNode',
23
22
  'PermissionNode',
24
23
  'ParamNode',
@@ -406,39 +405,6 @@ class SleepNode(ASTNode):
406
405
  }
407
406
 
408
407
 
409
- class IdentOperationNode(ASTNode):
410
- """
411
- Node representing an operation on an identifier in the AST.
412
- Manages operations on idendifiers (function calls)
413
- Ensure that the function call returns the associated class to allow nesting. Not mandatory in itself if it returns something
414
- """
415
-
416
- def __init__(self, ident: Token, function: Token, args: Token):
417
- """
418
- :param ident: Token representing the identifier (e.g., a class or object)
419
- :param function: Token representing the function to be called on the identifier
420
- :param args: Token representing the arguments passed to the function
421
- """
422
- self.ident = ident
423
- self.function = function
424
- self.args = args
425
-
426
- def __repr__(self):
427
- return f"<IDENT OPERATION> - {self.ident}.{self.function}({self.args})"
428
-
429
- def to_dict(self):
430
- """
431
- Convert the IdentOperationNode to a dictionary representation.
432
- :return: Dictionary representation of the IdentOperationNode.
433
- """
434
- return {
435
- "type": "IdentOperationNode",
436
- "ident": self.ident.to_dict(),
437
- "function": self.function.to_dict(),
438
- "args": self.args.to_dict()
439
- }
440
-
441
-
442
408
  class ParamNode(ASTNode):
443
409
  """
444
410
  Node representing a parameter in the AST.
@@ -595,16 +561,18 @@ class ListNode(ASTNode):
595
561
  continue
596
562
  count += 1
597
563
 
598
- def pop(self):
564
+ def pop(self, index: int = -1):
599
565
  """
600
566
  Remove and return the last element of the list.
601
567
  :return: The last element of the list.
602
568
  """
603
569
  if self.len_iterable == 0:
604
570
  raise IndexError("pop from empty list")
571
+ if 0 > index >= self.len_iterable or -self.len_iterable > index < 0:
572
+ raise IndexError("pop index out of range")
605
573
 
606
574
  self.len_iterable -= 1
607
- return self.iterable.pop()
575
+ return self.iterable.pop(index)
608
576
 
609
577
  def count(self):
610
578
  """
@@ -2,33 +2,13 @@ __all__ = [
2
2
  "parse",
3
3
  "parser_inline",
4
4
  "to_postfix",
5
- "parse_postfix_expression",
6
5
  "print_ast",
7
6
  "ast_to_dict",
8
7
  ]
9
8
 
10
9
  from typing import Union
11
10
 
12
- from .ast_nodes import (ASTNode,
13
- LengthNode,
14
- CommandNode,
15
- IfNode,
16
- LoopNode,
17
- ElseNode,
18
- ArgsCommandNode,
19
- ElifNode,
20
- VarNode,
21
- EndNode,
22
- SleepNode,
23
- IdentOperationNode,
24
- EmbedNode,
25
- FieldEmbedNode,
26
- PermissionNode,
27
- ParamNode,
28
- UiNode,
29
- UiButtonNode,
30
- UiSelectNode,
31
- StartNode)
11
+ from .ast_nodes import *
32
12
  from .._DshellTokenizer import dshell_operators
33
13
  from .._DshellTokenizer.dshell_token_type import DshellTokenType as DTT
34
14
  from .._DshellTokenizer.dshell_token_type import Token
@@ -181,15 +161,6 @@ def parse(token_lines: list[list[Token]], start_node: ASTNode) -> tuple[list[AST
181
161
  end_node = EndNode()
182
162
  last_block.body.append(end_node)
183
163
 
184
- elif first_token_line.value in ('length', 'len'):
185
- if len(tokens_by_line) != 3:
186
- raise SyntaxError(f"[LENGTH] Take 2 arguments on line {first_token_line.position} !")
187
- if tokens_by_line[1].type not in (DTT.IDENT, DTT.STR, DTT.LIST):
188
- raise SyntaxError(f"[LENGTH] Take an ident, str or list on line {tokens_by_line[1].position}, not {first_token_line.type} !")
189
-
190
- var_node = VarNode(tokens_by_line[1], body=[LengthNode(tokens_by_line[2])])
191
- last_block.body.append(var_node)
192
-
193
164
  ############################## DISCORD KEYWORDS ##############################
194
165
 
195
166
  elif first_token_line.type == DTT.DISCORD_KEYWORD:
@@ -282,9 +253,6 @@ def parse(token_lines: list[list[Token]], start_node: ASTNode) -> tuple[list[AST
282
253
  if len(tokens_by_line) == 1:
283
254
  last_block.body.append(CommandNode(name='sm', body=ArgsCommandNode([first_token_line])))
284
255
 
285
- else:
286
- last_block.body += parse_postfix_expression(to_postfix(tokens_by_line))
287
-
288
256
  elif first_token_line.type == DTT.STR:
289
257
  last_block.body.append(CommandNode(name='sm', body=ArgsCommandNode([first_token_line])))
290
258
 
@@ -297,13 +265,6 @@ def parse(token_lines: list[list[Token]], start_node: ASTNode) -> tuple[list[AST
297
265
  return blocks, pointeur
298
266
 
299
267
 
300
- """
301
- elif first_token_line.type == DTT.LIST: # si le token est une liste (qui comporte une liste python avec des Tokens)
302
- list_node = ListNode(first_token_line.value) # le .value est une liste python
303
- last_block.body.append(list_node)
304
- """
305
-
306
-
307
268
  def ast_to_dict(obj):
308
269
  if isinstance(obj, list):
309
270
  return [ast_to_dict(item) for item in obj]
@@ -375,42 +336,6 @@ def to_postfix(expression):
375
336
  return output
376
337
 
377
338
 
378
- def parse_postfix_expression(postfix_tokens: list[Token]) -> list[IdentOperationNode]:
379
- stack = []
380
-
381
- for tok in postfix_tokens:
382
-
383
- if tok.type in (DTT.IDENT, DTT.CALL_ARGS, DTT.INT, DTT.STR, DTT.LIST, DTT.FLOAT, DTT.BOOL):
384
- stack.append(tok)
385
-
386
- elif tok.type == DTT.MATHS_OPERATOR:
387
- if tok.value == '.':
388
- args = stack.pop()
389
- func = stack.pop()
390
- base = stack.pop()
391
- node = IdentOperationNode(ident=base, function=func, args=args)
392
- stack.append(node)
393
-
394
- elif tok.value == '->':
395
- value = stack.pop()
396
- base = stack.pop()
397
- fake_func = Token(DTT.IDENT, 'at', tok.position)
398
- fake_args = Token(DTT.CALL_ARGS, value.value, value.position)
399
- node = IdentOperationNode(ident=base, function=fake_func, args=fake_args)
400
- stack.append(node)
401
-
402
- else:
403
- raise SyntaxError(f"Opérateur non supporté dans les appels : {tok.value}")
404
-
405
- else:
406
- raise SyntaxError(f"Token inattendu : {tok}")
407
-
408
- if len(stack) != 1:
409
- raise SyntaxError("Expression mal formée ou incomplète")
410
-
411
- return stack
412
-
413
-
414
339
  def print_ast(ast: list[ASTNode], decalage: int = 0):
415
340
  for i in ast:
416
341
 
@@ -434,9 +359,6 @@ def print_ast(ast: list[ASTNode], decalage: int = 0):
434
359
  print(f"{' ' * decalage}ELSE -> ...")
435
360
  print_ast(i.else_body, decalage + 5)
436
361
 
437
- elif isinstance(i, IdentOperationNode):
438
- print(f"{' ' * decalage}IDENT_OPERATION -> {i.ident}.{i.function}({i.args})")
439
-
440
362
  elif isinstance(i, CommandNode):
441
363
  print(f"{' ' * decalage}COMMAND -> {i.name} : {i.body}")
442
364
 
@@ -10,15 +10,18 @@ __all__ = [
10
10
 
11
11
  from typing import Callable
12
12
 
13
+ from ..DISCORD_COMMANDS import utils_len, utils_list_add
13
14
  from ..DISCORD_COMMANDS.dshell_channel import *
14
15
  from ..DISCORD_COMMANDS.dshell_member import *
15
16
  from ..DISCORD_COMMANDS.dshell_message import *
16
17
  from ..DISCORD_COMMANDS.dshell_pastbin import *
17
18
  from ..DISCORD_COMMANDS.dshell_role import *
18
19
  from ..DISCORD_COMMANDS.dshell_interaction import *
20
+ from ..DISCORD_COMMANDS.utils.utils_global import *
21
+ from ..DISCORD_COMMANDS.utils.utils_list import *
19
22
 
20
23
  dshell_keyword: set[str] = {
21
- 'if', 'else', 'elif', 'loop', '#end', 'var', '#loop', '#if', 'sleep', 'param', '#param', 'length', 'len'
24
+ 'if', 'else', 'elif', 'loop', '#end', 'var', '#loop', '#if', 'sleep', 'param', '#param'
22
25
  }
23
26
 
24
27
  dshell_discord_keyword: set[str] = {
@@ -26,6 +29,15 @@ dshell_discord_keyword: set[str] = {
26
29
  }
27
30
  dshell_commands: dict[str, Callable] = {
28
31
 
32
+ 'length': utils_len,
33
+ 'len': utils_len,
34
+ 'add': utils_list_add,
35
+ 'remove': utils_list_remove,
36
+ 'clear': utils_list_clear,
37
+ 'pop': utils_list_pop,
38
+ 'sort': utils_list_sort,
39
+ 'reverse': utils_list_reverse,
40
+
29
41
  "gp": dshell_get_pastbin, # get pastbin
30
42
 
31
43
  "sm": dshell_send_message, # send message
@@ -18,7 +18,6 @@ table_regex: dict[DTT, Pattern] = {
18
18
  DTT.STR: compile(r'"((?:[^\\"]|\\.)*)"', flags=DOTALL),
19
19
  DTT.COMMENT: compile(r"::(.*?)$"),
20
20
  DTT.LIST: compile(r"\[(.*?)\]"),
21
- DTT.CALL_ARGS: compile(r"\((.*?)\)"),
22
21
  DTT.MENTION: compile(r'<(?:@!?|@&|#)([0-9]+)>'),
23
22
  DTT.SEPARATOR: compile(rf"(--)"),
24
23
  DTT.SUB_SEPARATOR: compile(rf"(~~)"),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dshellInterpreter
3
- Version: 0.2.15.2
3
+ Version: 0.2.15.4
4
4
  Summary: A Discord bot interpreter for creating custom commands and automations.
5
5
  Home-page: https://github.com/BOXERRMD/Dshell_Interpreter
6
6
  Author: Chronos
@@ -7,20 +7,22 @@ Dshell/DISCORD_COMMANDS/dshell_member.py,sha256=5Iw-2dydhYMZOw2nx0svZP9JpZWHOXC0
7
7
  Dshell/DISCORD_COMMANDS/dshell_message.py,sha256=zcWl6Y1W31h9MTHS-j9tLDwcrRiE_wGOu78zu2k0y9I,9101
8
8
  Dshell/DISCORD_COMMANDS/dshell_pastbin.py,sha256=H0tUJOwdzYBXvxqipK3mzoNZUKrSLcVm4EZlWbBRScs,796
9
9
  Dshell/DISCORD_COMMANDS/dshell_role.py,sha256=t_yRZRD0FKE2gT4dIDIsHz2PSZZztDVEkkqkG_OkNh4,5002
10
- Dshell/DISCORD_COMMANDS/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ Dshell/DISCORD_COMMANDS/utils/__init__.py,sha256=-amNcYysjgx3YDpDSnbQmJhnm3lbJere9K9aDH-YnJg,115
11
+ Dshell/DISCORD_COMMANDS/utils/utils_global.py,sha256=JDueE5jCIosUziWNuzzW7iw6_RjgGfHEszJXKgU6FR8,387
12
+ Dshell/DISCORD_COMMANDS/utils/utils_list.py,sha256=kJ1vgqdAKef-siAUvGwvKgD2ezMJpnFUP2UQ3v6-ARw,2569
11
13
  Dshell/DISCORD_COMMANDS/utils/utils_message.py,sha256=cQvJ15f49ddOjybARwkJKNFe3ITYQciF-pZHERFPkr0,2964
12
14
  Dshell/DISCORD_COMMANDS/utils/utils_thread.py,sha256=tVl4msEwrWHY-0AytI6eY3JSs-eIFUigDSJfK9mT1ww,1457
13
15
  Dshell/_DshellInterpreteur/__init__.py,sha256=xy5-J-R3YmY99JF3NBHTRRLsComFxpjnCA5xacISctU,35
14
- Dshell/_DshellInterpreteur/dshell_interpreter.py,sha256=I22N3R0eH0mK9KlepbUcvqP4YOmTCcSZdI5_CyIsy34,32716
16
+ Dshell/_DshellInterpreteur/dshell_interpreter.py,sha256=OGn6HHPrlVWVI9z7s90edBqrv3Fv410A0rPYW8JP-Hs,32096
15
17
  Dshell/_DshellParser/__init__.py,sha256=ONDfhZMvClqP_6tE8SLjp-cf3pXL-auQYnfYRrHZxC4,56
16
- Dshell/_DshellParser/ast_nodes.py,sha256=X7kw5nflGCi_h4FWlK5vytedR70Mwarj5NbhpaqYao4,19643
17
- Dshell/_DshellParser/dshell_parser.py,sha256=YUFfBbFQ1ApOCyVhx-0nJ6S6W5MOBG6YabbkM43BKVw,21708
18
+ Dshell/_DshellParser/ast_nodes.py,sha256=m6a4bMFVb0grMCyghWMeb4xABxdlWxFBbycnR388dg0,18518
19
+ Dshell/_DshellParser/dshell_parser.py,sha256=KD2ZbKYa1nnvroKmN8fIRD2exXre54Qx_roEBrTV7Mo,18588
18
20
  Dshell/_DshellTokenizer/__init__.py,sha256=LIQSRhDx2B9pmPx5ADMwwD0Xr9ybneVLhHH8qrJWw_s,172
19
- Dshell/_DshellTokenizer/dshell_keywords.py,sha256=7oeSKLXCsPRpyU31skCerOUMzd2cdm-GwofpmgTPkD0,5961
21
+ Dshell/_DshellTokenizer/dshell_keywords.py,sha256=4QvBXvuXJPjKWyhVqAPBYCqE95G7dG8waXD3XtmuoBw,6345
20
22
  Dshell/_DshellTokenizer/dshell_token_type.py,sha256=gYIb2XN2YcgeRgmar_rBDS5CGmwfmxihu8mOW_d6lbE,1533
21
- Dshell/_DshellTokenizer/dshell_tokenizer.py,sha256=RrJA2XpcFH2vS6SnRIn5Own_uL5orIDvpq74t8xD3og,7350
22
- dshellinterpreter-0.2.15.2.dist-info/licenses/LICENSE,sha256=lNgcw1_xb7QENAQi3uHGymaFtbs0RV-ihiCd7AoLQjA,1082
23
- dshellinterpreter-0.2.15.2.dist-info/METADATA,sha256=3QaELBxioT7TBr87RxJNDV_g0WP9wxLxcCUyC7uGB8A,1151
24
- dshellinterpreter-0.2.15.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
25
- dshellinterpreter-0.2.15.2.dist-info/top_level.txt,sha256=B4CMhtmchGwPQJLuqUy0GhRG-0cUGxKL4GqEbCiB_vE,7
26
- dshellinterpreter-0.2.15.2.dist-info/RECORD,,
23
+ Dshell/_DshellTokenizer/dshell_tokenizer.py,sha256=AJnUocD6hbU6wvjRAN5uDha5QQieTwXlHzZVtgRGaZQ,7307
24
+ dshellinterpreter-0.2.15.4.dist-info/licenses/LICENSE,sha256=lNgcw1_xb7QENAQi3uHGymaFtbs0RV-ihiCd7AoLQjA,1082
25
+ dshellinterpreter-0.2.15.4.dist-info/METADATA,sha256=FkIk1dGusH1JtAgBPDrT3FSPIDu3frzRXveXsjaWcC8,1151
26
+ dshellinterpreter-0.2.15.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
+ dshellinterpreter-0.2.15.4.dist-info/top_level.txt,sha256=B4CMhtmchGwPQJLuqUy0GhRG-0cUGxKL4GqEbCiB_vE,7
28
+ dshellinterpreter-0.2.15.4.dist-info/RECORD,,