← Back to Documentation

FSM Implementation Integration Summary

What Was Done

Successfully connected the Cure FSM standard library (lib/std/fsm.cure) with the underlying Erlang FSM runtime implementation using type-checked FFI bindings.

Changes Made

1. Updated lib/std/fsm.cure

Replaced all placeholder/no-op implementations with proper curify FFI bindings:

Core Functions (using cure_fsm_cure_api)

Additional Functions (using cure_fsm_builtins)

Architecture

┌─────────────────────────────────────────┐
│  Cure Program (e.g., turnstile.cure)   │
│  - Defines FSM with 'fsm' syntax       │
│  - Calls Std.Fsm functions             │
└────────────────┬────────────────────────┘
                 │
                 ↓
┌─────────────────────────────────────────┐
│  lib/std/fsm.cure                       │
│  - Type-checked API                     │
│  - curify FFI bindings                  │
└────────────────┬────────────────────────┘
                 │
                 ↓
┌─────────────────────────────────────────┐
│  src/fsm/cure_fsm_cure_api.erl          │
│  - Bridges Cure and Erlang runtime     │
│  - Resolves module FSM definitions     │
│  - Handles name resolution              │
└────────────────┬────────────────────────┘
                 │
                 ↓
┌─────────────────────────────────────────┐
│  src/fsm/cure_fsm_runtime.erl           │
│  - gen_server FSM execution engine     │
│  - Event processing & transitions      │
│  - Performance & monitoring            │
└─────────────────────────────────────────┘

How It Works

1. FFI with curify

The curify keyword creates type-checked FFI bindings:

curify start_fsm(mod: Atom): Any = {cure_fsm_cure_api, start_fsm, 1}

This:
- Type-checks arguments at compile time
- Generates call to cure_fsm_cure_api:start_fsm(Mod)
- Provides runtime type safety

2. FSM Lifecycle

  1. Define FSM in Cure module:
    cure fsm TurnstilePayload{...} do Locked --> |coin| Unlocked Locked --> |push| Locked ... end

  2. Compile - Generates Module:'__fsm_definition__'/0

  3. Start FSM:
    cure let fsm_pid = start_fsm(Turnstile)

  4. Send Events:
    cure fsm_cast(fsm_pid, {:coin, []})

  5. Query State:
    cure let {ok, {state, payload}} = fsm_state(fsm_pid)

3. Type Safety

Benefits

  1. Type Safety: Cure's type system validates FSM operations
  2. Performance: Direct Erlang calls with minimal overhead
  3. Integration: Seamless bridge between Cure and Erlang
  4. Completeness: Full FSM runtime capabilities exposed
  5. Error Handling: Proper error propagation with tagged tuples

Testing

Test with the existing example:

# Assuming the Cure compiler is built
./cure examples/turnstile.cure --verbose

The turnstile example demonstrates:
- FSM definition with payload
- Starting and naming FSM instances
- Sending events (coin, push)
- Querying state
- Pattern matching on results

Next Steps

To fully utilize the FSM system:

  1. Register FSM Types: Optionally pre-register FSM types in runtime
  2. Add More Examples: Create more FSM examples (traffic light, protocol, etc.)
  3. Performance Testing: Benchmark FSM event processing
  4. Documentation: Add more inline documentation
  5. Error Messages: Improve error reporting for FSM operations

Files Modified

Files Created

Existing Erlang implementation (unchanged):
- src/fsm/cure_fsm_runtime.erl - Core FSM execution engine
- src/fsm/cure_fsm_builtins.erl - FSM utility functions
- src/fsm/cure_fsm_cure_api.erl - Cure API wrapper

Existing examples (unchanged):
- examples/turnstile.cure - Turnstile FSM example
- examples/advanced_traffic_light_demo.erl - Traffic light demo

FSM Type System Implementation Summary

Completed Tasks

1. ✅ Standard Library - Fully Compiled

All standard library modules now compile successfully:

2. ✅ FSM Type System Implementation

Implemented comprehensive FSM type system support in cure_typechecker.erl:

FSM Definition Type Checking

Record Type Support

Type Environment Management

3. ✅ Fixed Standard Library Issues

lib/std/core.cure

lib/std/result.cure

lib/std/fsm.cure

lib/std/list.cure

4. ✅ Field Access Implementation

Added find_record_field/2 helper function that:
- Looks up field types in record definitions
- Returns {ok, FieldType} or not_found
- Works with record field definitions in environment

Enhanced infer_expr for field access:
- Handles both {record_type, Name} and {record_type, Name, Fields}
- Looks up full record definition when needed
- Properly finds field types in record definitions
- Returns field type for valid field accesses

5. ✅ Type System Enhancements

Binary Operator Handling

Type Conversion

Test Results

Passing Tests

Known Issues

Architecture Improvements

Type Environment Structure

Env = #{
  'TurnstileFSM' => {fsm_type, 'TurnstileFSM', States, InitialState},
  'TurnstilePayload' => {record_type, 'TurnstilePayload', Fields},
  % Other bindings...
}

Field Access Flow

  1. Parse field access as record.field
  2. Infer record expression type
  3. Look up record definition if needed
  4. Find field type in record fields
  5. Return field type

Record Type Handling

Files Modified

Core Type System

Standard Library

Verification Commands

# Compile standard library
make clean && make all

# Run core tests
erl -pa _build/ebin -noshell -eval 'fsm_test:run(), parser_test:run(), halt().'

# Verify stdlib modules
ls _build/ebin/Std.*.beam

Summary

The FSM type system is now fully implemented with:
- ✅ Complete FSM type checking
- ✅ Record type support with field access
- ✅ All 10 standard library modules compiled
- ✅ Core tests passing
- ✅ Proper type environment management
- ✅ Field access inference working

The implementation is production-ready for FSM features demonstrated in the examples, with a fully functional standard library.