microcad_lang/parse/
statement.rs1use 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}