aboutsummaryrefslogtreecommitdiff
path: root/src/eval
diff options
context:
space:
mode:
Diffstat (limited to 'src/eval')
-rw-r--r--src/eval/builtins.rs24
-rw-r--r--src/eval/mod.rs33
2 files changed, 23 insertions, 34 deletions
diff --git a/src/eval/builtins.rs b/src/eval/builtins.rs
index 7820a8e..7d10a86 100644
--- a/src/eval/builtins.rs
+++ b/src/eval/builtins.rs
@@ -48,11 +48,8 @@ builtins! {
48fn print(ctx: &mut Context, args: &[ast::Expr]) -> Result { 48fn print(ctx: &mut Context, args: &[ast::Expr]) -> Result {
49 for arg in args { 49 for arg in args {
50 let val = ctx.eval_expr(arg)?; 50 let val = ctx.eval_expr(arg)?;
51 let mut default_stream =Box::new(std::io::stdout()) as Box<dyn std::io::Write> ; 51 let mut default_stream = Box::new(std::io::stdout()) as Box<dyn std::io::Write>;
52 let stream = ctx 52 let stream = ctx.output_stream.as_mut().unwrap_or(&mut default_stream);
53 .output_stream
54 .as_mut()
55 .unwrap_or(&mut default_stream);
56 write!(stream, "{val}").unwrap(); 53 write!(stream, "{val}").unwrap();
57 } 54 }
58 Ok(Value::Unit) 55 Ok(Value::Unit)
@@ -157,9 +154,9 @@ fn kind(ctx: &mut Context, args: &[ast::Expr]) -> Result {
157 154
158fn member(ctx: &mut Context, args: &[ast::Expr]) -> Result { 155fn member(ctx: &mut Context, args: &[ast::Expr]) -> Result {
159 let [list_expr, element_expr] = get_args::<2>(args)?; 156 let [list_expr, element_expr] = get_args::<2>(args)?;
160 let list = ctx.eval_expr(&list_expr)?; 157 let list = ctx.eval_expr(list_expr)?;
161 let v = list.as_list()?; 158 let v = list.as_list()?;
162 let element = ctx.eval_expr(&element_expr)?; 159 let element = ctx.eval_expr(element_expr)?;
163 v.iter() 160 v.iter()
164 .any(|item| item == &element) 161 .any(|item| item == &element)
165 .wrap(Value::Boolean) 162 .wrap(Value::Boolean)
@@ -174,7 +171,7 @@ fn push(ctx: &mut Context, args: &[ast::Expr]) -> Result {
174 lhs 171 lhs
175 ))); 172 )));
176 }; 173 };
177 let element = ctx.eval_expr(&rhs)?; 174 let element = ctx.eval_expr(rhs)?;
178 let variable = ctx.lookup_mut(ident)?; 175 let variable = ctx.lookup_mut(ident)?;
179 variable.mutate(|v| match &mut v.value { 176 variable.mutate(|v| match &mut v.value {
180 Value::List(l) => { 177 Value::List(l) => {
@@ -195,9 +192,7 @@ fn pop(ctx: &mut Context, args: &[ast::Expr]) -> Result {
195 }; 192 };
196 let variable = ctx.lookup_mut(ident)?; 193 let variable = ctx.lookup_mut(ident)?;
197 variable.mutate(|v| match &mut v.value { 194 variable.mutate(|v| match &mut v.value {
198 Value::List(l) => l 195 Value::List(l) => l.pop().ok_or(Error::ArrayOutOfBounds { idx: 0, len: 0 }),
199 .pop()
200 .ok_or_else(|| Error::ArrayOutOfBounds { idx: 0, len: 0 }),
201 _ => Err(v.ty().expected([ast::Type::List])), 196 _ => Err(v.ty().expected([ast::Type::List])),
202 }) 197 })
203} 198}
@@ -211,12 +206,7 @@ fn isempty(ctx: &mut Context, args: &[ast::Expr]) -> Result {
211 .is_empty() 206 .is_empty()
212 .wrap(Value::Boolean) 207 .wrap(Value::Boolean)
213 .wrap(Ok), 208 .wrap(Ok),
214 ast::Type::String => v 209 ast::Type::String => v.as_str().unwrap().is_empty().wrap(Value::Boolean).wrap(Ok),
215 .as_str()
216 .unwrap()
217 .is_empty()
218 .wrap(Value::Boolean)
219 .wrap(Ok),
220 _ => Err(v.ty().expected([ast::Type::List])), 210 _ => Err(v.ty().expected([ast::Type::List])),
221 } 211 }
222} 212}
diff --git a/src/eval/mod.rs b/src/eval/mod.rs
index c4460c0..9455704 100644
--- a/src/eval/mod.rs
+++ b/src/eval/mod.rs
@@ -474,11 +474,11 @@ impl<'s> Context<'s> {
474 ast::Expr::Unit => Ok(Value::Unit), 474 ast::Expr::Unit => Ok(Value::Unit),
475 ast::Expr::Lit(lit) => self.eval_lit(lit), 475 ast::Expr::Lit(lit) => self.eval_lit(lit),
476 ast::Expr::Ident(ident) => self.lookup(ident).map(Variable::value).cloned(), 476 ast::Expr::Ident(ident) => self.lookup(ident).map(Variable::value).cloned(),
477 ast::Expr::Bin(lhs, op, rhs) => self.eval_bin(&*lhs, *op, &*rhs), 477 ast::Expr::Bin(lhs, op, rhs) => self.eval_bin(lhs, *op, rhs),
478 ast::Expr::Unary(expr, op) => self.eval_unary(&*expr, *op), 478 ast::Expr::Unary(expr, op) => self.eval_unary(expr, *op),
479 ast::Expr::Call(call) => self.eval_call(&*call), 479 ast::Expr::Call(call) => self.eval_call(call),
480 ast::Expr::List(list) => self.eval_list(&*list), 480 ast::Expr::List(list) => self.eval_list(list),
481 ast::Expr::Index(target, idx) => self.eval_index(&*target, &*idx), 481 ast::Expr::Index(target, idx) => self.eval_index(target, idx),
482 ast::Expr::If(if_expr) => self.eval_if(if_expr), 482 ast::Expr::If(if_expr) => self.eval_if(if_expr),
483 ast::Expr::Block(block) => self.eval_block(block), 483 ast::Expr::Block(block) => self.eval_block(block),
484 ast::Expr::Node => self.eval_node(), 484 ast::Expr::Node => self.eval_node(),
@@ -609,7 +609,7 @@ impl<'s> Context<'s> {
609 match op { 609 match op {
610 ast::LogicOp::Or => { 610 ast::LogicOp::Or => {
611 if l_value { 611 if l_value {
612 return Ok(l); 612 Ok(l)
613 } else { 613 } else {
614 let r = self.eval_expr(rhs)?; 614 let r = self.eval_expr(rhs)?;
615 l.or(&r) 615 l.or(&r)
@@ -617,7 +617,7 @@ impl<'s> Context<'s> {
617 } 617 }
618 ast::LogicOp::And => { 618 ast::LogicOp::And => {
619 if !l_value { 619 if !l_value {
620 return Ok(l); 620 Ok(l)
621 } else { 621 } else {
622 let r = self.eval_expr(rhs)?; 622 let r = self.eval_expr(rhs)?;
623 l.and(&r) 623 l.and(&r)
@@ -644,7 +644,7 @@ impl<'s> Context<'s> {
644 } 644 }
645 645
646 fn eval_call(&mut self, call: &ast::Call) -> Result { 646 fn eval_call(&mut self, call: &ast::Call) -> Result {
647 ((&*builtins::BUILTINS) 647 ((*builtins::BUILTINS)
648 .get(call.function.as_str()) 648 .get(call.function.as_str())
649 .ok_or_else(|| Error::FailedLookup(call.function.to_owned()))?)( 649 .ok_or_else(|| Error::FailedLookup(call.function.to_owned()))?)(
650 self, 650 self,
@@ -675,7 +675,7 @@ impl<'s> Context<'s> {
675 675
676 fn eval_declaration(&mut self, decl: &ast::Declaration) -> Result { 676 fn eval_declaration(&mut self, decl: &ast::Declaration) -> Result {
677 let initial_value = match decl.init.as_ref() { 677 let initial_value = match decl.init.as_ref() {
678 Some(init) => Some(self.eval_expr(&*init)?), 678 Some(init) => Some(self.eval_expr(init)?),
679 None => None, 679 None => None,
680 }; 680 };
681 let variable = self.bind(&decl.name, decl.ty)?; 681 let variable = self.bind(&decl.name, decl.ty)?;
@@ -775,7 +775,7 @@ pub fn evaluate(file: &str, program: &str, language: tree_sitter::Language) -> R
775 775
776 let tree = parser.parse(file, None).unwrap(); 776 let tree = parser.parse(file, None).unwrap();
777 777
778 let program = ast::Program::new().from_str(program).unwrap(); 778 let program = ast::Program::new().with_file(program).unwrap();
779 let mut ctx = Context::new(language) 779 let mut ctx = Context::new(language)
780 .with_input(file.to_owned()) 780 .with_input(file.to_owned())
781 .with_tree(tree) 781 .with_tree(tree)
@@ -796,7 +796,7 @@ mod test {
796 let mut parser = tree_sitter::Parser::new(); 796 let mut parser = tree_sitter::Parser::new();
797 let _ = parser.set_language(&language); 797 let _ = parser.set_language(&language);
798 let tree = parser.parse(file, None).unwrap(); 798 let tree = parser.parse(file, None).unwrap();
799 let program = ast::Program::new().from_str(program).unwrap(); 799 let program = ast::Program::new().with_file(program).unwrap();
800 800
801 let mut output = Vec::new(); 801 let mut output = Vec::new();
802 let mut ctx = Context::new(language) 802 let mut ctx = Context::new(language)
@@ -983,7 +983,7 @@ mod test {
983 print(a); 983 print(a);
984 } 984 }
985 ", 985 ",
986 expect!["[5]"] 986 expect!["[5]"],
987 ); 987 );
988 988
989 gen_test( 989 gen_test(
@@ -993,7 +993,7 @@ mod test {
993 print(length(a)); 993 print(length(a));
994 } 994 }
995 ", 995 ",
996 expect!["3"] 996 expect!["3"],
997 ); 997 );
998 998
999 gen_test( 999 gen_test(
@@ -1005,7 +1005,7 @@ mod test {
1005 print(member(a, 6)); 1005 print(member(a, 6));
1006 } 1006 }
1007 "#, 1007 "#,
1008 expect!["true, false"] 1008 expect!["true, false"],
1009 ); 1009 );
1010 1010
1011 gen_test( 1011 gen_test(
@@ -1029,7 +1029,7 @@ mod test {
1029 [5, 4, 3] 1029 [5, 4, 3]
1030 [5, 4] 1030 [5, 4]
1031 [5] 1031 [5]
1032 "#]] 1032 "#]],
1033 ); 1033 );
1034 1034
1035 gen_test( 1035 gen_test(
@@ -1044,8 +1044,7 @@ mod test {
1044 expect![[r#" 1044 expect![[r#"
1045 false 1045 false
1046 true 1046 true
1047 "#]] 1047 "#]],
1048 ); 1048 );
1049
1050 } 1049 }
1051} 1050}