minecraft-datapack-language 15.4.23__py3-none-any.whl → 15.4.26__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.
- minecraft_datapack_language/_version.py +2 -2
- minecraft_datapack_language/ast_nodes.py +1 -0
- minecraft_datapack_language/cli_build.py +25 -34
- minecraft_datapack_language/mdl_parser_js.py +96 -112
- {minecraft_datapack_language-15.4.23.dist-info → minecraft_datapack_language-15.4.26.dist-info}/METADATA +1 -1
- {minecraft_datapack_language-15.4.23.dist-info → minecraft_datapack_language-15.4.26.dist-info}/RECORD +10 -10
- {minecraft_datapack_language-15.4.23.dist-info → minecraft_datapack_language-15.4.26.dist-info}/WHEEL +0 -0
- {minecraft_datapack_language-15.4.23.dist-info → minecraft_datapack_language-15.4.26.dist-info}/entry_points.txt +0 -0
- {minecraft_datapack_language-15.4.23.dist-info → minecraft_datapack_language-15.4.26.dist-info}/licenses/LICENSE +0 -0
- {minecraft_datapack_language-15.4.23.dist-info → minecraft_datapack_language-15.4.26.dist-info}/top_level.txt +0 -0
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
28
28
|
commit_id: COMMIT_ID
|
29
29
|
__commit_id__: COMMIT_ID
|
30
30
|
|
31
|
-
__version__ = version = '15.4.
|
32
|
-
__version_tuple__ = version_tuple = (15, 4,
|
31
|
+
__version__ = version = '15.4.26'
|
32
|
+
__version_tuple__ = version_tuple = (15, 4, 26)
|
33
33
|
|
34
34
|
__commit_id__ = commit_id = None
|
@@ -176,7 +176,7 @@ def _generate_scoreboard_objectives(ast: Dict[str, Any], output_dir: Path) -> Li
|
|
176
176
|
if 'body' in func:
|
177
177
|
for statement in func['body']:
|
178
178
|
# Look for variable assignments and usage
|
179
|
-
if statement['type']
|
179
|
+
if statement['type'] == 'variable_assignment':
|
180
180
|
if statement['name'] not in seen_variables:
|
181
181
|
variables.append(statement['name'])
|
182
182
|
seen_variables.add(statement['name'])
|
@@ -280,7 +280,8 @@ def _process_say_command_with_variables(content: str, selector: str, variable_sc
|
|
280
280
|
var_selector = var_parts[1][:-1] # Remove trailing >
|
281
281
|
components.append(f'{{"score":{{"name":"{var_selector}","objective":"{base_var}"}}}}')
|
282
282
|
else:
|
283
|
-
# Simple variable: $variable$ -
|
283
|
+
# Simple variable: $variable$ - determine selector based on declared scope
|
284
|
+
var_selector = "@e[type=armor_stand,tag=mdl_server,limit=1]" # Default to global
|
284
285
|
if variable_scopes and var_name in variable_scopes:
|
285
286
|
declared_scope = variable_scopes[var_name]
|
286
287
|
if declared_scope == 'global':
|
@@ -289,8 +290,7 @@ def _process_say_command_with_variables(content: str, selector: str, variable_sc
|
|
289
290
|
var_selector = declared_scope
|
290
291
|
print(f"DEBUG: Variable {var_name} using declared scope {declared_scope} -> selector {var_selector}")
|
291
292
|
else:
|
292
|
-
|
293
|
-
print(f"DEBUG: Variable {var_name} has no declared scope, using default selector {var_selector}")
|
293
|
+
print(f"DEBUG: Variable {var_name} has no declared scope, using default global selector")
|
294
294
|
|
295
295
|
components.append(f'{{"score":{{"name":"{var_selector}","objective":"{var_name}"}}}}')
|
296
296
|
|
@@ -336,25 +336,16 @@ def _process_statement(statement: Any, namespace: str, function_name: str, state
|
|
336
336
|
var_name = statement['name']
|
337
337
|
value = statement['value']
|
338
338
|
|
339
|
-
#
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
339
|
+
# Determine the correct selector for this variable based on its declared scope
|
340
|
+
var_selector = selector # Default to current selector
|
341
|
+
if variable_scopes and var_name in variable_scopes:
|
342
|
+
declared_scope = variable_scopes[var_name]
|
343
|
+
if declared_scope == 'global':
|
344
|
+
var_selector = "@e[type=armor_stand,tag=mdl_server,limit=1]"
|
345
|
+
else:
|
346
|
+
var_selector = declared_scope
|
347
|
+
print(f"DEBUG: Variable {var_name} assignment using selector: {var_selector} (declared scope: {variable_scopes.get(var_name, 'none')})")
|
348
348
|
|
349
|
-
# For explicit scope assignments, use the specified scope
|
350
|
-
if explicit_scope == 'global':
|
351
|
-
var_selector = "@e[type=armor_stand,tag=mdl_server,limit=1]"
|
352
|
-
else:
|
353
|
-
var_selector = explicit_scope
|
354
|
-
print(f"DEBUG: Variable {var_name} assignment using explicit selector: {var_selector}")
|
355
|
-
|
356
|
-
# Handle assignment value processing for both types
|
357
|
-
if statement['type'] in ['variable_assignment', 'explicit_scope_assignment']:
|
358
349
|
# Handle different value types
|
359
350
|
if isinstance(value, int):
|
360
351
|
commands.append(f"scoreboard players set {var_selector} {var_name} {value}")
|
@@ -850,22 +841,22 @@ def _ast_to_pack(ast: Dict[str, Any], mdl_files: List[Path]) -> Pack:
|
|
850
841
|
else:
|
851
842
|
# Simple function call without scope
|
852
843
|
function.commands.append(f"function {func_namespace}:{func_name}")
|
853
|
-
elif statement.get('type')
|
844
|
+
elif statement.get('type') == 'variable_assignment':
|
854
845
|
# Handle variable assignments
|
855
846
|
var_name = statement['name']
|
856
847
|
value = statement['value']
|
857
848
|
|
858
|
-
# Determine selector based on
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
849
|
+
# Determine selector based on variable scope
|
850
|
+
var_selector = "@s" # Default
|
851
|
+
if 'variables' in ast:
|
852
|
+
for var_decl in ast['variables']:
|
853
|
+
if var_decl.get('name') == var_name:
|
854
|
+
var_scope = var_decl.get('scope')
|
855
|
+
if var_scope == 'global':
|
856
|
+
var_selector = "@e[type=armor_stand,tag=mdl_server,limit=1]"
|
857
|
+
elif var_scope:
|
858
|
+
var_selector = var_scope
|
859
|
+
break
|
869
860
|
|
870
861
|
if hasattr(value, 'value'):
|
871
862
|
# Simple literal value
|
@@ -316,15 +316,10 @@ class MDLParser:
|
|
316
316
|
suggestion="Replace 'for' with 'while' and adjust the loop structure"
|
317
317
|
)
|
318
318
|
|
319
|
-
# Check if this is a variable assignment
|
320
|
-
# Pattern 1: identifier = (simple assignment)
|
319
|
+
# Check if this is a variable assignment (identifier followed by =)
|
321
320
|
if (self.current + 1 < len(self.tokens) and
|
322
321
|
self.tokens[self.current + 1].type == TokenType.ASSIGN):
|
323
322
|
return self._parse_variable_assignment()
|
324
|
-
|
325
|
-
# Pattern 2: identifier<scope> = (explicit scope assignment)
|
326
|
-
elif self._is_explicit_scope_assignment():
|
327
|
-
return self._parse_explicit_scope_assignment()
|
328
323
|
else:
|
329
324
|
# Assume it's a command
|
330
325
|
return self._parse_command()
|
@@ -342,31 +337,29 @@ class MDLParser:
|
|
342
337
|
|
343
338
|
# Check for scope selector after variable name
|
344
339
|
scope = None
|
345
|
-
if not self._is_at_end() and self._peek().type == TokenType.
|
346
|
-
self._match(TokenType.
|
340
|
+
if not self._is_at_end() and self._peek().type == TokenType.LANGLE:
|
341
|
+
self._match(TokenType.LANGLE) # consume '<'
|
347
342
|
|
348
|
-
# Parse scope selector
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
self._match(TokenType.RANGLE) # consume '>'
|
369
|
-
scope = ''.join(scope_parts)
|
343
|
+
# Parse scope selector content
|
344
|
+
scope_parts = []
|
345
|
+
while not self._is_at_end() and self._peek().type != TokenType.RANGLE:
|
346
|
+
scope_parts.append(self._peek().value)
|
347
|
+
self._advance()
|
348
|
+
|
349
|
+
if self._is_at_end():
|
350
|
+
raise create_parser_error(
|
351
|
+
message="Unterminated scope selector",
|
352
|
+
file_path=self.source_file,
|
353
|
+
line=self._peek().line,
|
354
|
+
column=self._peek().column,
|
355
|
+
line_content=self._peek().value,
|
356
|
+
suggestion="Add a closing '>' to terminate the scope selector"
|
357
|
+
)
|
358
|
+
|
359
|
+
self._match(TokenType.RANGLE) # consume '>'
|
360
|
+
scope = ''.join(scope_parts)
|
361
|
+
# Update the name to include the scope selector
|
362
|
+
name = f"{name}<{scope}>"
|
370
363
|
|
371
364
|
self._match(TokenType.ASSIGN)
|
372
365
|
|
@@ -382,80 +375,40 @@ class MDLParser:
|
|
382
375
|
name_token = self._match(TokenType.IDENTIFIER)
|
383
376
|
name = name_token.value
|
384
377
|
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
self._match(TokenType.SEMICOLON)
|
391
|
-
|
392
|
-
return {"type": "variable_assignment", "name": name, "value": value}
|
393
|
-
|
394
|
-
def _is_explicit_scope_assignment(self) -> bool:
|
395
|
-
"""Check if current position is an explicit scope assignment pattern: var<scope> = value"""
|
396
|
-
if self.current >= len(self.tokens):
|
397
|
-
return False
|
378
|
+
# Check for scope selector after variable name
|
379
|
+
scope = None
|
380
|
+
if not self._is_at_end() and self._peek().type == TokenType.LANGLE:
|
381
|
+
self._match(TokenType.LANGLE) # consume '<'
|
398
382
|
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
return False
|
405
|
-
idx += 1
|
406
|
-
|
407
|
-
# Skip tokens until we find RANGLE
|
408
|
-
while idx < len(self.tokens) and self.tokens[idx].type != TokenType.RANGLE:
|
409
|
-
idx += 1
|
410
|
-
|
411
|
-
# Must find RANGLE
|
412
|
-
if idx >= len(self.tokens) or self.tokens[idx].type != TokenType.RANGLE:
|
413
|
-
return False
|
414
|
-
idx += 1
|
415
|
-
|
416
|
-
# Must have ASSIGN after RANGLE
|
417
|
-
if idx >= len(self.tokens) or self.tokens[idx].type != TokenType.ASSIGN:
|
418
|
-
return False
|
383
|
+
# Parse scope selector content
|
384
|
+
scope_parts = []
|
385
|
+
while not self._is_at_end() and self._peek().type != TokenType.RANGLE:
|
386
|
+
scope_parts.append(self._peek().value)
|
387
|
+
self._advance()
|
419
388
|
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
scope_parts.append(self._peek().value)
|
435
|
-
self._advance()
|
436
|
-
|
437
|
-
if self._is_at_end():
|
438
|
-
raise create_parser_error(
|
439
|
-
message="Unterminated scope selector in assignment",
|
440
|
-
file_path=self.source_file,
|
441
|
-
line=self._peek().line,
|
442
|
-
column=self._peek().column,
|
443
|
-
line_content=self._peek().value,
|
444
|
-
suggestion="Add a closing '>' to terminate the scope selector"
|
445
|
-
)
|
446
|
-
|
447
|
-
self._match(TokenType.RANGLE)
|
448
|
-
scope = ''.join(scope_parts)
|
389
|
+
if self._is_at_end():
|
390
|
+
raise create_parser_error(
|
391
|
+
message="Unterminated scope selector",
|
392
|
+
file_path=self.source_file,
|
393
|
+
line=self._peek().line,
|
394
|
+
column=self._peek().column,
|
395
|
+
line_content=self._peek().value,
|
396
|
+
suggestion="Add a closing '>' to terminate the scope selector"
|
397
|
+
)
|
398
|
+
|
399
|
+
self._match(TokenType.RANGLE) # consume '>'
|
400
|
+
scope = ''.join(scope_parts)
|
401
|
+
# Update the name to include the scope selector
|
402
|
+
name = f"{name}<{scope}>"
|
449
403
|
|
450
|
-
# Parse assignment
|
451
404
|
self._match(TokenType.ASSIGN)
|
452
405
|
|
453
|
-
# Parse the value
|
406
|
+
# Parse the value (could be a number or expression)
|
454
407
|
value = self._parse_expression()
|
455
408
|
|
456
409
|
self._match(TokenType.SEMICOLON)
|
457
410
|
|
458
|
-
return {"type": "
|
411
|
+
return {"type": "variable_assignment", "name": name, "scope": scope, "value": value}
|
459
412
|
|
460
413
|
def _parse_if_statement(self) -> IfStatement:
|
461
414
|
"""Parse if statement."""
|
@@ -756,8 +709,47 @@ class MDLParser:
|
|
756
709
|
"""Parse a command."""
|
757
710
|
command_parts = []
|
758
711
|
while not self._is_at_end() and self._peek().type != TokenType.SEMICOLON:
|
759
|
-
|
760
|
-
|
712
|
+
current_token = self._peek()
|
713
|
+
|
714
|
+
# Check if this is an identifier that might be followed by a scope selector
|
715
|
+
if current_token.type == TokenType.IDENTIFIER:
|
716
|
+
identifier_name = current_token.value
|
717
|
+
command_parts.append(identifier_name)
|
718
|
+
self._advance() # consume the identifier
|
719
|
+
|
720
|
+
# Look ahead to see if there's a scope selector
|
721
|
+
if not self._is_at_end() and self._peek().type == TokenType.LANGLE:
|
722
|
+
# This is a scoped variable - parse the scope selector
|
723
|
+
self._match(TokenType.LANGLE) # consume '<'
|
724
|
+
|
725
|
+
# Parse scope selector content
|
726
|
+
scope_parts = []
|
727
|
+
while not self._is_at_end() and self._peek().type != TokenType.RANGLE:
|
728
|
+
scope_parts.append(self._peek().value)
|
729
|
+
self._advance()
|
730
|
+
|
731
|
+
if self._is_at_end():
|
732
|
+
raise create_parser_error(
|
733
|
+
message="Unterminated scope selector in command",
|
734
|
+
file_path=self.source_file,
|
735
|
+
line=self._peek().line,
|
736
|
+
column=self._peek().column,
|
737
|
+
line_content=self._peek().value,
|
738
|
+
suggestion="Add a closing '>' to terminate the scope selector"
|
739
|
+
)
|
740
|
+
|
741
|
+
self._match(TokenType.RANGLE) # consume '>'
|
742
|
+
scope_selector = ''.join(scope_parts)
|
743
|
+
|
744
|
+
# Add the scope selector to the command parts
|
745
|
+
command_parts.append(f"<{scope_selector}>")
|
746
|
+
else:
|
747
|
+
# No scope selector, continue with next token
|
748
|
+
continue
|
749
|
+
else:
|
750
|
+
# Regular token, just add it
|
751
|
+
command_parts.append(current_token.value)
|
752
|
+
self._advance()
|
761
753
|
|
762
754
|
if self._is_at_end():
|
763
755
|
raise create_parser_error(
|
@@ -907,9 +899,10 @@ class MDLParser:
|
|
907
899
|
identifier_name = token.value
|
908
900
|
self._advance() # consume the identifier
|
909
901
|
|
910
|
-
# Check
|
902
|
+
# Check if this identifier is followed by a scope selector
|
911
903
|
if not self._is_at_end() and self._peek().type == TokenType.LANGLE:
|
912
|
-
|
904
|
+
# This is a scoped variable - parse the scope selector
|
905
|
+
self._match(TokenType.LANGLE) # consume '<'
|
913
906
|
|
914
907
|
# Parse scope selector content
|
915
908
|
scope_parts = []
|
@@ -927,21 +920,12 @@ class MDLParser:
|
|
927
920
|
suggestion="Add a closing '>' to terminate the scope selector"
|
928
921
|
)
|
929
922
|
|
930
|
-
self.
|
923
|
+
self._match(TokenType.RANGLE) # consume '>'
|
931
924
|
scope_selector = ''.join(scope_parts)
|
932
925
|
|
933
|
-
#
|
934
|
-
|
935
|
-
|
936
|
-
# Check if the identifier contains a scope selector (legacy single-token format)
|
937
|
-
elif '<' in identifier_name and identifier_name.endswith('>'):
|
938
|
-
# Extract variable name and scope selector
|
939
|
-
parts = identifier_name.split('<', 1)
|
940
|
-
if len(parts) == 2:
|
941
|
-
var_name = parts[0]
|
942
|
-
scope_selector = parts[1][:-1] # Remove the closing >
|
943
|
-
# For variable expressions in assignments, keep the full scoped name
|
944
|
-
return VariableExpression(identifier_name)
|
926
|
+
# Create a scoped variable expression
|
927
|
+
full_name = f"{identifier_name}<{scope_selector}>"
|
928
|
+
return VariableExpression(full_name)
|
945
929
|
|
946
930
|
# Regular variable expression without scope
|
947
931
|
return VariableExpression(identifier_name)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: minecraft-datapack-language
|
3
|
-
Version: 15.4.
|
3
|
+
Version: 15.4.26
|
4
4
|
Summary: Compile JavaScript-style MDL language or Python API into a Minecraft datapack (1.21+ ready). Features variables, control flow, error handling, and VS Code extension.
|
5
5
|
Project-URL: Homepage, https://www.mcmdl.com
|
6
6
|
Project-URL: Documentation, https://www.mcmdl.com/docs
|
@@ -1,8 +1,8 @@
|
|
1
1
|
minecraft_datapack_language/__init__.py,sha256=i-qCchbe5b2Fshgc6yCU9mddOLs2UBt9SAcLqfUIrT0,606
|
2
|
-
minecraft_datapack_language/_version.py,sha256=
|
3
|
-
minecraft_datapack_language/ast_nodes.py,sha256=
|
2
|
+
minecraft_datapack_language/_version.py,sha256=ZFtqs_SG6x6U-SOyZin31273WN7DoOUGVgDsZjWRysA,708
|
3
|
+
minecraft_datapack_language/ast_nodes.py,sha256=U-CB3R7p7OjaljI47BWsRrQtliw0yAWUrJVoxzOLmQw,2143
|
4
4
|
minecraft_datapack_language/cli.py,sha256=p5A_tEEXugN2NhQFbbgfwi4FxbWYD91RWeKR_A3Vuec,6263
|
5
|
-
minecraft_datapack_language/cli_build.py,sha256=
|
5
|
+
minecraft_datapack_language/cli_build.py,sha256=u0XIOH_zTARPC6dvWf-411OqrF7RjT7Z9Hkp6hTeZsI,47990
|
6
6
|
minecraft_datapack_language/cli_check.py,sha256=bPq9gHsxQ1CIiftkrAtRCifWkVAyjp5c8Oay2NNQ1qs,6277
|
7
7
|
minecraft_datapack_language/cli_colors.py,sha256=Hr8awY966bGSnVdXL3WnmRhSP1wH56vTQKGt5z-kIQM,7878
|
8
8
|
minecraft_datapack_language/cli_help.py,sha256=Rc-v9E2kctsdN_lMunqdKuZ8EZ8rcZIjBCOPrXLBQeE,21363
|
@@ -14,12 +14,12 @@ minecraft_datapack_language/linter.py,sha256=7UqbygC5JPCGg-BSOq65NB2xEJBu_OUOYII
|
|
14
14
|
minecraft_datapack_language/mdl_errors.py,sha256=mz6uyPkeBpbMHj4PiAyVecEVJ9_hdSfR45QAjG6oYf0,15690
|
15
15
|
minecraft_datapack_language/mdl_lexer_js.py,sha256=VvbhKm727khdSAABxa03hoIIA7H3hWi3RLp9BSXbhY0,28277
|
16
16
|
minecraft_datapack_language/mdl_linter.py,sha256=z85xoAglENurCh30bR7kEHZ_JeMxcYaLDcGNRAl-RAI,17253
|
17
|
-
minecraft_datapack_language/mdl_parser_js.py,sha256=
|
17
|
+
minecraft_datapack_language/mdl_parser_js.py,sha256=kaeTxzQDRDUj4YdpeR9Yrp8d8JCuOwmd36HZSeSrCgY,43992
|
18
18
|
minecraft_datapack_language/pack.py,sha256=nYiXQ3jgJlDfc4m-65f7C2LFhDRioaUU_XVy6Na4SJI,34625
|
19
19
|
minecraft_datapack_language/utils.py,sha256=Aq0HAGlXqj9BUTEjaEilpvzEW0EtZYYMMwOqG9db6dE,684
|
20
|
-
minecraft_datapack_language-15.4.
|
21
|
-
minecraft_datapack_language-15.4.
|
22
|
-
minecraft_datapack_language-15.4.
|
23
|
-
minecraft_datapack_language-15.4.
|
24
|
-
minecraft_datapack_language-15.4.
|
25
|
-
minecraft_datapack_language-15.4.
|
20
|
+
minecraft_datapack_language-15.4.26.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
21
|
+
minecraft_datapack_language-15.4.26.dist-info/METADATA,sha256=CP-fUjVPMIttFRw5N2w_ElF9baJ9wBCYjSbOjmSD-4A,37917
|
22
|
+
minecraft_datapack_language-15.4.26.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
23
|
+
minecraft_datapack_language-15.4.26.dist-info/entry_points.txt,sha256=c6vjBeCiyQflvPHBRyBk2nJCSfYt3Oc7Sc9V87ySi_U,108
|
24
|
+
minecraft_datapack_language-15.4.26.dist-info/top_level.txt,sha256=ADtFI476tbKLLxEAA-aJQAfg53MA3k_DOb0KTFiggfw,28
|
25
|
+
minecraft_datapack_language-15.4.26.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|