aboutsummaryrefslogtreecommitdiff
path: root/src/interpreter.rs
diff options
context:
space:
mode:
authorCody <cody@codyq.dev>2023-02-27 11:55:17 -0600
committerCody <cody@codyq.dev>2023-02-27 11:55:17 -0600
commit17110bf563c2f57ab4e9e25e977b74df06b8c1ab (patch)
tree5f63b6047db1771aee798293c86682ded0ca4fd6 /src/interpreter.rs
parentebfd74ddf0ef6372624ea171e06f8460d0e1351b (diff)
downloadsloth-17110bf563c2f57ab4e9e25e977b74df06b8c1ab.tar.gz
Functions beginnings
Diffstat (limited to 'src/interpreter.rs')
-rw-r--r--src/interpreter.rs47
1 files changed, 41 insertions, 6 deletions
diff --git a/src/interpreter.rs b/src/interpreter.rs
index aa9d441..b548d9e 100644
--- a/src/interpreter.rs
+++ b/src/interpreter.rs
@@ -1,11 +1,14 @@
use std::collections::HashMap;
-use std::fmt::Display;
+use std::fmt::{Debug, Display};
+
+use itertools::Itertools;
use crate::ast::{AstVisitor, Expr, Stmt};
use crate::lexer::{Literal, TokenType};
#[derive(Default)]
pub struct AstInterpreter {
+ pub callables: HashMap<String, Box<dyn SlothCallable>>,
memory: HashMap<String, (Value, bool)>,
}
@@ -54,11 +57,19 @@ impl AstVisitor<Value> for AstInterpreter {
binding,
range,
body,
- } => todo!(),
- Stmt::Return { value } => todo!(),
- Stmt::Print { value } => {
- println!("{}", self.visit_expr(value));
+ } => {
+ let Value::Number(lower_range) = self.visit_expr(&range.0) else { panic!("Lower range must be number") };
+ let Value::Number(upper_range) = self.visit_expr(&range.1) else { panic!("Upper range must be number") };
+
+ for i in lower_range..upper_range {
+ self.memory
+ .insert(binding.clone(), (Value::Number(i), false));
+ self.interpret(body);
+ }
+
+ self.memory.remove(binding);
}
+ Stmt::Return { value } => todo!(),
};
// FIXME: Honestly should probably abandon this "visitor" pattern. 2 functions
@@ -142,6 +153,16 @@ impl AstVisitor<Value> for AstInterpreter {
_ => panic!(),
}
}
+ Expr::Call { ident, arguments } => {
+ let argument_values = arguments.iter().map(|it| self.visit_expr(it)).collect_vec();
+ let Some(callable) = self.callables.remove(ident) else {
+ panic!("Unkown callable '{ident}'");
+ };
+
+ let result = callable.call(self, &argument_values);
+ self.callables.insert(ident.clone(), callable);
+ result
+ }
_ => unimplemented!("{:?}", expr),
}
}
@@ -155,7 +176,7 @@ impl AstInterpreter {
}
}
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Clone, Eq, PartialEq)]
pub enum Value {
Number(i32),
String(String),
@@ -163,6 +184,20 @@ pub enum Value {
Nil,
}
+pub trait SlothCallable {
+ fn call(&self, interpreter: &mut AstInterpreter, args: &[Value]) -> Value;
+}
+
+pub struct InternalFunction<'a>(pub &'a dyn Fn(&[Value]) -> Value);
+
+impl<'a> SlothCallable for InternalFunction<'a> {
+ fn call(&self, interpreter: &mut AstInterpreter, args: &[Value]) -> Value {
+ self.0(args)
+ }
+}
+
+// pub struct SlothFunction(Vec<Stmt>);
+
impl Display for Value {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {