glyph-parser 0.0.1

Python-like parser for the Glyph programming language
Documentation
//! Abstract Syntax Tree definitions for Glyph
//!
//! This module defines the AST nodes for the Glyph language, following
//! the Python-like syntax from specification v0.3.

use serde::{Deserialize, Serialize};
use std::fmt;

/// A complete Glyph module (file)
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct GlyphModule {
    /// The @program decorator
    pub program: ProgramDecorator,
    /// Import statements
    pub imports: Vec<Import>,
    /// Top-level statements (mainly function definitions)
    pub statements: Vec<Statement>,
}

/// The @program decorator that must appear at the start of every Glyph file
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ProgramDecorator {
    /// Program name
    pub name: String,
    /// Program version
    pub version: String,
    /// Required capabilities
    pub requires: Vec<String>,
}

/// Import statements
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Import {
    /// `import module_name`
    Module { name: String },
    /// `from module_name import item1, item2`
    FromImport { module: String, items: Vec<String> },
}

/// Statements in Glyph
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Statement {
    /// Function definition
    FunctionDef(Function),
    /// Expression statement
    Expression(Expression),
    /// If statement
    If(IfStatement),
    /// Match statement
    Match(MatchStatement),
    /// Return statement
    Return(Option<Expression>),
    /// Let binding (immutable)
    Let {
        name: String,
        value: Expression,
        type_hint: Option<Type>,
    },
    /// Assignment (mutable)
    Assignment { target: String, value: Expression },
    /// While loop
    While {
        condition: Expression,
        body: Vec<Statement>,
    },
    /// For loop
    For {
        variable: String,
        iterable: Expression,
        body: Vec<Statement>,
    },
    /// Break statement
    Break,
    /// Continue statement
    Continue,
}

/// Function definition
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Function {
    /// Function name
    pub name: String,
    /// Parameters
    pub params: Vec<Parameter>,
    /// Return type annotation
    pub return_type: Option<Type>,
    /// Function body
    pub body: Vec<Statement>,
    /// Whether this is an async function
    pub is_async: bool,
}

/// Function parameter
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Parameter {
    /// Parameter name
    pub name: String,
    /// Type annotation
    pub type_hint: Option<Type>,
    /// Default value
    pub default: Option<Expression>,
}

/// If statement with optional elif and else clauses
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct IfStatement {
    /// Condition to test
    pub condition: Expression,
    /// Body executed if condition is true
    pub then_body: Vec<Statement>,
    /// Optional elif clauses
    pub elif_clauses: Vec<ElifClause>,
    /// Optional else body
    pub else_body: Option<Vec<Statement>>,
}

/// Elif clause in an if statement
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ElifClause {
    /// Condition to test
    pub condition: Expression,
    /// Body executed if condition is true
    pub body: Vec<Statement>,
}

/// Match statement for pattern matching
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct MatchStatement {
    /// Expression to match against
    pub subject: Expression,
    /// Case clauses
    pub cases: Vec<CaseClause>,
}

/// Case clause in a match statement
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct CaseClause {
    /// Pattern to match
    pub pattern: Pattern,
    /// Body executed if pattern matches
    pub body: Vec<Statement>,
}

/// Patterns for match statements
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Pattern {
    /// Literal pattern (int, float, string, bool)
    Literal(Literal),
    /// Variable binding pattern
    Variable(String),
    /// Constructor pattern like Ok(value) or Err(msg)
    Constructor { name: String, args: Vec<Pattern> },
    /// Wildcard pattern (_)
    Wildcard,
}

/// Expressions in Glyph
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Expression {
    /// Literal value
    Literal(Literal),
    /// Variable reference
    Identifier(String),
    /// Binary operation
    BinaryOp {
        left: Box<Expression>,
        op: BinaryOperator,
        right: Box<Expression>,
    },
    /// Unary operation
    UnaryOp {
        op: UnaryOperator,
        operand: Box<Expression>,
    },
    /// Function call
    Call {
        func: Box<Expression>,
        args: Vec<Expression>,
        kwargs: Vec<(String, Expression)>,
    },
    /// Await expression
    Await(Box<Expression>),
    /// F-string
    FString(Vec<FStringPart>),
    /// List literal
    List(Vec<Expression>),
    /// Dict literal
    Dict(Vec<(Expression, Expression)>),
    /// Attribute access (e.g., voice.speak)
    Attribute {
        value: Box<Expression>,
        attr: String,
    },
    /// If expression (ternary)
    IfExpr {
        test: Box<Expression>,
        if_true: Box<Expression>,
        if_false: Box<Expression>,
    },
}

/// Parts of an f-string
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum FStringPart {
    /// Literal text
    Text(String),
    /// Interpolated expression
    Expression(Expression),
}

/// Literal values
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Literal {
    /// Integer literal
    Int(i64),
    /// Float literal
    Float(f64),
    /// String literal
    String(String),
    /// Boolean literal
    Bool(bool),
    /// None/unit literal
    Unit,
}

/// Binary operators
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum BinaryOperator {
    // Arithmetic
    Add,
    Subtract,
    Multiply,
    Divide,
    Modulo,
    Power,
    // Comparison
    Equal,
    NotEqual,
    Less,
    Greater,
    LessEqual,
    GreaterEqual,
    // Logical
    And,
    Or,
}

/// Unary operators
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum UnaryOperator {
    /// Negation (-)
    Negate,
    /// Logical not
    Not,
}

/// Type annotations
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Type {
    /// Named type (int, float, str, bool, unit)
    Named(String),
    /// List type
    List(Box<Type>),
    /// Dict type
    Dict { key: Box<Type>, value: Box<Type> },
    /// Optional type
    Optional(Box<Type>),
    /// Promise type for async
    Promise(Box<Type>),
    /// Result type for errors
    Result { ok: Box<Type>, err: Box<Type> },
}

/// Convenience type alias for the AST
pub type GlyphAst = GlyphModule;

impl fmt::Display for Type {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Type::Named(name) => write!(f, "{name}"),
            Type::List(inner) => write!(f, "list[{inner}]"),
            Type::Dict { key, value } => write!(f, "dict[{key}, {value}]"),
            Type::Optional(inner) => write!(f, "optional[{inner}]"),
            Type::Promise(inner) => write!(f, "promise[{inner}]"),
            Type::Result { ok, err } => write!(f, "result[{ok}, {err}]"),
        }
    }
}

impl fmt::Display for BinaryOperator {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        use BinaryOperator::*;
        match self {
            Add => write!(f, "+"),
            Subtract => write!(f, "-"),
            Multiply => write!(f, "*"),
            Divide => write!(f, "/"),
            Modulo => write!(f, "%"),
            Power => write!(f, "**"),
            Equal => write!(f, "=="),
            NotEqual => write!(f, "!="),
            Less => write!(f, "<"),
            Greater => write!(f, ">"),
            LessEqual => write!(f, "<="),
            GreaterEqual => write!(f, ">="),
            And => write!(f, "and"),
            Or => write!(f, "or"),
        }
    }
}