1use collect_upvars::collect_upvars;
4
5use crate::error::ErrorKind;
6
7use super::{Callable, ConValue, Environment, Error, IResult, Interpret, pattern};
8use cl_ast::{Function as FnDecl, Sym};
9use std::{
10 cell::{Ref, RefCell},
11 collections::HashMap,
12 rc::Rc,
13};
14
15pub mod collect_upvars;
16
17type Upvars = HashMap<Sym, ConValue>;
18
19#[derive(Clone, Debug)]
21pub struct Function {
22 decl: Rc<FnDecl>,
24 upvars: RefCell<Upvars>,
26}
27
28impl Function {
29 pub fn new(decl: &FnDecl) -> Self {
30 Self { decl: decl.clone().into(), upvars: Default::default() }
32 }
33 pub fn decl(&self) -> &FnDecl {
34 &self.decl
35 }
36 pub fn upvars(&self) -> Ref<'_, Upvars> {
37 self.upvars.borrow()
38 }
39 pub fn lift_upvars(&self, env: &Environment) {
40 let upvars = collect_upvars(&self.decl, env);
41 if let Ok(mut self_upvars) = self.upvars.try_borrow_mut() {
42 *self_upvars = upvars;
43 }
44 }
45}
46
47impl Callable for Function {
48 fn name(&self) -> Sym {
49 let FnDecl { name, .. } = *self.decl;
50 name
51 }
52 fn call(&self, env: &mut Environment, args: &[ConValue]) -> IResult<ConValue> {
53 let FnDecl { name, gens: _, bind, body, sign: _ } = &*self.decl;
54
55 let Some(body) = body else {
57 return Err(Error::NotDefined(*name));
58 };
59
60 let upvars = self.upvars.take();
61 let mut env = env.with_frame("upvars", upvars);
62
63 let mut frame = env.frame("fn args");
65 for (name, value) in pattern::substitution(&frame, bind, ConValue::Tuple(args.into()))? {
66 frame.insert(name, value);
67 }
68 let res = body.interpret(&mut frame);
69 drop(frame);
70 if let Some(upvars) = env.pop_values() {
71 self.upvars.replace(upvars);
72 }
73 match res {
74 Err(Error { kind: ErrorKind::Return(value), .. }) => Ok(value),
75 Err(Error { kind: ErrorKind::Break(value), .. }) => Err(Error::BadBreak(value)),
76 Err(Error { kind: ErrorKind::Panic(msg, depth), span: Some(span) }) => {
77 println!("{depth:>4}: {name}{bind} at {}", span.head);
78 Err(Error { kind: ErrorKind::Panic(msg, depth + 1), span: None })
79 }
80 other => other,
81 }
82 }
83}