This is a card in Dave's Virtual Box of Cards.

Interpreting if/else logic with a simple flat list of booleans

Created: 2023-12-12

While working on a hyperlink text game editor/player called Hiss the last couple days, I "discovered" a way to store and play if/else logic without a traditional tree structure (such as an AST (wikipedia.org)).

Like all good things, it became glaringly "obvious" in hindsight, but I’d never personally seen it before.

The Challenge: Represent nested if/else logic of any depth with just a flat list.

My interpreter’s instructions look something like this (pseudocode):

[
    { if foo == bar }
    { say "Foo is bar!" }
    { else }
    { say "Foo is NOT bar!" }
    { end if }
]

(Note that it’s just a flat list of instructions, not a tree. Also note that it’s not a series of compiled VM opcodes. Just if/else "instructions" with no other semantic information.)

The Solution: Just a flat list of boolean values and four simple rules are all you need to "play" such a script.

I call the list of boolean values the logic stack.

Check out these pseudocode examples. I am NOT indenting the nested statements to make it clear that these are all independent instructions. And yes, it does make it harder to read the examples.

This one has a false statement in the middle that gets inverted with an else:

instruction             logic stack
=================================================
if <true>               true
if <false>              true, false
else                    true, true
endif                   true
endif                   (empty also means "true")

This longer one starts off with a false statement. Note how there are true statements inside, but since the logic stack contains a false, none of the trues matter. We are in a true branch only when all of the values are true.

instruction             logic stack
=================================================
if <false>              false
if <true>               false, true
if <true>               false, true, true
else                    false, true, false
endif                   false, true
endif                   false
else                    true
if true                 true, true
else                    true, false
endif                   true
endif                   (empty also means "true")

Why?!

The full explanation is in the Hiss dev log (also linked above), but, in short:

  • Because I can and it’s a personal project so nobody can stop me HA HA HA!

  • The intention is to make a scripting language that has no errors.

With just one more rule and some guard statements (shown in action in the example below), you can make a scripting language in which it’s legal to put these statements in any order and my script player will not crash or produce any errors.

It may not do what you want (it can’t read your mind), but it will not complain.

This is perfectly valid HissScript (not pseudocode, though the exact syntax may have changed by the time you read this):

endif
Hello! No error here (endif doesn't explode on an empty list).
endif
else
This will never show up (else adds 'false' to an empty list).
endif
Hello! This will show up (the 'false' is popped by endif).

I want beginners of any kind (including children) to be able to write text-based, hyperlinked, choose-your-own adventure games with a minimum of frustration without resorting to a purely graphical interface.

(It’s also worth noting that Hiss shows the output of your script as you type and anything that isn’t recognized as a Hiss command appears on the screen as text.)

Conclusion

Again, it’s "obvious" in retrospect that a logic stack of booleans can represent your current position in a tree of if/else logic. Also obvious that all entries in the stack must be true for the current position to be in a "true" branch of the logic…​

But it was fun to "discover" such a simple and obvious thing after a couple failed attempts with more complicated logic. :-)