minecraft-datapack-language 16.0.3__py3-none-any.whl → 16.0.5__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.
@@ -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.3'
32
- __version_tuple__ = version_tuple = (16, 0, 3)
31
+ __version__ = version = '16.0.5'
32
+ __version_tuple__ = version_tuple = (16, 0, 5)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -94,6 +94,13 @@ class WhileLoop(ASTNode):
94
94
  body: List[ASTNode]
95
95
 
96
96
 
97
+ @dataclass
98
+ class ScheduledWhileLoop(ASTNode):
99
+ """Scheduled-while loop that iterates via Minecraft's schedule command each tick."""
100
+ condition: Any # Expression
101
+ body: List[ASTNode]
102
+
103
+
97
104
  @dataclass
98
105
  class HookDeclaration(ASTNode):
99
106
  """Hook declaration (on_load, on_tick)."""
@@ -11,7 +11,7 @@ from typing import Dict, List, Any, Optional
11
11
  from .ast_nodes import (
12
12
  Program, PackDeclaration, NamespaceDeclaration, TagDeclaration,
13
13
  VariableDeclaration, VariableAssignment, VariableSubstitution, FunctionDeclaration,
14
- FunctionCall, IfStatement, WhileLoop, HookDeclaration, RawBlock, MacroLine,
14
+ FunctionCall, IfStatement, WhileLoop, ScheduledWhileLoop, HookDeclaration, RawBlock, MacroLine,
15
15
  SayCommand, BinaryExpression, LiteralExpression, ParenthesizedExpression
16
16
  )
17
17
  from .dir_map import get_dir_map, DirMap
@@ -345,6 +345,8 @@ class MDLCompiler:
345
345
  return self._if_statement_to_command(statement)
346
346
  elif isinstance(statement, WhileLoop):
347
347
  return self._while_loop_to_command(statement)
348
+ elif isinstance(statement, ScheduledWhileLoop):
349
+ return self._scheduled_while_to_command(statement)
348
350
  elif isinstance(statement, FunctionCall):
349
351
  return self._function_call_to_command(statement)
350
352
  else:
@@ -607,6 +609,62 @@ class MDLCompiler:
607
609
  self._store_generated_function(loop_function_name, loop_body_lines)
608
610
 
609
611
  return "\n".join(lines)
612
+
613
+ def _scheduled_while_to_command(self, while_loop: ScheduledWhileLoop) -> str:
614
+ """Convert scheduledwhile to tick-scheduled loop to avoid recursion limits.
615
+ Strategy:
616
+ - Generate a unique loop function that contains the body, then conditionally schedules itself 1t later.
617
+ - Entry statement schedules the first tick run.
618
+ - Breakout occurs naturally by not scheduling when condition is false.
619
+ """
620
+ loop_function_name = self._generate_while_function_name()
621
+
622
+ # Schedule first iteration for next tick
623
+ lines: List[str] = []
624
+ lines.append(f"schedule function {self.current_namespace}:{loop_function_name} 1t")
625
+
626
+ # Build the loop function body
627
+ loop_body_lines: List[str] = [f"# Function: {self.current_namespace}:{loop_function_name}"]
628
+
629
+ if not hasattr(self, '_temp_sink_stack'):
630
+ self._temp_sink_stack = []
631
+ self._temp_sink_stack.append(loop_body_lines)
632
+ for stmt in while_loop.body:
633
+ if isinstance(stmt, VariableAssignment):
634
+ cmd = self._variable_assignment_to_command(stmt)
635
+ loop_body_lines.append(cmd)
636
+ elif isinstance(stmt, VariableDeclaration):
637
+ cmd = self._variable_declaration_to_command(stmt)
638
+ loop_body_lines.append(cmd)
639
+ elif isinstance(stmt, SayCommand):
640
+ cmd = self._say_command_to_command(stmt)
641
+ loop_body_lines.append(cmd)
642
+ elif isinstance(stmt, RawBlock):
643
+ loop_body_lines.append(stmt.content)
644
+ elif isinstance(stmt, IfStatement):
645
+ cmd = self._if_statement_to_command(stmt)
646
+ loop_body_lines.append(cmd)
647
+ elif isinstance(stmt, WhileLoop):
648
+ cmd = self._while_loop_to_command(stmt)
649
+ loop_body_lines.append(cmd)
650
+ elif isinstance(stmt, ScheduledWhileLoop):
651
+ cmd = self._scheduled_while_to_command(stmt)
652
+ loop_body_lines.append(cmd)
653
+ elif isinstance(stmt, FunctionCall):
654
+ cmd = self._function_call_to_command(stmt)
655
+ loop_body_lines.append(cmd)
656
+ self._temp_sink_stack.pop()
657
+
658
+ cond_str, invert_then = self._build_condition(while_loop.condition)
659
+ if invert_then:
660
+ # Inverted means schedule unless condition (NOT desired). We want continue-when-true.
661
+ # cond_str represents equality in inverted case; continue when not(cond) → use unless.
662
+ loop_body_lines.append(f"execute unless {cond_str} run schedule function {self.current_namespace}:{loop_function_name} 1t")
663
+ else:
664
+ loop_body_lines.append(f"execute if {cond_str} run schedule function {self.current_namespace}:{loop_function_name} 1t")
665
+
666
+ self._store_generated_function(loop_function_name, loop_body_lines)
667
+ return "\n".join(lines)
610
668
 
