Skip to content

Lowering & IR

Lowering & IR

Overview

The lowering stage transforms the typechecker’s ProgramT (Typed-IR) into CoreProgram (Core-IR), which is the final intermediate representation before LLVM code emission.

ProgramT (Typed-IR)
├── Comptime evaluation
├── Source preprocessing
├── IR node construction
CoreProgram (Core-IR)

CoreProgram Structure

The Core-IR is defined in src/lowering/coreir/nodes.tg:

struct CoreProgram:
normalized_source: String # Final normalized source
feature_set: String # Active features
enum_rows: String # Enum declarations
alias_rows: String # Type aliases
func_rows: String # Function declarations
lower_rows: String # Lowered IR nodes
error_count: i32 # Error counter
error_code: String # Last error code
error_message: String # Last error message
# 17 feature counters inherited from ProgramT

Lowering Sub-Stages

1. Compile-Time Evaluation (lowering/transform/comptime/)

Files:

  • eval.tg — Evaluates comptime blocks
  • flow.tg — Control flow for comptime execution
  • rewrite.tg — AST rewriting after comptime evaluation

2. Source Preprocessing (lowering/transform/preprocess/)

Files:

  • helpers.tg — Utility functions for preprocessing
  • parse.tg — Re-parse normalized source
  • text.tg — Text transformation utilities
  • value.tg — Value extraction and normalization

3. Program Transformation (lowering/transform/program.tg)

The main lowering entry point. It:

  1. Takes the ProgramT from the typechecker
  2. Applies preprocessing transforms
  3. Evaluates comptime blocks
  4. Produces the CoreProgram

Validation

The lowering pipeline includes a validate() function that checks for semantic errors in the normalized source. If validation fails, error E_TYPE_PIPELINE_VALIDATE is set on the program.

Error Handling

Core-IR errors are tracked through:

func core_set_error(core: CoreProgram, code: String, message: String) -> CoreProgram
func core_has_error(core: CoreProgram) -> i32

If any error occurs during lowering, the error count is incremented and the emitter stage will produce empty output.