cardillan / mindcode

A high level language for Mindustry Logic (mlog) and Mindustry Schematics.
http://mindcode.herokuapp.com/
MIT License
87 stars 13 forks source link

Variable in ubind optimized at the basic optimization level #126

Closed limonovthesecond2 closed 9 months ago

limonovthesecond2 commented 9 months ago

Code:

unit = @poly
ubind(unit)

Compiles to:

set unit @poly
ubind @poly

Expected:

set unit @poly
ubind unit
cardillan commented 9 months ago

This is an expected behavior. The protection granted to main variables (unit is a main variable in this code) at the basic optimization level only ensures the last value written to the variable is preserved even if it isn't subsequently used, as described in Data Flow Optimization/Optimization levels.

What is not explicitly mentioned in the documentation is that all other optimizations can be performed on main variables (it might be a good idea to expand the documentation). In this particular case, constant propagation was performed. set unit @poly is left in the code, because it is the last value assigned to unit, as mentioned above; on aggressive optimization level, this instruction would be removed.

To get the behavior you describe, you need to use a global variable - UNIT = @poly; ubind(UNIT) compiles to:

set UNIT @poly
ubind UNIT
end

In other words, if you want to be able to change a value assigned to a variable in compiled code, you need to use a global variable. This is also mentioned in the documentation, in the note in this chapter, but it would deserve a more prominent placement.

I plan to overhaul the Mindcode syntax, hopefully in the next few months, and one of the changes I want to do is to require special declaration for values that should support reassignment in the compiled code; something like this:

param unit = @poly
ubind(unit)

The param keyword will declare a constant, just like the const keyword, but will also create a variable holding the value of the constant and the compiler will ensure that changing the value assigned to the resulting variable in the compiled code is supported. This will (hopefully) make the feature more prominent and will allow more thorough optimization of global variables.

limonovthesecond2 commented 9 months ago

Thank you very much for your answer! I was aware of the use of a global variable from examples on the compiler site, however I also saw an example of ubind(unit_type) in flagging units which prompted me to open this issue