tcss_core/
ast.rs

1//! Abstract Syntax Tree (AST) definitions for TCSS
2//!
3//! This module defines the structure of the AST that represents parsed TCSS code.
4
5use serde::{Deserialize, Serialize};
6
7/// Root AST node representing a complete TCSS document
8#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
9pub struct Program {
10    pub nodes: Vec<ASTNode>,
11}
12
13impl Program {
14    pub fn new() -> Self {
15        Self { nodes: Vec::new() }
16    }
17
18    pub fn add_node(&mut self, node: ASTNode) {
19        self.nodes.push(node);
20    }
21}
22
23impl Default for Program {
24    fn default() -> Self {
25        Self::new()
26    }
27}
28
29/// Top-level AST nodes
30#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
31pub enum ASTNode {
32    /// Function definition: @fn name(params): body
33    Function {
34        name: String,
35        params: Vec<String>,
36        body: Vec<Statement>,
37    },
38    
39    /// Variable declaration: @var name: value
40    Variable {
41        name: String,
42        value: Expr,
43    },
44    
45    /// Import statement: @import 'path'
46    Import {
47        path: String,
48    },
49    
50    /// CSS rule: selector { properties }
51    CSSRule {
52        selector: String,
53        properties: Vec<Property>,
54    },
55}
56
57/// Statements within function bodies
58#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
59pub enum Statement {
60    /// Return statement: return expr
61    Return(Expr),
62    
63    /// Variable assignment within function
64    Assignment {
65        name: String,
66        value: Expr,
67    },
68    
69    /// Expression statement
70    Expression(Expr),
71}
72
73/// CSS property: name: value
74#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
75pub struct Property {
76    pub name: String,
77    pub value: Expr,
78}
79
80impl Property {
81    pub fn new(name: String, value: Expr) -> Self {
82        Self { name, value }
83    }
84}
85
86/// Expressions that can be evaluated
87#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
88pub enum Expr {
89    /// String literal: "hello"
90    Literal(String),
91    
92    /// Number: 42, 3.14
93    Number(f64),
94    
95    /// Number with unit: 16px, 2em, 50%
96    Unit {
97        value: f64,
98        unit: String,
99    },
100    
101    /// Color: #fff, #3498db
102    Color(String),
103    
104    /// Variable reference: primary-color
105    Variable(String),
106    
107    /// Binary operation: left op right
108    Binary {
109        op: BinaryOp,
110        left: Box<Expr>,
111        right: Box<Expr>,
112    },
113    
114    /// Function call: spacing(2)
115    FunctionCall {
116        name: String,
117        args: Vec<Expr>,
118    },
119    
120    /// Object/Map: { key: value, ... }
121    Object(Vec<(String, Expr)>),
122    
123    /// Array: [expr, expr, ...]
124    Array(Vec<Expr>),
125}
126
127/// Binary operators
128#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
129pub enum BinaryOp {
130    // Arithmetic
131    Add,      // +
132    Subtract, // -
133    Multiply, // *
134    Divide,   // /
135    Modulo,   // %
136    
137    // Comparison
138    Equal,        // ==
139    NotEqual,     // !=
140    Less,         // <
141    Greater,      // >
142    LessEqual,    // <=
143    GreaterEqual, // >=
144}
145
146impl BinaryOp {
147    /// Get the precedence of the operator (higher = binds tighter)
148    pub fn precedence(&self) -> u8 {
149        match self {
150            BinaryOp::Multiply | BinaryOp::Divide | BinaryOp::Modulo => 2,
151            BinaryOp::Add | BinaryOp::Subtract => 1,
152            BinaryOp::Equal | BinaryOp::NotEqual 
153            | BinaryOp::Less | BinaryOp::Greater 
154            | BinaryOp::LessEqual | BinaryOp::GreaterEqual => 0,
155        }
156    }
157}
158