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}