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(arena.push_string(s)),
16 Value::Ok(inner) => {
17 let inner_nv = NanValue::from_value(inner, arena);
18 let idx = arena.push_boxed(inner_nv);
19 NanValue::new_ok(idx)
20 }
21 Value::Err(inner) => {
22 let inner_nv = NanValue::from_value(inner, arena);
23 let idx = arena.push_boxed(inner_nv);
24 NanValue::new_err(idx)
25 }
26 Value::Some(inner) => {
27 let inner_nv = NanValue::from_value(inner, arena);
28 let idx = arena.push_boxed(inner_nv);
29 NanValue::new_some(idx)
30 }
31 Value::Tuple(items) => {
32 let nv_items: Vec<_> = items
33 .iter()
34 .map(|v| NanValue::from_value(v, arena))
35 .collect();
36 NanValue::new_tuple(arena.push_tuple(nv_items))
37 }
38 Value::List(aver_list) => {
39 let items: Vec<_> = aver_list
40 .to_vec()
41 .iter()
42 .map(|v| NanValue::from_value(v, arena))
43 .collect();
44 NanValue::new_list(arena.push_list(items))
45 }
46 Value::Map(map) => {
47 let mut nv_map = PersistentMap::new();
48 for (k, v) in map {
49 let nk = NanValue::from_value(k, arena);
50 let nv = NanValue::from_value(v, arena);
51 nv_map.insert(nk.map_key_hash(arena), (nk, nv));
52 }
53 let idx = arena.push(ArenaEntry::Map(nv_map));
54 NanValue::new_map(idx)
55 }
56 Value::Fn(f) => NanValue::new_fn(arena.push_fn(Rc::clone(f))),
57 Value::Builtin(name) => NanValue::new_builtin(arena.push_builtin(name)),
58 Value::Record { type_name, fields } => {
59 let type_id = arena.find_type_id(type_name).unwrap_or_else(|| {
60 let field_names: Vec<String> = fields.iter().map(|(n, _)| n.clone()).collect();
61 arena.register_record_type(type_name, field_names)
62 });
63 let nv_fields: Vec<_> = fields
64 .iter()
65 .map(|(_, v)| NanValue::from_value(v, arena))
66 .collect();
67 NanValue::new_record(arena.push_record(type_id, nv_fields))
68 }
69 Value::Variant {
70 type_name,
71 variant,
72 fields,
73 } => {
74 let type_id = arena
75 .find_type_id(type_name)
76 .unwrap_or_else(|| arena.register_sum_type(type_name, vec![variant.clone()]));
77 let variant_id = arena.find_variant_id(type_id, variant).unwrap_or_else(|| {
78 let variants = &mut arena.type_variant_names[type_id as usize];
80 let id = variants.len() as u16;
81 variants.push(variant.clone());
82 id
83 });
84 let nv_fields: Vec<_> = fields
85 .iter()
86 .map(|v| NanValue::from_value(v, arena))
87 .collect();
88 NanValue::new_variant(arena.push_variant(type_id, variant_id, nv_fields))
89 }
90 Value::Namespace { name, members } => {
91 let nv_members: Vec<_> = members
92 .iter()
93 .map(|(k, v)| (Rc::from(k.as_str()), NanValue::from_value(v, arena)))
94 .collect();
95 let idx = arena.push(ArenaEntry::Namespace {
96 name: Rc::from(name.as_str()),
97 members: nv_members,
98 });
99 NanValue::new_namespace(idx)
100 }
101 }
102 }
103
104 pub fn to_value(self, arena: &Arena) -> Value {
106 if self.is_float() {
107 return Value::Float(self.as_float());
108 }
109 match self.tag() {
110 TAG_INT => Value::Int(self.as_int(arena)),
111 TAG_IMMEDIATE => match self.payload() {
112 IMM_FALSE => Value::Bool(false),
113 IMM_TRUE => Value::Bool(true),
114 IMM_UNIT => Value::Unit,
115 IMM_NONE => Value::None,
116 _ => Value::Unit,
117 },
118 TAG_WRAPPER => {
119 let inner = arena.get_boxed(self.wrapper_index()).to_value(arena);
120 match self.wrapper_kind() {
121 WRAP_SOME => Value::Some(Box::new(inner)),
122 WRAP_OK => Value::Ok(Box::new(inner)),
123 WRAP_ERR => Value::Err(Box::new(inner)),
124 _ => Value::Unit,
125 }
126 }
127 TAG_STRING => Value::Str(arena.get_string(self.arena_index()).to_string()),
128 TAG_LIST => {
129 let vals: Vec<Value> = arena
130 .list_to_vec(self.arena_index())
131 .into_iter()
132 .map(|v| v.to_value(arena))
133 .collect();
134 Value::List(aver_rt::AverList::from_vec(vals))
135 }
136 TAG_TUPLE => {
137 let items = arena.get_tuple(self.arena_index());
138 Value::Tuple(items.iter().map(|v| v.to_value(arena)).collect())
139 }
140 TAG_MAP => {
141 let map = arena.get_map(self.arena_index());
142 let mut hm = HashMap::new();
143 for (k, v) in map.values() {
144 hm.insert(k.to_value(arena), v.to_value(arena));
145 }
146 Value::Map(hm)
147 }
148 TAG_RECORD => {
149 let (type_id, fields) = arena.get_record(self.arena_index());
150 let type_name = arena.get_type_name(type_id).to_string();
151 let field_names = arena.get_field_names(type_id);
152 let pairs: Vec<(String, Value)> = field_names
153 .iter()
154 .zip(fields)
155 .map(|(n, v)| (n.clone(), v.to_value(arena)))
156 .collect();
157 Value::Record {
158 type_name,
159 fields: pairs.into(),
160 }
161 }
162 TAG_VARIANT => {
163 let (type_id, variant_id, fields) = arena.get_variant(self.arena_index());
164 let type_name = arena.get_type_name(type_id).to_string();
165 let variant = arena.get_variant_name(type_id, variant_id).to_string();
166 let vals: Vec<Value> = fields.iter().map(|v| v.to_value(arena)).collect();
167 Value::Variant {
168 type_name,
169 variant,
170 fields: vals.into(),
171 }
172 }
173 TAG_FN => Value::Fn(Rc::clone(arena.get_fn_rc(self.arena_index()))),
174 TAG_BUILTIN => Value::Builtin(arena.get_builtin(self.arena_index()).to_string()),
175 TAG_NAMESPACE => {
176 let (name, members) = arena.get_namespace(self.arena_index());
177 let mut hm = HashMap::new();
178 for (k, v) in members {
179 hm.insert(k.to_string(), v.to_value(arena));
180 }
181 Value::Namespace {
182 name: name.to_string(),
183 members: hm,
184 }
185 }
186 _ => Value::Unit,
187 }
188 }
189}