Lugaru's Epsilon
Programmer's
Editor

Context:
Epsilon User's Manual and Reference
   Primitives and EEL Subroutines
      . . .
      Operating System Primitives
         System Primitives
         Window System Primitives
         Timing
         Calling Windows DLLs
         Running a Process
      Control Primitives
         . . .
         Built-in and User Variables
         Buffer-specific Variables
         Bytecode Files
         Starting and Finishing
         EEL Debugging and Profiling
         . . .
      Input Primitives
         Keys
         The Mouse
         Window Events
         . . .
         Binding Primitives
      . . .

Previous   Up    Next
Buffer-specific Variables  Primitives and EEL Subroutines   Starting and Finishing


Epsilon User's Manual and Reference > Primitives and EEL Subroutines > Control Primitives >

Bytecode Files

load_commands(char *file)
load_from_path(char *file)    /* control.e */
int load_eel_from_path(char *file, int flags)

The load_commands( ) primitive loads a bytecode file of command, subroutine and variable definitions into Epsilon after the EEL compiler has produced it from the .e source file. The primitive changes the name provided so that it has the appropriate .b extension, then opens and reads the file. The primitive prints a message and aborts to top-level if it cannot find the file or the file name is invalid.

The subroutine load_from_path( ) searches for a bytecode file using the lookpath( ) primitive (see Manipulating File Names) and loads it using load_commands( ).

The load_eel_from_path( ) subroutine searches for an EEL source file with the specified name using lookpath( ). Then it compiles and loads the file. Bits in the flags parameter tell it when to report errors to the user. By default, it doesn't. The 1 bit means complain if the file contained errors, and 2 means also complain if no file by that name was found. The 4 bit has it tell lookpath( ) to search the current directory first. The subroutine returns zero if the file compiled and loaded without errors, one if it wasn't found, and two for other errors.

int eel_compile(char *file, int use_fsys, char *flags,
                char *errors, int just_check)

The eel_compile( ) primitive lets Epsilon run the EEL compiler without having to invoke a command processor. File specifies the name of a file or buffer. If use_fsys is nonzero, it names a file; if use_fsys is zero, a buffer. The flags parameter may contain any desired command line flags. Compiler messages will go to the buffer named errors. Unless errors occur or the just_check parameter is nonzero, Epsilon will automatically load the result of the compilation. No bytecode file on disk will be modified. Note that when the compiler includes header files, it will always read them from disk, even if they happen to be in an Epsilon buffer.

The primitive returns 0 on success, 1 if the compilation had fatal errors and did not complete, 2 if the compiler could not be located, or -1 if the user aborted.

when_loading()          /* EEL subroutine */

Any subroutines with the special name when_loading( ) execute as they are read, and then go away. There may be more than one of these functions defined in a single file. (Note: When the last function defined in an EEL file has been deleted or replaced, Epsilon discards all the constant strings defined in that file. So a file that contains only a when_loading( ) function will lose its constant strings as soon as it exits. If a pointer to such a string must be put in a global variable, use the strsave( ) primitive to make a copy of it. See Memory Allocation.)

The autoload_commands( ) primitive described below executes any when_loading( ) functions defined in the file, just as load_commands( ) would. Epsilon never arranges for a when_loading( ) function to be autoloaded, and will execute and discard such functions as soon as they're loaded. If you run autoload_commands( ) on a file with when_loading( ) functions, Epsilon will execute them twice: once when it initially sets up the autoloading, and once when it autoloads the file.

user char *byte_extension;
user char *state_extension;

The extensions used for Epsilon's bytecode files and state files may vary with the operating system. Currently, all operating system versions of Epsilon use ".b" for bytecode files, and ".sta" for state files. The byte_extension and state_extension primitives hold the appropriate extension names for the particular version of Epsilon.

autoload(char *name, char *file, int issubr)
autoload_commands(char *file)

Epsilon has a facility to define functions that are not loaded into memory until they are invoked. The autoload( ) primitive takes the name of a function to define, and the name of a bytecode file it can be found in. The file name string may be in a temporary area, because Epsilon makes a copy of it.

The primitive's final parameter should be nonzero to indicate that the autoloaded function will be a subroutine, or zero if the function will be a command. (Recall that commands are designed to be invoked directly by the user, and may not take parameters, while subroutines are generally invoked by commands or other subroutines, and may take parameters.) Epsilon enters the command or subroutine in its name table with a special code to indicate that the function is an autoloaded function: NT_AUTOLOAD for commands, or NT_AUTOSUBR for subroutines.

When Epsilon wants to call an autoloaded function, it first invokes the EEL subroutine load_from_path( ), passing it the file name from the autoload( ) call. The standard definition of this function is in the file control.e. It searches for the file along the EPSPATH, as described in How Epsilon Finds its Files, and then loads the file. The load_from_path( ) subroutine reports an error and aborts the calling function if it cannot find the file.

When load_from_path( ) returns, Epsilon checks to see if the function is now defined as a regular, non-autoloaded function. If it is, Epsilon calls it. However, it is not necessarily an error if the function is still undefined. Sometimes a function's work can be done entirely by the when_loading( ) subroutines that are run and immediately discarded as a bytecode file loads.

For example, all the work of the set-color command was once done by a when_loading( ) function in the EEL file color.e. (In recent versions, it no longer uses autoloading.) Loading the corresponding bytecode file automatically ran this when_loading( ) function, which displayed some windows and let the user choose colors. When the user exited from the command, Epsilon discarded the code for the when_loading( ) function that displayed windows and interpreted keys, and finishes loading the bytecode file. The set-color command was still defined as a command that autoloads the color.b bytecode file, so the next time the user ran this command, Epsilon loaded the file again.

If the autoloaded function was called with parameters, but remains undefined after Epsilon tries to autoload it, Epsilon aborts the calling function with an error message. Functions that use the above technique to load temporarily may not take parameters.

Like load_commands( ), the primitive autoload_commands( ) takes the name of a compiled EEL bytecode file as a parameter. It loads any variables or bindings contained in the file, just like load_commands( ). But instead of loading the functions in the file, this primitive generates an autoload request for each function in the file. Whenever any EEL function tries to call a function in the file, Epsilon will load the entire file.



Previous   Up    Next
Buffer-specific Variables  Primitives and EEL Subroutines   Starting and Finishing


Lugaru Copyright (C) 1984, 2012 Lugaru Software Ltd. All Rights Reserved.