slvm/vm/
cons.rs

1use crate::{GVm, VMError, VMResult, Value, decode_u16, decode2, decode3, set_register};
2
3impl<ENV> GVm<ENV> {
4    pub(super) fn list(&mut self, wide: bool) -> VMResult<()> {
5        let (dest, start, end) = decode3!(self.ip_ptr, wide);
6        if end < start {
7            set_register!(self, dest as usize, Value::Nil);
8        } else {
9            let mut last_cdr = Value::Nil;
10            for i in (start..=end).rev() {
11                let car = self.register_unref(i as usize);
12                let cdr = last_cdr;
13                last_cdr = self.alloc_pair(car, cdr);
14            }
15            set_register!(self, dest as usize, last_cdr);
16        }
17        Ok(())
18    }
19
20    pub(super) fn append(&mut self, wide: bool) -> VMResult<()> {
21        let (dest, start, end) = decode3!(self.ip_ptr, wide);
22        if end < start {
23            set_register!(self, dest as usize, Value::Nil);
24        } else {
25            let mut last_cdr = Value::Nil;
26            let mut head = Value::Nil;
27            let mut loop_cdr;
28            for i in start..=end {
29                let lst = self.register_unref(i as usize);
30                match lst {
31                    Value::Nil => {}
32                    Value::Pair(_) | Value::List(_, _) => {
33                        let (car, cdr) = lst.get_pair(self).expect("Pair/List not a Pair or List?");
34                        loop_cdr = cdr;
35                        let cdr = last_cdr;
36                        last_cdr = self.alloc_pair(car, Value::Nil);
37                        match cdr {
38                            Value::Nil => head = last_cdr,
39                            Value::Pair(h) => {
40                                let (_, cdr) = self.get_pair_mut(h)?;
41                                *cdr = last_cdr;
42                            }
43                            Value::List(_, _) => {
44                                return Err(VMError::new_heap("Pair is not mutable!"));
45                            }
46                            _ => {}
47                        }
48                        loop {
49                            if let Value::Nil = loop_cdr {
50                                break;
51                            }
52                            match loop_cdr {
53                                Value::Pair(_) | Value::List(_, _) => {
54                                    let (car, ncdr) = loop_cdr
55                                        .get_pair(self)
56                                        .expect("Pair/List not a Pair or List?");
57                                    loop_cdr = ncdr;
58                                    let cdr = last_cdr;
59                                    last_cdr = self.alloc_pair(car, Value::Nil);
60                                    match cdr {
61                                        Value::Nil => head = last_cdr,
62                                        Value::Pair(h) => {
63                                            let (_, cdr) = self.get_pair_mut(h)?;
64                                            *cdr = last_cdr;
65                                        }
66                                        Value::List(_, _) => {
67                                            return Err(VMError::new_heap("Pair is not mutable!"));
68                                        }
69                                        _ => {}
70                                    }
71                                }
72                                _ => {
73                                    if i == end {
74                                        match last_cdr {
75                                            Value::Nil => head = loop_cdr,
76                                            Value::Pair(h) => {
77                                                let (_, cdr) = self.get_pair_mut(h)?;
78                                                *cdr = loop_cdr;
79                                            }
80                                            Value::List(_, _) => {
81                                                return Err(VMError::new_heap(
82                                                    "Pair is not mutable!",
83                                                ));
84                                            }
85                                            _ => {}
86                                        }
87                                    } else {
88                                        return Err(VMError::new_vm("APND: Param not a list."));
89                                    }
90                                    break;
91                                }
92                            }
93                        }
94                    }
95                    _ => {
96                        if i == end {
97                            match last_cdr {
98                                Value::Nil => head = lst,
99                                Value::Pair(h) => {
100                                    let (_, cdr) = self.get_pair_mut(h)?;
101                                    *cdr = lst;
102                                }
103                                Value::List(_, _) => {
104                                    return Err(VMError::new_heap("Pair is not mutable!"));
105                                }
106                                _ => {}
107                            }
108                        } else {
109                            return Err(VMError::new_vm("APND: Param not a list."));
110                        }
111                    }
112                }
113            }
114            set_register!(self, dest as usize, head);
115        }
116        Ok(())
117    }
118
119    pub(super) fn xar(&mut self, wide: bool) -> VMResult<()> {
120        let (pair_reg, val) = decode2!(self.ip_ptr, wide);
121        let pair = self.register_unref(pair_reg as usize);
122        let val = self.register_unref(val as usize);
123        match &pair {
124            Value::Pair(handle) => {
125                let (car, _) = self.get_pair_mut(*handle)?;
126                *car = val;
127            }
128            Value::List(_, _) => return Err(VMError::new_vm("XAR: Pair is read only.")),
129            _ => return Err(VMError::new_vm("XAR: Not a pair/conscell.")),
130        }
131        Ok(())
132    }
133
134    pub(super) fn xdr(&mut self, wide: bool) -> VMResult<()> {
135        let (pair_reg, val) = decode2!(self.ip_ptr, wide);
136        let pair = self.register_unref(pair_reg as usize);
137        let val = self.register_unref(val as usize);
138        match &pair {
139            Value::Pair(handle) => {
140                let (_, cdr) = self.get_pair_mut(*handle)?;
141                *cdr = val;
142            }
143            Value::List(_, _) => return Err(VMError::new_vm("XDR: Pair is read only.")),
144            _ => return Err(VMError::new_vm("XDR: Not a pair/conscell.")),
145        }
146        Ok(())
147    }
148}