//! SCAD parser for the Cord geometry system.
//!
//! Lexes and parses OpenSCAD source into an AST. Supports primitives,
//! transforms, boolean ops, for loops, if/else, ternary expressions,
//! and variable environments.

pub mod ast;
pub mod lexer;
pub mod parser;

use lexer::Lexer;
use parser::Parser;

#[derive(Debug)]
pub enum Error {
    Lex(lexer::LexError),
    Parse(parser::ParseError),
}

impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Error::Lex(e) => write!(f, "{e}"),
            Error::Parse(e) => write!(f, "{e}"),
        }
    }
}

impl std::error::Error for Error {}

pub fn parse(source: &str) -> Result<ast::Program, Error> {
    let mut lexer = Lexer::new(source);
    let tokens = lexer.tokenize().map_err(Error::Lex)?;
    let mut parser = Parser::new(tokens);
    parser.parse_program().map_err(Error::Parse)
}
