# Formal definition of I6's 'or' operator (not '||')

Is there a formal definition of the `or` operator’s function anywhere, or is it just a matter of intuition and example and/or decoding the compiler source?

I’m pretty sure you quoted everything the manual has to say in the previous thread.

Yes, but that’s not much, unfortunately (only the brief description on pages 19 and 20), and DM4 is sometimes not the whole story. I haven’t read every scrap of every bit of documentation yet, so I hoped that someone might come forward with something from a source I don’t know. (Those seem to show up regularly!)

For the benefit of those looking for such a definition, it appears from experimentation that the `or` operator has two distinct modes, depending on the type of comparison operator used:

• one for “positive-sense” comparison operators like `==`, `in`, `>`, and `<`
• one for “negative-sense” comparison operators like `~=` and `notin`

It appears that the compiler treats a positive-sense comparison such as

``````x == 5 or 6
``````

as the logical equivalent of

``````(x == 5) || (x == 6)
``````

On the other hand, it also appears that the compiler treats a negative-sense comparison such as

``````x ~= 5 or 6
``````

as the logical equivalent of

``````(~~(x == 5)) && (~~(x == 6))
``````

So a possible formal definition might be:

Given a condition with structure

``````[expression E] [operator O] [value V1] or [value V2] (... or [value Vn])
``````

When used in conjunction with positive-sense comparison operators, the `or` operator creates the equivalent of a logical OR between a series of conditions, each of which has a lefthand side of expression E, operator O, and a righthand side defined as one of the elements Vn in the `or`-ed list.

``````(E O V1) || (E O V2) || ... || (E O Vn)
``````

When used in conjunction with negative-sense operators, the `or` operator creates the equivalent of a logical AND between a series of negated conditions, each of which has a lefthand side of expression E, the positive-sense complement of operator O (designated ~O), and a righthand side defined as one of the elements Vn in the `or`-ed list.

``````(~~(E ~O V1)) && (~~(E ~O V2)) && ... && (~~(E ~O Vn))
``````

As noted elsewhere (see Next steps for Inform 6 compiler - #84 by zarf), this may cause confusion when using the `>=` or `<=` operators in conjunction with `or`, which are treated by the compiler (up to 6.35) as being negative-sense operators akin to `~<` and `~>`, respectively.

Please do feel free to point out any errors in the above and/or cite additional relevant sources.

2 Likes

Yep, that’s the long and short of it.

2 Likes

This is precisely what is happening. The key is that the positive and negative senses are defined by the Z-machine. There are `je`, `jg`, `jl`, and `jin` opcodes, so they are positive-sense, but no `jne`, `jge`, `jle`, or `jnotin` operators, so they are negative-sense.

(The Glulx conditionals work very differently, but there is some hairy code in the Glulx backend that keeps track of that distinction all the way up to where it emits the instruction.)