summaryrefslogtreecommitdiff
path: root/src/eval
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-01-26 21:16:36 +0100
committerLaurenz <laurmaedje@gmail.com>2021-01-26 21:16:36 +0100
commited929dd10c8cbf57bf590db8c63cd8878ce2a864 (patch)
tree04ef85ba18334cd694d0986f309cb97eb6a3d98b /src/eval
parente8470824352064fefbb5d0d30a728211d11cea53 (diff)
For loops 🔁
(does not support key-value patterns yet)
Diffstat (limited to 'src/eval')
-rw-r--r--src/eval/mod.rs36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/eval/mod.rs b/src/eval/mod.rs
index eaa0b08f..27c66095 100644
--- a/src/eval/mod.rs
+++ b/src/eval/mod.rs
@@ -182,6 +182,7 @@ impl Eval for Spanned<&Expr> {
Expr::Binary(v) => v.with_span(self.span).eval(ctx),
Expr::Let(v) => v.with_span(self.span).eval(ctx),
Expr::If(v) => v.with_span(self.span).eval(ctx),
+ Expr::For(v) => v.with_span(self.span).eval(ctx),
}
}
}
@@ -372,3 +373,38 @@ impl Eval for Spanned<&ExprIf> {
Value::Error
}
}
+
+impl Eval for Spanned<&ExprFor> {
+ type Output = Value;
+
+ fn eval(self, ctx: &mut EvalContext) -> Self::Output {
+ let iter = self.v.iter.eval(ctx);
+ if let Value::Array(array) = iter {
+ let mut output = match self.v.body.v {
+ Expr::Template(_) => Value::Template(vec![]),
+ _ => Value::None,
+ };
+
+ for value in array {
+ ctx.scopes.define(self.v.pat.v.as_str(), value);
+ let value = self.v.body.eval(ctx);
+
+ if let Value::Template(prev) = &mut output {
+ if let Value::Template(new) = value {
+ prev.extend(new);
+ }
+ }
+ }
+
+ return output;
+ } else if iter != Value::Error {
+ ctx.diag(error!(
+ self.v.iter.span,
+ "expected array, found {}",
+ iter.type_name(),
+ ));
+ }
+
+ Value::Error
+ }
+}