diff --git a/src/fns.rs b/src/fns.rs index e4eef5de..ee253aee 100644 --- a/src/fns.rs +++ b/src/fns.rs @@ -32,6 +32,20 @@ pub(crate) fn slice_into_list<'ob>( from_end.fold(tail.into(), |acc, obj| cons!(*obj, acc; cx)) } +pub(crate) fn build_list<'ob, E>( + mut iter: impl Iterator, E>>, + cx: &'ob Context, +) -> Result, E> { + let Some(first) = iter.next() else { return Ok(nil()) }; + let mut prev = cons!(first?; cx); + for elem in iter { + let new = cons!(elem?; cx); + prev.as_cons().set_cdr(new).unwrap(); + prev = new; + } + Ok(prev) +} + #[defun] pub(crate) fn eq(obj1: GcObj, obj2: GcObj) -> bool { obj1.ptr_eq(obj2) @@ -224,9 +238,7 @@ fn join<'ob>(list: &mut Vec>, seq: Gc>) -> Result<()> { #[defun] fn take<'ob>(n: i64, list: Gc>, cx: &'ob Context) -> Result> { let Ok(n) = usize::try_from(n) else { return Ok(nil()) }; - // TODO: remove this intermediate vector - let result: Vec<_> = list.elements().fallible().take(n).collect()?; - Ok(slice_into_list(&result, None, cx)) + Ok(build_list(list.elements().take(n), cx)?) } #[defun] diff --git a/src/interpreter.rs b/src/interpreter.rs index fc5ef16f..93a8ad67 100755 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -197,9 +197,11 @@ impl Interpreter<'_> { return Ok(form.bind(cx)); } let env = { - // TODO: remove temp vector - let env: Vec<_> = self.vars.iter().map(|x| x.bind(cx).into()).collect(); - crate::fns::slice_into_list(env.as_slice(), Some(cons!(true; cx)), cx) + let mut tail = cons!(true; cx); + for var in self.vars.iter().rev() { + tail = cons!(var.bind(cx), tail; cx); + } + tail }; Self::replace_doc_symbol(cons, cx)?; if let Some(closure_fn) = self.env.vars.get(sym::INTERNAL_MAKE_INTERPRETED_CLOSURE_FUNCTION)