microcad_lang/parse/
statement.rs1use crate::{parse::*, parser::*, rc::*, syntax::*};
5use microcad_syntax::ast;
6
7impl FromAst for Assignment {
8 type AstNode = ast::Assignment;
9
10 fn from_ast(node: &Self::AstNode, context: &ParseContext) -> Result<Self, ParseError> {
11 Ok(Assignment {
12 doc: node
13 .doc
14 .as_ref()
15 .map(|doc| DocBlock::from_ast(doc, context))
16 .transpose()?,
17 visibility: node
18 .visibility
19 .as_ref()
20 .map(|v| Visibility::from_ast(v, context))
21 .transpose()?
22 .unwrap_or_default(),
23 id: Identifier::from_ast(&node.name, context)?,
24 qualifier: node
25 .qualifier
26 .as_ref()
27 .map(|q| Qualifier::from_ast(q, context))
28 .transpose()?
29 .unwrap_or_default(),
30 specified_type: node
31 .ty
32 .as_ref()
33 .map(|ty| TypeAnnotation::from_ast(ty, context))
34 .transpose()?,
35 expression: Expression::from_ast(&node.value, context)?,
36 src_ref: context.src_ref(&node.span),
37 })
38 }
39}
40
41impl FromAst for AssignmentStatement {
42 type AstNode = ast::Assignment;
43
44 fn from_ast(node: &Self::AstNode, context: &ParseContext) -> Result<Self, ParseError> {
45 Ok(AssignmentStatement {
46 attribute_list: AttributeList::from_ast(&node.attributes, context)?,
47 assignment: Rc::new(Assignment::from_ast(node, context)?),
48 src_ref: context.src_ref(&node.span),
49 })
50 }
51}
52
53impl FromAst for IfStatement {
54 type AstNode = ast::If;
55
56 fn from_ast(node: &Self::AstNode, context: &ParseContext) -> Result<Self, ParseError> {
57 Ok(IfStatement {
58 cond: Expression::from_ast(&node.condition, context)?,
59 body: Body::from_ast(&node.body, context)?,
60 next_if: node
61 .next_if
62 .as_ref()
63 .map(|next| IfStatement::from_ast(next, context))
64 .transpose()?
65 .map(Box::new),
66 body_else: node
67 .else_body
68 .as_ref()
69 .map(|body| Body::from_ast(body, context))
70 .transpose()?,
71 src_ref: context.src_ref(&node.span),
72 })
73 }
74}
75
76impl FromAst for ExpressionStatement {
77 type AstNode = ast::ExpressionStatement;
78
79 fn from_ast(node: &Self::AstNode, context: &ParseContext) -> Result<Self, ParseError> {
80 Ok(ExpressionStatement {
81 src_ref: context.src_ref(&node.span),
82 attribute_list: AttributeList::from_ast(&node.attributes, context)?,
83 expression: Expression::from_ast(&node.expression, context)?,
84 })
85 }
86}
87
88impl FromAst for Statement {
89 type AstNode = ast::Statement;
90
91 fn from_ast(node: &Self::AstNode, context: &ParseContext) -> Result<Self, ParseError> {
92 Ok(match node {
93 ast::Statement::Module(module) => {
94 Statement::Module(Rc::new(ModuleDefinition::from_ast(module, context)?))
95 }
96 ast::Statement::Use(statement) => {
97 Statement::Use(UseStatement::from_ast(statement, context)?)
98 }
99 ast::Statement::Expression(ast::ExpressionStatement { expression: ast::Expression::If(if_statement), .. }) => {
100 Statement::If(IfStatement::from_ast(if_statement, context)?)
101 }
102 ast::Statement::Expression(statement) => {
103 Statement::Expression(ExpressionStatement::from_ast(statement, context)?)
104 }
105 ast::Statement::Workbench(w) => {
106 Statement::Workbench(<Rc<WorkbenchDefinition>>::from_ast(w, context)?)
107 }
108 ast::Statement::Function(f) => {
109 Statement::Function(Rc::new(FunctionDefinition::from_ast(f, context)?))
110 }
111 ast::Statement::Init(i) => {
112 Statement::Init(Rc::new(InitDefinition::from_ast(i, context)?))
113 }
114 ast::Statement::Return(r) => Statement::Return(ReturnStatement::from_ast(r, context)?),
115 ast::Statement::InnerAttribute(a) => {
116 Statement::InnerAttribute(Attribute::from_ast(a, context)?)
117 }
118 ast::Statement::Assignment(a) => {
119 Statement::Assignment(AssignmentStatement::from_ast(a, context)?)
120 }
121 ast::Statement::Comment(_) => unreachable!("comments are filtered out"),
122 ast::Statement::Error(span) => {
123 return Err(ParseError::InvalidStatement {
124 src_ref: context.src_ref(span),
125 });
126 }
127 })
128 }
129}
130
131impl FromAst for ReturnStatement {
132 type AstNode = ast::Return;
133
134 fn from_ast(node: &Self::AstNode, context: &ParseContext) -> Result<Self, ParseError> {
135 Ok(ReturnStatement {
136 result: node
137 .value
138 .as_ref()
139 .map(|res| Expression::from_ast(res, context))
140 .transpose()?,
141 src_ref: context.src_ref(&node.span),
142 })
143 }
144}
145
146impl FromAst for StatementList {
147 type AstNode = ast::StatementList;
148
149 fn from_ast(node: &Self::AstNode, context: &ParseContext) -> Result<Self, ParseError> {
150 Ok(StatementList(
151 node.statements
152 .iter()
153 .chain(node.tail.iter().map(|tail| tail.as_ref()))
154 .filter(|statement| !matches!(statement, ast::Statement::Comment(_)))
155 .map(|statement| Statement::from_ast(statement, context))
156 .collect::<Result<Vec<_>, _>>()?,
157 ))
158 }
159}
160
161impl FromAst for Qualifier {
162 type AstNode = ast::AssignmentQualifier;
163
164 fn from_ast(node: &Self::AstNode, _context: &ParseContext) -> Result<Self, ParseError> {
165 Ok(match node {
166 ast::AssignmentQualifier::Const => Qualifier::Const,
167 ast::AssignmentQualifier::Prop => Qualifier::Prop,
168 })
169 }
170}