minecraft-datapack-language 16.0.19__py3-none-any.whl → 16.0.20__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.19'
32
- __version_tuple__ = version_tuple = (16, 0, 19)
31
+ __version__ = version = '16.0.20'
32
+ __version_tuple__ = version_tuple = (16, 0, 20)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -1137,7 +1137,8 @@ class MDLCompiler:
1137
1137
  obj = parts[2]
1138
1138
  self._store_temp_command(f"scoreboard players operation @s {temp_var} = {scope} {obj}")
1139
1139
  else:
1140
- self._store_temp_command(f"scoreboard players set @s {temp_var} {left_value}")
1140
+ lit = self._normalize_integer_literal_string(str(left_value), ctx="addition left operand")
1141
+ self._store_temp_command(f"scoreboard players set @s {temp_var} {lit}")
1141
1142
  # Add right value
1142
1143
  if isinstance(expression.right, VariableSubstitution) or (isinstance(right_value, str) and right_value.startswith("score ")):
1143
1144
  parts = str(right_value).split()
@@ -1145,7 +1146,13 @@ class MDLCompiler:
1145
1146
  obj = parts[2]
1146
1147
  self._store_temp_command(f"scoreboard players operation @s {temp_var} += {scope} {obj}")
1147
1148
  else:
1148
- self._store_temp_command(f"scoreboard players add @s {temp_var} {right_value}")
1149
+ lit = self._normalize_integer_literal_string(str(right_value), ctx="addition right operand")
1150
+ if lit == "0":
1151
+ pass
1152
+ elif lit.startswith("-"):
1153
+ self._store_temp_command(f"scoreboard players remove @s {temp_var} {lit[1:]}")
1154
+ else:
1155
+ self._store_temp_command(f"scoreboard players add @s {temp_var} {lit}")
1149
1156
 
1150
1157
  elif expression.operator == "MINUS":
1151
1158
  if isinstance(expression.left, BinaryExpression):
@@ -1157,7 +1164,8 @@ class MDLCompiler:
1157
1164
  obj = parts[2]
1158
1165
  self._store_temp_command(f"scoreboard players operation @s {temp_var} = {scope} {obj}")
1159
1166
  else:
1160
- self._store_temp_command(f"scoreboard players set @s {temp_var} {left_value}")
1167
+ lit = self._normalize_integer_literal_string(str(left_value), ctx="subtraction left operand")
1168
+ self._store_temp_command(f"scoreboard players set @s {temp_var} {lit}")
1161
1169
  # Subtract right value
1162
1170
  if isinstance(expression.right, VariableSubstitution) or (isinstance(right_value, str) and right_value.startswith("score ")):
1163
1171
  parts = str(right_value).split()
@@ -1165,7 +1173,14 @@ class MDLCompiler:
1165
1173
  obj = parts[2]
1166
1174
  self._store_temp_command(f"scoreboard players operation @s {temp_var} -= {scope} {obj}")
1167
1175
  else:
1168
- self._store_temp_command(f"scoreboard players remove @s {temp_var} {right_value}")
1176
+ lit = self._normalize_integer_literal_string(str(right_value), ctx="subtraction right operand")
1177
+ if lit == "0":
1178
+ pass
1179
+ elif lit.startswith("-"):
1180
+ # x - (-k) == x + k
1181
+ self._store_temp_command(f"scoreboard players add @s {temp_var} {lit[1:]}")
1182
+ else:
1183
+ self._store_temp_command(f"scoreboard players remove @s {temp_var} {lit}")
1169
1184
 
1170
1185
  elif expression.operator == "MULTIPLY":
1171
1186
  if isinstance(expression.left, BinaryExpression):
@@ -1185,8 +1200,13 @@ class MDLCompiler:
1185
1200
  # For literal values, keep explicit multiply command for compatibility
1186
1201
  if isinstance(expression.right, LiteralExpression):
1187
1202
  # Normalize number formatting (e.g., 2.0 -> 2)
1188
- literal_str = self._expression_to_value(expression.right)
1189
- self._store_temp_command(f"scoreboard players multiply @s {temp_var} {literal_str}")
1203
+ literal_str = self._normalize_integer_literal_string(self._expression_to_value(expression.right), ctx="multiply literal")
1204
+ if literal_str == "0":
1205
+ self._store_temp_command(f"scoreboard players set @s {temp_var} 0")
1206
+ elif literal_str == "1":
1207
+ pass
1208
+ else:
1209
+ self._store_temp_command(f"scoreboard players multiply @s {temp_var} {literal_str}")
1190
1210
  else:
1191
1211
  # If right_value is a score reference string, strip the leading 'score '
