microcad_lang/parse/
statement.rs

1// Copyright © 2025 The µcad authors <info@ucad.xyz>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4use crate::{parse::*, parser::*, rc::*, syntax::*};
5
6impl Parse for Assignment {
7    fn parse(pair: Pair) -> ParseResult<Self> {
8        Ok(Self {
9            visibility: crate::find_rule!(pair, visibility)?,
10            qualifier: crate::find_rule!(pair, qualifier)?,
11            id: crate::find_rule!(pair, identifier)?,
12            specified_type: crate::find_rule_opt!(pair, r#type),
13            expression: crate::find_rule!(pair, expression)?,
14            src_ref: pair.into(),
15        })
16    }
17}
18
19impl Parse for AssignmentStatement {
20    fn parse(pair: Pair) -> crate::parse::ParseResult<Self> {
21        Ok(Self {
22            attribute_list: crate::find_rule!(pair, attribute_list)?,
23            assignment: crate::find_rule_opt!(pair, assignment).expect("Assignment"),
24            src_ref: pair.into(),
25        })
26    }
27}
28
29impl Parse for IfStatement {
30    fn parse(pair: Pair) -> ParseResult<Self> {
31        let mut cond = Default::default();
32        let mut body = None;
33        let mut body_else = None;
34        let mut next_if = None;
35
36        for pair in pair.inner() {
37            match pair.as_rule() {
38                Rule::expression => cond = Expression::parse(pair)?,
39                Rule::body => {
40                    if body.is_none() {
41                        body = Some(Body::parse(pair)?)
42                    } else {
43                        body_else = Some(Body::parse(pair)?)
44                    }
45                }
46                Rule::if_statement => {
47                    if next_if.is_none() {
48                        next_if = Some(Box::new(IfStatement::parse(pair)?));
49                    }
50                }
51                rule => unreachable!("Unexpected rule in if, got {:?}", rule),
52            }
53        }
54
55        let body = body.expect("Body");
56
57        Ok(IfStatement {
58            cond,
59            body,
60            body_else,
61            next_if,
62            src_ref: pair.into(),
63        })
64    }
65}
66
67impl Parse for ExpressionStatement {
68    fn parse(pair: Pair) -> crate::parse::ParseResult<Self> {
69        Parser::ensure_rules(
70            &pair,
71            &[Rule::expression_statement, Rule::final_expression_statement],
72        );
73
74        Ok(Self {
75            attribute_list: crate::find_rule!(pair, attribute_list)?,
76            expression: pair.find(Rule::expression).expect("Expression"),
77            src_ref: pair.into(),
78        })
79    }
80}
81
82impl Parse for Statement {
83    fn parse(pair: Pair) -> ParseResult<Self> {
84        Parser::ensure_rule(&pair, Rule::statement);
85        let first = pair.inner().next().expect(INTERNAL_PARSE_ERROR);
86        Ok(match first.as_rule() {
87            Rule::workbench_definition => Self::Workbench(Rc::<WorkbenchDefinition>::parse(first)?),
88            Rule::module_definition => Self::Module(Rc::<ModuleDefinition>::parse(first)?),
89            Rule::function_definition => Self::Function(Rc::<FunctionDefinition>::parse(first)?),
90            Rule::init_definition => Self::Init(Rc::new(InitDefinition::parse(first)?)),
91
92            Rule::use_statement => Self::Use(UseStatement::parse(first)?),
93            Rule::return_statement => Self::Return(ReturnStatement::parse(first)?),
94            Rule::if_statement => Self::If(IfStatement::parse(first)?),
95            Rule::inner_attribute => Self::InnerAttribute(Attribute::parse(first)?),
96
97            Rule::assignment_statement => Self::Assignment(AssignmentStatement::parse(first)?),
98            Rule::expression_statement | Rule::final_expression_statement => {
99                Self::Expression(ExpressionStatement::parse(first)?)
100            }
101            rule => unreachable!("Unexpected statement, got {:?} {:?}", rule, first.clone()),
102        })
103    }
104}
105
106impl Parse for ReturnStatement {
107    fn parse(pair: Pair) -> ParseResult<Self> {
108        let mut result = None;
109
110        for pair in pair.inner() {
111            match pair.as_rule() {
112                Rule::expression => result = Some(Expression::parse(pair)?),
113                rule => unreachable!("Unexpected rule in return, got {:?}", rule),
114            }
115        }
116
117        Ok(ReturnStatement {
118            result,
119            src_ref: pair.into(),
120        })
121    }
122}
123
124impl Parse for StatementList {
125    fn parse(pair: Pair) -> ParseResult<Self> {
126        let mut statements = Vec::new();
127
128        for pair in pair.inner() {
129            match pair.as_rule() {
130                Rule::final_expression_statement => {
131                    statements.push(Statement::Expression(ExpressionStatement::parse(pair)?));
132                }
133                Rule::statement => {
134                    statements.push(Statement::parse(pair)?);
135                }
136                _ => {}
137            }
138        }
139
140        Ok(Self(statements))
141    }
142}
143
144impl Parse for Qualifier {
145    fn parse(pair: Pair) -> ParseResult<Self> {
146        Parser::ensure_rule(&pair, Rule::qualifier);
147        match pair.as_str() {
148            "prop" => Ok(Self::Prop),
149            "const" => Ok(Self::Const),
150            _ => Ok(Self::Value),
151        }
152    }
153}