openscript 0.1.0

High-performance AI-powered scripting language runtime
Documentation
//! Abstract Syntax Tree definitions for OpenScript
//!
//! This module defines the AST nodes that represent parsed OpenScript code.
//! The AST is designed for efficient execution and easy manipulation.

use crate::value::Value;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

/// A complete OpenScript program
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Program {
    /// The sequence of statements in the program
    pub statements: Vec<Statement>,
}

/// Top-level statements in OpenScript
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Statement {
    /// Variable declaration: `let x = 5` or `const y = "hello"`
    VarDeclaration {
        /// The name of the variable
        name: String,
        /// The initial value of the variable
        value: Expression,
        /// Whether the variable is constant
        is_const: bool,
    },
    
    /// Assignment: `x = 10` or `x += 5`
    Assignment {
        /// The target of the assignment
        target: AssignmentTarget,
        /// The assignment operator
        operator: AssignmentOperator,
        /// The value to assign
        value: Expression,
    },
    
    /// Expression statement: `print("hello")`
    Expression(Expression),
    
    /// If statement with optional else
    If {
        /// The condition to evaluate
        condition: Expression,
        /// The block to execute if the condition is true
        then_branch: Vec<Statement>,
        /// The optional block to execute if the condition is false
        else_branch: Option<Vec<Statement>>,
    },
    
    /// While loop
    While {
        /// The condition to evaluate
        condition: Expression,
        /// The body of the loop
        body: Vec<Statement>,
    },
    
    /// For loop: `for item in collection`
    For {
        /// The name of the loop variable
        variable: String,
        /// The expression to iterate over
        iterable: Expression,
        /// The body of the loop
        body: Vec<Statement>,
    },
    
    /// Function definition
    Function {
        /// The name of the function
        name: String,
        /// The parameters of the function
        parameters: Vec<Parameter>,
        /// The body of the function
        body: Vec<Statement>,
        /// The optional return type of the function
        return_type: Option<Type>,
    },
    
    /// Return statement
    Return(Option<Expression>),
    
    /// Break statement
    Break,
    
    /// Continue statement
    Continue,
    
    /// Block statement
    Block(Vec<Statement>),
}

/// Assignment targets
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum AssignmentTarget {
    /// Simple variable: `x`
    Variable(String),
    /// Property access: `obj.prop`
    Property { 
        /// The object to access
        object: Expression, 
        /// The name of the property
        property: String 
    },
    /// Index access: `arr[0]`
    Index { 
        /// The object to index into
        object: Expression, 
        /// The index expression
        index: Expression 
    },
}

/// Assignment operators
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum AssignmentOperator {
    /// Direct assignment `=`
    Assign,
    /// Addition assignment `+=`
    PlusAssign,
    /// Subtraction assignment `-=`
    MinusAssign,
    /// Multiplication assignment `*=`
    MultiplyAssign,
    /// Division assignment `/=`
    DivideAssign,
    /// Modulo assignment `%=`
    ModuloAssign,
}

/// Expressions in OpenScript
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Expression {
    /// Literal values
    Literal(Value),
    
    /// Variable reference
    Variable(String),
    
    /// Binary operations: `a + b`, `x == y`
    Binary {
        /// The left-hand side of the operation
        left: Box<Expression>,
        /// The binary operator
        operator: BinaryOperator,
        /// The right-hand side of the operation
        right: Box<Expression>,
    },
    
    /// Unary operations: `-x`, `not y`
    Unary {
        /// The unary operator
        operator: UnaryOperator,
        /// The operand
        operand: Box<Expression>,
    },
    
    /// Function call: `print("hello")`
    Call {
        /// The expression being called
        callee: Box<Expression>,
        /// The arguments to the call
        arguments: Vec<Expression>,
    },
    
    /// Property access: `obj.prop`
    Property {
        /// The object to access
        object: Box<Expression>,
        /// The name of the property
        property: String,
    },
    
    /// Index access: `arr[0]`
    Index {
        /// The object to index into
        object: Box<Expression>,
        /// The index expression
        index: Box<Expression>,
    },
    
    /// Array literal: `[1, 2, 3]`
    Array(Vec<Expression>),
    
    /// Object literal: `{name: "John", age: 30}`
    Object(HashMap<String, Expression>),
    
    /// String interpolation: `"Hello ${name}"`
    StringInterpolation(Vec<StringPart>),
    
    /// Lambda function: `|x| x * 2`
    Lambda {
        /// The parameters of the lambda
        parameters: Vec<Parameter>,
        /// The body of the lambda
        body: Box<Expression>,
    },
    
    /// Conditional expression: `condition ? true_expr : false_expr`
    Conditional {
        /// The condition to evaluate
        condition: Box<Expression>,
        /// The expression to evaluate if the condition is true
        true_expr: Box<Expression>,
        /// The expression to evaluate if the condition is false
        false_expr: Box<Expression>,
    },
}

