In order to properly write code to be linked with IDL, it is necessary to understand a little about its internal operation. This section is intended to give just enough background to understand the material that follows.

Traditional interpreted languages work according to the following algorithm:

while (statements remaining) { 
  Get next statement.
  Perform lexical analysis and parse statement. 
  Execute statement.

This description is accurate at a conceptual level, and most early interpreters did their work in exactly this way. However, this scheme is inefficient because:

  • The meaning of each statement is determined by the relatively expensive operations of lexical analysis, parsing, and semantic analysis each and every time the statement is encountered.
  • Since each statement is considered in isolation, any statement that requires jumping to a different location in the program will require an expensive search for the target location. Usually, this search starts at the top of the file and moves forward until the target is found.

To avoid these problems, IDL uses a two-step process in which compilation and interpretation are separate.

The core of the system is the interpreter. The interpreter implements a simple, stack-based postfix language in which each instruction corresponds to a primitive of the IDL language. This internal form is a compact binary version of the IDL language routine. Routines written in the IDL language are compiled into this internal form by the IDL compiler when the .RUN executive command is issued, or when any other command requires a new routine to be executed. Once the IDL routine is compiled, the original version is ignored, and all references to the routine are to the compiled version.

Some of the advantages of this organization are:

  • The expensive compilation process is only performed once, no matter how often the resulting code is executed.
  • Statements are not considered in isolation, so the compiler keeps track of the information required to make jumping to a new location in the program fast.
  • The binary internal form is much faster to interpret than the original form.
  • The internal form is compact, leading to better use of main memory, and allowing more code to fit in any memory cache the computer might be using.

The Interpreter Stack

The primary data structure in the interpreter is the stack. The stack contains pointers to variables, which are implemented by IDL_VARIABLE structures (see The IDL_VARIABLE Structure). Pointers to IDL_VARIABLEs are referred to as IDL_VPTRs. Most interpreter instructions work by removing a predefined number of elements from the stack, performing their function, and then pushing the IDL_VPTR to the resulting IDL_VARIABLE back onto the stack.

The removed items are the arguments to the instruction, and the new element represents the result. In this sense, the IDL interpreter is no different from any other postfix language interpreter. When an IDL routine is compiled, the compiler checks the number of arguments passed to each system routine against the minimum and maximum number specified in an internal table of routines, and signals an error if an invalid number of arguments is specified.

At execution time, the interpreter instructions that execute system procedures and functions operate as follows:

  1. Look up the requested routine in the internal table of routines.
  2. Execute the routine that implements the desired routine.
  3. Remove the arguments from the stack.
  4. If the routine was a function, push its result onto the stack.

Thus, the compiler checks for the proper number of arguments, and the interpreter does all the work related to pushing and popping elements from the stack. The called function need only worry about executing its operation and providing a result.