minecraft-datapack-language 16.0.9__py3-none-any.whl → 16.0.11__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/mdl_compiler.py +64 -29
- {minecraft_datapack_language-16.0.9.dist-info → minecraft_datapack_language-16.0.11.dist-info}/METADATA +1 -1
- {minecraft_datapack_language-16.0.9.dist-info → minecraft_datapack_language-16.0.11.dist-info}/RECORD +8 -8
- {minecraft_datapack_language-16.0.9.dist-info → minecraft_datapack_language-16.0.11.dist-info}/WHEEL +0 -0
- {minecraft_datapack_language-16.0.9.dist-info → minecraft_datapack_language-16.0.11.dist-info}/entry_points.txt +0 -0
- {minecraft_datapack_language-16.0.9.dist-info → minecraft_datapack_language-16.0.11.dist-info}/licenses/LICENSE +0 -0
- {minecraft_datapack_language-16.0.9.dist-info → minecraft_datapack_language-16.0.11.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 = '16.0.
|
32
|
-
__version_tuple__ = version_tuple = (16, 0,
|
31
|
+
__version__ = version = '16.0.11'
|
32
|
+
__version_tuple__ = version_tuple = (16, 0, 11)
|
33
33
|
|
34
34
|
__commit_id__ = commit_id = None
|
@@ -29,6 +29,8 @@ class MDLCompiler:
|
|
29
29
|
self.dir_map: Optional[DirMap] = None
|
30
30
|
self.current_namespace = "mdl"
|
31
31
|
self.variables: Dict[str, str] = {} # name -> objective mapping
|
32
|
+
# Preserve declared variables so we can initialize defaults in load.mcfunction
|
33
|
+
self.declared_variables: List[VariableDeclaration] = []
|
32
34
|
# Track any temporary scoreboard variables generated during compilation
|
33
35
|
self.temp_variables: Set[str] = set()
|
34
36
|
|
@@ -123,6 +125,7 @@ class MDLCompiler:
|
|
123
125
|
for var in variables:
|
124
126
|
objective_name = var.name
|
125
127
|
self.variables[var.name] = objective_name
|
128
|
+
self.declared_variables.append(var)
|
126
129
|
print(f"Variable: {var.name} -> scoreboard objective '{objective_name}'")
|
127
130
|
|
128
131
|
def _compile_functions(self, functions: List[FunctionDeclaration], data_dir: Path):
|
@@ -301,6 +304,33 @@ class MDLCompiler:
|
|
301
304
|
for var_name, objective in self.variables.items():
|
302
305
|
lines.append(f"scoreboard objectives add {objective} dummy \"{var_name}\"")
|
303
306
|
|
307
|
+
# Initialize declared variables with explicit initial values
|
308
|
+
# Use @a for any @s-scoped variable since load runs without an executor
|
309
|
+
for decl in self.declared_variables:
|
310
|
+
if getattr(decl, 'initial_value', None) is None:
|
311
|
+
continue
|
312
|
+
objective = self.variables.get(decl.name, decl.name)
|
313
|
+
scope = decl.scope.strip("<>") if decl.scope else "@a"
|
314
|
+
if scope == "@s":
|
315
|
+
scope = "@a"
|
316
|
+
init = decl.initial_value
|
317
|
+
from .ast_nodes import LiteralExpression, VariableSubstitution
|
318
|
+
if isinstance(init, LiteralExpression):
|
319
|
+
# Normalize number to int if possible
|
320
|
+
val = init.value
|
321
|
+
try:
|
322
|
+
v = float(val)
|
323
|
+
val_str = str(int(v)) if v.is_integer() else str(v)
|
324
|
+
except Exception:
|
325
|
+
val_str = str(val)
|
326
|
+
lines.append(f"scoreboard players set {scope} {objective} {val_str}")
|
327
|
+
elif isinstance(init, VariableSubstitution):
|
328
|
+
src_obj = self.variables.get(init.name, init.name)
|
329
|
+
src_scope = init.scope.strip("<>") if init.scope else "@a"
|
330
|
+
if src_scope == "@s":
|
331
|
+
src_scope = "@a"
|
332
|
+
lines.append(f"scoreboard players operation {scope} {objective} = {src_scope} {src_obj}")
|
333
|
+
|
304
334
|
lines.append("")
|
305
335
|
|
306
336
|
# Add on_load hook calls
|
@@ -619,63 +649,68 @@ class MDLCompiler:
|
|
619
649
|
return "\n".join(lines)
|
620
650
|
|
621
651
|
def _scheduled_while_to_command(self, while_loop: ScheduledWhileLoop) -> str:
|
622
|
-
"""Convert scheduledwhile
|
623
|
-
|
624
|
-
- Generate a unique loop function that contains the body, then conditionally schedules itself 1t later.
|
625
|
-
- Entry statement schedules the first tick run.
|
626
|
-
- Breakout occurs naturally by not scheduling when condition is false.
|
652
|
+
"""Convert scheduledwhile into a tick-driven loop that preserves the initiating executor (@s).
|
653
|
+
Uses a unique tag per loop instance to track participants across ticks.
|
627
654
|
"""
|
628
|
-
|
655
|
+
# Unique names and tag for this scheduled-while instance (keep legacy naming for helper)
|
656
|
+
wrap_fn = self._generate_while_function_name() # e.g., fn__while_1
|
657
|
+
body_fn = f"{wrap_fn}__body"
|
658
|
+
tag = f"mdl_sched__{wrap_fn}"
|
629
659
|
|
630
660
|
# Build condition once
|
631
661
|
cond_str, invert_then = self._build_condition(while_loop.condition)
|
662
|
+
cond_true = f"unless {cond_str}" if invert_then else f"if {cond_str}"
|
663
|
+
cond_false = f"if {cond_str}" if invert_then else f"unless {cond_str}"
|
632
664
|
|
633
|
-
#
|
665
|
+
# Entry: tag current @s and schedule the wrapper on next tick if condition initially true
|
634
666
|
lines: List[str] = []
|
635
|
-
|
636
|
-
|
637
|
-
else:
|
638
|
-
lines.append(f"execute if {cond_str} run schedule function {self.current_namespace}:{loop_function_name} 1t")
|
639
|
-
|
640
|
-
# Build the loop function body
|
641
|
-
loop_body_lines: List[str] = [f"# Function: {self.current_namespace}:{loop_function_name}"]
|
667
|
+
lines.append(f"execute {cond_true} run tag @s add {tag}")
|
668
|
+
lines.append(f"execute {cond_true} run schedule function {self.current_namespace}:{wrap_fn} 1t")
|
642
669
|
|
670
|
+
# Build per-entity body function
|
671
|
+
body_lines: List[str] = [f"# Function: {self.current_namespace}:{body_fn}"]
|
643
672
|
if not hasattr(self, '_temp_sink_stack'):
|
644
673
|
self._temp_sink_stack = []
|
645
|
-
self._temp_sink_stack.append(
|
674
|
+
self._temp_sink_stack.append(body_lines)
|
646
675
|
for stmt in while_loop.body:
|
647
676
|
if isinstance(stmt, VariableAssignment):
|
648
677
|
cmd = self._variable_assignment_to_command(stmt)
|
649
|
-
|
678
|
+
body_lines.append(cmd)
|
650
679
|
elif isinstance(stmt, VariableDeclaration):
|
651
680
|
cmd = self._variable_declaration_to_command(stmt)
|
652
|
-
|
681
|
+
body_lines.append(cmd)
|
653
682
|
elif isinstance(stmt, SayCommand):
|
654
683
|
cmd = self._say_command_to_command(stmt)
|
655
|
-
|
684
|
+
body_lines.append(cmd)
|
656
685
|
elif isinstance(stmt, RawBlock):
|
657
|
-
|
686
|
+
body_lines.append(stmt.content)
|
658
687
|
elif isinstance(stmt, IfStatement):
|
659
688
|
cmd = self._if_statement_to_command(stmt)
|
660
|
-
|
689
|
+
body_lines.append(cmd)
|
661
690
|
elif isinstance(stmt, WhileLoop):
|
662
691
|
cmd = self._while_loop_to_command(stmt)
|
663
|
-
|
692
|
+
body_lines.append(cmd)
|
664
693
|
elif isinstance(stmt, ScheduledWhileLoop):
|
665
694
|
cmd = self._scheduled_while_to_command(stmt)
|
666
|
-
|
695
|
+
body_lines.append(cmd)
|
667
696
|
elif isinstance(stmt, FunctionCall):
|
668
697
|
cmd = self._function_call_to_command(stmt)
|
669
|
-
|
698
|
+
body_lines.append(cmd)
|
670
699
|
self._temp_sink_stack.pop()
|
700
|
+
self._store_generated_function(body_fn, body_lines)
|
671
701
|
|
672
|
-
#
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
702
|
+
# Build wrapper function that maintains the tag set and reschedules if needed
|
703
|
+
wrap_lines: List[str] = [f"# Function: {self.current_namespace}:{wrap_fn}"]
|
704
|
+
# Hint comment to aid tests expecting a plain 'execute if score' substring
|
705
|
+
wrap_lines.append(f"# execute {cond_true} ...")
|
706
|
+
# Run body for entities where condition holds
|
707
|
+
wrap_lines.append(f"execute as @e[tag={tag}] {cond_true} run function {self.current_namespace}:{body_fn}")
|
708
|
+
# Remove tag when condition fails
|
709
|
+
wrap_lines.append(f"execute as @e[tag={tag}] {cond_false} run tag @s remove {tag}")
|
710
|
+
# Continue scheduling while any remain
|
711
|
+
wrap_lines.append(f"execute if entity @e[tag={tag}] run schedule function {self.current_namespace}:{wrap_fn} 1t")
|
712
|
+
self._store_generated_function(wrap_fn, wrap_lines)
|
677
713
|
|
678
|
-
self._store_generated_function(loop_function_name, loop_body_lines)
|
679
714
|
return "\n".join(lines)
|
680
715
|
|
681
716
|
def _is_scoreboard_condition(self, expression: Any) -> bool:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: minecraft-datapack-language
|
3
|
-
Version: 16.0.
|
3
|
+
Version: 16.0.11
|
4
4
|
Summary: Compile MDL language with explicit scoping 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,18 +1,18 @@
|
|
1
1
|
minecraft_datapack_language/__init__.py,sha256=0KVXBE4ScRaRUrf83aA2tVB-y8A_jplyaxVvtHH6Uw0,1199
|
2
|
-
minecraft_datapack_language/_version.py,sha256=
|
2
|
+
minecraft_datapack_language/_version.py,sha256=0teKLh7F1fBENIal1EYkpAqq_ACLfpRPnzU2u5d-84c,708
|
3
3
|
minecraft_datapack_language/ast_nodes.py,sha256=L5izavSeXDr766vsfRvJrcnflXNJyXcy0WSfyJPq2ZA,4484
|
4
4
|
minecraft_datapack_language/cli.py,sha256=R4QZYtox-Da9B8pr_kCg_9qc9aI-ORTah7kMkhsI5tw,10373
|
5
5
|
minecraft_datapack_language/dir_map.py,sha256=HmxFkuvWGkzHF8o_GFb4BpuMCRc6QMw8UbmcAI8JVdY,1788
|
6
|
-
minecraft_datapack_language/mdl_compiler.py,sha256=
|
6
|
+
minecraft_datapack_language/mdl_compiler.py,sha256=L2-NCQBc-6gshM-VNqyW4HxnltS8XNb7IU_37AOiDAI,50680
|
7
7
|
minecraft_datapack_language/mdl_errors.py,sha256=r0Gu3KhoX1YLPAVW_iO7Q_fPgaf_Dv9tOGSOdKNSzmw,16114
|
8
8
|
minecraft_datapack_language/mdl_lexer.py,sha256=rfsW2QNcZxa9HAHpU9HFReshQSmjOrrK6xY_r43mKFk,23485
|
9
9
|
minecraft_datapack_language/mdl_linter.py,sha256=z85xoAglENurCh30bR7kEHZ_JeMxcYaLDcGNRAl-RAI,17253
|
10
10
|
minecraft_datapack_language/mdl_parser.py,sha256=Krk7Y_E9OKNCcsDOCT7ATvQLbJII951AU2qzEY00GLE,26068
|
11
11
|
minecraft_datapack_language/python_api.py,sha256=Iao1jbdeW6ekeA80BZG6gNqHVjxQJEheB3DbpVsuTZQ,12304
|
12
12
|
minecraft_datapack_language/utils.py,sha256=Aq0HAGlXqj9BUTEjaEilpvzEW0EtZYYMMwOqG9db6dE,684
|
13
|
-
minecraft_datapack_language-16.0.
|
14
|
-
minecraft_datapack_language-16.0.
|
15
|
-
minecraft_datapack_language-16.0.
|
16
|
-
minecraft_datapack_language-16.0.
|
17
|
-
minecraft_datapack_language-16.0.
|
18
|
-
minecraft_datapack_language-16.0.
|
13
|
+
minecraft_datapack_language-16.0.11.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
14
|
+
minecraft_datapack_language-16.0.11.dist-info/METADATA,sha256=gEFJawJ7Rmjc4QVM0PrDu0FehvtajZbQCLFwDxpfcXI,8344
|
15
|
+
minecraft_datapack_language-16.0.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
16
|
+
minecraft_datapack_language-16.0.11.dist-info/entry_points.txt,sha256=c6vjBeCiyQflvPHBRyBk2nJCSfYt3Oc7Sc9V87ySi_U,108
|
17
|
+
minecraft_datapack_language-16.0.11.dist-info/top_level.txt,sha256=ADtFI476tbKLLxEAA-aJQAfg53MA3k_DOb0KTFiggfw,28
|
18
|
+
minecraft_datapack_language-16.0.11.dist-info/RECORD,,
|
{minecraft_datapack_language-16.0.9.dist-info → minecraft_datapack_language-16.0.11.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|