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 Context) -> EvalResult<Value> {
21 match self {
22 Self::Workbench(w) => {
23 context.grant(w.as_ref())?;
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 context.grant(i)?;
40 Ok(Value::None)
41 }
42 Self::Init(i) => {
43 context.grant(i.as_ref())?;
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 Context) -> EvalResult<Option<Model>> {
53 let model: Option<Model> = match self {
54 Self::Workbench(w) => {
55 context.grant(w.as_ref())?;
56 None
57 }
58 Self::Module(m) => {
59 m.eval(context)?;
60
61 context.grant(m.as_ref())?;
62 None
63 }
64 Self::Function(f) => {
65 context.grant(f.as_ref())?;
66 None
67 }
68 Self::Init(i) => {
69 context.grant(i.as_ref())?;
70 None
71 }
72 Self::Return(r) => {
73 context.grant(r)?;
74 None
75 }
76 Self::Use(u) => {
77 u.eval(context)?;
78 None
79 }
80 Self::Assignment(a) => {
81 a.eval(context)?;
82 None
83 }
84 Self::If(i) => i.eval(context)?,
85 Self::Expression(e) => e.eval(context)?,
86 Self::InnerAttribute(a) => {
87 context.grant(a)?;
88 Default::default()
89 }
90 };
91
92 if let Some(ref model) = model {
93 if model.deduce_output_type() == OutputType::InvalidMixed {
94 context.error(self, EvalError::CannotMixGeometry)?;
95 }
96 }
97
98 Ok(model)
99 }
100}
101
102impl Eval<Value> for StatementList {
103 fn eval(&self, context: &mut Context) -> EvalResult<Value> {
104 for statement in self.iter() {
105 if let Value::Return(result) = statement.eval(context)? {
106 return Ok(*result);
107 }
108 }
109 Ok(Value::None)
110 }
111}
112
113impl Eval<Attributes> for StatementList {
115 fn eval(&self, context: &mut Context) -> EvalResult<Attributes> {
116 let mut attributes = Vec::new();
117 for statement in self.iter() {
118 if let Statement::InnerAttribute(attribute) = statement {
119 attributes.append(&mut attribute.eval(context)?);
120 }
121 }
122
123 Ok(Attributes(attributes))
124 }
125}
126
127impl Eval<Models> for StatementList {
128 fn eval(&self, context: &mut Context) -> EvalResult<Models> {
129 let mut models = Models::default();
130 let mut output_type = OutputType::NotDetermined;
131
132 for statement in self.iter() {
133 if let Some(model) = statement.eval(context)? {
134 output_type = output_type.merge(&model.deduce_output_type());
135 if output_type == OutputType::InvalidMixed {
136 context.error(statement, EvalError::CannotMixGeometry)?;
137 }
138 models.push(model);
139 }
140 }
141 models.deduce_output_type();
142 Ok(models)
143 }
144}