QM applications are written using QMBasic. Unlike many other programming languages, the individual source modules are not linked together to form a single executable program but remain separate items that are loaded into memory dynamically when they are first needed. This approach generally results in lower memory usage and easier maintenance.
The program modules are stored as simple text records, normally in directory files though use of hashed files is allowed. Each field of the record represents a line of the program (a transformation that corresponds exactly to how directory file records are stored by the underlying operating system). Although you may place your program modules in any file you wish or scatter them over several files, by convention programmers often use a file named BP (Basic Programs). The BASIC and RUN commands will look here for programs by default if no file name is given in the commands.
QMBasic modules are of four types:
Throughout all documentation, the word program is used to refer to all of the above module types unless the context explicitly states otherwise.
Before a program can be executed, the source form written by the developer must be compiled (translated into corresponding executable program modules) using the BASIC command. The executable items are written to records of the same name as the source in a separate directory file that has the same name as the source file but with a .OUT suffix added. For example, the compiled version of a program stored as MYPROG in BP will be in MYPROG in the BP.OUT file. Programs may be executed directly from the .OUT file or may be moved into the system catalogue using the CATALOGUE command. Subroutines, functions and class modules must be catalogued before use.
Often, it is useful to place QMBasic source code elements that are used in more than one program in a separate record which is read during compilation as though it was part of the main program. In particular, common data structures or names representing keys to subroutines may be handled in this way to ensure that all components of the application have a common view of the information instead of needing to make changes in many places. The SYSCOM file is an example of this technique with records containing keys and other values that you may need in many programs. The QMBasic $INCLUDE directive described later in this section is used to direct the compiler to include text from another record. Include records may be stored in any file and are not separately compiled as the text is imported into other programs. It is recommended that a suffix of .H is used on include record names as the compiler will automatically skip these when using a select list. This suffix has its origins in the C programming language where it is used to denote a "header file" that serves the same purpose as QMBasic include records.
A QMBasic program has a very simple to understand format. The program is made up of a series of statements. Each statement normally corresponds to a single line of source program text though it is possible to place multiple statements on a single line by separating them with semicolons. Some statements have a syntax which allows them to span multiple lines without special action. Any statement that includes a comma in its syntax may start a new line immediately after the comma. Other statements may be split over multiple lines by ending each line except the last with a tilde (~) character. Note that continuation lines are handled before any other analysis of the line and therefore a comment that ends with a tilde will be treated as continuing on the next line.
Lines commencing with an asterisk or an exclamation mark are treated as comments and ignored by the compiler. Comments can be included on the same line as a source program statement by using a semicolon to start a new statement followed by an asterisk or an exclamation mark. Blank lines and leading spaces are ignored by the compiler.
* A comment on a line of its own
A = 44 ;* This is a trailing comment
B = "abc" ; C = LEN(B) ;* Two statements on a single line
CALL MYSUBR(TITLE, ;* A subroutine call
DATA, ;* with each argument
ITEM.COUNT) ;* on a separate line
The compiler is not case sensitive in language keywords. By default, variable names are also case insensitive but this can be altered using the $MODE directive or the $BASIC.OPTIONS record. All program fragments in this documentation are shown in uppercase partly so that they stand out and partly because historically most multivalue software has been written in this way. Use of lowercase can make programs easier to read. Other conventions such as writing equated token names in uppercase can be used if desired.
A program usually commences with a PROGRAM, SUBROUTINE, FUNCTION or CLASS statement. This serves to identify the type of QMBasic item and to assign a name to it. If none of these statements is present it is assumed to be a program.
The formats of these statements are
where a subroutine may take up to 255 arguments, a function 254.
A program ends with an END statement. Only blank lines and comments may follow this final END. For compatibility with other multivalue database products there is a compiler option to make this final END optional.
On an ECS mode system, string constants may contain ECS characters. All other language elements are restricted to the 8-bit character set.