Reference manual

Verona, from source form to native boundary.

A guide to Verona’s programmable compilation model, core language, bundled base package, native boundary, and build environment.

1 — Foundation

Two layers of compilation

Verona has two cooperating compilation layers. The first is a metaprogramming layer: macros run at compile time, receive and return S-expressions, and can inspect, construct, combine, or generate the syntax that the next layer will compile. The second is the top-level-form compiler: it expands those forms, collects declarations, resolves signatures, and type-checks executable bodies.

This separation is deliberate. In the metaprogramming layer, a program is data: lists, identifiers, strings, and quoted templates. A macro can build a function, a protocol implementation, or a sequence of definitions without turning those declarations into runtime values.

source
  → reader syntax
  → compile-time macro evaluation
  → expanded top-level forms
  → declaration collection and type checking
  → native artifact

2 — Language

Verona core language

Verona programs are written as S-expressions. Names are case-sensitive, and ; begins a line comment. String and character literals are ASCII-only; strings are immutable NUL-terminated byte pointers. Named control characters include #\tab, #\newline, #\vertical_tab, #\form_feed, and #\return. A char automatically widens where an integer is expected.

Values and types

Verona typeMeaning
boolBoolean value.
charOne ASCII code unit.
i8…i64, u8…u64Fixed-width signed and unsigned integers.
isize, usizeTarget-width integers.
f32, f64Floating-point values.
(pointer T)Pointer to T; pointee information remains in Verona’s type system.
(array T N)Fixed-size array.
(function (T...) R)Function signature and function-pointer shape.
Product and sum typesNominal records and alternatives for structured data.
Opaque typeA type owned by another interface and usable only behind a pointer.
voidNo-value marker for a C-facing result, not a Verona value.
unit, neverThe sole unit value and a terminating control-flow result.

Nominal data

(type point (product (x i32) (y i32)))
(type option (sum (none) (some i32)))

(function unwrap ((value option)) i32
  (match value
    ((none) 0)
    ((some number) number)))

Core expressions

  • let, do, and return bind, sequence, and return values.
  • array-of and index create and access fixed arrays.
  • field reads a product field; match destructures sums and tuples. In a match pattern, _ discards its value and cannot be referenced in the case expression.
  • &, deref, assign, cast, and pointer-offset express memory access explicitly; places are read implicitly when used as values.

Polymorphism

Generics

Generic declarations dispatch by argument types and, when needed, the expected result type.

Type parameters

for binds type parameters for reusable typed functions.

Protocols

Protocols describe operations and constrain polymorphic functions.

Modules

import, export, and :as organize dotted modules and qualified names.

Declarations and reader features

  • type declares transparent aliases, opaque handles, products, and sums.
  • function, constant, and variable introduce program definitions.
  • external-function imports a C symbol; native-export exposes a compatible function to C.
  • Prefix a form with #+name to include it when a reader feature is available, or #-name when it is not.

The selected target provides platform, architecture, pointer-width, endianness, and object-format reader features. Add project features with repeated --feature NAME options.

#+darwin
(external-function mach-task-self
  "mach_task_self" () u32)

3 — Bundled package

Base library

The explicit base module provides surface declaration macros and the public protocol layer. Add base/src to a target’s module path, import it, and use its qualified forms.

Application programs should use operations exported by a module such as base, rather than compiler-internal %… primitives. Numeric type conversion is always explicit: use base:convert where a conversion is intended.

(import base)

(base:function total
  (for (a)
    ((base:numeric a)))
  ((left a) (right a))
  a
  (+ left right))

(base:function same
  (for (a)
    ((base:equality a)))
  ((left a) (right a))
  bool
  (= left right))

base:numeric

Supplies +, -, *, and /.

base:equality

Supplies =, including booleans.

base:ordering

Supplies <, <=, >, and >=.

Supported numbers

All three numeric protocols cover i8…i64, u8…u64, f32, and f64.

4 — Compile-time layer

Metaprogramming reference

Macros are compile-time programs that construct Verona syntax. A macro returns one expression form when used in executable code, or a sequence of top-level definitions when used at the top level. Source locations are retained by the compiler and restored after expansion.

The declarations in the explicit base module are imported macros, not built-in evaluator functions. compiler:definition and compiler:fold-left form the narrow compiler-facing bridge: the first constructs a compiler definition, and the second constructs a nested binary call tree.

Evaluator bindings

