View Source cure_ast (cure v0.1.0)

Cure Programming Language - AST Definitions

This module defines the Abstract Syntax Tree (AST) node types and structure for the Cure programming language. It provides comprehensive type definitions and helper functions for creating and manipulating AST nodes throughout the compilation pipeline.

Overview

The Cure AST represents the complete syntactic structure of Cure programs including:

  • Programs: Collections of top-level items
  • Modules: Module definitions with exports and items
  • Functions: Function definitions with parameters, return types, and bodies
  • Types: User-defined types, primitives, and complex type expressions
  • FSMs: Finite state machine definitions with states and transitions
  • Expressions: All forms of expressions (literals, function calls, control flow)
  • Patterns: Pattern matching constructs
  • Location Information: Source position tracking for error reporting

AST Structure

Top-Level Items

Programs consist of top-level items:

  • module_def() - Module definitions
  • function_def() - Regular function definitions
  • erlang_function_def() - Erlang interop functions
  • type_def() - User-defined type definitions
  • fsm_def() - Finite state machine definitions
  • import_def() - Import statements

Expression Types

Expressions represent computations and values:

  • literal_expr() - Literals (numbers, strings, atoms)
  • identifier_expr() - Variable and function names
  • function_call_expr() - Function calls with arguments
  • binary_op_expr() - Binary operations (+, -, *, etc.)
  • unary_op_expr() - Unary operations (-, not)
  • match_expr() - Pattern matching expressions
  • let_expr() - Let bindings
  • list_expr() - List literals
  • tuple_expr() - Tuple literals
  • record_expr() - Record construction
  • lambda_expr() - Anonymous functions

Type System

Type expressions represent Cure's type system:

  • primitive_type() - Built-in types (Int, String, Bool, etc.)
  • dependent_type() - Parameterized types with dependencies
  • function_type() - Function type signatures
  • union_type() - Union types (T | U)

  • list_type() - List types
  • tuple_type() - Tuple types
  • type_param() - Type parameters for generics

Pattern Matching

Patterns for destructuring and matching:

  • wildcard_pattern() - Wildcard patterns (_)
  • literal_pattern() - Literal value patterns
  • identifier_pattern() - Variable binding patterns
  • list_pattern() - List destructuring patterns
  • tuple_pattern() - Tuple destructuring patterns
  • record_pattern() - Record field patterns
  • constructor_pattern() - Constructor patterns (Ok(x), Error(e))

FSM Support

First-class finite state machine support:

  • fsm_def() - FSM type definitions
  • state_def() - Individual state definitions
  • transition() - State transitions with events, guards, and actions

Location Tracking

All AST nodes include location information for:

  • Error Reporting: Precise source locations for compilation errors
  • Debugging: Source mapping for runtime errors
  • IDE Support: Language server integration
  • Documentation: API documentation generation

Usage Example

%% Create a simple function definition
Params = [#param{name = x, type = int_type(), location = Location}],
Body = #literal_expr{value = 42, location = Location},
Function = cure_ast:new_function(identity, Params, int_type(), undefined, Body).

%% Create an FSM definition
States = [idle, running, stopped],
Initial = idle,
StateDefs = [IdleState, RunningState, StoppedState],
FSM = cure_ast:new_fsm(state_machine, States, Initial, StateDefs).

Design Principles

Immutability

AST nodes are immutable records that can be safely shared and transformed without side effects.

Composability

Complex AST structures are built by composing simpler nodes, enabling modular construction and transformation.

Location Preservation

Every AST node maintains source location information to support high-quality error messages and debugging.

Type Safety

Erlang type specifications ensure AST node integrity and enable static analysis tools to verify AST manipulation code.

Integration

This module integrates with:

  • Parser: Produces AST nodes from token streams
  • Type Checker: Analyzes and annotates AST with type information
  • Compiler: Transforms AST through various compilation phases
  • Error Reporter: Uses location information for error messages

Performance Considerations

  • Memory Efficient: Records are lightweight with minimal overhead
  • Copy-on-Write: Erlang's immutable data structures optimize memory usage
  • Pattern Matching: Efficient pattern matching on AST node types
  • Location Sharing: Location records can be shared between related nodes

Summary

Functions

Creates a new expression AST node with location information.

Creates a new FSM definition AST node.

Creates a new function definition AST node.

Creates a new module definition AST node.

Creates a new type definition AST node.

Types

binary_op_expr()

-type binary_op_expr() ::
          #binary_op_expr{op :: atom(), left :: expr(), right :: expr(), location :: location()}.

binding()

-type binding() :: #binding{pattern :: pattern(), value :: expr(), location :: location()}.

dependent_type()

-type dependent_type() ::
          #dependent_type{name :: atom(), params :: [type_param()], location :: location()}.

erlang_function_def()

-type erlang_function_def() ::
          #erlang_function_def{name :: atom(),
                               params :: [param()],
                               return_type :: type_expr(),
                               constraint :: expr() | undefined,
                               erlang_body :: string(),
                               location :: location()}.

