Skip to main content

regorus/
ast.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use crate::lexer::*;
5use crate::value::Value;
6use crate::*;
7
8use core::{cmp, fmt, ops::Deref};
9
10#[derive(Debug, PartialEq, Eq, Clone)]
11#[cfg_attr(feature = "ast", derive(serde::Serialize))]
12pub enum BinOp {
13    Intersection,
14    Union,
15}
16
17#[derive(Debug, PartialEq, Eq, Clone)]
18#[cfg_attr(feature = "ast", derive(serde::Serialize))]
19pub enum ArithOp {
20    Add,
21    Sub,
22    Mul,
23    Div,
24    Mod,
25}
26
27#[derive(Debug, PartialEq, Eq, Clone)]
28#[cfg_attr(feature = "ast", derive(serde::Serialize))]
29pub enum BoolOp {
30    Lt,
31    Le,
32    Eq,
33    Ge,
34    Gt,
35    Ne,
36}
37
38#[derive(Debug, PartialEq, Eq, Clone)]
39#[cfg_attr(feature = "ast", derive(serde::Serialize))]
40pub enum AssignOp {
41    Eq,
42    ColEq,
43}
44
45#[cfg_attr(feature = "ast", derive(serde::Serialize))]
46pub struct NodeRef<T> {
47    #[cfg_attr(feature = "ast", serde(flatten))]
48    r: Rc<T>,
49}
50
51impl<T> Clone for NodeRef<T> {
52    fn clone(&self) -> Self {
53        Self { r: self.r.clone() }
54    }
55}
56
57impl<T: fmt::Debug> fmt::Debug for NodeRef<T> {
58    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
59        self.r.as_ref().fmt(f)
60    }
61}
62
63impl<T> cmp::PartialEq for NodeRef<T> {
64    fn eq(&self, other: &Self) -> bool {
65        Rc::as_ptr(&self.r).eq(&Rc::as_ptr(&other.r))
66    }
67}
68
69impl<T> cmp::Eq for NodeRef<T> {}
70
71impl<T> cmp::Ord for NodeRef<T> {
72    fn cmp(&self, other: &Self) -> cmp::Ordering {
73        Rc::as_ptr(&self.r).cmp(&Rc::as_ptr(&other.r))
74    }
75}
76
77impl<T> cmp::PartialOrd for NodeRef<T> {
78    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
79        Some(self.cmp(other))
80    }
81}
82
83impl<T> Deref for NodeRef<T> {
84    type Target = T;
85
86    fn deref(&self) -> &Self::Target {
87        &self.r
88    }
89}
90
91impl<T> AsRef<T> for NodeRef<T> {
92    fn as_ref(&self) -> &T {
93        self.deref()
94    }
95}
96
97impl<T> NodeRef<T> {
98    pub fn new(t: T) -> Self {
99        Self { r: Rc::new(t) }
100    }
101}
102
103pub type Ref<T> = NodeRef<T>;
104
105#[derive(Debug)]
106#[cfg_attr(feature = "ast", derive(serde::Serialize))]
107pub enum Expr {
108    // Simple items that only have a span as content.
109    String {
110        span: Span,
111        value: Value,
112        eidx: u32,
113    },
114
115    RawString {
116        span: Span,
117        value: Value,
118        eidx: u32,
119    },
120
121    Number {
122        span: Span,
123        value: Value,
124        eidx: u32,
125    },
126
127    Bool {
128        span: Span,
129        value: Value,
130        eidx: u32,
131    },
132
133    Null {
134        span: Span,
135        value: Value,
136        eidx: u32,
137    },
138
139    Var {
140        span: Span,
141        value: Value,
142        eidx: u32,
143    },
144
145    // array
146    Array {
147        span: Span,
148        items: Vec<Ref<Expr>>,
149        eidx: u32,
150    },
151
152    // set
153    Set {
154        span: Span,
155        items: Vec<Ref<Expr>>,
156        eidx: u32,
157    },
158
159    Object {
160        span: Span,
161        fields: Vec<(Span, Ref<Expr>, Ref<Expr>)>,
162        eidx: u32,
163    },
164
165    // Comprehensions
166    ArrayCompr {
167        span: Span,
168        term: Ref<Expr>,
169        query: Ref<Query>,
170        eidx: u32,
171    },
172
173    SetCompr {
174        span: Span,
175        term: Ref<Expr>,
176        query: Ref<Query>,
177        eidx: u32,
178    },
179
180    ObjectCompr {
181        span: Span,
182        key: Ref<Expr>,
183        value: Ref<Expr>,
184        query: Ref<Query>,
185        eidx: u32,
186    },
187
188    Call {
189        span: Span,
190        fcn: Ref<Expr>,
191        params: Vec<Ref<Expr>>,
192        eidx: u32,
193    },
194
195    UnaryExpr {
196        span: Span,
197        expr: Ref<Expr>,
198        eidx: u32,
199    },
200
201    // ref
202    RefDot {
203        span: Span,
204        refr: Ref<Expr>,
205        field: (Span, Value),
206        eidx: u32,
207    },
208
209    RefBrack {
210        span: Span,
211        refr: Ref<Expr>,
212        index: Ref<Expr>,
213        eidx: u32,
214    },
215
216    // Infix expressions
217    BinExpr {
218        span: Span,
219        op: BinOp,
220        lhs: Ref<Expr>,
221        rhs: Ref<Expr>,
222        eidx: u32,
223    },
224
225    BoolExpr {
226        span: Span,
227        op: BoolOp,
228        lhs: Ref<Expr>,
229        rhs: Ref<Expr>,
230        eidx: u32,
231    },
232
233    ArithExpr {
234        span: Span,
235        op: ArithOp,
236        lhs: Ref<Expr>,
237        rhs: Ref<Expr>,
238        eidx: u32,
239    },
240
241    AssignExpr {
242        span: Span,
243        op: AssignOp,
244        lhs: Ref<Expr>,
245        rhs: Ref<Expr>,
246        eidx: u32,
247    },
248
249    Membership {
250        span: Span,
251        key: Option<Ref<Expr>>,
252        value: Ref<Expr>,
253        collection: Ref<Expr>,
254        eidx: u32,
255    },
256
257    #[cfg(feature = "rego-extensions")]
258    OrExpr {
259        span: Span,
260        lhs: Ref<Expr>,
261        rhs: Ref<Expr>,
262        eidx: u32,
263    },
264}
265
266impl Expr {
267    pub const fn span(&self) -> &Span {
268        match *self {
269            Self::String { ref span, .. }
270            | Self::RawString { ref span, .. }
271            | Self::Number { ref span, .. }
272            | Self::Bool { ref span, .. }
273            | Self::Null { ref span, .. }
274            | Self::Var { ref span, .. }
275            | Self::Array { ref span, .. }
276            | Self::Set { ref span, .. }
277            | Self::Object { ref span, .. }
278            | Self::ArrayCompr { ref span, .. }
279            | Self::SetCompr { ref span, .. }
280            | Self::ObjectCompr { ref span, .. }
281            | Self::Call { ref span, .. }
282            | Self::UnaryExpr { ref span, .. }
283            | Self::RefDot { ref span, .. }
284            | Self::RefBrack { ref span, .. }
285            | Self::BinExpr { ref span, .. }
286            | Self::BoolExpr { ref span, .. }
287            | Self::ArithExpr { ref span, .. }
288            | Self::AssignExpr { ref span, .. }
289            | Self::Membership { ref span, .. } => span,
290            #[cfg(feature = "rego-extensions")]
291            Self::OrExpr { ref span, .. } => span,
292        }
293    }
294
295    pub const fn eidx(&self) -> u32 {
296        match *self {
297            Self::String { eidx, .. }
298            | Self::RawString { eidx, .. }
299            | Self::Number { eidx, .. }
300            | Self::Bool { eidx, .. }
301            | Self::Null { eidx, .. }
302            | Self::Var { eidx, .. }
303            | Self::Array { eidx, .. }
304            | Self::Set { eidx, .. }
305            | Self::Object { eidx, .. }
306            | Self::ArrayCompr { eidx, .. }
307            | Self::SetCompr { eidx, .. }
308            | Self::ObjectCompr { eidx, .. }
309            | Self::Call { eidx, .. }
310            | Self::UnaryExpr { eidx, .. }
311            | Self::RefDot { eidx, .. }
312            | Self::RefBrack { eidx, .. }
313            | Self::BinExpr { eidx, .. }
314            | Self::BoolExpr { eidx, .. }
315            | Self::ArithExpr { eidx, .. }
316            | Self::AssignExpr { eidx, .. }
317            | Self::Membership { eidx, .. } => eidx,
318            #[cfg(feature = "rego-extensions")]
319            Self::OrExpr { eidx, .. } => eidx,
320        }
321    }
322}
323
324#[derive(Debug)]
325#[cfg_attr(feature = "ast", derive(serde::Serialize))]
326pub enum Literal {
327    SomeVars {
328        span: Span,
329        vars: Vec<Span>,
330    },
331    SomeIn {
332        span: Span,
333        key: Option<Ref<Expr>>,
334        value: Ref<Expr>,
335        collection: Ref<Expr>,
336    },
337    Expr {
338        span: Span,
339        expr: Ref<Expr>,
340    },
341    NotExpr {
342        span: Span,
343        expr: Ref<Expr>,
344    },
345    Every {
346        span: Span,
347        key: Option<Span>,
348        value: Span,
349        domain: Ref<Expr>,
350        query: Ref<Query>,
351    },
352}
353
354#[derive(Debug)]
355#[cfg_attr(feature = "ast", derive(serde::Serialize))]
356pub struct WithModifier {
357    pub span: Span,
358    pub refr: Ref<Expr>,
359    pub r#as: Ref<Expr>,
360}
361
362#[derive(Debug)]
363#[cfg_attr(feature = "ast", derive(serde::Serialize))]
364pub struct LiteralStmt {
365    pub span: Span,
366    pub literal: Literal,
367    #[cfg_attr(feature = "ast", serde(skip_serializing_if = "Vec::is_empty"))]
368    pub with_mods: Vec<WithModifier>,
369    pub sidx: u32,
370}
371
372#[derive(Debug)]
373#[cfg_attr(feature = "ast", derive(serde::Serialize))]
374pub struct Query {
375    pub span: Span,
376    pub stmts: Vec<LiteralStmt>,
377    pub qidx: u32,
378}
379
380#[derive(Debug)]
381#[cfg_attr(feature = "ast", derive(serde::Serialize))]
382pub struct RuleAssign {
383    pub span: Span,
384    pub op: AssignOp,
385    pub value: Ref<Expr>,
386}
387
388#[derive(Debug)]
389#[cfg_attr(feature = "ast", derive(serde::Serialize))]
390pub struct RuleBody {
391    pub span: Span,
392    pub assign: Option<RuleAssign>,
393    pub query: Ref<Query>,
394}
395
396#[derive(Debug)]
397#[cfg_attr(feature = "ast", derive(serde::Serialize))]
398pub enum RuleHead {
399    Compr {
400        span: Span,
401        refr: Ref<Expr>,
402        assign: Option<RuleAssign>,
403    },
404    Set {
405        span: Span,
406        refr: Ref<Expr>,
407        key: Option<Ref<Expr>>,
408    },
409    Func {
410        span: Span,
411        refr: Ref<Expr>,
412        args: Vec<Ref<Expr>>,
413        assign: Option<RuleAssign>,
414    },
415}
416
417#[derive(Debug)]
418#[cfg_attr(feature = "ast", derive(serde::Serialize))]
419pub enum Rule {
420    Spec {
421        span: Span,
422        head: RuleHead,
423        bodies: Vec<RuleBody>,
424    },
425    Default {
426        span: Span,
427        refr: Ref<Expr>,
428        args: Vec<Ref<Expr>>,
429        op: AssignOp,
430        value: Ref<Expr>,
431    },
432}
433
434impl Rule {
435    pub const fn span(&self) -> &Span {
436        match *self {
437            Self::Spec { ref span, .. } | Self::Default { ref span, .. } => span,
438        }
439    }
440}
441
442#[derive(Debug)]
443#[cfg_attr(feature = "ast", derive(serde::Serialize))]
444pub struct Package {
445    pub span: Span,
446    pub refr: Ref<Expr>,
447}
448
449#[derive(Debug)]
450#[cfg_attr(feature = "ast", derive(serde::Serialize))]
451pub struct Import {
452    pub span: Span,
453    pub refr: Ref<Expr>,
454    #[cfg_attr(feature = "ast", serde(skip_serializing_if = "Option::is_none"))]
455    pub r#as: Option<Span>,
456}
457
458#[derive(Debug)]
459#[cfg_attr(feature = "ast", derive(serde::Serialize))]
460pub struct Module {
461    pub package: Package,
462    pub imports: Vec<Import>,
463    #[cfg_attr(feature = "ast", serde(rename(serialize = "rules")))]
464    pub policy: Vec<Ref<Rule>>,
465    pub rego_v1: bool,
466    // Target name if specified via __target__ rule
467    #[cfg_attr(feature = "ast", serde(skip_serializing_if = "Option::is_none"))]
468    pub target: Option<String>,
469    // Number of expressions in the module.
470    pub num_expressions: u32,
471    // Number of statements in the module.
472    pub num_statements: u32,
473    // Number of queries in the module.
474    pub num_queries: u32,
475}
476
477pub type ExprRef = Ref<Expr>;