The new implementation of the topographic part of MQL is proving its worth already. It is something that I can actually wrap my head around, in contrast to the old spaghetty-like, crufty code that had been beplagued with many a patchy patch.

I've changed the code in three important ways over the last couple of days:

  1. First, I've made it so that the current straw-in-the-making is always available on the stack. This is an important step towards fixing the bugs in the object reference code (see the SourceForge.Net bug-tracker for exactly what I mean).
  2. Second, I've added an OR construct between strings of blocks.
  3. Third, I've added some new constraints (which I think nobody was using anyway), just to make sure that the implementation does what it's supposed to do.

The OR construct simply looks like this:

[Clause [Phrase function=Objc] [Phrase function=Cmpl] OR [Phrase function=Cmpl] [Phrase function=Objc] ]

This finds all clauses inside of which there are two phrases, with one being an Object and the other being a Complement, in either order. The OR works between strings of blocks, not between individual blocks.

You can have as many OR-separated strings of blocks as you like.

As regards the new constraints, they can all be explained by the concept of "export barrier", and they all work on object reference declarations and object reference usages. An "export barrier" works "upwards" in the MQL query parse tree, and says that you can't use an object reference that has been declared "below" the export barrier. The three export barriers are: the Kleene Star, NOTEXIST, and the OR construct between object blocks.

For example, this is not allowed:

[Clause [Phrase as p1] OR [Phrase function=p1.function] ]

Here, the OR acts as an "export barrier" disallowing the object reference usage of p1.

Neither can you say:

[Clause [Phrase [Word AS w1] ]* // OOPS! Kleene Star acts as export barrier. [Word lexeme=w1.lexeme] ]

Nor can you say:

[Clause
NOTEXIST [Phrase
[Word AS w1]
] // OOPS! NOTEXIST acts as an export barrier!
]
[Clause
[Word lexeme=w1.lexeme]
]

But notice that the export barrier does not work "downwards": This IS allowed:

[Clause [Phrase as p1 [Phrase function = p1.function] OR // This is NOT an export-barrier for p1! [Phrase function <> p1.function AND phrase_type=NP] ] ]

This is allowed because p1 has been declared above the OR construct. If it were declared below the OR construct, the OR construct would have been an export barrier. The other way around, it isn't.

The reason I've implemented the export barriers for OR is so as to ensure that when an object reference is used, it is always declared so as to be given a value. If we had allowed it to be declared below an OR and used above the OR, then it might not always be given a meaningful value (or any value at all).

The reason for the Kleene Star being an export barrier is that I wish to reduce the complexity of the upcoming fix of the object reference system. I might relax that restriction once I know exactly how to do it, but for now, I'd rather have the restriction in place. The problem is that inside a Kleene Star, we might get multiple values to put in the symbol table.

The reason for NOTEXIST being an export barrier is that we really do wish for something not to exist, so for us to refer to something inside something which does not exist is a bit self-contradictory...

These changes will appear in the first public release after 1.2.0.pre171.