ribrdb / desynced-tools

Tools for working with behaviors and blueprints from Desynced.
MIT License
4 stars 3 forks source link

Expose compareItem, compareEntity and checkNumber #51

Closed swazrgb closed 5 months ago

swazrgb commented 6 months ago

These were previously marked as operators, but unfortunately it is not possible for us to always compile the correct comparison.

Given the following example:

export function f(p1: Value, p2: Value) {
  if (p1 == p2) {
    notify("Equals!");
  }
}

It is impossible to know whether the user meant compareItem, compareEntity or checkNumber (with ==).

One approach, which I've seen traces of in the code, might be to add virtual properties on Value that allows the user to indicate whether they want to interpret it as an item, entity or number.

But as a user, I would prefer to be able to simply write

if (compareItem(p1, p2)) {
  // ...
}

which matches what I'm used to from the game, and clearly shows my intent.

This also allows me to write:

switch (checkNumber(p1, p2)) {
  case ">=":
  case "=":
    notify("Hello World");
    break;
}

While only invoking checkNumber once. It would be nice to be able to write:

if (p1 >= p2 || p1 == p2) {
  notify("Hello World");
}

But this requires more work with the compiler, and is still ambiguous since the user could have meant:

(compareNumber(p1, p2) == ">=" || compareItem(p1, p2))

The implementation of the == operator can be kept, and perhaps still improved, but I'd like to also be able to use these instructions as-is.

ribrdb commented 5 months ago

My initial thought was we could use '==' and '===' to decide, but that only works for 2 comparison types and it seems like there's actually 3.