1192
1212
  if isinstance(right_value, str) and right_value.startswith("score "):
@@ -1198,7 +1218,17 @@ class MDLCompiler:
1198
1218
  else:
1199
1219
  self._store_temp_command(f"scoreboard players operation @s {temp_var} *= {right_value}")
1200
1220
  else:
1201
- self._store_temp_command(f"scoreboard players operation @s {temp_var} *= {right_value}")
1221
+ # If RHS is a numeric literal string (incl. negatives), use multiply
1222
+ if self._is_numeric_literal_string(right_value):
1223
+ lit = self._normalize_integer_literal_string(str(right_value), ctx="multiply literal string")
1224
+ if lit == "0":
1225
+ self._store_temp_command(f"scoreboard players set @s {temp_var} 0")
1226
+ elif lit == "1":
1227
+ pass
1228
+ else:
1229
+ self._store_temp_command(f"scoreboard players multiply @s {temp_var} {lit}")
1230
+ else:
1231
+ self._store_temp_command(f"scoreboard players operation @s {temp_var} *= {right_value}")
1202
1232
 
1203
1233
  elif expression.operator == "DIVIDE":
1204
1234
  if isinstance(expression.left, BinaryExpression):
@@ -1218,8 +1248,17 @@ class MDLCompiler:
1218
1248
  # For literal values, keep explicit divide command for compatibility
1219
1249
  if isinstance(expression.right, LiteralExpression):
1220
1250
  # Normalize number formatting (e.g., 2.0 -> 2)
1221
- literal_str = self._expression_to_value(expression.right)
1222
- self._store_temp_command(f"scoreboard players divide @s {temp_var} {literal_str}")
1251
+ lit = self._normalize_integer_literal_string(self._expression_to_value(expression.right), ctx="divide literal")
1252
+ if lit == "0":
1253
+ raise MDLCompilerError("Division by zero literal is not allowed", "Use a non-zero integer literal")
1254
+ if lit == "1":
1255
+ pass
1256
+ elif lit.startswith("-"):
1257
+ abs_lit = lit[1:]
1258
+ self._store_temp_command(f"scoreboard players divide @s {temp_var} {abs_lit}")
1259
+ self._store_temp_command(f"scoreboard players multiply @s {temp_var} -1")
1260
+ else:
1261
+ self._store_temp_command(f"scoreboard players divide @s {temp_var} {lit}")
1223
1262
  else:
1224
1263
  # If right_value is a score reference string, strip the leading 'score '
1225
1264
  if isinstance(right_value, str) and right_value.startswith("score "):
@@ -1231,7 +1270,21 @@ class MDLCompiler:
1231
1270
  else:
1232
1271
  self._store_temp_command(f"scoreboard players operation @s {temp_var} /= {right_value}")
1233
1272
  else:
1234
- self._store_temp_command(f"scoreboard players operation @s {temp_var} /= {right_value}")
1273
+ # If RHS is a numeric literal string (incl. negatives), use divide
1274
+ if self._is_numeric_literal_string(right_value):
1275
+ lit = self._normalize_integer_literal_string(str(right_value), ctx="divide literal string")
1276
+ if lit == "0":
1277
+ raise MDLCompilerError("Division by zero literal is not allowed", "Use a non-zero integer literal")
1278
+ if lit == "1":
1279
+ pass
1280
+ elif lit.startswith("-"):
1281
+ abs_lit = lit[1:]
1282
+ self._store_temp_command(f"scoreboard players divide @s {temp_var} {abs_lit}")
1283
+ self._store_temp_command(f"scoreboard players multiply @s {temp_var} -1")
1284
+ else:
1285
+ self._store_temp_command(f"scoreboard players divide @s {temp_var} {lit}")
1286
+ else:
1287
+ self._store_temp_command(f"scoreboard players operation @s {temp_var} /= {right_value}")
1235
1288
  else:
1236
1289
  # For other operators, just set the value
1237
1290
  self._store_temp_command(f"scoreboard players set @s {temp_var} 0")
@@ -1243,6 +1296,36 @@ class MDLCompiler:
1243
1296
  else:
1244
1297
  # Fallback: do nothing, but keep behavior predictable
1245
1298
  pass
