mod primitive;
pub use self::primitive::Primitive;
use crate::ProcessContext;
use stak_vm::{Error, Heap, Memory, PrimitiveSet};
use winter_maybe_async::maybe_async;
pub struct ProcessContextPrimitiveSet<T: ProcessContext> {
process_context: T,
}
impl<T: ProcessContext> ProcessContextPrimitiveSet<T> {
pub const fn new(process_context: T) -> Self {
Self { process_context }
}
}
impl<T: ProcessContext, H: Heap> PrimitiveSet<H> for ProcessContextPrimitiveSet<T> {
type Error = Error;
#[maybe_async]
fn operate(&mut self, memory: &mut Memory<H>, primitive: usize) -> Result<(), Self::Error> {
match primitive {
Primitive::COMMAND_LINE => {
memory.set_register(memory.null()?);
for argument in self.process_context.command_line_rev() {
let string = memory.build_raw_string(argument)?;
let list = memory.cons(string.into(), memory.register())?;
memory.set_register(list);
}
memory.push(memory.register().into())?;
}
Primitive::ENVIRONMENT_VARIABLES => {
memory.set_register(memory.null()?);
for (key, value) in self.process_context.environment_variables() {
let pair = memory.allocate(memory.null()?.into(), memory.null()?.into())?;
let list = memory.cons(pair.into(), memory.register())?;
memory.set_register(list);
let string = memory.build_raw_string(key)?;
memory.set_car_value(memory.car(memory.register())?, string.into())?;
let string = memory.build_raw_string(value)?;
memory.set_cdr_value(memory.car(memory.register())?, string.into())?;
}
memory.push(memory.register().into())?;
}
_ => return Err(Error::IllegalPrimitive),
}
Ok(())
}
}