/// Parts of an interpolated string
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum StringPart {
    /// Literal string part
    Literal(String),
    /// Expression to be interpolated
    Expression(Expression),
}

/// Binary operators
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum BinaryOperator {
    /// Addition `+`
    Add,
    /// Subtraction `-`
    Subtract,
    /// Multiplication `*`
    Multiply,
    /// Division `/`
    Divide,
    /// Modulo `%`
    Modulo,
    /// Power `**`
    Power,

    /// Equality `==`
    Equal,
    /// Inequality `!=`
    NotEqual,
    /// Less than `<`
    Less,
    /// Less than or equal `<=`
    LessEqual,
    /// Greater than `>`
    Greater,
    /// Greater than or equal `>=`
    GreaterEqual,

    /// Logical AND `&&`
    And,
    /// Logical OR `||`
    Or,

    /// String concatenation `+`
    Concat,

    /// Bitwise AND `&`
    BitwiseAnd,
    /// Bitwise OR `|`
    BitwiseOr,
    /// Bitwise XOR `^`
    BitwiseXor,
    /// Left shift `<<`
    LeftShift,
    /// Right shift `>>`
    RightShift,
}

/// Unary operators
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum UnaryOperator {
    /// Negation: `-x`
    Minus,
    /// Logical not: `not x`
    Not,
    /// Bitwise not: `~x`
    BitwiseNot,
}

/// Function parameter
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Parameter {
    /// The name of the parameter
    pub name: String,
    /// The optional type of the parameter
    pub param_type: Option<Type>,
    /// The optional default value of the parameter
    pub default_value: Option<Expression>,
}

/// Type annotations
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Type {
    /// String type
    String,
    /// Number type
    Number,
    /// Boolean type
    Boolean,
    /// Array type
    Array(Box<Type>),
    /// Object type
    Object(HashMap<String, Type>),
    /// Function type
    Function {
        /// Parameter types
        parameters: Vec<Type>,
        /// Return type
        return_type: Box<Type>,
    },
    /// Any type
    Any,
    /// Null type
    Null,
}

impl Statement {
    /// Check if this statement can affect control flow
    pub fn is_control_flow(&self) -> bool {
        matches!(
            self,
            Statement::If { .. }
                | Statement::While { .. }
                | Statement::For { .. }
                | Statement::Return(_)
                | Statement::Break
                | Statement::Continue
        )
    }

    /// Check if this is a declaration statement
    pub fn is_declaration(&self) -> bool {
        matches!(
            self,
            Statement::VarDeclaration { .. } | Statement::Function { .. }
        )
    }
}

impl Expression {
    /// Check if this expression is a literal value
    pub fn is_literal(&self) -> bool {
        matches!(self, Expression::Literal(_))
    }

    /// Check if this expression can be evaluated at compile time
    pub fn is_constant(&self) -> bool {
        match self {
            Expression::Literal(_) => true,
            Expression::Array(elements) => elements.iter().all(|e| e.is_constant()),
            Expression::Object(fields) => fields.values().all(|e| e.is_constant()),
            Expression::Binary { left, right, .. } => {
                left.is_constant() && right.is_constant()
            }
            Expression::Unary { operand, .. } => operand.is_constant(),
            _ => false,
        }
    }

    /// Get the precedence of this expression for parsing
    pub fn precedence(&self) -> u8 {
        match self {
            Expression::Binary { operator, .. } => operator.precedence(),
            Expression::Unary { .. } => 7,
            Expression::Call { .. } | Expression::Property { .. } | Expression::Index { .. } => 8,
            _ => 0,
        }
    }
}

impl BinaryOperator {
    /// Get operator precedence for parsing
    pub fn precedence(&self) -> u8 {
        match self {
            BinaryOperator::Or => 1,
            BinaryOperator::And => 2,
            BinaryOperator::Equal | BinaryOperator::NotEqual => 3,
            BinaryOperator::Less
            | BinaryOperator::LessEqual
            | BinaryOperator::Greater
            | BinaryOperator::GreaterEqual => 4,
            BinaryOperator::BitwiseOr => 5,
            BinaryOperator::BitwiseXor => 6,
            BinaryOperator::BitwiseAnd => 7,
            BinaryOperator::LeftShift | BinaryOperator::RightShift => 8,
            BinaryOperator::Add | BinaryOperator::Subtract | BinaryOperator::Concat => 9,
            BinaryOperator::Multiply | BinaryOperator::Divide | BinaryOperator::Modulo => 10,
            BinaryOperator::Power => 11,
        }
    }
}