1299
+
1300
+ def _is_numeric_literal_string(self, s: Any) -> bool:
1301
+ """Return True if s is a string representing an integer literal (incl. negatives)."""
1302
+ if not isinstance(s, str):
1303
+ return False
1304
+ try:
1305
+ # Allow floats that are integer-valued like "2.0" by casting then checking is_integer
1306
+ if "." in s:
1307
+ f = float(s)
1308
+ return f.is_integer()
1309
+ int(s)
1310
+ return True
1311
+ except Exception:
1312
+ return False
1313
+
1314
+ def _normalize_integer_literal_string(self, s: str, ctx: str = "") -> str:
1315
+ """Normalize a numeric literal string to an integer string, or raise MDLCompilerError.
1316
+ Accepts negatives and floats that are mathematically integers (e.g., "2.0").
1317
+ """
1318
+ try:
1319
+ f = float(s)
1320
+ except Exception:
1321
+ raise MDLCompilerError(f"Expected integer literal, got '{s}'", f"Invalid numeric literal in {ctx}")
1322
+ if not float(f).is_integer():
1323
+ raise MDLCompilerError(f"Scoreboards are integer-only; got non-integer '{s}'", f"Use integers in {ctx}")
1324
+ n = int(f)
1325
+ # Normalize -0 to 0
1326
+ if n == 0:
1327
+ return "0"
1328
+ return str(n)
1246
1329
 
1247
1330
  def _generate_temp_variable_name(self) -> str:
1248
1331
  """Generate a unique temporary variable name."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: minecraft-datapack-language
3
- Version: 16.0.19
3
+ Version: 16.0.20
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=Y9AKuL_9dQTuwAdAm-tOXFpJ2Ltnsjm1_Nklu8wputY,708
2
+ minecraft_datapack_language/_version.py,sha256=ZcIcMufnj-tPySvFqfRV1Vfi4VfjctQQTwFmsEGNEQA,708
3
3
  minecraft_datapack_language/ast_nodes.py,sha256=L5izavSeXDr766vsfRvJrcnflXNJyXcy0WSfyJPq2ZA,4484
4
4
  minecraft_datapack_language/cli.py,sha256=shmQtNNXgw5XNlGquAR52wWtYeNyYusZTwwCZl56mMU,9522
5
5
  minecraft_datapack_language/dir_map.py,sha256=HmxFkuvWGkzHF8o_GFb4BpuMCRc6QMw8UbmcAI8JVdY,1788
6
- minecraft_datapack_language/mdl_compiler.py,sha256=AA3SZC7k8O1UbhlY6uEaxCVNsDK6jlPf5HDdi-OS0hk,63367
6
+ minecraft_datapack_language/mdl_compiler.py,sha256=lR33Oi7hNTeEarEw60c93ThL4_KWYaHUl42YMiXsW4g,68106
7
7
  minecraft_datapack_language/mdl_errors.py,sha256=r0Gu3KhoX1YLPAVW_iO7Q_fPgaf_Dv9tOGSOdKNSzmw,16114
8
8
  minecraft_datapack_language/mdl_lexer.py,sha256=YuRflOkoMOcjECPAZzoAkJciMks5amWMtGbcTIVKmAs,24166
9
9
  minecraft_datapack_language/mdl_linter.py,sha256=z85xoAglENurCh30bR7kEHZ_JeMxcYaLDcGNRAl-RAI,17253
10
10
  minecraft_datapack_language/mdl_parser.py,sha256=vIcPRudxDaezNy85Q5CBcumLhCglofCNITsrRmj9YWw,27302
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.19.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
14
- minecraft_datapack_language-16.0.19.dist-info/METADATA,sha256=s1mTXRppWEMJFAMWDt7k3poHbZC1gL1n0WFp6JdB4T8,8344
15
- minecraft_datapack_language-16.0.19.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
16
- minecraft_datapack_language-16.0.19.dist-info/entry_points.txt,sha256=c6vjBeCiyQflvPHBRyBk2nJCSfYt3Oc7Sc9V87ySi_U,108
17
- minecraft_datapack_language-16.0.19.dist-info/top_level.txt,sha256=ADtFI476tbKLLxEAA-aJQAfg53MA3k_DOb0KTFiggfw,28
18
- minecraft_datapack_language-16.0.19.dist-info/RECORD,,
13
+ minecraft_datapack_language-16.0.20.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
14
+ minecraft_datapack_language-16.0.20.dist-info/METADATA,sha256=J8Fwzv1piUYoNxfCG11EYzbV2amGwX9KC7ofCtSBNuE,8344
15
+ minecraft_datapack_language-16.0.20.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
16
+ minecraft_datapack_language-16.0.20.dist-info/entry_points.txt,sha256=c6vjBeCiyQflvPHBRyBk2nJCSfYt3Oc7Sc9V87ySi_U,108
17
+ minecraft_datapack_language-16.0.20.dist-info/top_level.txt,sha256=ADtFI476tbKLLxEAA-aJQAfg53MA3k_DOb0KTFiggfw,28
18
+ minecraft_datapack_language-16.0.20.dist-info/RECORD,,