minecraft-datapack-language 16.0.13__py3-none-any.whl → 16.0.15__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.13'
32
- __version_tuple__ = version_tuple = (16, 0, 13)
31
+ __version__ = version = '16.0.15'
32
+ __version_tuple__ = version_tuple = (16, 0, 15)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -819,12 +819,58 @@ class MDLCompiler:
819
819
  else:
820
820
  return str(expression)
821
821
 
822
+ def _normalize_operator(self, op_in: Any) -> Optional[str]:
823
+ """Normalize operator tokens/strings to Minecraft execute/scoreboard symbols.
824
+ Returns one of: '>', '>=', '<', '<=', '==', '!=' or None if unknown.
825
+ """
826
+ # Direct symbol passthrough
827
+ if op_in in ('>', '>=', '<', '<=', '==', '!='):
828
+ return op_in
829
+ # TokenType instances
830
+ try:
831
+ if op_in == TokenType.GREATER:
832
+ return '>'
833
+ if op_in == TokenType.GREATER_EQUAL:
834
+ return '>='
835
+ if op_in == TokenType.LESS:
836
+ return '<'
837
+ if op_in == TokenType.LESS_EQUAL:
838
+ return '<='
839
+ if op_in == TokenType.EQUAL:
840
+ return '=='
841
+ if op_in == TokenType.NOT_EQUAL:
842
+ return '!='
843
+ except Exception:
844
+ pass
845
+ # String names from bindings or parser
846
+ if isinstance(op_in, str):
847
+ upper = op_in.upper()
848
+ if upper == 'GREATER':
849
+ return '>'
850
+ if upper == 'GREATER_EQUAL':
851
+ return '>='
852
+ if upper == 'LESS':
853
+ return '<'
854
+ if upper == 'LESS_EQUAL':
855
+ return '<='
856
+ if upper == 'EQUAL' or upper == 'EQ':
857
+ return '=='
858
+ if upper == 'NOT_EQUAL' or upper == 'NE':
859
+ return '!='
860
+ return None
861
+
822
862
  def _expression_to_condition(self, expression: Any) -> str:
823
863
  """Legacy: Convert expression to a naive condition string (internal use)."""
824
864
  if isinstance(expression, BinaryExpression):
825
865
  left = self._expression_to_value(expression.left)
826
866
  right = self._expression_to_value(expression.right)
827
- return f"{left} {expression.operator} {right}"
867
+ op_sym = self._normalize_operator(expression.operator)
868
+ # Minecraft scoreboard uses '=' instead of '=='
869
+ if op_sym == '==':
870
+ op_text = '='
871
+ else:
872
+ op_text = op_sym if op_sym is not None else str(expression.operator)
873
+ return f"{left} {op_text} {right}"
828
874
  else:
829
875
  return self._expression_to_value(expression)
830
876
 
@@ -835,12 +881,18 @@ class MDLCompiler:
835
881
  # Default: generic expression string, no inversion
836
882
  invert_then = False
837
883
 
884
+ # Helpers local to this method to keep concerns contained
885
+ def unwrap(e: Any) -> Any:
886
+ while isinstance(e, ParenthesizedExpression):
887
+ e = e.expression
888
+ return e
889
+
838
890
  if isinstance(expression, BinaryExpression):
839
- left = expression.left
840
- right = expression.right
841
- op = expression.operator
891
+ left = unwrap(expression.left)
892
+ right = unwrap(expression.right)
893
+ op_sym = self._normalize_operator(expression.operator)
842
894
  # Variable vs literal
843
- if isinstance(left, VariableSubstitution) and isinstance(right, LiteralExpression) and isinstance(right.value, (int, float)):
895
+ if op_sym and isinstance(left, VariableSubstitution) and isinstance(right, LiteralExpression) and isinstance(right.value, (int, float)):
844
896
  objective = self.variables.get(left.name, left.name)
845
897
  scope = left.scope.strip("<>")
846
898
  # Normalize number
@@ -850,41 +902,47 @@ class MDLCompiler:
850
902
  v = None
851
903
  if v is not None:
852
904
  n = int(v) if float(v).is_integer() else v
853
- if op == TokenType.GREATER:
905
+ if op_sym == ">":
854
906
  rng = f"{int(n)+1}.." if isinstance(n, int) else f"{v+1}.."
855
907
  return (f"score {scope} {objective} matches {rng}", False)
856
- if op == TokenType.GREATER_EQUAL:
908
+ if op_sym == ">=":
857
909
  rng = f"{int(n)}.."
858
910
  return (f"score {scope} {objective} matches {rng}", False)
859
- if op == TokenType.LESS:
911
+ if op_sym == "<":
860
912
  rng = f"..{int(n)-1}"
861
913
  return (f"score {scope} {objective} matches {rng}", False)
862
- if op == TokenType.LESS_EQUAL:
914
+ if op_sym == "<=":
863
915
  rng = f"..{int(n)}"
864
916
  return (f"score {scope} {objective} matches {rng}", False)
