Ironically this only requires a very minor change in the calling code and an added member for the VMFunction to tell that code how many parameters to pass.
This change will allow to turn the vast majority of action functions into regular members, the only ones that still need to be an action function are the few that actually use the pointers.
This is not testable right now because finally the action function mess has come full circle. The current setup makes it impossible to call action functions from non-action functions because the needed info is local to the functions.
Long avoided, this needs to be refactored now so that the different semantics for action functions are no longer needed.
- VC++ generated horribly stupid code for x64 when incrementing pc at the
beginning of each instruction by storing hundreds of copies of it for
every opcode executed. Incrementing pc at the end avoids this madness.
- It is possible I messed something up with this change. Hopefully not.
- fixed: FxMemberIdentifier checked for ClassPointers instead of object pointers to resolve the left hand side of the expression.
- allow comparison of pointers.
This also means that for now Lua-style multi-assignments are disabled, those should be easy to enable by making some changes to the assignment_statement grammar so that it doesn't recognize single assignments, but for now this is low priority because it adds a significant amount of complexity to do this right with functions that have multiple return values.
The generated object code can definitely use an optimization pass but that's something left for later when more things are working. Right now it creates one opcode more than necessary for all member accesses (instead of using the offset in the store command it calculates an actual address of the variable in another address register) and can create one too many for non-constant expressions being assigned to local variables (a move between two registers because the emitted expression on the right hand side does not know that it can emit to the actual variable's register.)
- create proper variable data from the function prototype instead of assuming that there's just 3 pointers.
- added a printable name to VMScriptFunction for error output during gameplay in case something goes wrong.
All break and continue statements were collected in one list, and each loop statement taking hold of that entire list, including the breaks and continues from previous outer loops.
Changed it so that loop statements contain the jump addresses themselves and set a pointer in FCompileContext, so that the jump point can be set directly in the loop statement - and an error printed if there is none in the resolving stage, not the emitting one.
Consolidated the identical backpatching code of the three loop statement nodes into a subfunction.
- disable generation of the parser's trace file in debug builds.
This increases parsing time by a factor of 15 and is only needed when debugging a problem in the grammar.
- handle all binary operators which are already implemented in the code generator.
- implemented sizeof/alignof operators in code generator.
- rewrote RequestAddress so that its return value is not the writability of an address but the mere existence. Also changed it to not output errors itself because those cannot be dealt with by the calling function.