1use crate::ast::ExpressionIdGenerator;
2use crate::error::LemmaError;
3use crate::parser::Rule;
4use crate::semantic::*;
5use pest::iterators::Pair;
6
7pub(crate) fn parse_rule_definition(
8 pair: Pair<Rule>,
9 id_gen: &mut ExpressionIdGenerator,
10) -> Result<LemmaRule, LemmaError> {
11 let span = crate::ast::Span::from_pest_span(pair.as_span());
12 let mut rule_name = None;
13 let mut rule_expression = None;
14
15 for inner_pair in pair.into_inner() {
16 match inner_pair.as_rule() {
17 Rule::rule_name => rule_name = Some(inner_pair.as_str().to_string()),
18 Rule::rule_expression => {
19 rule_expression = Some(parse_rule_expression(inner_pair, id_gen)?)
20 }
21 _ => {}
22 }
23 }
24
25 let name = rule_name.ok_or_else(|| {
26 LemmaError::Engine("Grammar error: rule_definition missing rule_name".to_string())
27 })?;
28 let (expression, unless_clauses) = rule_expression.ok_or_else(|| {
29 LemmaError::Engine("Grammar error: rule_definition missing rule_expression".to_string())
30 })?;
31
32 Ok(LemmaRule {
33 name,
34 expression,
35 unless_clauses,
36 span: Some(span),
37 })
38}
39
40fn parse_rule_expression(
41 pair: Pair<Rule>,
42 id_gen: &mut ExpressionIdGenerator,
43) -> Result<(Expression, Vec<UnlessClause>), LemmaError> {
44 let mut expression = None;
45 let mut unless_clauses = Vec::new();
46
47 for inner_pair in pair.into_inner() {
48 match inner_pair.as_rule() {
49 Rule::expression_group => {
50 expression = Some(crate::parser::expressions::parse_or_expression(
51 inner_pair, id_gen,
52 )?);
53 }
54 Rule::unless_statement => {
55 let unless_clause = parse_unless_statement(inner_pair, id_gen)?;
56 unless_clauses.push(unless_clause);
57 }
58 _ => {}
59 }
60 }
61
62 let expr = expression.ok_or_else(|| {
63 LemmaError::Engine("Grammar error: rule_expression missing expression_group".to_string())
64 })?;
65 Ok((expr, unless_clauses))
66}
67
68fn parse_unless_statement(
69 pair: Pair<Rule>,
70 id_gen: &mut ExpressionIdGenerator,
71) -> Result<UnlessClause, LemmaError> {
72 let span = crate::ast::Span::from_pest_span(pair.as_span());
73 let mut condition = None;
74 let mut result = None;
75
76 for inner_pair in pair.clone().into_inner() {
77 match inner_pair.as_rule() {
78 Rule::expression_group => {
79 if condition.is_none() {
80 condition = Some(crate::parser::expressions::parse_or_expression(
81 inner_pair, id_gen,
82 )?);
83 } else {
84 result = Some(crate::parser::expressions::parse_or_expression(
85 inner_pair, id_gen,
86 )?);
87 }
88 }
89 Rule::veto_expression => {
90 let veto_span = crate::ast::Span::from_pest_span(inner_pair.as_span());
91 let message = inner_pair
94 .clone()
95 .into_inner()
96 .find(|p| p.as_rule() == Rule::string_literal)
97 .map(|string_pair| {
98 let content = string_pair.as_str();
99 content[1..content.len() - 1].to_string()
100 });
101 let kind = ExpressionKind::Veto(VetoExpression { message });
102 result = Some(Expression::new(kind, Some(veto_span), id_gen.next_id()));
103 }
104 _ => {}
105 }
106 }
107
108 let cond = condition.ok_or_else(|| {
109 LemmaError::Engine("Grammar error: unless_statement missing condition".to_string())
110 })?;
111 let res = result.ok_or_else(|| {
112 LemmaError::Engine("Grammar error: unless_statement missing result".to_string())
113 })?;
114
115 Ok(UnlessClause {
116 condition: cond,
117 result: res,
118 span: Some(span),
119 })
120}