cl-interpret: copy-capture closures
This commit is contained in:
parent
d3e20e53d0
commit
ccfa4c7723
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
Callable,
|
||||
convalue::ConValue,
|
||||
env::{Environment, Place},
|
||||
env::Environment,
|
||||
error::{Error, ErrorKind, IResult},
|
||||
function::collect_upvars::CollectUpvars,
|
||||
interpret::Interpret,
|
||||
@ -11,11 +11,11 @@ use cl_ast::{Sym, ast_visitor::Visit};
|
||||
use std::{collections::HashMap, fmt::Display};
|
||||
|
||||
/// Represents an ad-hoc anonymous function
|
||||
/// which captures surrounding state by reference.
|
||||
/// which captures surrounding state by COPY
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Closure {
|
||||
decl: cl_ast::Closure,
|
||||
lift: HashMap<Sym, Place>,
|
||||
lift: HashMap<Sym, Option<ConValue>>,
|
||||
}
|
||||
|
||||
impl Closure {
|
||||
@ -24,7 +24,7 @@ impl Closure {
|
||||
|
||||
impl Closure {
|
||||
pub fn new(env: &mut Environment, decl: &cl_ast::Closure) -> Self {
|
||||
let lift = CollectUpvars::new(env).visit(decl).finish();
|
||||
let lift = CollectUpvars::new(env).visit(decl).finish_copied();
|
||||
Self { decl: decl.clone(), lift }
|
||||
}
|
||||
}
|
||||
@ -42,8 +42,8 @@ impl Callable for Closure {
|
||||
let mut env = env.frame(Self::NAME);
|
||||
|
||||
// place lifts in scope
|
||||
for (name, place) in lift {
|
||||
env.insert(*name, Some(ConValue::Ref(*place)));
|
||||
for (name, value) in lift.clone() {
|
||||
env.insert(name, value);
|
||||
}
|
||||
|
||||
let mut env = env.frame("args");
|
||||
|
@ -99,6 +99,11 @@ impl Environment {
|
||||
function.call(self, args)
|
||||
}
|
||||
|
||||
/// Gets all registered globals, bound or unbound.
|
||||
pub fn globals(&self) -> &HashMap<Sym, Option<ConValue>> {
|
||||
&self.global
|
||||
}
|
||||
|
||||
/// Adds builtins
|
||||
///
|
||||
/// # Panics
|
||||
|
@ -7,12 +7,7 @@ use cl_ast::{
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
pub fn collect_upvars(f: &Function, env: &Environment) -> super::Upvars {
|
||||
CollectUpvars::new(env)
|
||||
.visit(f)
|
||||
.finish()
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k, env.get_id(v).cloned()))
|
||||
.collect()
|
||||
CollectUpvars::new(env).visit(f).finish_copied()
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@ -31,6 +26,14 @@ impl<'env> CollectUpvars<'env> {
|
||||
std::mem::take(&mut self.upvars)
|
||||
}
|
||||
|
||||
pub fn finish_copied(&mut self) -> super::Upvars {
|
||||
let Self { env, upvars, blacklist: _ } = self;
|
||||
std::mem::take(upvars)
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k, env.get_id(v).cloned()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn add_upvar(&mut self, name: &Sym) {
|
||||
let Self { env, upvars, blacklist } = self;
|
||||
if blacklist.contains(name) || upvars.contains_key(name) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user