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}