View Source cure_codegen (cure v0.1.0)
Cure Programming Language - BEAM Code Generator
The code generator transforms typed Cure AST into BEAM bytecode, enabling Cure programs to run on the Erlang Virtual Machine. It handles all Cure language features including dependent types, finite state machines, pattern matching, and integration with Erlang/OTP.
Features
Complete Language Support
- Module Compilation: Full module support with imports/exports
 - Function Compilation: Regular and dependent function types
 - Expression Compilation: All Cure expressions to BEAM instructions
 - Pattern Matching: Efficient pattern compilation with optimization
 - Type Integration: Uses type information for optimizations
 
FSM Code Generation
- Native FSM Support: Compiles FSMs to gen_statem behaviors
 - State Optimization: Optimizes state transitions and data access
 - Guard Compilation: Efficient guard expression compilation
 - Action Compilation: Action sequences to BEAM instructions
 
BEAM Integration
- Bytecode Generation: Direct BEAM bytecode emission
 - Module Attributes: Proper module metadata generation
 - Export Lists: Correct function export handling
 - Debug Information: Optional debug info generation
 
Optimization Features
- Configurable Levels: Multiple optimization levels (0-3)
 - Type-directed: Uses type information for better code
 - Dead Code Elimination: Removes unused code paths
 - Instruction Optimization: BEAM instruction-level optimizations
 
Compilation Pipeline
1. Program Compilation
%% Compile entire program
{ok, Modules} = cure_codegen:compile_program(AST),
%% With custom options
Options = [{optimize, 2}, {debug_info, true}],
{ok, Modules} = cure_codegen:compile_program(AST, Options).2. Module Compilation
%% Compile single module
Module = #module_def{name = 'MyModule', exports = Exports, items = Items},
{ok, CompiledModule} = cure_codegen:compile_module(Module),
%% Generate BEAM file
cure_codegen:write_beam_module(CompiledModule, "MyModule.beam").3. Function Compilation
%% Compile individual function
Func = #function_def{name = add, params = Params, body = Body},
{ok, CompiledFunc, State} = cure_codegen:compile_function(Func).Code Generation Process
Phase 1: AST Analysis
- Type Information: Extract and validate type annotations
 - Import Resolution: Process module imports and dependencies
 - Export Analysis: Validate and process export specifications
 - Dependency Analysis: Build function dependency graph
 
Phase 2: Instruction Generation
- Expression Compilation: Convert expressions to BEAM instructions
 - Pattern Compilation: Generate efficient pattern matching code
 - Guard Compilation: Compile guard expressions
 - Control Flow: Generate conditionals, loops, and jumps
 
Phase 3: Optimization
- Instruction Optimization: Peephole optimizations
 - Register Allocation: Efficient register usage
 - Jump Optimization: Minimize jumps and labels
 - Constant Folding: Compile-time constant evaluation
 
Phase 4: Module Assembly
- Function Assembly: Combine compiled functions
 - Attribute Generation: Create module attributes
 - Export List: Generate proper export specifications
 - BEAM File: Produce final BEAM bytecode file
 
Compilation Options
Standard Options
Options = [
    {debug_info, true},      % Include debug information
    {optimize, 2},           % Optimization level 0-3
    {warnings, true},        % Enable compilation warnings
    {strict_types, true},    % Strict type checking
    {fsm_integration, true}  % Enable FSM features
].Optimization Levels
- Level 0: No optimizations (fastest compile, debugging)
 - Level 1: Basic optimizations (safe, minimal impact)
 - Level 2: Standard optimizations (default, balanced)
 - Level 3: Aggressive optimizations (maximum performance)
 
Expression Compilation
Literals
42          → {integer, 42}
"hello"     → {string, "hello"}
true        → {atom, true}
[1,2,3]     → {cons, {integer,1}, {cons, {integer,2}, ...}}Function Calls
foo(x, y)   → {call, {atom, foo}, [VarX, VarY]}
Mod.func(x) → {call, {remote, {atom, 'Mod'}, {atom, func}}, [VarX]}Pattern Matching
match value do
    {ok, x} -> x
    error -> 0
endCompiles to efficient jump table with pattern tests.
FSM Compilation
Finite state machines compile to standard Erlang gen_statem:
fsm Counter do
    states: [idle, counting]
    initial: idle
    
    state idle do
        event start -> counting
    end
endGenerates:
init/1callback for initialization- State callback functions for each state
 - Event handling with pattern matching
 - State data management
 
