The object-oriented Lava interpreter

The point-and-click operations of the Lava programmer (using LavaPE) operate directly on an internal tree-representation of the lava program (a kind of "abstract syntax tree"). Particularly the executable Lava constructs correspond to specific C++ classes. The C++ class of a Lava statement or expression construct comprises an "Execute" or "Evaluate" member function, respectively. These essentially make up the Lava interpreter (together with various functions of the Lava run time system, of course). Note that also the logical conjunctions (like ";" = "and", "or", "not", "if-then-else", "switch", ...) and the quantifiers ("declare", "foreach", "exists", "select") are represented in this way and have specific "Execute" functions (or "Evaluate" for the "select" expression).

So the Lava interpreter is not a separate piece of program of its own but is, in a sense, spread over the C++ classes representing the various executable Lava constructs.

The internal tree-representation of a Lava program is transformed into an ASN.1 encoding when the program is stored in a file. The interpreter reads this ASN.1 representation into main memory before execution, transforms it back into the original tree-representation and recursively checks the entire program for correctness and completeness. The check functions for the executable constructs are again member functions of the C++ classes corresponding to the respective constructs. They are essentially the same check functions that are also applied after each point-and-click editing operation of the Lava programmer at programming time, but would typically compute additional information that is needed at execution time, for instance "virtual function tables" (VFT's), relative positions of functions within these VFT's, relative positions of local variables on the run time stack and of member objects within the containing object.

Advantages of the object-oriented Lava interpreter as compared with a VM or "byte code" interpreter:

  1. The object-oriented interpreter of Lava operates on whole Lava constructs whose interpretation is performed by small and efficient C++ functions, whereas a byte code interpreter operates on the very low level of tiny, individual bytes. Hence an object-oriented interpreter can be expected to run significantly faster than a byte code interpreter.
  2. The development of an object-oriented interpreter is much easier than the development of a virtual machine.
  3. In particular, by reinterpreting a Lava program as a C++ program in this way we can utilize many features of the C++ run time system directly for Lava; for instance, C++ exception handling to handle non-catchable Lava exceptions ("fatal errors"), C++ threads (or rather the QThread class of Qt) to implement concurrent execution in Lava; even the C++ run time stack can be used directly as Lava run time stack with the help of very few inline assembler statements. We need not reconstruct all these features from scratch on a byte code / virtual machine level.
  4. It is much easier to adapt an object-oriented interpreter to new or modified language constructs.
  5. Compilation into byte code is not required.
  6. Delicate and error-prone byte code verification before execution is not required.