Statements and Functions

This section is speculative, and subject to change.

Here, for discussion sake, I'd like to describe the semantics of an OpenEdge application in terms of two broad categories.

The first is basic expressions and control flow. These are things that can be represented by any language, and includes looping and conditional branching. These will be represented explicitly in our IR.

The second is platform runtime support. Most statements and functions in 4GL/ABL are not simple expressions or control flow, but instead are direct references to the OpenEdge platform runtime support. Those statements and functions will likely be represented in our IR by calls to stubs, that is, calls to unimplemented subroutines.

To some extent, the two are intertwined. Consider the FOR EACH construct, which provides basic expression evaluation and looping, but also uses platform runtime support for buffer iteration over rows in tables. In cases such as these, our tree transform will have to tease the two apart, so that basic expressions and control flow are represented explicitly, and the use of platform runtime support is represented by calls to subroutines.

Statements in 4GL/ABL can be enormous. In OpenEdge itself, the statement is compiled to an AST, and that AST is interpreted by the runtime. If, in our IR, we treat most statements as calls to subroutines, it is tricky to come up with an appropriate representation for passing all of the data contained in the statement's AST branch to the subroutine. There needs to be a happy medium between implementing the semantics of the subroutine itself, which we don't want to do, and just passing the entire AST as an argument to the subroutine stub, which would defeat our goal of using the IR for data flow analysis. Update: I'm pretty sure I've come up with a good way to handle this. More to come soon!