function, object, parser, and executer rewrites

This commit is contained in:
2024-10-18 02:21:31 -04:00
parent 34569248d3
commit f2cfb03fa1
6 changed files with 401 additions and 454 deletions

79
src/function.rs Normal file
View File

@@ -0,0 +1,79 @@
use crate::parser::ParseTree;
use crate::executor::{Executor, RuntimeError};
use crate::{Type, Object, Value};
use std::collections::HashMap;
use std::fmt::{self, Display};
#[derive(Clone, Debug, PartialEq)]
pub struct FunctionType(pub Box<Type>, pub Vec<Type>);
impl Display for FunctionType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Function({}, {})", self.0, self.1.iter().map(|x| format!("{x}")).collect::<Vec<_>>().join(", "))
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct Function {
name: Option<String>,
t: FunctionType,
arg_names: Vec<String>,
body: Box<ParseTree>,
}
impl Function {
pub(crate) fn lambda(t: FunctionType, arg_names: Vec<String>, body: Box<ParseTree>) -> Self {
Self {
name: None,
t,
arg_names,
body
}
}
pub(crate) fn named(name: &str, t: FunctionType, arg_names: Vec<String>, body: Box<ParseTree>) -> Self {
Self {
name: Some(name.to_string()),
t,
arg_names,
body
}
}
pub fn name(&self) -> Option<&str> {
self.name.as_ref().map(|x| x.as_str())
}
pub fn get_type(&self) -> FunctionType {
self.t.clone()
}
pub(crate) fn call(&mut self,
globals: HashMap<String, Object>,
locals: HashMap<String, Object>,
args: Vec<Object>) -> Result<Value, RuntimeError>
{
let mut tree = vec![Ok(*self.body.clone())].into_iter();
let mut exec = Executor::new(&mut tree)
.locals(locals.clone())
.globals(globals.clone());
for (obj, name) in std::iter::zip(args.into_iter(), self.arg_names.clone().into_iter()) {
exec = exec.add_local(name.clone(), obj);
}
if let Some(name) = self.name().map(|x| x.to_string()) {
exec = exec.add_local(name, Object::function(self.clone(), globals, locals));
}
exec.next().unwrap()
}
}
impl Display for Function {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.t)
}
}