wurstscript / WurstScript

Programming language and toolkit to create Warcraft III Maps
https://wurstlang.org
Apache License 2.0
226 stars 28 forks source link

[WIP] Lua typecasting #997

Closed Jampi0n closed 3 years ago

Jampi0n commented 3 years ago

This is an attempt to fix the lua bugs described in #994 and #995 (outside of the null string issue). I marked it WIP, because it contains parts that can be improved, needs some clean up and better unit tests. My understanding of the code base is limited, so I'm sure there is lots of stuff that should be done differently.

I will summarize the changes and how it works:

  1. The fromIndex and toIndex functions have been restored for lua. This is important, because these functions are added to the intermediate program and omitting them would result in a different intermediate program for lua and JASS. Compiletime functions are run on the intermediate program, so they need to be the same semantically and especially their types need to match.
  2. This means implicitly that generics are implemented as integers, because generic arguments will be converted to index and generic return values will be converted from index. Since lua has no fixed types, the function bodies of generic functions do not need to be changed. They will just only deal with integers now (and class types, but they are considered integers by the intermediate language).
  3. In order to ensure type safety in lua, the fromIndex and toIndex functions are wrapped in functions that ensure the correct types: typeFromIndex(...) -> typeFromIndex(intEnsure(...)) and typeToIndex(...) -> intEnsure(typeToIndex(...)) If for example HashMap.get now returns nil (the indexToObject function will return nil for non existing keys), the intEnsure function that is wrapped around HashMap.get will convert nil to 0. While these functions are added to the intermediate program in lua, the program is still semantically the same as without these function, because they are just identity functions for the intermediate language.
  4. During compiletime, class types are still represented as integers, so they will evaluate to 0 if they are null. Compiletime expression that evaluate to 0 and are not of numeric type will be replaced by null/nil.

This could serve as temporary fix until the new generics are implemented. If this is considered useful I can do some improvements, but I didn't want to spend more time on something that may not be of use.

Frotty commented 3 years ago

As we discussed in DMs, I will merge this even if the implementation might not be ideal, since it makes the lua backend finally usable and new generics/type classes still seem a bit far in the future. Thanks a lot for all the work you invested into this 👍