dshellInterpreter 1.2.7.3__tar.gz → 1.2.7.4__tar.gz
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.
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/utils/utils_type_validation.py +1 -1
- dshellinterpreter-1.2.7.4/Dshell/DshellPreProcess/dshell_preprocess.py +73 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DshellTokenizer/dshell_keywords.py +20 -8
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DshellTokenizer/dshell_tokenizer.py +60 -83
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/full_import.py +1 -0
- {dshellinterpreter-1.2.7.3/dshellInterpreter.egg-info → dshellinterpreter-1.2.7.4}/PKG-INFO +1 -1
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4/dshellInterpreter.egg-info}/PKG-INFO +1 -1
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/setup.py +1 -1
- dshellinterpreter-1.2.7.3/Dshell/DshellPreProcess/dshell_preprocess.py +0 -41
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/__init__.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/dshell_channel.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/dshell_embed.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/dshell_file.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/dshell_interaction.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/dshell_member.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/dshell_message.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/dshell_pastbin.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/dshell_role.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/dshell_ui.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/utils/__init__.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/utils/utils_embed.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/utils/utils_file.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/utils/utils_global.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/utils/utils_list.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/utils/utils_member.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/utils/utils_message.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/utils/utils_numbers.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/utils/utils_permissions.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/utils/utils_string.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/utils/utils_thread.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DshellInterpreteur/__init__.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DshellInterpreteur/cached_messages.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DshellInterpreteur/dshell_arguments.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DshellInterpreteur/dshell_global_variables.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DshellInterpreteur/dshell_interpreter.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DshellInterpreteur/dshell_iterators.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DshellInterpreteur/dshell_scope.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DshellInterpreteur/errors.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DshellInterpreteur/utils_interpreter.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DshellParser/__init__.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DshellParser/ast_nodes.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DshellParser/dshell_parser.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DshellParser/errors.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DshellPreProcess/__init__.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DshellTokenizer/__init__.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DshellTokenizer/dshell_token_type.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/__init__.py +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/LICENSE +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/README.md +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/dshellInterpreter.egg-info/SOURCES.txt +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/dshellInterpreter.egg-info/dependency_links.txt +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/dshellInterpreter.egg-info/requires.txt +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/dshellInterpreter.egg-info/top_level.txt +0 -0
- {dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/setup.cfg +0 -0
|
@@ -117,7 +117,7 @@ def _validate_optional_permission(value, param_name: StrNode, command_name: StrN
|
|
|
117
117
|
:param command_name: The command name for error messages (optional)
|
|
118
118
|
:raises TypeError: If the value is not None and not a PermissionNode
|
|
119
119
|
"""
|
|
120
|
-
if
|
|
120
|
+
if value is not None and not isinstance(value, _MissingSentinel) and not isinstance(value, PermissionNode):
|
|
121
121
|
raise TypeError(f"[{command_name}] -> {param_name} must be a PermissionNode or None, not {type(value).__name__}")
|
|
122
122
|
|
|
123
123
|
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
from ..full_import import sub, MULTILINE, StrEnum, search, compile, DOTALL
|
|
2
|
+
|
|
3
|
+
class PreProcessorInstructions(StrEnum):
|
|
4
|
+
DEFINE = "define"
|
|
5
|
+
|
|
6
|
+
class PreProcessorData:
|
|
7
|
+
def __init__(self, instruction: str, symbol: str, value: str):
|
|
8
|
+
self.instruction = instruction
|
|
9
|
+
self.symbol = symbol
|
|
10
|
+
self.value = value
|
|
11
|
+
|
|
12
|
+
def define(code: str, pre_processor_data: PreProcessorData) -> str:
|
|
13
|
+
"""
|
|
14
|
+
Replace all symbol with the current value
|
|
15
|
+
:param code: the code before tokenization
|
|
16
|
+
:param pre_processor_data: all data for the ##define pre-processor
|
|
17
|
+
:return:
|
|
18
|
+
"""
|
|
19
|
+
return sub(f"(?<![a-zA-Z]){pre_processor_data.symbol}(?![a-zA-Z])", pre_processor_data.value, code)
|
|
20
|
+
|
|
21
|
+
pre_processor_pattern = compile(r"^\s*## *([a-zA-Z]+) +([a-zA-Z]+)(?: +(.*))?$", flags=MULTILINE|DOTALL)
|
|
22
|
+
def preProcessor(code: list[str]) -> list[str]:
|
|
23
|
+
"""
|
|
24
|
+
Execute preprocessor line
|
|
25
|
+
:param code: a list of code line before tokenization
|
|
26
|
+
:return: a new list of string after pre-processor and since pre-processor instructions
|
|
27
|
+
"""
|
|
28
|
+
pre_processor_data: list[PreProcessorData] = list()
|
|
29
|
+
new_code: list[str] = []
|
|
30
|
+
|
|
31
|
+
for line in code:
|
|
32
|
+
|
|
33
|
+
line = removeCommentPreProcessor(line)
|
|
34
|
+
|
|
35
|
+
if pre_processor_match := search(pre_processor_pattern, line):
|
|
36
|
+
|
|
37
|
+
instruction: str = pre_processor_match.group(1).lower()
|
|
38
|
+
symbol: str = pre_processor_match.group(2)
|
|
39
|
+
value: str = pre_processor_match.group(3)
|
|
40
|
+
if instruction in PreProcessorInstructions:
|
|
41
|
+
pre_processor_data.append(PreProcessorData(instruction, symbol, value))
|
|
42
|
+
|
|
43
|
+
else:
|
|
44
|
+
# apply pre-processor instructions
|
|
45
|
+
line = applyPreProcessor(line, pre_processor_data)
|
|
46
|
+
new_code.append(line)
|
|
47
|
+
|
|
48
|
+
return new_code
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def applyPreProcessor(code: str, pre_processor_data: list[PreProcessorData]) -> str:
|
|
53
|
+
"""
|
|
54
|
+
Apply preprocessor data to code
|
|
55
|
+
:param line: the current line before tokenization
|
|
56
|
+
:param pre_processor_data:
|
|
57
|
+
:return:
|
|
58
|
+
"""
|
|
59
|
+
for pre_processor in pre_processor_data:
|
|
60
|
+
match pre_processor.instruction:
|
|
61
|
+
case "define":
|
|
62
|
+
code = define(code, pre_processor)
|
|
63
|
+
|
|
64
|
+
return code
|
|
65
|
+
|
|
66
|
+
def removeCommentPreProcessor(code: str) -> str:
|
|
67
|
+
"""
|
|
68
|
+
Remove all comment in the code
|
|
69
|
+
:param code:
|
|
70
|
+
:return:
|
|
71
|
+
"""
|
|
72
|
+
# add \ before or in :: like \:: or :\: disable comment. Usable in string to add :: characters sequence.
|
|
73
|
+
return sub(r"(?<!\\):(?<!\\)?:.*", "", code, flags=MULTILINE)
|
{dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DshellTokenizer/dshell_keywords.py
RENAMED
|
@@ -10,7 +10,7 @@ __all__ = [
|
|
|
10
10
|
|
|
11
11
|
from ..DISCORD_COMMANDS import *
|
|
12
12
|
|
|
13
|
-
from ..full_import import Callable
|
|
13
|
+
from ..full_import import Callable, ChainMap
|
|
14
14
|
from ..DshellInterpreteur.dshell_iterators import IntIterator
|
|
15
15
|
|
|
16
16
|
|
|
@@ -175,7 +175,16 @@ Tuple format: (function, precedence, number of operands min, number of operands
|
|
|
175
175
|
Optional[index to translate into value])
|
|
176
176
|
"""
|
|
177
177
|
|
|
178
|
-
|
|
178
|
+
Operator = tuple[
|
|
179
|
+
Callable,
|
|
180
|
+
int,
|
|
181
|
+
int,
|
|
182
|
+
int,
|
|
183
|
+
Optional[int],
|
|
184
|
+
]
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
dshell_mathematical_operators: dict[str, Operator] = {
|
|
179
188
|
|
|
180
189
|
r"++": (lambda a: a + 1, 6, 1, 1, None),
|
|
181
190
|
r"--": (lambda a: a - 1, 6, 1, 1, None),
|
|
@@ -198,14 +207,14 @@ dshell_mathematical_operators: dict[str, tuple[Callable, int, int, int, Optional
|
|
|
198
207
|
|
|
199
208
|
}
|
|
200
209
|
|
|
201
|
-
dshell_logical_word_operators: dict[str,
|
|
210
|
+
dshell_logical_word_operators: dict[str, Operator] = {
|
|
202
211
|
r"and": (lambda a, b: bool(a and b), 2, 2, 2, None),
|
|
203
212
|
r"or": (lambda a, b: bool(a or b), 1, 2, 2, None),
|
|
204
213
|
r"not": (lambda a: not a, 3, 1, 1, None),
|
|
205
214
|
r"in": (lambda a, b: a in b, 4, 2, 2, None),
|
|
206
215
|
}
|
|
207
216
|
|
|
208
|
-
dshell_logical_operators: dict[str,
|
|
217
|
+
dshell_logical_operators: dict[str, Operator] = {
|
|
209
218
|
|
|
210
219
|
r"==": (lambda a, b: a == b, 4, 2, 2, None),
|
|
211
220
|
r"<=": (lambda a, b: a <= b, 4, 2, 2, None),
|
|
@@ -223,10 +232,13 @@ dshell_logical_operators: dict[str, tuple[Callable, int, int, int, Optional[int]
|
|
|
223
232
|
r">": (lambda a, b: a > b, 4, 2, 2, None),
|
|
224
233
|
r"!": (lambda a: not a, 3, 1, 1, None),
|
|
225
234
|
r"?": (lambda condition, first, second: first if condition else second, 1, 3, 3, 1),
|
|
226
|
-
#r".": (lambda target, attribute: target.call(attribute) if hasattr(target, attribute) and hasattr(target, 'call') else None, 9, 2, 2), # attribute access operator
|
|
227
|
-
|
|
228
235
|
}
|
|
229
236
|
|
|
230
|
-
dshell_operators:
|
|
237
|
+
dshell_operators: ChainMap[str, Operator] = ChainMap(
|
|
238
|
+
dshell_logical_operators,
|
|
239
|
+
dshell_logical_word_operators,
|
|
240
|
+
dshell_mathematical_operators)
|
|
241
|
+
|
|
242
|
+
"""dshell_operators: dict[str, tuple[Callable, int, int, int, Optional[int]]] = dshell_logical_operators.copy()
|
|
231
243
|
dshell_operators.update(dshell_logical_word_operators)
|
|
232
|
-
dshell_operators.update(dshell_mathematical_operators)
|
|
244
|
+
dshell_operators.update(dshell_mathematical_operators)"""
|
{dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DshellTokenizer/dshell_tokenizer.py
RENAMED
|
@@ -12,10 +12,8 @@ from Dshell.full_import import (
|
|
|
12
12
|
ASCII,
|
|
13
13
|
DOTALL,
|
|
14
14
|
IGNORECASE,
|
|
15
|
-
MULTILINE,
|
|
16
15
|
compile,
|
|
17
16
|
escape,
|
|
18
|
-
findall,
|
|
19
17
|
finditer,
|
|
20
18
|
Match,
|
|
21
19
|
sub)
|
|
@@ -27,7 +25,7 @@ from .dshell_keywords import (dshell_keyword,
|
|
|
27
25
|
dshell_logical_operators,
|
|
28
26
|
dshell_logical_word_operators)
|
|
29
27
|
|
|
30
|
-
from ..DshellPreProcess.dshell_preprocess import preProcessor
|
|
28
|
+
from ..DshellPreProcess.dshell_preprocess import preProcessor
|
|
31
29
|
|
|
32
30
|
MASK_CHARACTER = '§'
|
|
33
31
|
|
|
@@ -37,10 +35,9 @@ def is_line_empty(line: str) -> bool:
|
|
|
37
35
|
:param line: The line to check.
|
|
38
36
|
:return: True if the line is empty, False otherwise.
|
|
39
37
|
"""
|
|
40
|
-
return all(c in (MASK_CHARACTER, ' ') for c in line)
|
|
38
|
+
return all(c in (MASK_CHARACTER, ' ', '\n') for c in line)
|
|
41
39
|
|
|
42
40
|
table_regex: dict[DTT, Pattern] = {
|
|
43
|
-
DTT.COMMENT: compile(r"::(.*)", flags=MULTILINE),
|
|
44
41
|
DTT.STR: compile(r'"((?:[^\\"]|\\.)*)"', flags=DOTALL),
|
|
45
42
|
DTT.EVAL_L_EXPRESSION: compile(r"({)"),
|
|
46
43
|
DTT.EVAL_R_EXPRESSION: compile(r"(})"),
|
|
@@ -54,7 +51,7 @@ table_regex: dict[DTT, Pattern] = {
|
|
|
54
51
|
DTT.PARAMETER: compile(rf"--\s*([A-Za-z_]+)\s*", flags=ASCII),
|
|
55
52
|
DTT.MENTION: compile(r'<(?:@[!&]?|#)([0-9]+)>'),
|
|
56
53
|
DTT.KEYWORD: compile(rf"(?<!\w)(#?{'|'.join(dshell_keyword)})(?!\w)"),
|
|
57
|
-
DTT.DISCORD_KEYWORD: compile(rf"(
|
|
54
|
+
DTT.DISCORD_KEYWORD: compile(rf"(?<![\w\-])(#?{'|'.join(dshell_discord_keyword)})(?![\w\-])" , flags=IGNORECASE),
|
|
58
55
|
DTT.COMMAND: compile(rf"\b({'|'.join(dshell_commands.keys())})\b", flags=IGNORECASE),
|
|
59
56
|
DTT.FLOAT: compile(r"(\d+\.\d+)"),
|
|
60
57
|
DTT.HEXA: compile(r"(0[Xx][0-9a-fA-F]+)"),
|
|
@@ -66,21 +63,19 @@ table_regex: dict[DTT, Pattern] = {
|
|
|
66
63
|
DTT.BOOL: compile(r"(True|False)", flags=IGNORECASE),
|
|
67
64
|
DTT.NONE: compile(r"(None)", flags=IGNORECASE),
|
|
68
65
|
DTT.IDENT: compile(rf"([A-Za-z0-9_]+)"),
|
|
69
|
-
DTT.ANY_CHARACTER: compile(rf"([^{MASK_CHARACTER}\n]+)"),
|
|
70
66
|
}
|
|
71
67
|
|
|
68
|
+
backslash_pattern = compile(r"\\(.)", flags=DOTALL)
|
|
72
69
|
|
|
73
70
|
class DshellTokenizer:
|
|
74
71
|
|
|
75
|
-
def __init__(self, code: str
|
|
72
|
+
def __init__(self, code: str):
|
|
76
73
|
"""
|
|
77
74
|
Initialize the tokenizer.
|
|
78
75
|
:param code: The code to tokenize
|
|
79
76
|
:param match_any_character: Whether to match any character
|
|
80
77
|
"""
|
|
81
78
|
self.code: str = code
|
|
82
|
-
self.match_any_character: bool = match_any_character
|
|
83
|
-
self.data_pre_processor: list[PreProcessorData] = []
|
|
84
79
|
|
|
85
80
|
def start(self):
|
|
86
81
|
"""
|
|
@@ -88,6 +83,7 @@ class DshellTokenizer:
|
|
|
88
83
|
Returns an array of tokens per line (normally separated by \\n)
|
|
89
84
|
"""
|
|
90
85
|
split_commands = self.split(self.code)
|
|
86
|
+
split_commands = preProcessor(split_commands)
|
|
91
87
|
return self.tokenizer(split_commands)
|
|
92
88
|
|
|
93
89
|
def tokenizer(self, command_lines: list[str]) -> list[list[Token]]:
|
|
@@ -96,74 +92,47 @@ class DshellTokenizer:
|
|
|
96
92
|
:param command_lines: The code separated into multiple lines by the split method
|
|
97
93
|
"""
|
|
98
94
|
tokens: list[list[Token]] = []
|
|
95
|
+
ident_tokens = 0
|
|
99
96
|
|
|
100
|
-
line_number =
|
|
101
|
-
|
|
102
|
-
tokens_per_line: list[Token] = []
|
|
103
|
-
is_comment: bool = False
|
|
97
|
+
for line_number, line in enumerate(command_lines, start=1):
|
|
98
|
+
line: str = command_lines[line_number-1] # get the current line
|
|
104
99
|
|
|
100
|
+
# if the line is empty or already tokenized, pass the line.
|
|
105
101
|
if is_line_empty(line):
|
|
106
|
-
line_number += 1
|
|
107
102
|
continue
|
|
108
103
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
continue
|
|
112
|
-
else:
|
|
113
|
-
if self.data_pre_processor:
|
|
114
|
-
for processor_data in self.data_pre_processor:
|
|
115
|
-
line = applyPreProcessor(line, processor_data)
|
|
116
|
-
|
|
117
|
-
for token_type, pattern in table_regex.items(): # iterate the regex table to test all patterns on the line
|
|
118
|
-
|
|
119
|
-
if is_comment:
|
|
120
|
-
is_comment = False
|
|
121
|
-
break
|
|
122
|
-
|
|
123
|
-
if is_line_empty(line):
|
|
124
|
-
break
|
|
104
|
+
tokens.append([])
|
|
105
|
+
tokens_per_line = tokens[ident_tokens]
|
|
125
106
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
for match in finditer(pattern, line): # iterate the match results to get their positions
|
|
107
|
+
for token_type, regex in table_regex.items():
|
|
108
|
+
for match in finditer(regex, line):
|
|
130
109
|
match: Match
|
|
131
110
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
is_comment = True
|
|
135
|
-
break
|
|
136
|
-
else:
|
|
137
|
-
line = line[:match.start()]
|
|
138
|
-
continue
|
|
139
|
-
|
|
140
|
-
start_match = match.start() # start position of the match
|
|
111
|
+
start_match = match.start()
|
|
112
|
+
end_match = match.end()
|
|
141
113
|
|
|
142
|
-
token = Token(token_type, match.group(1), (line_number, start_match))
|
|
114
|
+
token = Token(token_type, match.group(1), (line_number, start_match))
|
|
143
115
|
tokens_per_line.append(token)
|
|
144
116
|
|
|
145
117
|
if token_type == DTT.STR:
|
|
146
|
-
token.value =
|
|
147
|
-
|
|
148
|
-
len_match = len(match.group(0)) # length of the match found
|
|
149
|
-
line = line[:start_match] + (MASK_CHARACTER * len_match) + line[
|
|
150
|
-
match.end():] # replace the match to avoid matching it a second time
|
|
151
|
-
|
|
152
|
-
tokens_per_line.sort(key=lambda
|
|
153
|
-
token: token.position[1]) # sort the position based on token match positions to have them in code order
|
|
154
|
-
if tokens_per_line:
|
|
118
|
+
token.value = sub(backslash_pattern, lambda m: escape(m.group(1)), token.value)
|
|
155
119
|
|
|
156
|
-
|
|
157
|
-
|
|
120
|
+
len_match = len(match.group(0))
|
|
121
|
+
line = line[:start_match] + MASK_CHARACTER * len_match + line[end_match:]
|
|
158
122
|
|
|
159
|
-
|
|
123
|
+
tokens_per_line.sort(key=lambda t: t.position[1])
|
|
160
124
|
|
|
161
|
-
|
|
125
|
+
if tokens_per_line:
|
|
126
|
+
tokens[ident_tokens] = self.parse_group(tokens_per_line, line_number)
|
|
162
127
|
|
|
128
|
+
ident_tokens += 1
|
|
163
129
|
return tokens
|
|
164
130
|
|
|
165
131
|
@staticmethod
|
|
166
|
-
def split(command: str,
|
|
132
|
+
def split(command: str,
|
|
133
|
+
global_split='\n',
|
|
134
|
+
keep_grouping_character=True,
|
|
135
|
+
grouping_character='"') -> list[
|
|
167
136
|
str]:
|
|
168
137
|
"""
|
|
169
138
|
Separate commands into a list while respecting strings between quotes.
|
|
@@ -175,31 +144,39 @@ class DshellTokenizer:
|
|
|
175
144
|
:return: A list of split commands with restored strings.
|
|
176
145
|
"""
|
|
177
146
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
147
|
+
result: list[str] = []
|
|
148
|
+
in_string: bool = False # True if we are in a string
|
|
149
|
+
backslash: bool = False
|
|
150
|
+
line: list[str] = [] # buffer for each line
|
|
151
|
+
|
|
152
|
+
for char in command:
|
|
153
|
+
|
|
154
|
+
if backslash:
|
|
155
|
+
line.append('\\')
|
|
156
|
+
line.append(char)
|
|
157
|
+
backslash = False
|
|
158
|
+
|
|
159
|
+
elif char == global_split and not in_string:
|
|
160
|
+
result.append(''.join(line))
|
|
161
|
+
line.clear()
|
|
162
|
+
|
|
163
|
+
elif char == grouping_character:
|
|
164
|
+
in_string = not in_string
|
|
165
|
+
if keep_grouping_character:
|
|
166
|
+
line.append(char)
|
|
167
|
+
|
|
168
|
+
elif char == '\\':
|
|
169
|
+
backslash = True
|
|
170
|
+
|
|
171
|
+
else:
|
|
172
|
+
line.append(char)
|
|
173
|
+
|
|
174
|
+
result.append(''.join(line))
|
|
175
|
+
|
|
199
176
|
return result
|
|
200
177
|
|
|
201
178
|
@staticmethod
|
|
202
|
-
def parse_group(
|
|
179
|
+
def parse_group(tokens_in_line: list[Token],
|
|
203
180
|
line_position: int):
|
|
204
181
|
"""
|
|
205
182
|
Parse all list in the current token line and return the modified list line.
|
|
@@ -227,8 +204,8 @@ class DshellTokenizer:
|
|
|
227
204
|
last_tokens[-1].value.append(token)
|
|
228
205
|
|
|
229
206
|
i = 0
|
|
230
|
-
while i < len(
|
|
231
|
-
token =
|
|
207
|
+
while i < len(tokens_in_line):
|
|
208
|
+
token = tokens_in_line[i]
|
|
232
209
|
|
|
233
210
|
if token.type == DTT.LIST_L:
|
|
234
211
|
if last_tokens:
|
|
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
|
|
|
5
5
|
|
|
6
6
|
setup(
|
|
7
7
|
name="dshellInterpreter",
|
|
8
|
-
version="1.2.7.
|
|
8
|
+
version="1.2.7.4",
|
|
9
9
|
author="Chronos",
|
|
10
10
|
author_email="vagabonwalybi@gmail.com",
|
|
11
11
|
description="A Discord bot interpreter for creating custom commands and automations.",
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
from ..full_import import search, sub, Optional
|
|
2
|
-
|
|
3
|
-
class PreProcessorData:
|
|
4
|
-
def __init__(self, instruction: str, symbol: str, value: str):
|
|
5
|
-
self.instruction = instruction
|
|
6
|
-
self.symbol = symbol
|
|
7
|
-
self.value = value
|
|
8
|
-
|
|
9
|
-
def define(line: str, pre_processor_data: PreProcessorData) -> str:
|
|
10
|
-
"""
|
|
11
|
-
Replace all symbol with the current value
|
|
12
|
-
:param line: the current line before tokenization
|
|
13
|
-
:param pre_processor_data: all data for the ##define pre-processor
|
|
14
|
-
:return:
|
|
15
|
-
"""
|
|
16
|
-
return sub(f"(?<![a-zA-Z]){pre_processor_data.symbol}(?![a-zA-Z])", pre_processor_data.value, line)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def preProcessor(line: str) -> Optional[PreProcessorData]:
|
|
20
|
-
"""
|
|
21
|
-
Execute preprocessor line
|
|
22
|
-
:param line: the current line before tokenization
|
|
23
|
-
:return:
|
|
24
|
-
"""
|
|
25
|
-
pre_process_match = search(r"^\s*##([a-zA-Z]+)\s+([a-zA-Z]+)\s+(.*)$", line)
|
|
26
|
-
if pre_process_match:
|
|
27
|
-
return PreProcessorData(pre_process_match.group(1).lower(), pre_process_match.group(2), pre_process_match.group(3))
|
|
28
|
-
return None
|
|
29
|
-
|
|
30
|
-
def applyPreProcessor(line: str, pre_processor_data: PreProcessorData):
|
|
31
|
-
"""
|
|
32
|
-
Apply preprocessor data to code
|
|
33
|
-
:param line: the current line before tokenization
|
|
34
|
-
:param pre_processor_data:
|
|
35
|
-
:return:
|
|
36
|
-
"""
|
|
37
|
-
match pre_processor_data.instruction:
|
|
38
|
-
case "define":
|
|
39
|
-
return define(line, pre_processor_data)
|
|
40
|
-
|
|
41
|
-
return None
|
|
File without changes
|
{dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/dshell_channel.py
RENAMED
|
File without changes
|
{dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/dshell_embed.py
RENAMED
|
File without changes
|
{dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/dshell_file.py
RENAMED
|
File without changes
|
|
File without changes
|
{dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/dshell_member.py
RENAMED
|
File without changes
|
{dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/dshell_message.py
RENAMED
|
File without changes
|
{dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/dshell_pastbin.py
RENAMED
|
File without changes
|
{dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/dshell_role.py
RENAMED
|
File without changes
|
{dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/dshell_ui.py
RENAMED
|
File without changes
|
{dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/utils/__init__.py
RENAMED
|
File without changes
|
{dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/utils/utils_embed.py
RENAMED
|
File without changes
|
{dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/utils/utils_file.py
RENAMED
|
File without changes
|
|
File without changes
|
{dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DISCORD_COMMANDS/utils/utils_list.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DshellInterpreteur/__init__.py
RENAMED
|
File without changes
|
{dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DshellInterpreteur/cached_messages.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DshellInterpreteur/dshell_scope.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DshellParser/dshell_parser.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/Dshell/DshellTokenizer/dshell_token_type.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/dshellInterpreter.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/dshellInterpreter.egg-info/requires.txt
RENAMED
|
File without changes
|
{dshellinterpreter-1.2.7.3 → dshellinterpreter-1.2.7.4}/dshellInterpreter.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|