Skip to content

Releases: rx-modules/bolt-expressions

v0.17.0

10 Aug 18:48
Compare
Choose a tag to compare

Feature

Fix

  • Contrib.commands failed to parse data sources with empty path (3663d96)
  • Make nbt_type argument of Data.cast optional (beca595)
  • Type checking failing for expandable compound types (3b8c57e)
  • Improve source reuse optimization (6f1aef7)

v0.16.1

23 Jun 18:11
Compare
Choose a tag to compare

Fix

  • Remove scientific notation formatting for small scale numbers (e72080d)

v0.16.0

23 Feb 22:16
Compare
Choose a tag to compare

Feature

  • Overloaded len function for data sources (792657b)
obj["$length"] = len(storage.arr)
# execute store result score $length obj run data get storage name:path arr

storage.last_slot[Byte] = len(storage.Items) - 1
# execute store result score $i0 bolt.expr.temp run data get storage name:path Items
# execute store result storage name:path last_slot byte 1 run scoreboard players remove $i0 bolt.expr.temp 1
  • Add string data source indexing and slicing (4b5fa58)
# must specify the data type
message = storage.msg[str]

storage.a = message[5:]
# data modify storage name:path a set string storage name:path msg 5

storage.chars.append(message[0])
# data modify storage name:path chars append string storage name:path msg 0 1

message[0] = "c"
# TypeError: String data source does not support index/slice assignment.

storage.value[0] # list indexing
storage.value[0:5] # generic data sources dont accept slices

Fix

  • Add store result inlining rule (006750b)
  • Lazy sources should discard previous value when reused (2101335)

v0.15.0

16 Feb 23:54
Compare
Choose a tag to compare

Feature

  • Add source branching and comparison operators (f8d8ec4)
a, b, c = obj["$a", "$b", "$c"]
value = storage.value

if not a:
  a = 0

if a > b:
    say a greater than b!

c = (a <= b)*50 + (value >= 3)*3
  • Improved if..elif..else with __multibranch__ (1746226)
if not a:
  say a is 0 or does not exist
elif a < 0:
  say a is negative
elif a > 0:
  say a is positive
else:
  say impossible
  • Data comparison operator (749dd79)
from nbtlib import Byte

item = storage.item

# execute if data storage test:temp item{id: "minecraft:stone"} ...
if item.id == "minecraft:stone":
  say holding a stone!

# execute if data storage test:temp item{Count: 1b}
if item.Count == Byte(1):
  say just one item.

# matching a compound
if item == {id: "minecraft:diamond", Count: Byte(3)}:
  ...

# matching a score
if storage.time == obj["$time"]:
  say ...

# comparing two data sources
if storage.value != storage.prev_value:
  say value changed!
  storage.prev_value = storage.value
else:
  say value not changed.
  • Add and/or operator support for sources/lazy sources (f8013e9)

Fix

  • Strip run execute from commands (c8648f2)

v0.14.0

05 Feb 16:17
Compare
Choose a tag to compare

Feature

  • Operations now return lazy sources (6832b91)
a = 5 + obj["@s"] / 2
# $2384k242hd495_2 bolt.expr.temp (generated name)
# does not emit any command yet

print(a.is_lazy()) # True

obj["$value"] = obj["$b"] * a
# expanded on expression while it's lazy.
# might produce repeated commands if "a" switches
# to early evaluation later on.

a.evaluate()
# triggers early evaluation of "a".
# commands are inserted where "a" was originally evaluated.

print(a.is_lazy()) # False

obj["$value2"] = a # copies "a"
  • Support dicts, lists, arrays and union types as data source types (1097f5f)
class Item(TypedDict): # from the typing module
    id: str
    Count: Byte # from nbtlib
    tag: dict[str, Any]

hotbar = storage.hotbar[list[Item]]
first_item = hotbar[0]
first_item.Count = obj["$count"]
# execute store result storage ... hotbar[0].Count byte 1 run scoreboard players get ...
first_item.id = 5
# "Int" does not match "String"

hotbar.append({id: "stone"})
# "{id: String}" is missing required key "Count" of type "Byte"

hotbar[0].merge({x:5})
# "{x: Int}" has extra key "x" not present in "Item"

