Progress
Programming
Handbook


Compile-time Versus Run-time Code

Like many languages, the Progress 4GL includes two basic types of code:

However, as an interpretive language, Progress syntax combines compile-time and run-time components in many more ways than a compiled language like C. The flexibility of this syntax helps implement the rich variety of overridable defaults that characterizes the Progress 4GL.

Compile-time Code

Certain statements exist only to generate r-code when Progress compiles them. These are compile-time statements. That is, they create static data and user interface resources (widgets) that the run-time statements can reference and modify, but not destroy, during execution.

Run-time Code

Run-time statements use the static resources created by compile-time statements, but can also create, use, and destroy dynamic resources at run time. That is, run-time statements include statements that interact with static resources, dynamic resources, or both. Many run-time statements also include compile-time options. These are options that generate resources at compile time that are later used by the same statements at run time.

Which Code Is Which?

How can you identify the type of code you are using? There are some general features of 4GL syntax that provide the clues. The following procedure that computes factorials, p-ctrt0.p, illustrates many of these features.

Compile-time Syntax Elements

Most compile-time code consists of the following syntax elements:

Run-time Syntax Elements

Most run-time code consists of the following syntax elements:

How Compile-time Code and Run-time Code Interact

Because the Progress 4GL is a run-time interpreted language, it can combine compile-time and run-time code in a number of interesting and powerful ways.

For example, as noted earlier, some run-time statements can also include compile-time options. Thus, you can define a static frame in which to display data using a FORM statement, then add options to that static frame definition using Frame phrase options in subsequent run-time statements, such as FOR and DISPLAY.

In example procedure p-ctrt1.p, the data fields, frame type, and title for frame alpha are all defined at compile time and in three different statements:

p-ctrt1.p
DEFINE VARIABLE iter AS INTEGER. 
DEFINE FRAME alpha Customer.Name Customer.Phone. 
iter = 10. 
MESSAGE "iter =" iter VIEW-AS ALERT-BOX. 
FOR EACH Customer WITH FRAME alpha iter DOWN: 
    iter = 5. 
    DISPLAY name phone balance WITH TITLE "Customer Balances". 
END. 
MESSAGE "iter =" iter VIEW-AS ALERT-BOX. 

This procedure also illustrates a compile-time option (DOWN) qualified by a run-time expression (iter). The DOWN option specifies the type of frame for frame alpha at compile time. However, the number of iterations (rows of data displayed) in the down frame are determined at run time. This is possible, because certain design-oriented widget options (attributes) can actually be modified up to the point that the widget is realized (ready for viewing by the window system). Progress realizes frame alpha, a static widget, at the point of its first use, in the DISPLAY statement.

Another interesting thing about this procedure is that the iter value that qualifies the DOWN option is set after the DOWN option appears in the code:

FOR EACH Customer WITH FRAME alpha iter DOWN: 
    iter = 5. 
           . 
           . 
           . 

This is possible because Progress knows where the run-time iteration value for the DOWN option comes from at run time, and uses the last value set before the frame is realized in the DISPLAY statement.

NOTE: If the value for a run-time expression is unknown (?), Progress uses whatever default applies to the qualified compile-time option. So, in the example, if iter is not assigned a value before its use with the DOWN option, Progress uses the DOWN option default. In this case, the alpha frame displays as many rows as the frame can fit in its window.

A powerful example of the interaction between compile-time and run-time code is the use of the VALUE option in a number of run-time statements. In example procedure p-ctrt2.p, the VALUE option allows you to use a run-time expression (proc-name[proci]) to provide a compile-time object name:

p-ctrt2.p
DEFINE VARIABLE proci AS INTEGER. 
DEFINE VARIABLE whand AS WIDGET-HANDLE. 
DEFINE VARIABLE proc-name AS CHARACTER EXTENT 3 
    INIT ["p-join2.p", "p-foftab.p", "p-wow1.p"]. 
CREATE WINDOW whand. CURRENT-WINDOW = whand. 
MESSAGE "These are STATIC procedure executions." VIEW-AS ALERT-BOX. 
RUN p-join2.p. 
DELETE WIDGET whand. 
CREATE WINDOW whand. CURRENT-WINDOW = whand. 
RUN p-foftab.p. 
DELETE WIDGET whand. 
CREATE WINDOW whand. CURRENT-WINDOW = whand. 
RUN p-wow1.p. 
DELETE WIDGET whand. 
DO proci = 1 TO 3: 
    CREATE WINDOW whand. CURRENT-WINDOW = whand. 
    IF proci = 1 THEN 
        MESSAGE "These are DYNAMIC procedure executions." 
            VIEW-AS ALERT-BOX. 
    RUN VALUE(proc-name[proci]). 
    DELETE WIDGET whand. 
END. 

In the RUN statement, the object name is the name of a procedure to execute. Procedure p-ctrt2.p thus shows how the same three procedures can be executed using static compile-time object names or using object names evaluated by the VALUE option at run time.

NOTE: The three procedures executed by p-ctrt2.p, including p-join2.p, p-foftab.p, and p-wow1.p appear in later chapters of this manual and are also available on-line. For more information on accessing the on-line versions, see the preface of this manual.

Further examples of compile-time/run-time interactions appear throughout this manual, especially in the chapters on blocks, widgets, and interface design.


Copyright © 2004 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095