This stage takes a valid Dana program (after semantic analysis) and generates LLVM IR code.
The IR is written to stdout, so it can be redirected into a .ll file and then compiled with clang together with the Dana runtime library.
- Emits LLVM IR for all valid Dana programs.
- Supports function definitions, procedure calls, control flow, and expressions.
- Declares and links against built-in runtime functions (I/O, strings, conversions).
- Produces portable LLVM IR targeting
x86_64-pc-linux-gnu. - Stable exit codes (
0on success, non-zero on error).
- The semantic analyzer must be built first (LLVM IR generation depends on its AST).
- LLVM 14 (tested with the default package on Debian 12. Later LLVM versions introduce header and function name changes that can cause incompatibility).
- clang (for assembling IR and linking the runtime library).
- make, flex, bison, and a C++17 compiler.
From this directory:
make # build LLVM code generator
make clean # remove generated .cpp/.o files
make distclean # remove all generated files, including the danac binaryThe build produces the binary: ./danac.
Usage: ./danac [OPTIONS] [FILE]
Generate LLVM IR from FILE, or standard input if FILE is omitted.
Options:
-h, --help Show this help and exit
Examples:
./danac program.dana > program.ll # Compile source to LLVM IR
./danac < input.dana > out.ll # Read from stdin, write IR to filedef hello
writeString: "Hello world!\n"
./danac hello.dana > hello.ll; ModuleID = 'Dana Program'
source_filename = "Dana Program"
target triple = "x86_64-pc-linux-gnu"
@.str = private constant [14 x i8] c"Hello world!\0A\00", align 1
declare void @writeString(i8*)
define void @hello() {
entry:
call void @writeString(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i32 0, i32 0))
ret void
}
define i32 @main() {
entry:
call void @hello()
ret i32 0
}After saving the IR to a file:
./danac hello.dana > hello.ll
clang -o hello hello.ll libdanart.a
./helloOutput:
Hello world!
For convenience, a wrapper script automates the process:
Usage: ./danac.sh [-h] [-o output] <input.dana>
Options:
-h Show this help message and exit
-o <output> Name of the output executable (default: a.out)
Example:
./danac.sh -o hello hello.dana
./hello0— success (LLVM IR generated)- non-zero — semantic or code generation error (message printed to stderr)
Use the repository’s Python test harness:
cd ../testing
python3 test_llvm.pyThe script:
- Runs
danacon all programs intesting/programs/. - Saves IR into
testing/ll/. - Uses clang to compile
.llinto an executable, linked withlibdanart.a. - Saves binary into
testing/bin. - Executes the binary with inputs from
testing/input/. - Compares program output against reference results in
testing/result/.
- Ensure LLVM 14 and clang are installed and available in
$PATH. - The runtime library
libdanart.amust be present in the same directory or linked with-Land-loptions. - If the
libdanart.ais deleted you can restore it by runninggcc -c dana_runtime.c -o dana_runtime.o ar rcs libdanart.a dana_runtime.o - If compilation fails with
target tripleissues, verify that your LLVM and clang versions match your system architecture. - IR is printed to stdout (using
danac) — don’t forget to redirect (>) to capture it in a file.