Skip to main content

online_dsl_forge/sema/
dialect.rs

1use crate::parser::{AstExpression, BinaryOp, Diagnostic, ExprKind, UnaryOp};
2
3#[derive(Debug, Clone, Copy, Default, Eq, PartialEq)]
4pub enum ExpressionDialect {
5  #[default]
6  Generic,
7  OxiRuleV1,
8}
9
10impl ExpressionDialect {
11  pub(crate) fn validate(self, expression: &AstExpression, diagnostics: &mut Vec<Diagnostic>) {
12    match self {
13      Self::Generic => {}
14      Self::OxiRuleV1 => validate_oxirule_v1(expression, diagnostics),
15    }
16  }
17}
18
19fn validate_oxirule_v1(expression: &AstExpression, diagnostics: &mut Vec<Diagnostic>) {
20  match &expression.kind {
21    ExprKind::Float { .. } => diagnostics.push(Diagnostic::new(
22      "OxiRule V1 does not support float literals",
23      expression.span,
24    )),
25    ExprKind::Array { items } => {
26      diagnostics.push(Diagnostic::new(
27        "OxiRule V1 does not support array literals",
28        expression.span,
29      ));
30      for item in items {
31        validate_oxirule_v1(item, diagnostics);
32      }
33    }
34    ExprKind::Unary {
35      op: UnaryOp::Neg,
36      expr,
37    } => {
38      diagnostics.push(Diagnostic::new(
39        "OxiRule V1 does not support unary numeric negation",
40        expression.span,
41      ));
42      validate_oxirule_v1(expr, diagnostics);
43    }
44    ExprKind::Unary { expr, .. } => validate_oxirule_v1(expr, diagnostics),
45    ExprKind::Binary { left, op, right } => {
46      if matches!(
47        op,
48        BinaryOp::Sub | BinaryOp::Mul | BinaryOp::Div | BinaryOp::Rem
49      ) {
50        diagnostics.push(Diagnostic::new(
51          format!("OxiRule V1 does not support operator {}", op.as_str()),
52          expression.span,
53        ));
54      }
55      validate_oxirule_v1(left, diagnostics);
56      validate_oxirule_v1(right, diagnostics);
57    }
58    ExprKind::Member { receiver, .. } => validate_oxirule_v1(receiver, diagnostics),
59    ExprKind::FunctionCall { args, .. } => {
60      for arg in args {
61        validate_oxirule_v1(arg, diagnostics);
62      }
63    }
64    ExprKind::MethodCall { receiver, args, .. } => {
65      validate_oxirule_v1(receiver, diagnostics);
66      for arg in args {
67        validate_oxirule_v1(arg, diagnostics);
68      }
69    }
70    ExprKind::Null
71    | ExprKind::Bool { .. }
72    | ExprKind::Int { .. }
73    | ExprKind::String { .. }
74    | ExprKind::Identifier { .. } => {}
75  }
76}