export_spec()

-type export_spec() :: #export_spec{name :: atom(), arity :: integer(), location :: location()}.

expr()

field_expr()

-type field_expr() :: #field_expr{name :: atom(), value :: expr(), location :: location()}.

field_pattern()

-type field_pattern() :: #field_pattern{name :: atom(), pattern :: pattern(), location :: location()}.

fsm_def()

-type fsm_def() ::
          #fsm_def{name :: atom(),
                   states :: [atom()],
                   initial :: atom(),
                   state_defs :: [state_def()],
                   location :: location()}.

function_call_expr()

-type function_call_expr() ::
          #function_call_expr{function :: expr(), args :: [expr()], location :: location()}.

function_def()

-type function_def() ::
          #function_def{name :: atom(),
                        params :: [param()],
                        return_type :: type_expr() | undefined,
                        constraint :: expr() | undefined,
                        body :: expr(),
                        location :: location()}.

function_type()

-type function_type() ::
          #function_type{params :: [type_expr()], return_type :: type_expr(), location :: location()}.

identifier_expr()

-type identifier_expr() :: #identifier_expr{name :: atom(), location :: location()}.

identifier_pattern()

-type identifier_pattern() :: #identifier_pattern{name :: atom(), location :: location()}.

import_def()

-type import_def() :: #import_def{module :: atom(), items :: [atom()] | all, location :: location()}.

item()

-type item() ::
          module_def() | function_def() | erlang_function_def() | type_def() | fsm_def() | import_def().

lambda_expr()

-type lambda_expr() :: #lambda_expr{params :: [param()], body :: expr(), location :: location()}.

let_expr()

-type let_expr() :: #let_expr{bindings :: [binding()], body :: expr(), location :: location()}.

list_expr()

-type list_expr() :: #list_expr{elements :: [expr()], location :: location()}.

list_pattern()

-type list_pattern() ::
          #list_pattern{elements :: [pattern()], tail :: pattern() | undefined, location :: location()}.

list_type()

-type list_type() ::
          #list_type{element_type :: type_expr(), length :: expr() | undefined, location :: location()}.

literal_expr()

-type literal_expr() :: #literal_expr{value :: term(), location :: location()}.

literal_pattern()

-type literal_pattern() :: #literal_pattern{value :: term(), location :: location()}.

location()

-type location() :: #location{line :: integer(), column :: integer(), file :: string() | undefined}.

match_clause()

-type match_clause() ::
          #match_clause{pattern :: pattern(),
                        guard :: expr() | undefined,
                        body :: expr(),
                        location :: location()}.

match_expr()

-type match_expr() :: #match_expr{expr :: expr(), patterns :: [match_clause()], location :: location()}.

module_def()

-type module_def() ::
          #module_def{name :: atom(),
                      exports :: [export_spec()],
                      items :: [item()],
                      location :: location()}.

param()

-type param() :: #param{name :: atom(), type :: type_expr(), location :: location()}.

pattern()

primitive_type()

-type primitive_type() :: #primitive_type{name :: atom(), location :: location()}.

program()

-type program() :: [item()].

record_expr()

-type record_expr() :: #record_expr{name :: atom(), fields :: [field_expr()], location :: location()}.

record_pattern()

-type record_pattern() ::
          #record_pattern{name :: atom(), fields :: [field_pattern()], location :: location()}.

state_def()

-type state_def() :: #state_def{name :: atom(), transitions :: [transition()], location :: location()}.

transition()

-type transition() ::
          #transition{event :: expr(),
                      guard :: expr() | undefined,
                      target :: atom(),
                      action :: expr() | undefined,
                      location :: location()}.

