Open aap opened 5 years ago
Hi ape, good to see you out here!
I the issue to gta3script-specs, since this seems like a language design issue rather than an implementation one, I assume it's ok on your side (EDIT: Ok, GitHub does not allow transfers between organizations, great).
Indeed. The lack of short-circuits made the scripters perform these deeply nested IF chains.
It's interesting to note GTA2script had a more complex if construct, which among other things, permitted short-circuit evaluation.
I think the correct way to handle this is by IFX
not ANDX
. Think at MISS2.EXE intermediate language level, there is no command named AND
. The IF (and IFNOT) construct is compiled to a IF n
(IFNOT n
) command followed by n
commands. The semantics of the IF
(IFNOT
) command is to evaluate the n
following commands and jumps to its corresponding ELSE
/ENDIF
command if their conjunction is (not) false.
Similarly, an IFX
statement would compile into IFX n
similarly to above, except it would evaluate at most n commands, and jump on the first false.
I think IFAND
could be a good name.
All that said, I'm against the addition of this feature. It seems to be a fundamental design choice, and they coded five games without bothering. It's rather easy to transform a very simple language into a complex language by adding syntactic changes every here and there. Given scripters annoyed by this pattern, I would rethink my position.
Hope you understand.
Sure, i understand not wanting to change the language spec. I have implemented a short circuit and in my decompiler now and this:
030C30 IF IS_PLAYER_PLAYING global_218
030C3B IF IS_PLAYER_IN_ANY_CAR global_218
030C46 IF global_8f1 == 0
030C52 IF DOES_VEHICLE_EXIST global_8f1
030C5D IF NOT IS_CAR_DEAD global_8f1
030C68 IF IS_CAR_MODEL global_8f1 162
030C76 PRINT_HELP 'TANK'
030C80 CALL F4284 5000
030C8D global_1e4 = 1
000000 ENDIF
000000 ENDIF
000000 ENDIF
000000 ENDIF
000000 ENDIF
000000 ENDIF
turns into
030C30 IF IS_PLAYER_PLAYING global_218
030C3C ALSO IS_PLAYER_IN_ANY_CAR global_218
030C47 ALSO global_8f1 == 0
030C53 ALSO DOES_VEHICLE_EXIST global_8f1
030C5E ALSO NOT IS_CAR_DEAD global_8f1
030C69 ALSO IS_CAR_MODEL global_8f1 162
030C76 PRINT_HELP 'TANK'
030C80 CALL F4284 5000
030C8D global_1e4 = 1
000000 ENDIF
It also improves else-analysis because now a deeply nested IF with a GOTO to after an ELSE part of an outer IF can now be analyzed as a proper ELSE, even if they used a manual GOTO in the source.
I have been working on a decompiler recently and noticed quite a lot of nested IFs that are essentially a short circuit AND. I think these were written as a chain of manual 'GOTO else' by the scripters. The language would benefit from a proper short circuit AND. If we can decide on a syntax and you implement it, the decompiler output could be a bit nicer. Two ideas for a syntax: either use a modified IF (say IFX) and only allows AND or use a modified AND (say ANDX) with the regular old IF. I don't know which one is better, but I think I'd prefer the second.
EDIT: an example: