stak_process_context/
primitive_set.rs

1mod primitive;
2
3pub use self::primitive::Primitive;
4use crate::ProcessContext;
5use stak_vm::{Error, Heap, Memory, PrimitiveSet};
6use winter_maybe_async::maybe_async;
7
8/// A primitive set for process context.
9pub struct ProcessContextPrimitiveSet<T: ProcessContext> {
10    process_context: T,
11}
12
13impl<T: ProcessContext> ProcessContextPrimitiveSet<T> {
14    /// Creates a primitive set.
15    pub const fn new(process_context: T) -> Self {
16        Self { process_context }
17    }
18}
19
20impl<T: ProcessContext, H: Heap> PrimitiveSet<H> for ProcessContextPrimitiveSet<T> {
21    type Error = Error;
22
23    #[maybe_async]
24    fn operate(&mut self, memory: &mut Memory<H>, primitive: usize) -> Result<(), Self::Error> {
25        match primitive {
26            Primitive::COMMAND_LINE => {
27                memory.set_register(memory.null()?);
28
29                for argument in self.process_context.command_line_rev() {
30                    let string = memory.build_raw_string(argument)?;
31                    let list = memory.cons(string.into(), memory.register())?;
32                    memory.set_register(list);
33                }
34
35                memory.push(memory.register().into())?;
36            }
37            Primitive::ENVIRONMENT_VARIABLES => {
38                memory.set_register(memory.null()?);
39
40                for (key, value) in self.process_context.environment_variables() {
41                    let pair = memory.allocate(memory.null()?.into(), memory.null()?.into())?;
42                    let list = memory.cons(pair.into(), memory.register())?;
43                    memory.set_register(list);
44
45                    let string = memory.build_raw_string(key)?;
46                    memory.set_car_value(memory.car(memory.register())?, string.into())?;
47
48                    let string = memory.build_raw_string(value)?;
49                    memory.set_cdr_value(memory.car(memory.register())?, string.into())?;
50                }
51
52                memory.push(memory.register().into())?;
53            }
54            _ => return Err(Error::IllegalPrimitive),
55        }
56
57        Ok(())
58    }
59}