microcad_lang/eval/statements/
mod.rs1use crate::{eval::*, model::*};
9
10mod assignment_statement;
11mod expression_statement;
12mod if_statement;
13mod marker;
14mod return_statement;
15mod use_statement;
16
17pub use use_statement::*;
18
19impl Eval for Statement {
20 fn eval(&self, context: &mut EvalContext) -> EvalResult<Value> {
21 match self {
22 Self::Workbench(w) => {
23 w.grant(context)?;
24 Ok(Value::None)
25 }
26 Self::Module(m) => m.eval(context),
27 Self::Function(f) => f.eval(context),
28 Self::Use(u) => {
29 u.eval(context)?;
30 Ok(Value::None)
31 }
32 Self::Assignment(a) => {
33 a.eval(context)?;
34 Ok(Value::None)
35 }
36 Self::If(i) => i.eval(context),
37 Self::Expression(e) => e.eval(context),
38 Self::InnerAttribute(i) => {
39 i.grant(context)?;
40 Ok(Value::None)
41 }
42 Self::Init(i) => {
43 i.grant(context)?;
44 Ok(Value::None)
45 }
46 Self::Return(r) => r.eval(context),
47 }
48 }
49}
50
51impl Eval<Option<Model>> for Statement {
52 fn eval(&self, context: &mut EvalContext) -> EvalResult<Option<Model>> {
53 let model: Option<Model> = match self {
54 Self::Workbench(w) => {
55 w.grant(context)?;
56 None
57 }
58 Self::Module(m) => {
59 m.eval(context)?;
60 None
61 }
62 Self::Function(f) => {
63 f.grant(context)?;
64 None
65 }
66 Self::Init(i) => {
67 i.grant(context)?;
68 None
69 }
70 Self::Return(r) => {
71 r.grant(context)?;
72 None
73 }
74 Self::Use(u) => {
75 u.eval(context)?;
76 None
77 }
78 Self::Assignment(a) => {
79 a.eval(context)?;
80 None
81 }
82 Self::If(i) => i.eval(context)?,
83 Self::Expression(e) => e.eval(context)?,
84 Self::InnerAttribute(a) => {
85 a.grant(context)?;
86 None
87 }
88 };
89
90 if let Some(ref model) = model {
91 if model.deduce_output_type() == OutputType::InvalidMixed {
92 context.error(self, EvalError::CannotMixGeometry)?;
93 }
94 }
95
96 Ok(model)
97 }
98}
99
100impl Eval<Value> for StatementList {
101 fn eval(&self, context: &mut EvalContext) -> EvalResult<Value> {
102 for statement in self.iter() {
103 if let Value::Return(result) = statement.eval(context)? {
104 return Ok(*result);
105 }
106 }
107 Ok(Value::None)
108 }
109}
110
111impl Eval<Attributes> for StatementList {
113 fn eval(&self, context: &mut EvalContext) -> EvalResult<Attributes> {
114 let mut attributes = Vec::new();
115 for statement in self.iter() {
116 if let Statement::InnerAttribute(attribute) = statement {
117 attributes.append(&mut attribute.eval(context)?);
118 }
119 }
120
121 Ok(Attributes(attributes))
122 }
123}
124
125impl Eval<Models> for StatementList {
126 fn eval(&self, context: &mut EvalContext) -> EvalResult<Models> {
127 let mut models = Models::default();
128 let mut output_type = OutputType::NotDetermined;
129
130 for statement in self.iter() {
131 if let Some(model) = statement.eval(context)? {
132 output_type = output_type.merge(&model.deduce_output_type());
133 if output_type == OutputType::InvalidMixed {
134 context.error(statement, EvalError::CannotMixGeometry)?;
135 }
136 models.push(model);
137 }
138 }
139 models.deduce_output_type();
140 Ok(models)
141 }
142}