tuple_expr()

-type tuple_expr() :: #tuple_expr{elements :: [expr()], location :: location()}.

tuple_pattern()

-type tuple_pattern() :: #tuple_pattern{elements :: [pattern()], location :: location()}.

tuple_type()

-type tuple_type() :: #tuple_type{element_types :: [type_expr()], location :: location()}.

type_def()

-type type_def() ::
          #type_def{name :: atom(),
                    params :: [atom()],
                    definition :: type_expr(),
                    location :: location()}.

type_expr()

-type type_expr() ::
          primitive_type() |
          dependent_type() |
          function_type() |
          union_type() |
          list_type() |
          tuple_type().

type_param()

-type type_param() ::
          #type_param{name :: atom() | undefined, value :: type_expr() | expr(), location :: location()}.

unary_op_expr()

-type unary_op_expr() :: #unary_op_expr{op :: atom(), operand :: expr(), location :: location()}.

union_type()

-type union_type() :: #union_type{types :: [type_expr()], location :: location()}.

wildcard_pattern()

-type wildcard_pattern() :: #wildcard_pattern{location :: location()}.

Functions

new_expr/3

-spec new_expr(atom(), term(), location()) -> expr().

Creates a new expression AST node with location information.

Arguments

  • Type - Expression type (literal, identifier, etc.)
  • Data - Expression data appropriate for the type
  • Location - Source location information

Returns

  • expr() - Expression AST node
  • error({unknown_expr_type, Type, Data, Location}) - Unknown expression type

Supported Types

  • literal - Creates a literal expression from the value
  • identifier - Creates an identifier expression from the name

Example

Literal = cure_ast:new_expr(literal, 42, Location),
Identifier = cure_ast:new_expr(identifier, variable_name, Location).

Note

This is a limited helper function that only supports basic expression types. For complex expressions, construct the records directly.

new_fsm(Name, States, Initial, StateDefs, Location)

-spec new_fsm(atom(), [atom()], atom(), [state_def()], location()) -> fsm_def().

Creates a new FSM definition AST node.

Arguments

  • Name - FSM name (atom)
  • States - List of state names
  • Initial - Initial state name
  • StateDefs - List of state definitions with transitions
  • Location - Source location information

Returns

  • fsm_def() - FSM definition AST node

Example

States = [idle, running, stopped],
StateDefs = [IdleState, RunningState, StoppedState],
FSM = cure_ast:new_fsm(counter, States, idle, StateDefs, Location).

new_function(Name, Params, ReturnType, Constraint, Body, Location)

-spec new_function(atom(), [param()], type_expr() | undefined, expr() | undefined, expr(), location()) ->
                      function_def().

Creates a new function definition AST node.

Arguments

  • Name - Function name (atom)
  • Params - List of function parameters
  • ReturnType - Return type expression (undefined if not specified)
  • Constraint - Optional constraint expression for the function
  • Body - Function body expression
  • Location - Source location information

Returns

  • function_def() - Function definition AST node

Example

Params = [#param{name = x, type = IntType, location = Loc}],
Body = #literal_expr{value = 42, location = Loc},
Function = cure_ast:new_function(identity, Params, IntType, undefined, Body, Location).

new_module(Name, Exports, Items, Location)

-spec new_module(atom(), [export_spec()], [item()], location()) -> module_def().

Creates a new module definition AST node.

Arguments

  • Name - Module name (atom)
  • Exports - List of export specifications
  • Items - List of top-level items in the module
  • Location - Source location information

Returns

  • module_def() - Module definition AST node

Example

Exports = [#export_spec{name = hello, arity = 1, location = Loc}],
Items = [FunctionDef],
Module = cure_ast:new_module('MyModule', Exports, Items, Location).

new_type_def(Name, Params, Definition, Location)

-spec new_type_def(atom(), [atom()], type_expr(), location()) -> type_def().

Creates a new type definition AST node.

Arguments

  • Name - Type name (atom)
  • Params - List of type parameter names
  • Definition - Type expression defining the type
  • Location - Source location information

Returns

  • type_def() - Type definition AST node

Example

Params = [t],
Definition = #union_type{types = [IntType, StringType], location = Loc},
TypeDef = cure_ast:new_type_def('Maybe', Params, Definition, Location).