function, object, parser, and executer rewrites
This commit is contained in:
79
src/function.rs
Normal file
79
src/function.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user