1use super::*;
2use std::collections::HashMap;
3
4use crate::value::Value;
5
6pub trait NanValueConvert {
11 fn from_value(val: &Value, arena: &mut Arena) -> NanValue;
12 fn to_value(self, arena: &Arena) -> Value;
13}
14
15impl NanValueConvert for NanValue {
16 fn from_value(val: &Value, arena: &mut Arena) -> NanValue {
18 match val {
19 Value::Int(i) => NanValue::from_aver_int(i.clone(), arena),
20 Value::Float(f) => NanValue::new_float(*f),
21 Value::Bool(b) => NanValue::new_bool(*b),
22 Value::Unit => NanValue::UNIT,
23 Value::None => NanValue::NONE,
24 Value::Str(s) => NanValue::new_string_value(s, arena),
25 Value::Ok(inner) => {
26 let inner_nv = NanValue::from_value(inner, arena);
27 NanValue::new_ok_value(inner_nv, arena)
28 }
29 Value::Err(inner) => {
30 let inner_nv = NanValue::from_value(inner, arena);
31 NanValue::new_err_value(inner_nv, arena)
32 }
33 Value::Some(inner) => {
34 let inner_nv = NanValue::from_value(inner, arena);
35 NanValue::new_some_value(inner_nv, arena)
36 }
37 Value::Tuple(items) => {
38 let nv_items: Vec<_> = items
39 .iter()
40 .map(|v| NanValue::from_value(v, arena))
41 .collect();
42 NanValue::new_tuple(arena.push_tuple(nv_items))
43 }
44 Value::List(aver_list) => {
45 let items: Vec<_> = aver_list
46 .to_vec()
47 .iter()
48 .map(|v| NanValue::from_value(v, arena))
49 .collect();
50 if items.is_empty() {
51 NanValue::EMPTY_LIST
52 } else {
53 NanValue::new_list(arena.push_list(items))
54 }
55 }
56 Value::Vector(vec) => {
57 let items: Vec<_> = vec.iter().map(|v| NanValue::from_value(v, arena)).collect();
58 if items.is_empty() {
59 NanValue::EMPTY_VECTOR
60 } else {
61 NanValue::new_vector(arena.push_vector(items))
62 }
63 }
64 Value::Map(map) => {
65 if map.is_empty() {
66 return NanValue::EMPTY_MAP;
67 }
68 let mut nv_map = PersistentMap::new();
69 for (k, v) in map {
70 let nk = NanValue::from_value(k, arena);
71 let nv = NanValue::from_value(v, arena);
72 nv_map = nv_map.insert(nk.map_key_hash_deep(arena), (nk, nv));
77 }
78 let idx = arena.push(ArenaEntry::Map(nv_map));
79 NanValue::new_map(idx)
80 }
81 Value::Fn(f) => NanValue::new_fn(arena.push_fn(Rc::clone(f))),
82 Value::Builtin(name) => NanValue::new_builtin(arena.push_builtin(name)),
83 Value::Record { type_name, fields } => {
84 let type_id = arena.find_type_id(type_name).unwrap_or_else(|| {
85 let field_names: Vec<String> = fields.iter().map(|(n, _)| n.clone()).collect();
86 arena.register_record_type(type_name, field_names)
87 });
88 let nv_fields: Vec<_> = fields
89 .iter()
90 .map(|(_, v)| NanValue::from_value(v, arena))
91 .collect();
92 NanValue::new_record(arena.push_record(type_id, nv_fields))
93 }
94 Value::Variant {
95 type_name,
96 variant,
97 fields,
98 } => {
99 let type_id = arena
100 .find_type_id(type_name)
101 .unwrap_or_else(|| arena.register_sum_type(type_name, vec![variant.clone()]));
102 let variant_id = arena
103 .find_variant_id(type_id, variant)
104 .unwrap_or_else(|| arena.register_variant_name(type_id, variant.clone()));
105 let nv_fields: Vec<_> = fields
106 .iter()
107 .map(|v| NanValue::from_value(v, arena))
108 .collect();
109 if nv_fields.is_empty() {
110 NanValue::new_nullary_variant(arena.push_nullary_variant_symbol(
111 arena.find_ctor_id(type_id, variant_id).unwrap(),
112 ))
113 } else if nv_fields.len() == 1 {
114 if let Some(ctor_id) = arena.find_ctor_id(type_id, variant_id)
115 && let Some(iv) = NanValue::try_new_inline_variant(ctor_id, nv_fields[0])
116 {
117 return iv;
118 }
119 NanValue::new_variant(arena.push_variant(type_id, variant_id, nv_fields))
120 } else {
121 NanValue::new_variant(arena.push_variant(type_id, variant_id, nv_fields))
122 }
123 }
124 Value::Namespace { name, members } => {
125 let nv_members: Vec<_> = members
126 .iter()
127 .map(|(k, v)| (Rc::from(k.as_str()), NanValue::from_value(v, arena)))
128 .collect();
129 let idx = arena.push(ArenaEntry::Namespace {
130 name: Rc::from(name.as_str()),
131 members: nv_members,
132 });
133 NanValue::new_namespace(idx)
134 }
135 }
136 }
137
138 fn to_value(self, arena: &Arena) -> Value {
140 if self.is_float() {
141 return Value::Float(self.as_float());
142 }
143 if let Some((kind, inner)) = self.wrapper_parts(arena) {
144 let inner = inner.to_value(arena);
145 return match kind {
146 WRAP_SOME => Value::Some(Box::new(inner)),
147 WRAP_OK => Value::Ok(Box::new(inner)),
148 WRAP_ERR => Value::Err(Box::new(inner)),
149 _ => Value::Unit,
150 };
151 }
152 if let Some((type_id, variant_id, inner)) = self.inline_variant_info(arena) {
153 let type_name = arena.get_type_name(type_id).to_string();
154 let variant = arena.get_variant_name(type_id, variant_id).to_string();
155 return Value::Variant {
156 type_name,
157 variant,
158 fields: vec![inner.to_value(arena)].into(),
159 };
160 }
161 if let Some((type_id, variant_id, fields)) = self.variant_parts(arena) {
162 let type_name = arena.get_type_name(type_id).to_string();
163 let variant = arena.get_variant_name(type_id, variant_id).to_string();
164 let vals: Vec<Value> = fields.iter().map(|v| v.to_value(arena)).collect();
165 return Value::Variant {
166 type_name,
167 variant,
168 fields: vals.into(),
169 };
170 }
171 match self.tag() {
172 TAG_INT => Value::Int(self.as_aver_int(arena)),
173 TAG_IMMEDIATE => match self.payload() {
174 IMM_FALSE => Value::Bool(false),
175 IMM_TRUE => Value::Bool(true),
176 IMM_UNIT => Value::Unit,
177 _ => Value::Unit,
178 },
179 TAG_NONE => Value::None,
180 TAG_SOME | TAG_OK | TAG_ERR => {
181 unreachable!("wrapper conversion handled before tag switch")
182 }
183 TAG_STRING => Value::Str(arena.get_string_value(self).to_string()),
184 TAG_LIST => {
185 let vals: Vec<Value> = arena
186 .list_to_vec_value(self)
187 .into_iter()
188 .map(|v| v.to_value(arena))
189 .collect();
190 Value::List(aver_rt::AverList::from_vec(vals))
191 }
192 TAG_VECTOR => {
193 let items = arena.vector_ref_value(self);
194 let vals: Vec<Value> = items.iter().map(|v| v.to_value(arena)).collect();
195 Value::Vector(aver_rt::AverVector::from_vec(vals))
196 }
197 TAG_TUPLE => {
198 let items = arena.get_tuple(self.arena_index());
199 Value::Tuple(items.iter().map(|v| v.to_value(arena)).collect())
200 }
201 TAG_MAP => {
202 let map = arena.map_ref_value(self);
203 let mut hm = HashMap::new();
204 for (k, v) in map.values() {
205 hm.insert(k.to_value(arena), v.to_value(arena));
206 }
207 Value::Map(hm)
208 }
209 TAG_RECORD => {
210 let (type_id, fields) = arena.get_record(self.arena_index());
211 let type_name = arena.get_type_name(type_id).to_string();
212 let field_names = arena.get_field_names(type_id);
213 let pairs: Vec<(String, Value)> = field_names
214 .iter()
215 .zip(fields)
216 .map(|(n, v)| (n.clone(), v.to_value(arena)))
217 .collect();
218 Value::Record {
219 type_name,
220 fields: pairs.into(),
221 }
222 }
223 TAG_VARIANT | TAG_INLINE_VARIANT => {
224 unreachable!("variant conversion handled before tag switch")
225 }
226 TAG_SYMBOL => match self.symbol_kind() {
227 SYMBOL_FN => Value::Fn(Rc::clone(arena.get_fn_rc(self.symbol_index()))),
228 SYMBOL_BUILTIN => {
229 Value::Builtin(arena.get_builtin(self.symbol_index()).to_string())
230 }
231 SYMBOL_NAMESPACE => {
232 let (name, members) = arena.get_namespace(self.symbol_index());
233 let mut hm = HashMap::new();
234 for (k, v) in members {
235 hm.insert(k.to_string(), v.to_value(arena));
236 }
237 Value::Namespace {
238 name: name.to_string(),
239 members: hm,
240 }
241 }
242 SYMBOL_NULLARY_VARIANT => {
243 unreachable!("variant conversion handled before tag switch")
244 }
245 _ => Value::Unit,
246 },
247 _ => Value::Unit,
248 }
249 }
250}