865
- if op == TokenType.EQUAL:
917
+ if op_sym == "==":
866
918
  rng = f"{int(n)}"
867
919
  return (f"score {scope} {objective} matches {rng}", False)
868
- if op == TokenType.NOT_EQUAL:
920
+ if op_sym == "!=":
869
921
  rng = f"{int(n)}"
870
922
  return (f"score {scope} {objective} matches {rng}", True)
923
+ # Literal vs variable (swap sides)
924
+ if op_sym and isinstance(left, LiteralExpression) and isinstance(left.value, (int, float)) and isinstance(right, VariableSubstitution):
925
+ # Swap by inverting the operator appropriately, then reuse logic
926
+ invert_map = {
927
+ ">": "<",
928
+ ">=": "<=",
929
+ "<": ">",
930
+ "<=": ">=",
931
+ "==": "==",
932
+ "!=": "!="
933
+ }
934
+ swapped = BinaryExpression(left=right, operator=invert_map.get(op_sym, op_sym), right=left)
935
+ return self._build_condition(swapped)
871
936
  # Variable vs variable
872
- if isinstance(left, VariableSubstitution) and isinstance(right, VariableSubstitution):
937
+ if op_sym and isinstance(left, VariableSubstitution) and isinstance(right, VariableSubstitution):
873
938
  lobj = self.variables.get(left.name, left.name)
874
939
  lscope = left.scope.strip("<>")
875
940
  robj = self.variables.get(right.name, right.name)
876
941
  rscope = right.scope.strip("<>")
877
- if op in (TokenType.GREATER, TokenType.GREATER_EQUAL, TokenType.LESS, TokenType.LESS_EQUAL, TokenType.EQUAL):
878
- comp_map = {
879
- TokenType.GREATER: ">",
880
- TokenType.GREATER_EQUAL: ">=",
881
- TokenType.LESS: "<",
882
- TokenType.LESS_EQUAL: "<=",
883
- TokenType.EQUAL: "="
884
- }
885
- comp = comp_map[op]
942
+ if op_sym in (">", ">=", "<", "<=", "=="):
943
+ comp = op_sym if op_sym != "==" else "="
886
944
  return (f"score {lscope} {lobj} {comp} {rscope} {robj}", False)
887
- if op == TokenType.NOT_EQUAL:
945
+ if op_sym == "!=":
888
946
  # Use equals with inversion
889
947
  return (f"score {lscope} {lobj} = {rscope} {robj}", True)
890
948
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: minecraft-datapack-language
3
- Version: 16.0.13
3
+ Version: 16.0.15
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=zPid2C66t3qy7IALtBamczEZhSi2TvHUc9FEEgCFwOc,708
2
+ minecraft_datapack_language/_version.py,sha256=K7VsHAmJlEhd8XJV9-Y3WI0coNAa98VyEMvOhlue3zI,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=-ZwjHgJ8jJej8iiMovkbE8ry0aiLmXHc5rJ5Agj3Ep4,52293
6
+ minecraft_datapack_language/mdl_compiler.py,sha256=OuCk3SSPj4Cac5dYihWL6Nd-y5H4T5LGlCh55bGUkts,54538
7
7
  minecraft_datapack_language/mdl_errors.py,sha256=r0Gu3KhoX1YLPAVW_iO7Q_fPgaf_Dv9tOGSOdKNSzmw,16114
8
8
  minecraft_datapack_language/mdl_lexer.py,sha256=bDzAj39-kfnX0uVlYQg1oQ7YDb-JO9UZx8jbODQqg6E,23902
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.13.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
14
- minecraft_datapack_language-16.0.13.dist-info/METADATA,sha256=0JbN_CstF60oTN4ypgfcq1JbLE0Q2nO3dcL_NWfioS8,8344
15
- minecraft_datapack_language-16.0.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
16
- minecraft_datapack_language-16.0.13.dist-info/entry_points.txt,sha256=c6vjBeCiyQflvPHBRyBk2nJCSfYt3Oc7Sc9V87ySi_U,108
17
- minecraft_datapack_language-16.0.13.dist-info/top_level.txt,sha256=ADtFI476tbKLLxEAA-aJQAfg53MA3k_DOb0KTFiggfw,28
18
- minecraft_datapack_language-16.0.13.dist-info/RECORD,,
13
+ minecraft_datapack_language-16.0.15.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
14
+ minecraft_datapack_language-16.0.15.dist-info/METADATA,sha256=IFwvyBTp7KpUGsHgWff_iK5Oo6TBR1pVLxh-xW0HUPc,8344
15
+ minecraft_datapack_language-16.0.15.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
16
+ minecraft_datapack_language-16.0.15.dist-info/entry_points.txt,sha256=c6vjBeCiyQflvPHBRyBk2nJCSfYt3Oc7Sc9V87ySi_U,108
17
+ minecraft_datapack_language-16.0.15.dist-info/top_level.txt,sha256=ADtFI476tbKLLxEAA-aJQAfg53MA3k_DOb0KTFiggfw,28
18
+ minecraft_datapack_language-16.0.15.dist-info/RECORD,,