Compiling a HBasic program
When you start the HBasic interpreter to execute a HBasic source program
or the compiler to create an executable binary both functions need the HBasic
parser to check the syntax of the source code. The parser has to do three
different things when beeing started.
- Checks the syntax of the source code and and find errors in it
- Create runtime code for the interpreter or executable code for the
compiler
- Create some infomation about the structures found to support debugging
and further compilation
Since the infomation about the structure of the source code is already
needed for further parser actions there are two parsing phases in HBasic.
The first one will only gather information about the source code and the
second one generates the code for the interpreter or compiler. You can find
some more information about the compilation in the following documents.
Parser steps in HBasic
The best documentation for the steps the parser executes is always the
program itself. This document should give some hints that may help to understand
the parser. The main parsing function is start_compiler in the source_file
parse0.cpp. The following table shows some steps that will be executed
by the parser.
Step |
Description |
Used with |
Prepare output file |
Open and prepare the compiler output hbasic.s |
C |
Preparse source files |
Find declarations and structures. Search for "Sub", "Event", "Inherits"
... |
I+C |
Create package list |
Write description for list of packages used with the project. |
I+C |
Assign Events |
Assign Labels for Functions that may be executed when an event will
be raised |
C |
Main compile |
Compile all modules and create runtime code |
I+C |
Assign breakpoints |
Create special break-code at breakpoint addresses |
I |
Assign Events |
Assign destination address for functions that may be executed when
an event will be raised. |
I |
Create global initcode |
Create code that will be started first after starting program execution. |
I+C |
Start program |
Start interpreter or assemble, link and start compiler code. |
I+C |
Documenting structures created by the parser
Code of the interpreter
The interpreter code is separated into bytecode that will be executed at
runtime and additional data that describes some information the interpreter
needs at runtime. The most important part of this additional information
is a description of the GUI structure the user has created in the GUI-designer.
The interpreter will try to execute the bytecode which is constructed out
of code-tags which describe the interpreter code that should be executed.
The code tags are numbers starting with 0. A list of the known code-tags
can be found in the file defines.h (Names starting with CODE_*). These code
tags use additional information which will be placed behing the code tag
in the runtime code. There may be for example a code to open dialog that
has been set up in the GUI editor with some additional information about
which dialog should be opened.
CODE_OPEN_DIA <form description>
You can find a description of the code-tags that will be used with HBasic
and some examples what code the parser creates for some common source code
statements in "List of interpreter code tags".
Runtime variables for the interpreter
Code of the compiler
If you want to create an executable program with the compiler the HBasic
program will execute the following steps:
- create an assembler source (hbasic.s file) with the compiled BASIC
code and further data to describe the GUI and other data of the project
- call the assembler as for the hbasic.s file to create an object
file hbasic.o
- link the object file hbasic.o with the compiler runtime library (program
gcc or ln and library rt_compiler) to create an
executable file hbasic.exe.
The code for the compiler will be generated with the same parser as the
code for the interpreter. This is useful because the compiler executes similar
code and uses similar runtime-structures as the interpreter. The main difference
is that the compiler executes pure machine language to access variables or
call library functions where the interpreter reads a code tag and then calls
the depending runtime functions to access variables or library functions of
the interpreter. Another difference is that the code for the interpreter uses
absolute jump addresses when setting up loops or subroutine calls whereas
the compiler uses symbolic labels and jumps to symbolic labels which will
be linked to the runtime addresses or code offsets by the linker program.
The parser code (see Parsing steps in HBasic
) uses a global variable to check if if should create code for the compiler
or interpreter. In the C-source code there are two macros (CODE_FOR_COMPILER
and CODE_FOR_INTERPRETER) that return a value of TRUE if code for the compiler
or code for the interpreter should be created.
Directory for the compiler
The compiler creates all files in the directory /usr/local/hbasic/compiler.
The assembler source will be called hbasic.s. The executable program can be
found in hbasic.exe. Copy this program to another place or computer if you
want to use it as a standalone program. Remember to copy the packages in
the directory /usr/local/hbasic/packages too if your program needs them.
Compiler library and runtime memory structure
open: parsing steps in HBasic
Documenting structures created by the parser
runtime variables for interpreter
xx Compiler library and runtime memory structure
xx list of interpreter code tags