cardillan / mindcode

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

Feature request - Compiled remarks #140

Closed tom-leys closed 1 month ago

tom-leys commented 2 months ago

I saw a construct I liked in some hand-written logic. Remarks that are not meant to be executed (see the jumps over the print statements)

image

Potentially have a type of comment block (say ///) that creates these. Kind of a

/// blah
/// blah2

to

if false 
    print("blah")
    print("blah2") 
end

which does not get optimized away.

It would be super-neat if you could use printf type statements which get fully condensed. That would be useful for loop unrolling.

cardillan commented 2 months ago

That would indeed be a good feature to have! Especially coupled with an option to omit these remarks from the resulting code.

I'll need to figure out a way to have these remarks make it through the optimization. The optimizer is quite keen on removing unreachable code :D

cardillan commented 1 month ago

What about this:

This allows two uses for the remark function: either placing the remarks into the code as in the example above, or using it to activate/deactivate additional output (say, for debugging) using a compiler switch.

Example:

/// Configurable options:
IMPACT_STAR = 1
POWER_OUT = 236

/// Don't touch anything below
/// It's encrypted with dark magic

for i in 1 ... 10
    remark("Iteration $i:")
    ...
end

I'm open to suggestions of a better name for the remark function.

tom-leys commented 1 month ago

Sounds perfect. remark() is a great name for this. An alternative name is rem, which is what was used in MS-DOS batch files. But I prefer the longer name remark.

cardillan commented 1 month ago

There's a small problem I forgot to address: remarks are kept as a "virtual" instruction which is analogous to print, but gets processed at the end - after all optimizations are done, but before labels are resolved - and is either removed from the code, made passive by adding a jump around it, or just left in depending on compiler option remarks. This means that this instruction, unlike any other, doesn't have a fixed size. When the setting is none, the effective size is 0, in active mode the size is 1 and in passive mode the size is 2 or 1 (2 for the first instruction in a block, but 1 for subsequent ones, as there's just one jump over the entire block). Currently the size is always taken as 2. This makes the size calculations for optimizations for speed a bit off.

I won't handle the varying instruction size in passive mode (in some circumstances the calculation will be a bit off on the safe side), but I'll be able to correctly calculate the size in none and active modes. This will be in the next release.