Preprocessor
The preprocessor is a compilation stage that operates on lexer tokens,
before the parser. It resolves #-directives and macro references.
All preprocessor directives begin with #.
#include
#include inserts the contents of another file at the point of the directive.
#include "sum.gof"
func void main[]
2 2 sum // `sum` is defined in sum.gof
end
Inclusion is recursive: definitions from the included file are available at
the include site, and the included file may itself #include other files.
Module include
Including a directory includes the file with the same name inside it:
#include "dir" // includes `dir/dir.gof`
This simplifies library layout: a library foo is a directory foo/ with
foo/foo.gof as its entry point.
Include-once
Each file is included at most once per compilation, even if it is
#included from multiple places.
Search strategy
When resolving #include, Gofra searches in this order:
- The directory of the including file.
- The directory of the main file.
- Include search directories (
-isd/--include-search-dir).
#define and #undef
#define creates a macro. #undef removes it.
#define MACRO 2
The macro can be used anywhere in the code after its definition:
MACRO MACRO + // 2 2 + = 4
From the command line
Macros can be defined from the CLI with -D:
gofra build -Ddebug=1 main.gof
This is useful for debug flags and feature toggles.
#ifdef, #ifndef, #endif
Conditional compilation based on macro definition:
#ifdef DEBUG
// compiled only if DEBUG is defined
#endif
#ifndef DEBUG
// compiled only if DEBUG is not defined
#endif
Built-in macros
Gofra defines two macros for the target:
| Macro | Example | Meaning |
|---|---|---|
OS_{NAME} |
OS_LINUX, OS_DARWIN |
Target operating system |
ARCH_{NAME} |
ARCH_AMD64, ARCH_AARCH64 |
Target architecture |
IS_{ENDIANNES}_ENDIAN |
IS_LITTLE_ENDIAN, IS_BIG_ENDIAN |
... |
For example, compiling for Darwin on ARM64 defines OS_DARWIN and
ARCH_AARCH64.