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::new_int(*i, 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(arena), (nk, nv));
73 }
74 let idx = arena.push(ArenaEntry::Map(nv_map));
75 NanValue::new_map(idx)
76 }
77 Value::Fn(f) => NanValue::new_fn(arena.push_fn(Rc::clone(f))),
78 Value::Builtin(name) => NanValue::new_builtin(arena.push_builtin(name)),
79 Value::Record { type_name, fields } => {
80 let type_id = arena.find_type_id(type_name).unwrap_or_else(|| {
81 let field_names: Vec<String> = fields.iter().map(|(n, _)| n.clone()).collect();
82 arena.register_record_type(type_name, field_names)
83 });
84 let nv_fields: Vec<_> = fields
85 .iter()
86 .map(|(_, v)| NanValue::from_value(v, arena))
87 .collect();
88 NanValue::new_record(arena.push_record(type_id, nv_fields))
89 }
90 Value::Variant {
91 type_name,
92 variant,
93 fields,
94 } => {
95 let type_id = arena
96 .find_type_id(type_name)
97 .unwrap_or_else(|| arena.register_sum_type(type_name, vec![variant.clone()]));
98 let variant_id = arena
99 .find_variant_id(type_id, variant)
100 .unwrap_or_else(|| arena.register_variant_name(type_id, variant.clone()));
101 let nv_fields: Vec<_> = fields
102 .iter()
103 .map(|v| NanValue::from_value(v, arena))
104 .collect();
105 if nv_fields.is_empty() {
106 NanValue::new_nullary_variant(arena.push_nullary_variant_symbol(
107 arena.find_ctor_id(type_id, variant_id).unwrap(),
108 ))
109 } else if nv_fields.len() == 1 {
110 if let Some(ctor_id) = arena.find_ctor_id(type_id, variant_id)
111 && let Some(iv) = NanValue::try_new_inline_variant(ctor_id, nv_fields[0])
112 {
113 return iv;
114 }
115 NanValue::new_variant(arena.push_variant(type_id, variant_id, nv_fields))
116 } else {
117 NanValue::new_variant(arena.push_variant(type_id, variant_id, nv_fields))
118 }
119 }
120 Value::Namespace { name, members } => {
121 let nv_members: Vec<_> = members
122 .iter()
123 .map(|(k, v)| (Rc::from(k.as_str()), NanValue::from_value(v, arena)))
124 .collect();
125 let idx = arena.push(ArenaEntry::Namespace {
126 name: Rc::from(name.as_str()),
127 members: nv_members,
128 });
129 NanValue::new_namespace(idx)
130 }
131 }
132 }
133
134 fn to_value(self, arena: &Arena) -> Value {
136 if self.is_float() {
137 return Value::Float(self.as_float());
138 }
139 if let Some((kind, inner)) = self.wrapper_parts(arena) {
140 let inner = inner.to_value(arena);
141 return match kind {
142 WRAP_SOME => Value::Some(Box::new(inner)),
143 WRAP_OK => Value::Ok(Box::new(inner)),
144 WRAP_ERR => Value::Err(Box::new(inner)),
145 _ => Value::Unit,
146 };
147 }
148 if let Some((type_id, variant_id, inner)) = self.inline_variant_info(arena) {
149 let type_name = arena.get_type_name(type_id).to_string();
150 let variant = arena.get_variant_name(type_id, variant_id).to_string();
151 return Value::Variant {
152 type_name,
153 variant,
154 fields: vec![inner.to_value(arena)].into(),
155 };
156 }
157 if let Some((type_id, variant_id, fields)) = self.variant_parts(arena) {
158 let type_name = arena.get_type_name(type_id).to_string();
159 let variant = arena.get_variant_name(type_id, variant_id).to_string();
160 let vals: Vec<Value> = fields.iter().map(|v| v.to_value(arena)).collect();
161 return Value::Variant {
162 type_name,
163 variant,
164 fields: vals.into(),
165 };
166 }
167 match self.tag() {
168 TAG_INT => Value::Int(self.as_int(arena)),
169 TAG_IMMEDIATE => match self.payload() {
170 IMM_FALSE => Value::Bool(false),
171 IMM_TRUE => Value::Bool(true),
172 IMM_UNIT => Value::Unit,
173 _ => Value::Unit,
174 },
175 TAG_NONE => Value::None,
176 TAG_SOME | TAG_OK | TAG_ERR => {
177 unreachable!("wrapper conversion handled before tag switch")
178 }
179 TAG_STRING => Value::Str(arena.get_string_value(self).to_string()),
180 TAG_LIST => {
181 let vals: Vec<Value> = arena
182 .list_to_vec_value(self)
183 .into_iter()
184 .map(|v| v.to_value(arena))
185 .collect();
186 Value::List(aver_rt::AverList::from_vec(vals))
187 }
188 TAG_VECTOR => {
189 let items = arena.vector_ref_value(self);
190 let vals: Vec<Value> = items.iter().map(|v| v.to_value(arena)).collect();
191 Value::Vector(aver_rt::AverVector::from_vec(vals))
192 }
193 TAG_TUPLE => {
194 let items = arena.get_tuple(self.arena_index());
195 Value::Tuple(items.iter().map(|v| v.to_value(arena)).collect())
196 }
197 TAG_MAP => {
198 let map = arena.map_ref_value(self);
199 let mut hm = HashMap::new();
200 for (k, v) in map.values() {
201 hm.insert(k.to_value(arena), v.to_value(arena));
202 }
203 Value::Map(hm)
204 }
205 TAG_RECORD => {
206 let (type_id, fields) = arena.get_record(self.arena_index());
207 let type_name = arena.get_type_name(type_id).to_string();
208 let field_names = arena.get_field_names(type_id);
209 let pairs: Vec<(String, Value)> = field_names
210 .iter()
211 .zip(fields)
212 .map(|(n, v)| (n.clone(), v.to_value(arena)))
213 .collect();
214 Value::Record {
215 type_name,
216 fields: pairs.into(),
217 }
218 }
219 TAG_VARIANT | TAG_INLINE_VARIANT => {
220 unreachable!("variant conversion handled before tag switch")
221 }
222 TAG_SYMBOL => match self.symbol_kind() {
223 SYMBOL_FN => Value::Fn(Rc::clone(arena.get_fn_rc(self.symbol_index()))),
224 SYMBOL_BUILTIN => {
225 Value::Builtin(arena.get_builtin(self.symbol_index()).to_string())
226 }
227 SYMBOL_NAMESPACE => {
228 let (name, members) = arena.get_namespace(self.symbol_index());
229 let mut hm = HashMap::new();
230 for (k, v) in members {
231 hm.insert(k.to_string(), v.to_value(arena));
232 }
233 Value::Namespace {
234 name: name.to_string(),
235 members: hm,
236 }
237 }
238 SYMBOL_NULLARY_VARIANT => {
239 unreachable!("variant conversion handled before tag switch")
240 }
241 _ => Value::Unit,
242 },
243 _ => Value::Unit,
244 }
245 }
246}