Error Handling
The code generator provides detailed error information:
- Compilation Errors: Unsupported constructs, type mismatches
 - Generation Errors: BEAM instruction generation failures
 - Optimization Errors: Failed optimizations (non-fatal)
 - File I/O Errors: BEAM file writing errors
 
Integration with Type System
Uses type information for:
- Type Erasure: Remove type annotations while preserving semantics
 - Optimization: Type-directed optimizations and specializations
 - Error Prevention: Catch type-related errors during compilation
 - Runtime Checks: Generate minimal runtime type checks where needed
 
BEAM Compatibility
Generates standard BEAM bytecode compatible with:
- Erlang/OTP: Full compatibility with Erlang runtime
 - Elixir: Can be called from Elixir code
 - LFE/Gleam: Compatible with other BEAM languages
 - Standard Tools: Works with standard BEAM tools (debugger, profiler)
 
Performance Characteristics
- Compilation Speed: Linear in program size for most constructs
 - Generated Code: Comparable performance to hand-written Erlang
 - Memory Usage: Efficient memory usage during compilation
 - Optimization Impact: 10-40% performance improvement at higher levels
 
Thread Safety
The code generator is stateless at the module level and can safely compile multiple modules concurrently. Individual function compilation maintains local state that is not shared between threads.
Summary
Functions
Compiles a Cure expression to BEAM instructions using default state.
Compiles a finite state machine definition to BEAM runtime functions.
Compiles a single Cure function to BEAM bytecode using default options.
Compiles a single Cure module to BEAM bytecode using default options.
Compiles a complete Cure program to BEAM bytecode using default options.
Generates a BEAM bytecode file from a compiled Cure module.
Writes a compiled Cure module to a BEAM file.
Functions
Compiles a Cure expression to BEAM instructions using default state.
This is the main expression compilation entry point that handles conversion of all Cure expression types to equivalent BEAM bytecode instructions.
Arguments
Expr- Expression AST node (various expr record types)
Returns
{Instructions, State}- BEAM instructions and updated compilation state{error, Reason}- Compilation error details
Example
Expr = #binary_op_expr{op = '+', left = {literal, 5}, right = {literal, 3}},
{Instructions, _State} = cure_codegen:compile_expression(Expr).Supported Expression Types
- Literals (integers, atoms, strings, booleans)
 - Identifiers (variables, function references)
 - Binary operations (arithmetic, logical, comparison)
 - Function calls (local and remote)
 - Control flow (if/else, pattern matching)
 - Data structures (lists, tuples, records)
 - Lambda expressions and blocks
 - String interpolation
 - Type annotations
 
Error Handling
Returns detailed error information for unsupported expressions, type mismatches, and compilation failures.
Compiles a finite state machine definition to BEAM runtime functions.
This function transforms a Cure FSM definition into executable BEAM code that integrates with the FSM runtime system. It generates helper functions for spawning, controlling, and querying FSM instances.
Arguments
FSMDef- FSM definition AST node (#fsm_def{})State- Current compilation state
Returns
{ok, {fsm, CompiledFSM}, NewState}- Successfully compiled FSM{error, Reason}- Compilation error details
Generated Functions
For an FSM named Counter, generates:
Counter_spawn/0- Spawn FSM with default initial stateCounter_spawn/1- Spawn FSM with custom initial dataCounter_send/2- Send event to FSM instanceCounter_state/1- Get current state of FSM instanceCounter_stop/1- Stop FSM instance gracefullyCounter_definition/0- Get compiled FSM definition
Example
FSM = #fsm_def{
    name = 'Counter',
    states = [idle, counting],
    initial = idle,
    state_defs = [IdleState, CountingState]
},
{ok, {fsm, CompiledFSM}, NewState} = compile_fsm_impl(FSM, State).FSM Runtime Integration
- Compiles FSM to cure_fsm_runtime format
 - Generates proper BEAM bytecode for FSM operations
 - Integrates with gen_statem behavior patterns
 - Handles state transitions, events, and timeouts
 - Provides type-safe FSM interface functions
 
State Management
FSMs maintain state data through:
- Initial state setup from spawn parameters
 - State data transformation during transitions
 - Event payload integration with state data
 - Timeout handling with state persistence
 
Compiles a single Cure function to BEAM bytecode using default options.
This function handles standalone function compilation, primarily used for testing and development. In normal compilation, functions are compiled as part of module compilation.
Arguments
FunctionAST- Function AST node (function_def record or tuple format)
Returns
{ok, CompiledFunction, State}- Successfully compiled function with state{error, Reason}- Compilation error details
Example
FuncAST = #function_def{
    name = add,
    params = [x, y],
    body = {binary_op, '+', {var, x}, {var, y}}
},
{ok, CompiledFunc, _State} = cure_codegen:compile_function(FuncAST).Function Processing
- Converts function parameters to BEAM registers
 - Compiles function body expressions to BEAM instructions
 - Handles pattern matching in parameters
 - Generates proper function entry and exit code
 - Applies function-level optimizations
 