FunctionSignaturePurpose
+(+ NUMBER...)Bootstrap arithmetic for evaluator tests and simple bootstrap macros; not a general-purpose macro library.
definitions(definitions FORM...)Return zero or more top-level S-expression forms.
compiler:definition(compiler:definition PRIMITIVE ARGUMENTS)Build a compiler %… definition from its positional arguments.
compiler:fold-left(compiler:fold-left HEAD INITIAL FORMS)Build nested binary calls headed by HEAD.
symbol, symbol-name, symbol-concatIdentifier operationsConstruct, inspect, and join identifiers.
keyword, keyword-concatIdentifier operationsConstruct identifiers for keyword-style conventions; they are not reserved source keywords.
string-concat, string-length, substringString operationsConstruct and inspect strings.
list, cons, car, cdr, append, lengthList operationsConstruct and inspect finite, proper S-expression lists.

Quotes and templates

'FORM quotes an S-expression, `FORM quasiquotes a template, and ,FORM evaluates and inserts an S-expression inside that template.

(import base)

(base:macro generated-function (type)
  `(base:function ,(keyword-concat (keyword "generated-") ,type)
     () ,type 42))

5 — Native boundary

Native interoperability and LLVM

Verona lowers typed programs through LLVM to native artifacts. The LLVM layer implements Verona’s native-code pipeline; the language itself exposes a defined C ABI boundary for interoperating with existing native software.

Use external-function to import a C symbol and native-export to publish a compatible Verona function. Static and shared libraries receive a generated .h file beside the artifact.

Value shapeC contractAvailability
bool_BoolParameters and results.
charuint8_tParameters and results.
Narrow signed and unsigned integersint8_t/int16_t, uint8_t/uint16_tC ABI sign or zero extension.
Other numbersMatching fixed-width integer, float, or doubleParameters and results.
PointersC pointerIncludes pointers to aggregates, opaque handles, void, and compatible functions.
Arrays, products, and sumsGenerated C-compatible wrapper or structBy value when their contents are compatible.
Opaque typesForward-declared struct NamePointer-only.
Function typeC function pointerOnly as (pointer (function (...) R)).
voidvoidResult of an imported C function only.
(external-function strlen "strlen" ((pointer u8)) usize)

(function add ((left i32) (right i32)) i32
  (+ left right))

(native-export add "verona_add")

Variadic APIs and APIs that need exact C-layout callback storage require dedicated bindings before they can be called safely.

6 — Package setup

Configuring environment

Verona packages use two independent environment variables. VERONA_SOURCE_DIR identifies the absolute root directory containing Verona package sources. VERONA_LIBRARY_DIR identifies the absolute root directory containing installed Verona package artifacts.

export VERONA_SOURCE_DIR="$HOME/.local/src/verona"
export VERONA_LIBRARY_DIR="$HOME/.local/lib/verona"

These variables describe Verona package locations only. They do not configure C-library discovery; native libraries remain target-specific build inputs.

The bundled bootstrap tutorial checks both variables, explains any missing setup, and prints links to the Verona site and source repository. Run it from the repository root with make bootstrap.

7 — Build tools

Build and package tooling

Commands

verona --version
verona compile SOURCE [options]
verona build TARGET OUTPUT-DIRECTORY [--feature NAME]...

compile builds one root source file. build finds verona.build in the current directory and writes the selected target beneath the output directory.

Build file

(executable app
  (root app.main)
  (module-path "src")
  (optimize 2)
  (library "sqlite3"))

Build files are declarative data: Verona forms inside them are never expanded or evaluated.

Compile options

OptionDescription
--version, -VPrint the Verona release version.
-o PATH, --output PATHSet the artifact path.
--emit object|executable|static-library|shared-libraryChoose artifact kind; executable is the default.
--target TRIPLESelect a native target triple.
--cpu CPUSelect a CPU; defaults to generic.
--features FEATURESPass a target-feature string.
--feature NAMEEnable a reader feature; repeatable.
-l NAME, --library NAMELink -lNAME; repeatable.
-L PATH, --library-path PATHAdd a library-search path; repeatable.
--framework NAMELink a Darwin framework; repeatable and Darwin-only.

Executable arguments

An executable can receive the platform command line with a C-compatible entry declaration. argc includes the executable name; argv points to its NUL-terminated byte strings.

(function main ((argc i32) (argv (pointer (pointer u8)))) exit-code
  (let ((first-argument (pointer u8)
                        (deref (pointer-offset argv 1))))
    ; parse first-argument when argc is at least 2
    0))

verona.build clauses

A build file contains one or more executable, static-library, or shared-library declarations. Every target requires exactly one (root module.name) clause.

ClauseDescription
(root module.name)Required root module.
(module-path "PATH")Add a module search path; repeatable. Defaults to the build file directory.
(target native)Use the native target; the default.
(target "TRIPLE")Use an explicit target triple.
(optimize 0)…(optimize 3)Set optimization; default is 0.
(version "VERSION")Declare a release version for the target.
(features NAME...)Set target reader features; may appear once.
(library "NAME")Link a native library; repeatable.
(library-path "PATH")Add a native library-search path; repeatable.
(framework "NAME")Link a Darwin framework; repeatable and Darwin-only.