stak_process_context/
primitive_set.rs

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