Directives
Compiler directives (or pragmas) are statements that describe how the compiler should handle source code. Directives are safe to use. It is checked by the compiler and incorrect usage is warned.
For a directive to be valid, it must be used correctly in the right place. The directive must be strt with the #
prefix.
For example to directives:
#typedef
Top Directives
Top directives are must be placed at top of source file. Usually contains specific compiler configurations for file or package.
Arguments
The arguments of the directives are separated by spaces. The directive must be followed by the required arguments, separated by spaces.
For example:
#deprecated "my reason"
fn myFunc() {}
Directive Expressions
Some directives are evaluates the expression you wrote with a custom syntax, and if the expression returns true
as a result, your file will be included in the build. Expression must always return boolean. Expressions are only logical. So the variables you will use are boolean and the binary operations you can do are only logical and and logical or.
Your variables are set automatically by your compiler. The variables you can use are the same as in file annotation. They are variables that are also described in the platform support documentation.
WARNING
Evaluation results in false
on any syntax errors and empty expressions.
Syntax
The syntax is simple and easy to learn. The logical and operator is &&
and the logical or operator is ||
. These are exactly the same as Jule. The precedence of these operators is also the same. First, the logical or (||
) operator is evaluated, then the logical and (&&
) operator is evaluated. You also have parentheses. The parentheses, of course, are evaluated first. In addition to these, logical not (!
) operator is also available.
Variables
Here is the list of variables and their existence:
windows
: operating system is windowsdarwin
: operating system is darwinlinux
: operating system is linuxunix
: operating system is UNIX, or UNIX-likei386
: cpu architecture is intel 386arm64
: cpu architecture is ARM64amd64
: cpu architecture is AMD64x32
: 32-bit cpu architecturex64
: 64-bit cpu architectureproduction
: production compilation enabledtest
: compiling for testingclang
: backend compiler is Clanggcc
: backend compiler is GCCcpp14
: using C++14 standardcpp17
: using C++17 standardcpp20
: using C++20 standard
Examples
Here is an example code via build
directive:
#build (darwin || windows) && x64
#build unix && !darwin
Directive: pass
Directive pass is a top directive. Passes compiler flags to generated compile command for compiling source code. Uses string literal as argument, but literals are not processed, accepts directly. So, you can't use escape sequences like original string literals. Pass directives adds to command-lines after source files
INFO
There are no issue if you are using same passes. The compiler will eliminate duplicate passes.
For example:
#pass "-framework Foundation"
#pass "-framework Cocoa"
fn main() {
// ...
}
Directive: build
The build
directive is a top directive. Different way of specific programming such as platform specific programming. It can be used with or instead of file annotation. Unlike file annotation, it is a directive, not a naming convention.
Plese look at the specific programming section for more information.
Directive: typedef
In binded structs, if the structure is a typedef
use this will configure code generation correctly. Otherwise, the struct will be treated as a classical structures.
Directive: cdef
In binded functions, if the function is a #define
, it configures code generation to be compatible.
Directive: namespace
Adds namesapce selection for supported binded types. Uses string literal as argument, but literals are not processed, accepts directly. So, you can't use escape sequences like original string literals.
Directive: deprecated
Definitions qualify as deprecated. For more information, read the Deprecation section.
Directive: test
Declares test function. For more information, read the Writing Tests section.
Directive export
The export
directive is an important part of Integrated Jule. Determines how existing definitions are passed to the backend. This way you have a fixed identifier and can provide an API to the backend language for your Jule codes.
For more information, read the API development section.