Is there a goto command?

I know everyone is going to gasp at this, but I have a huge nested if statement and need to “escape” out of it to another part is that possible?

Not really, no. The Inform way to handle this is generally to split your huge nested if statement out into a bunch of separate rules and/or rulebooks.

I came from Applesoft BASIC straight to Inform, so at times I have similar thoughts about how I wish I could just do a raw GOTO. You often can get the same effect without too much hassle. I find it only gets fiddlesome when you’re running through a big rulebook and would like to jump around inside it.

First, you may or may not know that any rulebook or piece of code can stop itself running with lines like:

stop the action;
rule succeeds;
rule fails;
instead (do something else); (e.g ‘instead try taking inventory’)

These all have different effects depending on the circumstances, but what they have in common is - no more lines of code from the current block will be executed after one of these lines is hit.

An easy way to ‘escape’ from a pile of if-thens is with ‘instead’. Instead stops the current action running dead and runs the new one you specify.

The new action could be an attempt to try a command known to the game:

instead try jumping;

or it could be an internal (to the code world) action you create yourself.

For instance, you can define an action called hypeout like so: (which just makes the player act hyperactively stupid for a moment)

To hype out: try singing; try jumping; try taking player; try killing player.

This isn’t a wonderful example as it’s using only verb actions – you could put any code in the ‘hype out’ action that you like – but the upshot is, if you’re buried in your ifs and thens and you suddenly want to end that whole bit of code and just do the hype out routine instead, all you have to do is put in the line:

instead hype out;

Note that if your game is using the notions of actions succeeding and failing, exiting a routine with ‘instead’ sets a default result of failure (though in some cases, the action might have proceeded far enough that it must succeed - for instance, you can’t ‘fail’ after reaching the carry out stage of an action.) This doesn’t mean the code fails or anything ‘real’ and negative happens, but if you also use code which checks in retrospect whether an action succeeds or fails, using ‘instead’ may result in a ‘fail’ result being set.

Therefore if you want to be really safe about declaring the original piece of code to have succeede’, you can get exactly the same outcome as using ‘instead’, but with a successful outcome and codestop, like so:

(at the moment you want to exit the if-thens to hype out…)

hype out; rule succeeds;

This runs hype out, returns to the if-thens, then immediately stops with the result ‘success’ thanks to the rule succeeds.

So I haven’t dealt with the trauma of trying to jump around in big rulebooks, but hopefully what I’ve said here will start to show you the kind of goto-y mechanisms you can use.

  • Wade

I was able to refactor my code so I didn’t need it. I also didn’t know how to block my ifs with tabs. I can now, and have logic blocks and fall-throughs implemented correctly.

So fortunately this is redundant, but Ron Newcomb managed to implement GOTOs in his reimplementation of the parser in Inform 7 – where he was translating a big hunk of I6 code that itself had GOTOs I guess. It seems to work like this:

[ I would love to remove all GOTOs from the parser's source, never mind the performance implications. But some functions are just too convoluted for me to disentangle while keeping faith that they would work like the originals. ] A control label is a kind of value. Some control labels are the finished control label. To at this point (here - a control label): (- .{here}; -). To go back/-- up/down to where (here - a control label): (- jump {here}; -).

Which enables him to write things like “(At this point we ReParse)” and later “(go back up to where we ReParse)”. It seems to involve borrowing a “jump” from Inform 6.

But it’s surely much better that you refactored your code!

Also, the I6 jumps (and therefore Ron’s control labels) are local. They will let you jump around within a single I6 function, but won’t let you goto anywhere else in your code. I guess that is one reason the Inform parser is all one huge monster of a function.

I’m just impressed that the extension works at all given the complexity of the parser function.