611
669
  def _is_scoreboard_condition(self, expression: Any) -> bool:
612
670
  """Check if an expression is a scoreboard comparison."""
@@ -33,6 +33,7 @@ class TokenType:
33
33
  IF = "IF"
34
34
  ELSE = "ELSE"
35
35
  WHILE = "WHILE"
36
+ SCHEDULED_WHILE = "SCHEDULED_WHILE"
36
37
  ON_LOAD = "ON_LOAD"
37
38
  ON_TICK = "ON_TICK"
38
39
  EXEC = "EXEC"
@@ -599,6 +600,7 @@ class MDLLexer:
599
600
  'if': TokenType.IF,
600
601
  'else': TokenType.ELSE,
601
602
  'while': TokenType.WHILE,
603
+ 'scheduledwhile': TokenType.SCHEDULED_WHILE,
602
604
  'on_load': TokenType.ON_LOAD,
603
605
  'on_tick': TokenType.ON_TICK,
604
606
  'exec': TokenType.EXEC,
@@ -9,7 +9,7 @@ from .mdl_errors import MDLParserError
9
9
  from .ast_nodes import (
10
10
  ASTNode, Program, PackDeclaration, NamespaceDeclaration, TagDeclaration,
11
11
  VariableDeclaration, VariableAssignment, VariableSubstitution, FunctionDeclaration,
12
- FunctionCall, IfStatement, WhileLoop, HookDeclaration, RawBlock, MacroLine,
12
+ FunctionCall, IfStatement, WhileLoop, ScheduledWhileLoop, HookDeclaration, RawBlock, MacroLine,
13
13
  SayCommand, TellrawCommand, ExecuteCommand, ScoreboardCommand,
14
14
  BinaryExpression, UnaryExpression, ParenthesizedExpression, LiteralExpression,
15
15
  ScopeSelector
@@ -87,6 +87,8 @@ class MDLParser:
87
87
  statements.append(self._parse_if_statement())
88
88
  elif self._peek().type == TokenType.WHILE:
89
89
  statements.append(self._parse_while_loop())
90
+ elif self._peek().type == TokenType.SCHEDULED_WHILE:
91
+ statements.append(self._parse_scheduled_while_loop())
90
92
  elif self._peek().type == TokenType.DOLLAR and self._peek(1).type == TokenType.EXCLAMATION:
91
93
  statements.append(self._parse_raw_block())
92
94
  elif self._peek().type == TokenType.IDENTIFIER:
@@ -348,6 +350,18 @@ class MDLParser:
348
350
  self._expect(TokenType.RBRACE, "Expected '}' to end while body")
349
351
 
350
352
  return WhileLoop(condition=condition, body=body)
353
+
354
+ def _parse_scheduled_while_loop(self) -> ScheduledWhileLoop:
355
+ """Parse scheduledwhile loop: scheduledwhile condition { body }"""
356
+ self._expect(TokenType.SCHEDULED_WHILE, "Expected 'scheduledwhile' keyword")
357
+
358
+ condition = self._parse_expression()
359
+
360
+ self._expect(TokenType.LBRACE, "Expected '{' to start while body")
361
+ body = self._parse_block()
362
+ self._expect(TokenType.RBRACE, "Expected '}' to end while body")
363
+
364
+ return ScheduledWhileLoop(condition=condition, body=body)
351
365
 
352
366
  def _parse_hook_declaration(self) -> HookDeclaration:
353
367
  """Parse hook declaration: on_load/on_tick namespace:name<scope>;"""
@@ -524,6 +538,8 @@ class MDLParser:
524
538
  statements.append(self._parse_if_statement())
525
539
  elif self._peek().type == TokenType.WHILE:
526
540
  statements.append(self._parse_while_loop())
541
+ elif self._peek().type == TokenType.SCHEDULED_WHILE:
542
+ statements.append(self._parse_scheduled_while_loop())
527
543
  elif self._peek().type == TokenType.EXEC:
528
544
  statements.append(self._parse_function_call())
529
545
  elif self._peek().type == TokenType.MACRO_LINE:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: minecraft-datapack-language
3
- Version: 16.0.3
3
+ Version: 16.0.5
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
@@ -0,0 +1,18 @@
1
+ minecraft_datapack_language/__init__.py,sha256=0KVXBE4ScRaRUrf83aA2tVB-y8A_jplyaxVvtHH6Uw0,1199
2
+ minecraft_datapack_language/_version.py,sha256=5eUnbGX41cw4x_iyQa8Ni4HiMgC19n416l0EMUwLHfw,706
3
+ minecraft_datapack_language/ast_nodes.py,sha256=L5izavSeXDr766vsfRvJrcnflXNJyXcy0WSfyJPq2ZA,4484
4
+ minecraft_datapack_language/cli.py,sha256=R4QZYtox-Da9B8pr_kCg_9qc9aI-ORTah7kMkhsI5tw,10373
5
+ minecraft_datapack_language/dir_map.py,sha256=HmxFkuvWGkzHF8o_GFb4BpuMCRc6QMw8UbmcAI8JVdY,1788
6
+ minecraft_datapack_language/mdl_compiler.py,sha256=rYNaxvVRje2ot1RaUHibF4HItxca2MovntH0kjx65Vc,47808
7
+ minecraft_datapack_language/mdl_errors.py,sha256=r0Gu3KhoX1YLPAVW_iO7Q_fPgaf_Dv9tOGSOdKNSzmw,16114
8
+ minecraft_datapack_language/mdl_lexer.py,sha256=rfsW2QNcZxa9HAHpU9HFReshQSmjOrrK6xY_r43mKFk,23485
9
+ minecraft_datapack_language/mdl_linter.py,sha256=z85xoAglENurCh30bR7kEHZ_JeMxcYaLDcGNRAl-RAI,17253
10
+ minecraft_datapack_language/mdl_parser.py,sha256=Krk7Y_E9OKNCcsDOCT7ATvQLbJII951AU2qzEY00GLE,26068
11
+ minecraft_datapack_language/python_api.py,sha256=Iao1jbdeW6ekeA80BZG6gNqHVjxQJEheB3DbpVsuTZQ,12304
12
+ minecraft_datapack_language/utils.py,sha256=Aq0HAGlXqj9BUTEjaEilpvzEW0EtZYYMMwOqG9db6dE,684
13
+ minecraft_datapack_language-16.0.5.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
14
+ minecraft_datapack_language-16.0.5.dist-info/METADATA,sha256=K2CNC7E-v1wQA-cvRREQfc8ClamgHzNPxJyWY9K2Olc,8343
15
+ minecraft_datapack_language-16.0.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
16
+ minecraft_datapack_language-16.0.5.dist-info/entry_points.txt,sha256=c6vjBeCiyQflvPHBRyBk2nJCSfYt3Oc7Sc9V87ySi_U,108
17
+ minecraft_datapack_language-16.0.5.dist-info/top_level.txt,sha256=ADtFI476tbKLLxEAA-aJQAfg53MA3k_DOb0KTFiggfw,28
18
+ minecraft_datapack_language-16.0.5.dist-info/RECORD,,
@@ -1,18 +0,0 @@
1
- minecraft_datapack_language/__init__.py,sha256=0KVXBE4ScRaRUrf83aA2tVB-y8A_jplyaxVvtHH6Uw0,1199
2
- minecraft_datapack_language/_version.py,sha256=ZzL1luJQ5Xsyk9nl0-sOfrvRBFL0a9MDofeSfFIrSVI,706
3
- minecraft_datapack_language/ast_nodes.py,sha256=UzUxKLkjBisUd5Gu7sAiNXIIPIjNoRzELq4LfIFcnSY,4290
4
- minecraft_datapack_language/cli.py,sha256=R4QZYtox-Da9B8pr_kCg_9qc9aI-ORTah7kMkhsI5tw,10373
5
- minecraft_datapack_language/dir_map.py,sha256=HmxFkuvWGkzHF8o_GFb4BpuMCRc6QMw8UbmcAI8JVdY,1788
6
- minecraft_datapack_language/mdl_compiler.py,sha256=Fny9kxjN1X8ghAGjcASOEX7Uf1VwVhbSctLR3z4j9r4,44757
7
- minecraft_datapack_language/mdl_errors.py,sha256=r0Gu3KhoX1YLPAVW_iO7Q_fPgaf_Dv9tOGSOdKNSzmw,16114
8
- minecraft_datapack_language/mdl_lexer.py,sha256=dVwdgUmdQI7EJaFtoKZpq6rj5156YVjt44mMee-MDIs,23388
9
- minecraft_datapack_language/mdl_linter.py,sha256=z85xoAglENurCh30bR7kEHZ_JeMxcYaLDcGNRAl-RAI,17253
10
- minecraft_datapack_language/mdl_parser.py,sha256=axyjdrcgqeOpbmWolasiIZAjV_RpFaP5QiafLPXAhms,25223
11
- minecraft_datapack_language/python_api.py,sha256=Iao1jbdeW6ekeA80BZG6gNqHVjxQJEheB3DbpVsuTZQ,12304
12
- minecraft_datapack_language/utils.py,sha256=Aq0HAGlXqj9BUTEjaEilpvzEW0EtZYYMMwOqG9db6dE,684
13
- minecraft_datapack_language-16.0.3.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
14
- minecraft_datapack_language-16.0.3.dist-info/METADATA,sha256=MvNegD-ZES76aokgaBpxOC0aJi1Hl2PQsdahx2QU1wQ,8343
15
- minecraft_datapack_language-16.0.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
16
- minecraft_datapack_language-16.0.3.dist-info/entry_points.txt,sha256=c6vjBeCiyQflvPHBRyBk2nJCSfYt3Oc7Sc9V87ySi_U,108
17
- minecraft_datapack_language-16.0.3.dist-info/top_level.txt,sha256=ADtFI476tbKLLxEAA-aJQAfg53MA3k_DOb0KTFiggfw,28
18
- minecraft_datapack_language-16.0.3.dist-info/RECORD,,