The Library Maker
Structural Requirements of Libraries
Hints for Programming Libraries
The Exported_Symbols Procedure
Error Messages of the Library Maker
You are probably already familiar with the Extension Library, which is supplied
together with Omikron Basic. It refers to a collection of procedures and functions,
which have been coded in such a way as to fit them into one single line; however,
the editor will show only the beginning of this line. The actual program code of
the library remains invisible and cannot be modified either. Thus, a library represents
a type of command extension for Omikron Basic and corresponds approximately to "Include
Files" in the programming language C.
Using the function 'Make Library' from the program menu, it is now possible for users and programmers to generate such libraries on their own.
What type of procedures and functions are contained in a library, is either known
because the programer has written the library him- or herself or by consulting the
manual accompanying the library.
Structural Requirements of Libraries
In order to be able to generate a library from a BASIC program, the source text has to meet certain requirements:
A library may only consist of procedures and functions. Only commentaries and braces for folding up program sections are permitted outside of the use of procedures and functions. In addition, the command COMPILER is permitted if followed by one of the two control words "LIB_MAKER OFF" or "LIB_MAKER ON".
The first procedure names the library. When calling this procedure, a copyright notice should be displayed. It is best to use the command FORM_ALERT for this. The procedure may be indented and commentary lines or folding braces may precede it.
The source text has to contain a procedure with the name Exported_Symbols. It is useful and practical to incorporate it immediately as the second procedure into the source text . All procedures, functions, variables, fields, and labels, which are to be callable from outside of the library, have to appear in it at least once.
While it might serve a purpose to be generous with the global availability when
dealing with procedures and functions, global variables and fields should be handled
with caution, the fewer, the better. This is the easiest way to prevent future "data
leaks", which can lead to grave and difficult to understand errors down the
It is best not to export any labels at all. If it seems really unavoidable to export a label, they need to be called with GOTO or GOSUB, respectively.
Important: If you would like to access functions and procedures that are located outside the library from within the library, they have to appear in the procedure Exported_Symbols as well.
Procedures and/or functions may not be nested. This means that another procedure definition may not be initiated from within an already existing procedure definition.
Structure commands have to appear in the correct order. Thus, first FOR and then NEXT, first REPEAT, then UNTIL, etc. This means that, for example, it is not permitted to begin a loop with FOR, then to jump with GOTO to a NEXT, which is located ahead of the FOR. But such extreme and confusing constructions should be avoided anyhow.
Structures have to have well-defined starting and ending points, that is, each FOR requires a NEXT, etc. These also have to be located within the same procedure or function, respectively. Of course, additional exits using EXIT are permitted.
IF constructions have to be clearly organized as well. This requires, for example, that in the case of multi-line IFs, an ENDIF has to be present and it has to be located behind the IF.
The corresponding applies to SELECT structures, but the Library Maker does not check these, i.e., a library with a flawed SELECT structure will be translated without an error message. However, once this library will be linked with programs, this will result in errors, which then will be difficult to locate, especially for users of the library who do not possess the source text.
Never use GOTO or GOSUB to jump from one procedure to another. If the other procedure is not called at any other time, it will not be incorporated into the compiled product. The jump command with GOTO or GOSUB, respectively, then leads into nothingness. And it is really not considered to be good programming style either.
Everything having to do with the program code, which is required for a procedure or a function, has to be included in said procedure or function itself. Thus, libraries have to contain, e.g., DATA lines within the procedure, which also contains the READ command. An alternative option is to place DATA lines into a pseudo procedure, which is seemingly called by the procedure with the READ command using an "IF 0 THEN Pseudo_Procedure". However, this alternative is not recommended!
No structure may start behind a one-line IF (e.g., a loop or an additional IF structure), which extends over several lines.
of the command MEMORY_BLOCK is not possible in libraries.
Hints for Programming Libraries
Avoid using GOTO and GOSUB. There is nothing that cannot be handled with other constructions as well. There are a few cases, however, where the use of GOTO or GOSUB might be sensible. Then labels - and not line numbers - have to be used as targets because the entire library is after all contained in one single line.
Use global variables as little as possible. Each global variable is a potential source for errors. The dangers are however lessened by the fact that all variables that are not explicitly exported are library-local, that is, they can neither be queried nor modified from the outside.
If it seems absolutely unavoidable to export global variables, they should then be named with an expressive name. It should be obvious just by the name, what purpose this exported variable serves. The names should also be chosen in such a way as to ensure that they cannot accidentally be used for another purpose within a program text to which the library has been added.
The programmer should document all global variables, procedures, and functions, which have been exported by his or her library so that users of this library may not be surprised by odd side effects, e.g., containing an exported variable, procedure, or function in the library that is also used in the user program - but in that case for different purposes.
Each library, which requires specific data structures, should have an Init procedure in which all global variables are initialized and arrays dimensioned and which sets the library into a well defined basic state as a whole.
If the data structures required by a library occupy a certain amount of memory, then the library should also possess an Exit procedure which, for example, frees occupied memory blocks and reduces arrays to their minimal size.
During the creation of the library, the programmer has the opportunity to indicate a release date (if desired also the time) and a version number. This opportunity should be utilized to clearly identify the library created by the programer. Information indicated here will later appear in the library line behind the library name.
a library is generated, which is to be used for a longer period of time or which
is maybe also to be published, the function 'Clean
Sweep' should be called from the program menu in the editor. The editor
subsequently will delete all no longer needed symbols from the source text of the
library, which will shorten the library. The Library Maker itself does not check
if an identifier has ever been used in the library.
The Exported_Symbols Procedure
The procedure Exported_Symbols is absolutely necessary for the creation of a library. All symbols (procedures, functions, variables, arrays, and labels as well), which do not appear in this procedure will be transformed into library-local symbols when the library is being generated, thus they can only be accessed from within the library. Consequently, a function can then, e.g., call an internal sub-function, which can never be accessed from the outside (that is, from the BASIC program or from other libraries). This ensures that in cases when several libraries are used no unintended overlapping is possible. Hence, two different libraries cannot contain two internal functions with the same name, which would lead to an error. Global variables of a library, which are not being exported are thus no longer accessible and modifiable from outside of the library. As a result, an error source is eliminated.
The exported symbols have to be listed in an syntactically correct form in the Exported_Symbols procedure. This means the following:
Variables and arrays have to be listed in the procedure in the form of an assignement. In these cases it is of no significance whether they are located on the left or on the right side of the equal sign. In the case of arrays, the number of variables has to be correct as well.
Functions have to appear in an assihgnement as well. This is possible only on the right side of the equal sign. A suitable variable has to be listed on the left side of this equation. In cases of string functions, this is then a string variable.
Procedures are written as procedure calls using the standard method. Of course, the number of parameters has to be here correct as well.
Labels can be included in Exported_Symbols using a GOSUB or GOTO command.
However, even though the procedure Exported_Symbols is parsed by the Library Maker, it is not taken over into the library code and is thus not contained in the finished library. Therefore it may not be called either, which also would serve no purpose whatsoever. At the same time, this proves that the parameter types added to functions and procedures in Exported_Symbols, can be any the programmer desires to use. The only requirement is that whatever is listed on the left side of the equal sign has to correspond to what is written on the right side. Otherwise, the editor will not tokenize the line.
Exported_Symbols itself is a procedure without passing parameter. This procedure may also not call itself (almost recursive), because this procedure name is not needed outside of the library. The procedure Exported_Symbols would also never be included in the library. Thus, the compiler would never be able to translate a call from outside.
If a LOCAL command is located within the Exported_Symbols procedure, the subsequent variables are also treated as locals. Therefore these variables are library-local, even though they appear within the procedure. This can be used to arrange the procedure more clearly by declaring Void or Dummy as local variables of Exported_Symbols, employing them wherever parameters are needed.
Incidentally, all imported symbols definitely have to be incorporated into the Exported_Symbols procedure. These are procedures and functions, which are called from inside the library, but are defined in another library or in the program itself.
The Library Maker happens to search the Exported_Symbols
procedure at the very beginning of its work process by scanning the program from
the beginning to its end. These symbols are founded a bit faster if they are listed
as far at the top of the source text as possible. Since the position of this procedure
has no further impact on the translation process, it should be listed as the second
procedure, immediately after the naming procedure. However, it should not be the
first procedure because you surely do not want to name your library "Exported_Symbols"
Error Messages of the Library Maker
A variety of different error messages can occur during the creation of a library. Similarly to the compiler, they appear in the active translation window. Insofar as they are not self-explanatory (e.g., UNTIL without REPEAT), they are discussed in detail below:
DEF PROC Exported_Symbols missing:
The Library Maker differentiates between two global procedures, functions, variables,
and library-local procedures, functions, variables. The advantage of this differentiation
is that procedures with the same name do not interfere with one another when they
exist in different libraries, which are linked to the same BASIC program. So that
the Library Maker knows which procedures, functions, and variables are supposed to
be global - and thus also may be called by the BASIC program or other libraries,
all identifiers have to be declared in an Exported_Symbols
procedure. If this procedure does not exist (or is empty), the library would become
totally inaccessible from the outside and therefore an error message is issued.
Not allowed command outside of PROC/FN:
A Library represents a collection of procedures and functions, which can be loaded to the program additionally if needed. In that case, only those parts are to be incorporated into the compiled product which are also really needed. The compiler is only able to determine which parts of a library are actually required if these are neatly and clearly separated. Therefore, a library may consist only of procedures and functions. Only commentaries and braces for folding up program sections are permitted outside of the use of procedures and functions as well as the command COMPILER if it has the control words "LIB_MAKER OFF" or "LIB_MAKER ON" as parameters (and only these).
MEMORY_BLOCK not allowed:
Memory blocks are not possible in libraries because how to locate them is not defined. Consequently, they have to be additionally loaded into the main program or placed into DATA's byte-by-byte and then transferred to a memory block with MEMORY using a library function/procedure (e.g., the Init procedure).
DEF PROC within DEF PROC:
Before a procedure/function has been concluded with END_PROC/END_FN, a new procedure/function
definition has begun using DEF PROC/FN. It is likely that the END_PROC/END_FN was
Structure not closed:
This error occurs if a structure (FOR, WHILE, REPEAT ...) has been opened but has not been closed again before the end of the respective procedure.
Not enough memory reserved:
To generate the library code, the Library Maker requires memory in the application heap of the Omikron Basic editor. If this error message appears, you either have to close windows that are no longer needed or reserve more memory - by accessing the 'Memory Settings...' in the mode menu and - if needed - also by using the Finder to adjust the available memory setting in the 'Get Info' menu option in the file menu.
© 1997-2001 Berkhan-Software