mapres 3.dev16__py3-none-any.whl → 3.dev18__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.
- mapres/evaluator.py +5 -100
- {mapres-3.dev16.dist-info → mapres-3.dev18.dist-info}/METADATA +1 -1
- {mapres-3.dev16.dist-info → mapres-3.dev18.dist-info}/RECORD +6 -6
- {mapres-3.dev16.dist-info → mapres-3.dev18.dist-info}/WHEEL +0 -0
- {mapres-3.dev16.dist-info → mapres-3.dev18.dist-info}/licenses/LICENSE +0 -0
- {mapres-3.dev16.dist-info → mapres-3.dev18.dist-info}/top_level.txt +0 -0
mapres/evaluator.py
CHANGED
|
@@ -14,73 +14,45 @@ class Evaluator:
|
|
|
14
14
|
self.ctx = ctx or {}
|
|
15
15
|
self._seen = set() # cycle detection
|
|
16
16
|
|
|
17
|
-
# public api
|
|
18
17
|
def evaluate(self, node):
|
|
19
18
|
return self._eval(node)
|
|
20
19
|
|
|
21
|
-
# internal dispatch
|
|
22
20
|
def _eval(self, node):
|
|
23
21
|
if isinstance(node, TemplateNode):
|
|
24
22
|
return self._eval_template(node)
|
|
25
|
-
|
|
26
23
|
if isinstance(node, TextNode):
|
|
27
24
|
return node.text
|
|
28
|
-
|
|
29
25
|
if isinstance(node, IdentNode):
|
|
30
26
|
return self._eval_ident(node)
|
|
31
|
-
|
|
32
27
|
if isinstance(node, CallNode):
|
|
33
28
|
return self._eval_call(node)
|
|
34
|
-
|
|
35
29
|
raise EvaluationError(f'Unknown AST node: {node}')
|
|
36
30
|
|
|
37
|
-
# template
|
|
38
31
|
def _eval_template(self, node: TemplateNode):
|
|
39
32
|
parts = []
|
|
40
33
|
for child in node.children:
|
|
41
34
|
parts.append(self._eval(child))
|
|
42
35
|
out = ''.join(parts)
|
|
43
36
|
|
|
44
|
-
# recursion
|
|
45
|
-
if self._has_recursive_maps():
|
|
46
|
-
seen = set()
|
|
47
|
-
depth = 0
|
|
48
|
-
max_depth = self._get_max_depth()
|
|
49
|
-
|
|
50
|
-
while depth < max_depth:
|
|
51
|
-
new_out = self._re_resolve(out)
|
|
52
|
-
if new_out == out:
|
|
53
|
-
break
|
|
54
|
-
if new_out in seen:
|
|
55
|
-
raise EvaluationError('Cycle detected in template recursion')
|
|
56
|
-
seen.add(new_out)
|
|
57
|
-
out = new_out
|
|
58
|
-
depth += 1
|
|
59
|
-
|
|
37
|
+
# recursion disabled for now
|
|
60
38
|
return out
|
|
61
39
|
|
|
62
|
-
# identifier
|
|
63
40
|
def _eval_ident(self, node: IdentNode):
|
|
64
41
|
name = node.name
|
|
65
42
|
|
|
66
|
-
# ignore_delimiters: treat token as literal for this syntax
|
|
67
|
-
if self._syntax_ignores_delimiters(node.syntax):
|
|
68
|
-
return self._literal_from_syntax(name, node.syntax)
|
|
69
|
-
|
|
70
|
-
# cycle detection
|
|
71
43
|
if name in self._seen:
|
|
72
44
|
raise EvaluationError(f"Cycle detected in identifier '{name}'")
|
|
73
45
|
self._seen.add(name)
|
|
74
46
|
|
|
75
47
|
parts = name.split('.')
|
|
76
48
|
|
|
77
|
-
#
|
|
49
|
+
# ctx first
|
|
78
50
|
val = self._lookup_hierarchical(self.ctx, parts)
|
|
79
51
|
if val is not None:
|
|
80
52
|
self._seen.remove(name)
|
|
81
53
|
return str(val)
|
|
82
54
|
|
|
83
|
-
#
|
|
55
|
+
# syntax-bound maps
|
|
84
56
|
for m in self.layerstack.all_maps():
|
|
85
57
|
if getattr(m, '__syntax__', None) not in (None, node.syntax):
|
|
86
58
|
continue
|
|
@@ -94,15 +66,9 @@ class Evaluator:
|
|
|
94
66
|
self._seen.remove(name)
|
|
95
67
|
raise MissingKeyError(name)
|
|
96
68
|
|
|
97
|
-
# call (nested token)
|
|
98
69
|
def _eval_call(self, node: CallNode):
|
|
99
70
|
outer = node.name
|
|
100
71
|
|
|
101
|
-
# ignore_delimiters: treat call token as literal
|
|
102
|
-
if self._syntax_ignores_delimiters(node.syntax):
|
|
103
|
-
arg_text = self._eval(node.arg)
|
|
104
|
-
return self._literal_from_syntax(outer, node.syntax, is_call=True, arg_text=arg_text)
|
|
105
|
-
|
|
106
72
|
if outer in self._seen:
|
|
107
73
|
raise EvaluationError(f"Cycle detected in call '{outer}'")
|
|
108
74
|
self._seen.add(outer)
|
|
@@ -130,7 +96,6 @@ class Evaluator:
|
|
|
130
96
|
self._seen.remove(outer)
|
|
131
97
|
raise MissingKeyError(f'{outer}({arg_value})')
|
|
132
98
|
|
|
133
|
-
# helpers
|
|
134
99
|
def _map_to_dict(self, m):
|
|
135
100
|
if hasattr(m, 'as_map'):
|
|
136
101
|
return m.as_map()
|
|
@@ -148,74 +113,14 @@ class Evaluator:
|
|
|
148
113
|
cur = cur[p]
|
|
149
114
|
return cur
|
|
150
115
|
|
|
116
|
+
# recursion helpers now unused
|
|
151
117
|
def _has_recursive_maps(self):
|
|
152
|
-
for m in self.layerstack.all_maps():
|
|
153
|
-
if getattr(m, '__recursive__', False):
|
|
154
|
-
return True
|
|
155
118
|
return False
|
|
156
119
|
|
|
157
120
|
def _get_max_depth(self):
|
|
158
|
-
|
|
159
|
-
getattr(m, '__max_depth__', 10)
|
|
160
|
-
for m in self.layerstack.all_maps()
|
|
161
|
-
if getattr(m, '__recursive__', False)
|
|
162
|
-
]
|
|
163
|
-
return max(depths) if depths else 0
|
|
121
|
+
return 0
|
|
164
122
|
|
|
165
123
|
def _re_resolve(self, text: str) -> str:
|
|
166
124
|
tokens = Tokenizer(text).tokenize()
|
|
167
125
|
ast = Parser(tokens).parse()
|
|
168
126
|
return self.evaluate(ast)
|
|
169
|
-
|
|
170
|
-
def _syntax_ignores_delimiters(self, syntax_name: str) -> bool:
|
|
171
|
-
for m in self.layerstack.all_maps():
|
|
172
|
-
if getattr(m, '__syntax__', None) == syntax_name:
|
|
173
|
-
if getattr(m, '__ignore_delimiters__', False):
|
|
174
|
-
return True
|
|
175
|
-
return False
|
|
176
|
-
|
|
177
|
-
def _literal_from_syntax(self, name: str, syntax_name: str, is_call: bool = False, arg_text: str | None = None) -> str:
|
|
178
|
-
if not is_call:
|
|
179
|
-
if syntax_name == 'colons':
|
|
180
|
-
return f':{name}:'
|
|
181
|
-
if syntax_name == 'braces':
|
|
182
|
-
return f'{{{{{name}}}}}'
|
|
183
|
-
if syntax_name == 'dollars':
|
|
184
|
-
return f'${{{name}}}'
|
|
185
|
-
if syntax_name == 'angles':
|
|
186
|
-
return f'<{name}>'
|
|
187
|
-
if syntax_name == 'pipes':
|
|
188
|
-
return f'|{name}|'
|
|
189
|
-
if syntax_name == 'percents':
|
|
190
|
-
return f'%{name}%'
|
|
191
|
-
if syntax_name == 'paren_dollars':
|
|
192
|
-
return f'$({name})'
|
|
193
|
-
if syntax_name == 'at_tags':
|
|
194
|
-
return f'@{name}@'
|
|
195
|
-
if syntax_name == 'hash_tags':
|
|
196
|
-
return f'#{name}#'
|
|
197
|
-
return name
|
|
198
|
-
|
|
199
|
-
# call literal: syntax-specific wrapping of name(arg_text)
|
|
200
|
-
arg = arg_text or ''
|
|
201
|
-
inner = f'{name}({arg})'
|
|
202
|
-
|
|
203
|
-
if syntax_name == 'colons':
|
|
204
|
-
return f':{inner}:'
|
|
205
|
-
if syntax_name == 'braces':
|
|
206
|
-
return f'{{{{{inner}}}}}'
|
|
207
|
-
if syntax_name == 'dollars':
|
|
208
|
-
return f'${{{inner}}}'
|
|
209
|
-
if syntax_name == 'angles':
|
|
210
|
-
return f'<{inner}>'
|
|
211
|
-
if syntax_name == 'pipes':
|
|
212
|
-
return f'|{inner}|'
|
|
213
|
-
if syntax_name == 'percents':
|
|
214
|
-
return f'%{inner}%'
|
|
215
|
-
if syntax_name == 'paren_dollars':
|
|
216
|
-
return f'$({inner})'
|
|
217
|
-
if syntax_name == 'at_tags':
|
|
218
|
-
return f'@{inner}@'
|
|
219
|
-
if syntax_name == 'hash_tags':
|
|
220
|
-
return f'#{inner}#'
|
|
221
|
-
return inner
|
|
@@ -2,7 +2,7 @@ mapres/__init__.py,sha256=t23ofM-wzpPByYi1rEQonxyU1yyza4ZzwwHDZUa5QqA,1010
|
|
|
2
2
|
mapres/ast.py,sha256=6PcMkwtNHYD8xEkdyzDgn_mRTj1ZaWSyuHZK3BtXiuo,427
|
|
3
3
|
mapres/cache.py,sha256=hbvsoc6Qw3RhWAEfOOpKHtC7i9EomoUgWzyd4dnH71w,333
|
|
4
4
|
mapres/datamap.py,sha256=v9DAIYaS-vkBU1BKmshGYnquZa2JPwcct661zaEFocs,5256
|
|
5
|
-
mapres/evaluator.py,sha256=
|
|
5
|
+
mapres/evaluator.py,sha256=19oUC5BGqMz0j0SDsE_FJkL7C6HR4DTDlztvAJR-HkU,3631
|
|
6
6
|
mapres/exceptions.py,sha256=D2XKnrMkZDyUXQt2PmaKbj08FObWU00yXKGHwNpjvww,222
|
|
7
7
|
mapres/layers.py,sha256=sFc1eUOBg2BoB2cBXIleq8RMYcg5GZpUoCnGh-uKN6U,1380
|
|
8
8
|
mapres/parser.py,sha256=8XLCzYosvh81bN-Jddc1AM4w0X7bsHnBzmA8sq5_72w,4018
|
|
@@ -11,8 +11,8 @@ mapres/tokenizer.py,sha256=js0S1s8MkltdQoH5V1cLjdY0fFqZoGqmtP_OhEJEM6M,6539
|
|
|
11
11
|
mapres/maps/__init__.py,sha256=lIRRfem1Fw4iynuwUQ7BY5qrC4fbJKxqLivao2_Dtm4,239
|
|
12
12
|
mapres/maps/color.py,sha256=noRTGFNo9xLl5YEhX0tttV6i_oDAiptXmRVnkr5EzwM,1348
|
|
13
13
|
mapres/maps/time.py,sha256=TyncycYoIGVZWps32qWlFy2a2hTayvZWVHu9uh2nid8,2050
|
|
14
|
-
mapres-3.
|
|
15
|
-
mapres-3.
|
|
16
|
-
mapres-3.
|
|
17
|
-
mapres-3.
|
|
18
|
-
mapres-3.
|
|
14
|
+
mapres-3.dev18.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
15
|
+
mapres-3.dev18.dist-info/METADATA,sha256=5Kx-vfrbYympon_lWZsDhJagWAcOKQI51mvKC3D1-Cc,1476
|
|
16
|
+
mapres-3.dev18.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
|
|
17
|
+
mapres-3.dev18.dist-info/top_level.txt,sha256=5LMVQqJdtyjxfzv7wJBOZ-360m0Yc79w_-Y7s3n6cTw,7
|
|
18
|
+
mapres-3.dev18.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|