cl-interpret: Builtin refactor

- Everything is different now
  - Builtins are now built on top of Rust functions, so they can be recursive!
  - TODO: allow macro-defined builtins to call each other?
- The builtins! macro is a lot nicer to work with
  - No redundant return value
  - Maps the result over Into::into, allowing for type inference!
  - Uses explicit pattern syntax instead of weird binding, where possible
  - Does not #[allow(unused)], so you'll get unused variable warnings now!
This commit is contained in:
2025-01-31 03:34:45 -06:00
parent 0c2b0002ce
commit d95d35268e
6 changed files with 230 additions and 211 deletions

View File

@@ -4,9 +4,9 @@
use cl_ast::{format::FmtAdapter, ExprKind, Sym};
use super::{
builtin::Builtin,
error::{Error, IResult},
function::Function,
BuiltIn, Callable, Environment,
function::Function, Callable, Environment,
};
use std::{collections::HashMap, ops::*, rc::Rc};
@@ -47,7 +47,7 @@ pub enum ConValue {
/// A callable thing
Function(Rc<Function>),
/// A built-in function
BuiltIn(&'static dyn BuiltIn),
Builtin(&'static Builtin),
}
impl ConValue {
@@ -113,14 +113,14 @@ impl Callable for ConValue {
fn name(&self) -> Sym {
match self {
ConValue::Function(func) => func.name(),
ConValue::BuiltIn(func) => func.name(),
ConValue::Builtin(func) => func.name(),
_ => "".into(),
}
}
fn call(&self, interpreter: &mut Environment, args: &[ConValue]) -> IResult<ConValue> {
match self {
Self::Function(func) => func.call(interpreter, args),
Self::BuiltIn(func) => func.call(interpreter, args),
Self::Builtin(func) => func.call(interpreter, args),
_ => Err(Error::NotCallable(self.clone())),
}
}
@@ -170,7 +170,7 @@ from! {
ExprKind => ConValue::Quote,
Function => ConValue::Function,
Vec<ConValue> => ConValue::Tuple,
&'static dyn BuiltIn => ConValue::BuiltIn,
&'static Builtin => ConValue::Builtin,
}
impl From<()> for ConValue {
fn from(_: ()) -> Self {
@@ -328,7 +328,7 @@ impl std::fmt::Display for ConValue {
ConValue::Function(func) => {
write!(f, "{}", func.decl())
}
ConValue::BuiltIn(func) => {
ConValue::Builtin(func) => {
write!(f, "{}", func.description())
}
}