ovsm/parser/
ast.rs

1use serde::{Deserialize, Serialize};
2use std::fmt;
3
4/// Complete OVSM program
5#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
6pub struct Program {
7    /// Program metadata from header comments
8    pub metadata: ProgramMetadata,
9    /// Top-level statements in the program
10    pub statements: Vec<Statement>,
11}
12
13/// Program metadata (from header comments)
14#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
15pub struct ProgramMetadata {
16    /// Estimated execution time
17    pub time_estimate: Option<String>,
18    /// Estimated cost
19    pub cost_estimate: Option<String>,
20    /// Confidence level (0-100)
21    pub confidence: Option<u8>,
22    /// List of available tools
23    pub available_tools: Vec<String>,
24}
25
26/// Statements
27#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
28pub enum Statement {
29    /// Variable assignment: $x = expr
30    Assignment {
31        /// Name of the variable to assign to
32        name: String,
33        /// Expression value to assign
34        value: Expression,
35    },
36
37    /// Constant definition: CONST NAME = value
38    ConstantDef {
39        /// Name of the constant (uppercase)
40        name: String,
41        /// Constant value expression
42        value: Expression,
43    },
44
45    /// If statement
46    If {
47        /// Condition expression to evaluate
48        condition: Expression,
49        /// Statements to execute if condition is true
50        then_branch: Vec<Statement>,
51        /// Optional statements to execute if condition is false
52        else_branch: Option<Vec<Statement>>,
53    },
54
55    /// While loop
56    While {
57        /// Loop condition expression
58        condition: Expression,
59        /// Statements to execute in loop body
60        body: Vec<Statement>,
61    },
62
63    /// For loop: FOR $item IN collection
64    For {
65        /// Loop variable name
66        variable: String,
67        /// Expression to iterate over
68        iterable: Expression,
69        /// Statements to execute in loop body
70        body: Vec<Statement>,
71    },
72
73    /// Break statement
74    Break {
75        /// Optional condition for conditional break
76        condition: Option<Expression>,
77    },
78
79    /// Continue statement
80    Continue {
81        /// Optional condition for conditional continue
82        condition: Option<Expression>,
83    },
84
85    /// Return statement
86    Return {
87        /// Optional value to return
88        value: Option<Expression>,
89    },
90
91    /// Expression statement
92    Expression(Expression),
93
94    /// Try-catch block
95    Try {
96        /// Statements to execute in try block
97        body: Vec<Statement>,
98        /// Catch clauses to handle errors
99        catch_clauses: Vec<CatchClause>,
100    },
101
102    /// Parallel execution block
103    Parallel {
104        /// Tasks to execute in parallel
105        tasks: Vec<Statement>,
106    },
107
108    /// Wait strategy
109    WaitStrategy(WaitStrategy),
110
111    /// Decision point
112    Decision {
113        /// Description of the decision being made
114        description: String,
115        /// Branches representing different decision paths
116        branches: Vec<DecisionBranch>,
117    },
118
119    /// Guard clause
120    Guard {
121        /// Guard condition expression
122        condition: Expression,
123        /// Statements to execute if guard fails
124        else_body: Vec<Statement>,
125    },
126}
127
128/// Expressions
129#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
130pub enum Expression {
131    // Literals
132    /// Integer literal expression
133    IntLiteral(i64),
134    /// Floating-point literal expression
135    FloatLiteral(f64),
136    /// String literal expression
137    StringLiteral(String),
138    /// Boolean literal expression
139    BoolLiteral(bool),
140    /// Null literal expression
141    NullLiteral,
142
143    // Collections
144    /// Array literal expression
145    ArrayLiteral(Vec<Expression>),
146    /// Object literal expression with key-value pairs
147    ObjectLiteral(Vec<(String, Expression)>),
148    /// Range expression [start..end]
149    Range {
150        /// Start expression of the range
151        start: Box<Expression>,
152        /// End expression of the range (exclusive)
153        end: Box<Expression>,
154    },
155
156    // Variables
157    /// Variable reference expression
158    Variable(String),
159
160    // Binary operations
161    /// Binary operation expression
162    Binary {
163        /// Binary operator to apply
164        op: BinaryOp,
165        /// Left operand expression
166        left: Box<Expression>,
167        /// Right operand expression
168        right: Box<Expression>,
169    },
170
171    // Unary operations
172    /// Unary operation expression
173    Unary {
174        /// Unary operator to apply
175        op: UnaryOp,
176        /// Operand expression
177        operand: Box<Expression>,
178    },
179
180    // Ternary operator: condition ? then : else
181    /// Ternary conditional expression
182    Ternary {
183        /// Condition expression to evaluate
184        condition: Box<Expression>,
185        /// Expression to evaluate if condition is true
186        then_expr: Box<Expression>,
187        /// Expression to evaluate if condition is false
188        else_expr: Box<Expression>,
189    },
190
191    /// Tool or function call
192    ToolCall {
193        /// Name of the tool/function to call
194        name: String,
195        /// Arguments to pass to the tool
196        args: Vec<Argument>,
197    },
198
199    /// Lambda function expression (x => x * 2)
200    Lambda {
201        /// Parameter names for the lambda
202        params: Vec<String>,
203        /// Body expression of the lambda
204        body: Box<Expression>,
205    },
206
207    /// Field access expression (object.field)
208    FieldAccess {
209        /// Object being accessed
210        object: Box<Expression>,
211        /// Name of the field to access
212        field: String,
213    },
214
215    /// Index access expression (array\[index\])
216    IndexAccess {
217        /// Array or collection being indexed
218        array: Box<Expression>,
219        /// Index expression
220        index: Box<Expression>,
221    },
222
223    /// Grouping expression with parentheses (expr)
224    Grouping(Box<Expression>),
225}
226
227/// Binary operators
228#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
229pub enum BinaryOp {
230    // Arithmetic
231    /// Addition operator (+)
232    Add,
233    /// Subtraction operator (-)
234    Sub,
235    /// Multiplication operator (*)
236    Mul,
237    /// Division operator (/)
238    Div,
239    /// Modulo operator (%)
240    Mod,
241    /// Power operator (**)
242    Pow,
243
244    // Comparison
245    /// Equality operator (==)
246    Eq,
247    /// Inequality operator (!=)
248    NotEq,
249    /// Less than operator (<)
250    Lt,
251    /// Greater than operator (>)
252    Gt,
253    /// Less than or equal operator (<=)
254    LtEq,
255    /// Greater than or equal operator (>=)
256    GtEq,
257
258    // Logical
259    /// Logical AND operator
260    And,
261    /// Logical OR operator
262    Or,
263
264    // Special
265    /// Membership test operator (IN)
266    In,
267}
268
269/// Unary operators
270#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
271pub enum UnaryOp {
272    /// Negation operator (-x)
273    Neg,
274    /// Logical NOT operator (!x)
275    Not,
276}
277
278/// Function/tool call argument
279#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
280pub struct Argument {
281    /// Argument name (None for positional, Some for named)
282    pub name: Option<String>,
283    /// Argument value expression
284    pub value: Expression,
285}
286
287impl Argument {
288    /// Creates a positional argument
289    pub fn positional(value: Expression) -> Self {
290        Argument { name: None, value }
291    }
292
293    /// Creates a named argument
294    pub fn named(name: String, value: Expression) -> Self {
295        Argument {
296            name: Some(name),
297            value,
298        }
299    }
300}
301
302/// Decision branch
303#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
304pub struct DecisionBranch {
305    /// Branch name
306    pub name: String,
307    /// Branch condition expression
308    pub condition: Expression,
309    /// Statements to execute if condition is true
310    pub body: Vec<Statement>,
311}
312
313/// Catch clause
314#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
315pub struct CatchClause {
316    /// Type of error to catch (None catches all)
317    pub error_type: Option<ErrorType>,
318    /// Statements to execute when error is caught
319    pub body: Vec<Statement>,
320}
321
322/// Error types for catch
323#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
324pub enum ErrorType {
325    /// Fatal error that cannot be recovered
326    Fatal,
327    /// Recoverable error
328    Recoverable,
329    /// Warning level error
330    Warning,
331}
332
333/// Wait strategies for parallel execution
334#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
335pub enum WaitStrategy {
336    /// Wait for all tasks to complete
337    WaitAll,
338    /// Wait for any task to complete
339    WaitAny,
340    /// Race tasks against each other
341    Race,
342}
343
344/// Operator precedence levels
345#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
346pub enum Precedence {
347    /// No precedence
348    None,
349    /// Assignment operators (=)
350    Assignment,
351    /// Logical OR operator
352    Or,
353    /// Logical AND operator
354    And,
355    /// Equality operators (==, !=)
356    Equality,
357    /// Comparison operators (<, >, <=, >=)
358    Comparison,
359    /// Addition and subtraction (+, -)
360    Term,
361    /// Multiplication, division, modulo (*, /, %)
362    Factor,
363    /// Unary operators (!, -)
364    Unary,
365    /// Power operator (**)
366    Power,
367    /// Call operators (., (), [])
368    Call,
369    /// Primary expressions (literals, identifiers)
370    Primary,
371}
372
373impl BinaryOp {
374    /// Returns the precedence level of this binary operator
375    pub fn precedence(&self) -> Precedence {
376        match self {
377            BinaryOp::Or => Precedence::Or,
378            BinaryOp::And => Precedence::And,
379            BinaryOp::Eq | BinaryOp::NotEq => Precedence::Equality,
380            BinaryOp::Lt | BinaryOp::Gt | BinaryOp::LtEq | BinaryOp::GtEq => Precedence::Comparison,
381            BinaryOp::Add | BinaryOp::Sub => Precedence::Term,
382            BinaryOp::Mul | BinaryOp::Div | BinaryOp::Mod => Precedence::Factor,
383            BinaryOp::Pow => Precedence::Power,
384            BinaryOp::In => Precedence::Comparison,
385        }
386    }
387}
388
389impl fmt::Display for BinaryOp {
390    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
391        match self {
392            BinaryOp::Add => write!(f, "+"),
393            BinaryOp::Sub => write!(f, "-"),
394            BinaryOp::Mul => write!(f, "*"),
395            BinaryOp::Div => write!(f, "/"),
396            BinaryOp::Mod => write!(f, "%"),
397            BinaryOp::Pow => write!(f, "**"),
398            BinaryOp::Eq => write!(f, "=="),
399            BinaryOp::NotEq => write!(f, "!="),
400            BinaryOp::Lt => write!(f, "<"),
401            BinaryOp::Gt => write!(f, ">"),
402            BinaryOp::LtEq => write!(f, "<="),
403            BinaryOp::GtEq => write!(f, ">="),
404            BinaryOp::And => write!(f, "AND"),
405            BinaryOp::Or => write!(f, "OR"),
406            BinaryOp::In => write!(f, "IN"),
407        }
408    }
409}
410
411impl fmt::Display for UnaryOp {
412    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
413        match self {
414            UnaryOp::Neg => write!(f, "-"),
415            UnaryOp::Not => write!(f, "!"),
416        }
417    }
418}
419
420#[cfg(test)]
421mod tests {
422    use super::*;
423
424    #[test]
425    fn test_precedence_ordering() {
426        assert!(BinaryOp::Add.precedence() > BinaryOp::And.precedence());
427        assert!(BinaryOp::Mul.precedence() > BinaryOp::Add.precedence());
428        assert!(BinaryOp::Pow.precedence() > BinaryOp::Mul.precedence());
429    }
430
431    #[test]
432    fn test_argument_construction() {
433        let pos_arg = Argument::positional(Expression::IntLiteral(42));
434        assert!(pos_arg.name.is_none());
435        assert_eq!(pos_arg.value, Expression::IntLiteral(42));
436
437        let named_arg = Argument::named("x".to_string(), Expression::IntLiteral(42));
438        assert_eq!(named_arg.name, Some("x".to_string()));
439    }
440}