Edit: the below is the "squeaky clean" option. I just realized what you meant with the numbers, to fool the compiler and decompiler. Simplifying the hacking process.
Yes, it's a good idea/option and allows to get this feature before hacking the compiler. I think i would support it as a intermediate step, because i would like to get my filthy paws on this feature as soon as possible.
However, a point: that number can't be one that is already used in the block. Otherwise, the TobEx runtime would replace the number by the variable since it has no way to differentiate them! This is something to think for the "squeaky clean" compiler implementation.
To implement this this way "only" requires the tobex runtime options below. The scripter would be acting as the compiler to checking that the variables don't clash.
"squeaky clean" option:
If you need more than one int variable, maybe use a growable datastructure.
Record("somevar", "Global", VAR1)<-- the compiler, replaces it by a number not in all of the block, tobex records the number in the datastructure
Record("somevar2", "Global", VAR1)<-- same constant. Compiler needs to use the same number used before, not a new one. Tobex runtime needs to NOT replace VAR1 by the dereference due to the previous record (since it's in a record, it's a store operation, not a read).
In fact, if it is forward replacing that variable, it can stop here, since the rest will only get replaced again. (premature optimization, root of all evil, etc)
Record("somevar", "Global", VAR2)<-- new constant
Record("somevar", "Global", VAR3)<-- etc
VARX would need to be recognized as "valid" by the compiler/decompiler. Using numbers allows this, as long as the numbers are not the same as other real numbers in the block, there should be no ill effects.
Constants are only associated to numbers by the compiler in "Record" statements (otherwise undeclared variables would typecheck and cause problems to the script in runtime).
HP(LastSeenBy(Myself),VAR1) <-- compiler references same number.
Tobex runtime (somehow) recognizes the constant, and dereferences it's internal array to inject the number stored by Record before the action/trigger is run.
Maybe when record happens it replaces all forward references in memory in the same block.
HP(LastSeenBy(Myself),VAR6) <-- not recorded variable. Compiler should (ideally) warn of this and exit.
...
END<-- end of the block, compiler clears it's VAR->number mapping, tobex clears the constant datastructure, stops replacing.
(this doesn't appear to need hacking the decompiler, but the numbers would be strange when you used constants before. This already happens with IDS files though)
Aside 1: it's desirable to use the "Record" operation both in the action sequence and the Trigger sequence, with the same name if possible.
That VARXXX variables can be used after the transition from the Trigger to the Actions, is desirable, but not really required (it's just a gotcha if it is not).
Aside 2: Am unsure if Record-as-a-trigger should return always true, or only if the variable was in the LOCALS/GLOBALS/AREA mappings. Also unsure about it's behavior in a OR().
Aside 3: i think it's a little bit silly that if i want to perform arithmetic under a local with this system, i can:
1) move a LOCAL variable to a GLOBAL one by storing it in a variable and using SetGlobal.
2) perform the operation
3) move a GLOBAL variable to a LOCAL one by storing it in a variable and using SetGlobal.
Silly isn't it? Maybe there could be a shortcut?
Regardless, multiply, abs, subtraction and maybe modulo would be nice to have - integer division might be dangerous (X/0) - but it's also nice...
This was my attempt at a "formal" specification. I'm sure Ascension64 already thought of all of this and more
Edited by i30817, 25 November 2011 - 02:50 AM.