diff --git a/crates/saft-eval/src/interpreter.rs b/crates/saft-eval/src/interpreter.rs index 099908c..eacbd14 100644 --- a/crates/saft-eval/src/interpreter.rs +++ b/crates/saft-eval/src/interpreter.rs @@ -5,6 +5,7 @@ use saft_ast::{Block, Expr, Ident, Item, Module, Statement}; use saft_common::span::{Span, Spanned}; use std::borrow::Borrow; use std::collections::HashMap; +use std::rc::Rc; #[macro_export] macro_rules! exotic { @@ -141,10 +142,10 @@ impl Interpreter { params, body, }) => { - let fun = Value::Function(Function::SaftFunction(SaftFunction { + let fun = Value::Function(Rc::new(Function::SaftFunction(SaftFunction { params: params.clone(), body: body.clone(), - })); + }))); self.env.declare(ident, fun); Ok(()) } @@ -316,8 +317,10 @@ impl Interpreter { arg_vals.push(self.eval_expr(arg)?); } - match fun.v { - Value::Function(Function::SaftFunction(SaftFunction { params, body })) => { + match &fun.v { + Value::Function(fun) + if let Function::SaftFunction(SaftFunction { params, body }) = fun.as_ref() => + { match self.scoped(|interpreter| { if arg_vals.len() != params.len() { return Err(Exception::ArgMismatch { @@ -339,7 +342,9 @@ impl Interpreter { Err(e) => return Err(e), } } - Value::Function(Function::NativeFunction(NativeFuncData { f, .. })) => { + Value::Function(fun) + if let Function::NativeFunction(NativeFuncData { f, .. }) = fun.as_ref() => + { f(self, &s, arg_vals)? } _ => { diff --git a/crates/saft-eval/src/natives.rs b/crates/saft-eval/src/natives.rs index beffafd..e7a56b1 100644 --- a/crates/saft-eval/src/natives.rs +++ b/crates/saft-eval/src/natives.rs @@ -1,3 +1,5 @@ +use std::rc::Rc; + use crate::interpreter::{ControlFlow, Interpreter}; use crate::{cast_error, exotic}; use saft_common::span::{Span, Spanned}; @@ -69,6 +71,6 @@ fn add_native(env: &mut Env) { let data = N::data(); env.declare_unspanned( &data.name.into(), - Value::Function(Function::NativeFunction(data)), + Value::Function(Rc::new(Function::NativeFunction(data))), ); } diff --git a/crates/saft-eval/src/value.rs b/crates/saft-eval/src/value.rs index ef2e61d..12c366a 100644 --- a/crates/saft-eval/src/value.rs +++ b/crates/saft-eval/src/value.rs @@ -1,5 +1,5 @@ use crate::interpreter::{ControlFlow, Interpreter}; -use std::borrow::Borrow; +use std::{borrow::Borrow, rc::Rc}; use saft_ast::Block; use saft_common::span::{Span, Spanned}; @@ -8,7 +8,7 @@ use saft_common::span::{Span, Spanned}; pub enum Value { Nil, Num(Num), - Function(Function), + Function(Rc), String(String), Vec(Vec), } @@ -18,8 +18,10 @@ impl Value { match self { Value::Nil => "nil".into(), Value::Num(num) => num.repr(), - Value::Function(Function::SaftFunction(..)) => "".into(), - Value::Function(Function::NativeFunction(..)) => "".into(), + Value::Function(fun) => match fun.as_ref() { + Function::SaftFunction(_) => "".into(), + Function::NativeFunction(_) => "".into(), + }, Value::String(s) => format!("\"{}\"", s), Value::Vec(vals) => { let mut buf = String::new();