ffc is the compiler driver for Lazy Fortran and LFortran Infer-style
source. It compiles supported Fortran programs to native object files and
executables via FortFront's typed AST and LIRIC's session C API.
Fortran / Lazy Fortran source
-> FortFront typed AST + diagnostics
-> ffc lowering + runtime ABI
-> LIRIC C API (via ISO_C_BINDING)
-> object file / executable
FortFront stays backend-neutral. ffc owns lowering, ABI, runtime calls,
LIRIC bindings, and object/exe emission. The retired MLIR/HLFIR
experiment lives only in git history.
The public contract is docs/SUPPORT_CONTRACT.md. It lists every
supported construct, its ABI, and every tracked gap with issue links.
Refer to that document instead of this README for the feature list.
Current slices include compound formatted print with literal I, X,
F, and A descriptors on stdout; fixed-size rank-1 and rank-2 arrays with
integer, real, and real(8) elements; scalar element access, array
sections, whole-array copy, elemental arithmetic, and the array intrinsics
size, shape, sum, product, maxval, minval, dot_product,
matmul, transpose, reshape, lbound, ubound, count, any, and
all; scalar element read and write on an allocated 1-D integer allocatable
(a(i)); and whole-array assignment from an array constructor to a 1-D
integer allocatable with auto-reallocation (a = [e1, e2, ...]). Scalar
integer pointer/target with p => t, read/write through p,
associated(p), and nullify(p) is supported, as are constant-folded
selected_int_kind and selected_real_kind. Derived types support single
inheritance (type, extends(parent) :: child) with parent-first component
layout. A module procedure may contains internal procedures, lowered as
flat functions. Module-level integer variables persist as globals and are
visible across use. The associate construct binds scalar selectors. The
scalar numeric intrinsics mod, modulo, sign, dim, int, nint,
floor, ceiling, real, dble are supported, as are the bit intrinsics
iand, ior, ieor, not, ishft, ishftc, ibits, btest, and
mvbits. The character intrinsics len, len_trim, trim, adjustl,
adjustr, index, scan, verify, repeat, achar, and iachar are
supported. The real transcendental intrinsics lower to libm: sqrt, exp,
log, log10, sin, cos, tan, asin, acos, atan, atan2,
sinh, cosh, tanh, asinh, acosh, atanh, erf, erfc, gamma,
log_gamma, and hypot.
The LIRIC static library must be on the linker path:
cd ../liric && cmake -S . -B build -G Ninja && cmake --build build
cd ../ffc
export LIBRARY_PATH=../liric/build
fpm build
fpm testfpm build produces the ffc binary; fpm test runs the behavioural
test suite.
Compile a minimal program:
printf 'program main\nend program main\n' > /tmp/empty.f90
LIBRARY_PATH=../liric/build fpm run ffc -- /tmp/empty.f90 -o /tmp/empty
/tmp/empty
echo $?docs/CONFORMANCE.md documents the conformance gauntlet runner that
drives external Fortran test corpora through the full ffc pipeline.
It produces an xfail-style report with JSONL output.
app/ffc.f90- CLI entry.src/- lowering, LIRIC bindings, CLI options (fpm auto-discovers).test/- behavioural tests; each file is a standaloneprogram test_*picked up by fpm auto-discovery.docs/-SUPPORT_CONTRACT.md,RUNTIME_ABI.md,DEVELOPER_GUIDE.md,API_REFERENCE.md,C_API_USAGE.md,MIGRATION_GUIDE.md,CONFORMANCE.md.BACKLOG.md,DESIGN.md- planning docs.
- Free-form Fortran 2003+; no implicit typing; declarations at scope top.
- Modules under 500 lines (hard cap 1000); functions under 50 lines
(hard cap 100). Split into
*.incfiles (already used heavily) when the lowerer grows. - Symbols
snake_case, derived types end in_t. - Each new supported construct lands as a code change in
src/session_program_lowering_*plus a behavioural test undertest/. UpdateREADME.mdanddocs/SUPPORT_CONTRACT.mdin the same commit.