treescript-interpreter 0.1.1

TreeScript interpreter, with some built-in libraries and API to create more
Documentation
use treescript_interpreter::lib_process::{BasicLibProcessError, Config, LibProcess};
use treescript_interpreter::session::LibrarySpec;
use treescript_interpreter::value::Value;

struct Lib;

impl Lib {
  fn map_inner(
    &self,
    f: Value,
    items: &Value,
    rest: &Value,
  ) -> Result<Value, BasicLibProcessError> {
    if let Value::Record { head, props } = rest {
      match head.as_str() {
        "Nil" => return Ok(Value::nil()),
        "Cons" => {
          let mut y = f.clone();
          y.subst(&Value::hole(1), &props[0]);
          let ys = self.map_inner(f, items, &props[1])?;
          return Ok(Value::cons(y, ys));
        }
        _ => (),
      }
    }

    return Err(BasicLibProcessError::InvalidArgTypes {
      actual: vec![items.clone()],
      expected: String::from("list"),
    });
  }

  fn map(&self, f: Value, items: Value) -> Result<Value, BasicLibProcessError> {
    return self.map_inner(f, &items, &items);
  }
}

impl LibProcess for Lib {
  type Error = BasicLibProcessError;

  fn dependencies() -> Vec<LibrarySpec> {
    return Vec::new();
  }

  fn configure(&mut self, _config: Config) {}

  fn call_fun(&mut self, name: String, args: Vec<Value>) -> Result<Value, Self::Error> {
    match name.as_str() {
      "Map" => {
        if args.len() != 2 {
          return Err(BasicLibProcessError::InvalidNumArgs {
            fun: String::from("Map"),
            expected: 2,
            actual: args.len(),
          });
        }
        let mut args_iter = args.into_iter();
        let arg0 = args_iter.next().unwrap();
        let arg1 = args_iter.next().unwrap();
        return self.map(arg0, arg1);
      }
      _ => return Err(BasicLibProcessError::UnknownFunction(name)),
    };
  }
}

fn main() {
  Lib.run_main();
}