# AGENTS.md - Guide for Coding Agents

This document provides essential information for agentic coding agents working on the pascal-rs Pascal compiler project.

## Project Overview

pascal-rs is a production-ready optimizing Pascal compiler written in Rust. It features a modular architecture with comprehensive Pascal language support, advanced optimizations, and a modern CLI interface.

## Build Commands

```bash
# Build the project (debug)
cargo build

# Build optimized release version
cargo build --release

# Run all tests
cargo test

# Run specific test categories
cargo test --lib                    # Unit tests in src/
cargo test --test integration_test  # Integration tests in tests/
cargo test lexer                    # Lexer-specific tests
cargo test parser                   # Parser-specific tests
cargo test codegen                  # Code generation tests
cargo test threading                # Threading/concurrency tests

# Run a single test
cargo test test_name                # Replace test_name with actual test function

# Check code without building
cargo check

# Format code
cargo fmt

# Run linter
cargo clippy

# Generate documentation
cargo doc --open

# Run with specific features
cargo build --features lsp          # Build with LSP support
cargo build --features mcp          # Build with MCP server support
cargo build --features gui          # Build with macOS GUI support
cargo build --features profile      # CPU profiling (pascal run --profile)
```

## Project Structure

```
pascal-rs/
├── src/                    # Main source code
│   ├── lexer.rs           # Lexical analysis
│   ├── parser/            # Syntax parsing (modular)
│   │   ├── mod.rs
│   │   ├── expression.rs
│   │   ├── statement.rs
│   │   └── decl.rs
│   ├── ast.rs             # Abstract Syntax Tree definitions (unified)
│   ├── enhanced_codegen.rs # Code generation
│   ├── tokens.rs          # Token definitions
│   ├── enhanced_tokens.rs # Extended token definitions
│   ├── error.rs           # Error types
│   ├── loader.rs          # Module loading system
│   ├── resolver.rs        # Symbol resolution
│   ├── ppu.rs             # PPU (precompiled unit) handling
│   ├── parallel.rs        # Parallel compilation support
│   ├── simd.rs            # SIMD/vectorization support
│   ├── register_allocator.rs # Register allocation
│   ├── traits/            # Trait definitions for testability
│   │   ├── mod.rs
│   │   ├── lexer.rs
│   │   ├── parser.rs
│   │   ├── codegen.rs
│   │   └── optimizer.rs
│   └── utils/             # Utility modules
├── tests/                 # Test suites
│   ├── unit/             # Unit tests
│   └── integration/      # Integration tests
├── examples/             # Example Pascal programs
└── Cargo.toml           # Project configuration
```

## Code Style Guidelines

### General Conventions
- Follow Rust 2024 edition standards
- Use `rustfmt` for formatting (default settings)
- Use `clippy` for linting (default settings)
- Prefer `thiserror` for error types
- Use `anyhow::Result` for application-level error handling
- Comprehensive documentation with `///` for public APIs
- Module-level documentation with `//!`

### Naming Conventions
- **Types/Structs/Enums**: `PascalCase` (e.g., `Lexer`, `Parser`, `CodeGenerator`)
- **Functions/Methods**: `snake_case` (e.g., `parse_program`, `generate_code`)
- **Constants**: `SCREAMING_SNAKE_CASE` (e.g., `DEFAULT_OPTIMIZATION_LEVEL`)
- **Modules**: `snake_case` (e.g., `lexer`, `parser`, `codegen`)
- **Features**: `snake_case` (e.g., `lsp_support`, `mcp_server`)

### Imports Organization
```rust
// Standard library imports
use std::collections::HashMap;
use std::fs::File;
use std::path::PathBuf;

// External crate imports
use anyhow::Result;
use clap::{Parser, Subcommand};
use colored::Colorize;
use logos::Logos;
use serde::{Deserialize, Serialize};
use thiserror::Error;

// Internal imports
use crate::ast::{Expression, Statement, Type};
use crate::tokens::Token;
use crate::traits::LexerCapability;
```

### Error Handling
- Use `thiserror` for custom error types
- Implement proper error chaining with `source()`
- Include context information in error messages
- Use `anyhow::Result` for main application functions

Example:
```rust
#[derive(Error, Debug)]
pub enum CompileError {
    #[error("Failed to parse file {path}: {source}")]
    ParseError { 
        path: PathBuf,
        #[source]
        source: ParseError,
    },
    
    #[error("Code generation failed: {0}")]
    CodegenError(String),
}
```

### Testing Guidelines
- Unit tests in `tests/unit/` directory
- Integration tests in `tests/integration/` directory
- Test modules follow same structure as source
- Use descriptive test names: `test_feature_under_test_condition`
- Use `tempfile` for temporary files in tests
- Use `assert_cmd` for CLI testing
### Traits and Interfaces
- Define traits for major components (`LexerCapability`, `ParserCapability`, etc.)
- Use trait objects for dependency injection
- Implement mock versions for testing
- Keep traits focused and cohesive

### Module System
- Use `mod.rs` for module organization
- Re-export commonly used types at crate level
- Use visibility modifiers (`pub(crate)`, `pub(super)`) appropriately
- Keep modules focused with single responsibility

### Async/Threading
- Use `Arc<RwLock<T>>` for shared mutable state
- Use `rayon` for parallel processing
- Implement thread-safe APIs where needed
- Include threading tests with concurrent access

### Performance Considerations
- Use `Vec<T>` for dynamic arrays
- Use `Box<T>` for large recursive data structures
- Prefer references over cloning where possible
- Use `Cow<str>` for string data that might be borrowed

## Common Patterns

### Parser Implementation
```rust
impl Parser {
    pub fn new(lexer: Lexer) -> Self {
        Self { lexer, current_token: None }
    }
    
    pub fn parse_program(&mut self) -> Result<Program, ParseError> {
        self.expect_token(Token::ProgramKeyword)?;
        let name = self.parse_identifier()?;
        let block = self.parse_block()?;
        Ok(Program { name, block })
    }
}
```

### Error Conversion
```rust
impl From<LexerError> for ParseError {
    fn from(err: LexerError) -> Self {
        ParseError::LexerError(err)
    }
}
```

### CLI Command Structure
```rust
#[derive(Parser)]
struct Cli {
    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    Compile {
        input: PathBuf,
        #[arg(short, long)]
        output: Option<PathBuf>,
    },
}
```

## Feature Flags

The project uses optional features:
- `mcp`: MCP server support for AI integration
- `lsp`: Language Server Protocol support
- `gui`: macOS GUI support with Cocoa
- `debug`: Debug information generation
- `profile`: Profiling support

## Development Workflow

1. Create feature branch from main
2. Implement changes following style guidelines
3. Add comprehensive tests
4. Run `cargo fmt`, `cargo clippy`, and `cargo test`
5. Submit pull request

## Testing Single Components

To test a specific component:
```bash
# Test lexer only
cargo test lexer --lib

# Test parser with verbose output
cargo test parser --lib -- --nocapture

# Test specific function
cargo test test_function_name -- --exact

# Run tests with specific features
cargo test --features lsp
```

## Common Gotchas

- AST types are in `ast.rs` (unified module)
- Some modules are temporarily commented out in `lib.rs` due to compatibility
- Error conversion between modules needs explicit `From` implementations
- Token definitions split between basic and enhanced versions