Limitations
- Creates minimal compilation state for standalone compilation
 - May not have access to full module context for imports/types
 - Primarily intended for testing individual functions
 
Compiles a single Cure module to BEAM bytecode using default options.
This function handles compilation of complete module definitions including exports, imports, function definitions, FSM definitions, and type definitions. It converts Cure module AST to BEAM-compatible Erlang forms.
Arguments
ModuleAST- Module AST node (module_def record or tuple format)
Returns
{ok, CompiledModule}- Successfully compiled module ready for BEAM{error, Reason}- Compilation error with details
Example
ModuleAST = #module_def{
    name = 'MyModule',
    exports = [{foo, 2}, {bar, 1}],
    items = [FuncDef1, FuncDef2]
},
{ok, BeamModule} = cure_codegen:compile_module(ModuleAST),
cure_codegen:write_beam_module(BeamModule, "MyModule.beam").Module Processing
- Processes imports and builds import environment
 - Validates and converts export specifications
 - Compiles all module items (functions, FSMs, types)
 - Generates proper BEAM module structure with attributes
 - Handles both old and new AST formats for compatibility
 
Supported Module Items
- Function definitions (regular and Erlang functions)
 - FSM definitions (compiled to gen_statem)
 - Record and type definitions
 - Import and export declarations
 
Compiles a complete Cure program to BEAM bytecode using default options.
This is a convenience function that calls compile_program/2 with default compilation options.
Arguments
AST- List of top-level AST items (modules, functions, etc.)
Returns
{ok, Modules}- Successfully compiled modules{error, {compilation_failed, Errors}}- Compilation failures
Example
AST = cure_parser:parse_file("program.cure"),
{ok, Modules} = cure_codegen:compile_program(AST),
lists:foreach(fun(Module) ->
    cure_codegen:write_beam_module(Module, filename(Module))
end, Modules).Default Options
Uses standard compilation options: debug_info, optimization level 1, warnings enabled, strict types, and FSM integration.
Generates a BEAM bytecode file from a compiled Cure module.
This function converts the internal compiled module representation to standard Erlang abstract forms, then uses the Erlang compiler to produce a BEAM bytecode file compatible with the Erlang Virtual Machine.
Arguments
Module- Compiled module data (map with functions, exports, etc.)OutputPath- File path where BEAM file should be written
Returns
{ok, {ModuleName, OutputPath}}- Successfully generated BEAM file{error, Reason}- Generation error details
Example
{ok, CompiledModule} = cure_codegen:compile_module(ModuleAST),
{ok, {MyModule, "MyModule.beam"}} = 
    cure_codegen:generate_beam_file(CompiledModule, "MyModule.beam").Process Steps
- Form Conversion: Convert internal representation to Erlang forms
 - Erlang Compilation: Use Erlang compiler to generate bytecode
 - File Writing: Write binary BEAM data to specified path
 - Error Handling: Provide detailed errors at each step
 
BEAM Compatibility
Generated BEAM files are fully compatible with:
- Standard Erlang/OTP runtime
 - Elixir and other BEAM languages
 - BEAM development and debugging tools
 - Hot code reloading and distribution
 
Error Types
{write_failed, Reason}- File system errors{compile_failed, Errors, Warnings}- Erlang compiler errors- Form conversion errors from convert_to_erlang_forms/1
 
Writes a compiled Cure module to a BEAM file.
This is a convenience function that calls generate_beam_file/2 to convert a compiled module to BEAM bytecode and write it to the specified path.
Arguments
Module- Compiled module data from compile_module/1,2OutputPath- File path where BEAM file should be written
Returns
{ok, {ModuleName, OutputPath}}- Successfully written BEAM file{error, Reason}- File writing or compilation error
Example
{ok, CompiledModule} = cure_codegen:compile_module(AST),
{ok, {MyModule, "MyModule.beam"}} = 
    cure_codegen:write_beam_module(CompiledModule, "MyModule.beam"),
%% Load and test the module
code:load_file(MyModule),
MyModule:function_name(args).Use Cases
- Final step in Cure compilation pipeline
 - Integration with build systems and tools
 - Deployment of Cure modules to BEAM environments
 - Testing and development workflows