hotbar = [1, 2, 3]
# Elements of "list[Int]" and "list[Item]" are not compatible
# "Int" is not a compound type with fixed keys and is not compatible with "Item"

message = storage.msg[str | list[str]]

message = ["hello", "world"]
# fine
message = "hello world"
# fine
message = [{a: "b"}, {b: 5}]
# "list[{a: String} | {b: Int}]" is not compatible with "String | list[String]"
  • Numeric literal casting (9874ca9)
storage.pos[list[Double]] = [43, 0, 5]
# [43.0d, 0.0d, 5.0d]

storage.item[Item] = {id: "glass", Count: 5, tag: {}}
# {id: "glass", Count: 5b, tag: {}}

storage.flag[Byte] = 128
# raises an exception because 128 can't be represented as Byte.

storage.number[Byte | Long] = 4 # can't cast when write type is a union
# "Int" is not compatible with "Byte | Long"

storage.number[Byte | None] = 4 # only if it's optional
# 4b
  • Separate data source interfaces for each nbt type (dbe9a74)
storage.msg[str] - 1
# TypeError: unsupported operand type(s) for -: 'DataSource' and 'int'

storage.value[int].oops
# TypeError: Data source of type 'Int' does not have named keys

storage.c[dict[str, Any]][0]
# TypeError: Data source of type 'dict[String, typing.Any]' object is not indexable

storage.arr[list[int]]({a: 0})
# TypeError: Data source of type 'list[Int]' does not support compound matching

Fix

  • Only cast numeric nbt types (86d49b1)

v0.13.1

24 Jan 01:00
Compare
Choose a tag to compare

Fix

v0.13.0

23 Jan 23:59
Compare
Choose a tag to compare

Breaking

  • Removed TempScoreSource (add0eda)
  • Removed ConstantScoreSource (add0eda)
  • ExpressionNode objects now require a ctx parameter that can either be beet's Context or Expression. This includes ScoreSource and DataSource. (add0eda)
  • Removed the ExpressionNode.create factory method. Use the constructor as expected (add0eda)
  • Renamed Score class to Objective (awkward name for the object returned by Scoreboard) (72afafe)
  • The internal optimizer now works with a restricted IR (690eb40)
  • Replaced resolver with a serializer to produce command strings (8252db4)

Feature

  • Specify data source types using square brackets (score/data casting only) (b7b96fb)
from nbtlib import Double, Byte

storage.x[Double] = obj["@s"]
# execute store result storage ... double 1 run scoreboard players get @s obj

# applying a scale
storage.x[Double] = obj["@s"] / 100

count = storage.item.Count[Byte]

# right side is casted to byte
count = obj["$count"]
count = storage.value

value = storage.value[Byte]

# no casting happens when both sides have the same type
count = value
# data modify ... count set from storage ... value
  • Added DataSource merge operation as | (binary or) (add0eda)
storage.result = storage.a | storage.b | storage.c
# data modify storage ... result set from storage ... a
# data modify storage ... result merge from storage ... b
# data modify storage ... result merge from storage ... c

Fix

  • Reuse temporary score names (0eb9556)
  • Make api not dependent of Context object (72afafe)
  • Reduce number of temporaries used for score and data operations (8756e50)

v0.12.2

08 Jan 01:55
Compare
Choose a tag to compare

Fix

  • Fix inheritance of expression nodes and dataclasses.replace (bd6ac3d)

v0.12.1

31 Dec 02:46
Compare
Choose a tag to compare

Fix

  • Preserve key/default logic of builtin min/max functions (c127114)

v0.12.0

30 Dec 23:04
Compare
Choose a tag to compare

Feature

  • Support literal floating numbers on score multiplication/division (eea20d4)
a, b = obj["$a", "$b"]

a = b * 1.5
# a = (b * 3)/2

a = b / 3.14
# a = (b*50)/157

Fix

  • Make wrapped min/max functions behave more like the builtin ones (7e3b400)
storage = Data.storage(example:temp)
a, b, c = obj["$a", "$b", "$c"]

# variadic arguments
m = min(a, b, c)

# nested min/max calls
n = max(0, min(a, 100))

# iterable
values = (a, b, c, storage.value, *obj["$j", "$k"])
o = max(values)
  • Remove commands that multiply/divide by 1, add/subtract by 0 (6d8cf88)