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