1use std::{hash::Hash, rc::Rc};
2use ordered_float::OrderedFloat;
3use ordered_hash_map::OrderedHashMap;
4use crate::parser::Atom;
5
6#[derive(PartialEq, Eq, Clone, Debug)]
7pub enum Value {
8 Int(i64),
9 UInt(u64),
10 Float(OrderedFloat<f64>),
12 Null,
13 Bool(bool),
14 Bytes(Rc<Vec<u8>>),
15 String(Rc<String>),
16 Map(Rc<OrderedHashMap<Value, Value>>),
17 List(Rc<Vec<Value>>),
18 Function(Rc<FnValue>)
19}
20
21#[derive(PartialEq, Eq, Debug)]
22pub struct FnValue {
23 pub name: &'static str,
24 pub overloads: &'static [Overload],
25}
26
27pub type Func = fn(lhs: &Value, rhs: &Value) -> Value;
28
29#[derive(PartialEq, Eq, Debug)]
30pub struct Overload {
31 pub key: &'static str,
32 pub func: Func
33}
34
35impl Into<bool> for Value {
36 fn into(self) -> bool {
37 match self {
38 Value::Int(v) => v != 0,
39 Value::UInt(v) => v != 0,
40 Value::Float(v) => v != 0.0,
41 Value::Null => false,
42 Value::Bool(v) => v,
43 Value::Bytes(v) => v.len() > 0,
44 Value::String(v) => v.len() > 0,
45 Value::Map(v) => v.len() > 0,
46 Value::List(v) => v.len() > 0,
47 Value::Function(_) => true,
48 }
49 }
50}
51
52impl Hash for Value {
53 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
54 core::mem::discriminant(self).hash(state);
56 }
57}
58
59impl From<Atom> for Value {
60 fn from(atom: Atom) -> Self {
61 match atom {
62 Atom::Int(i) => Value::Int(i),
63 Atom::UInt(ui) => Value::UInt(ui),
64 Atom::Float(f) => Value::Float(f.into()),
65 Atom::Bool(b) => Value::Bool(b),
66 Atom::Null => Value::Null,
67 Atom::Bytes(b) => Value::Bytes(b),
68 Atom::String(s) => Value::String(s),
69 }
70 }
71}
72
73impl std::fmt::Display for Value {
74 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75 match self {
76 Value::Int(v) => write!(f, "int({})", v),
77 Value::UInt(v) => write!(f, "uint({})", v),
78 Value::Float(v) => write!(f, "float({})", v),
79 Value::Null => write!(f, "null"),
80 Value::Bool(v) => write!(f, "bool({})", v),
81 Value::Bytes(v) => write!(f, "bytes(len = {})", v.len()),
82 Value::String(v) => write!(f, "string({})", v),
83 Value::Map(v) => write!(f, "map(len = {})", v.len()),
84 Value::List(v) => write!(f, "list(len = {})", v.len()),
85 Value::Function(v) => write!(f, "function(name = {})", v.name),
86 }
87 }
88}
89
90impl std::ops::Mul for Value {
91 type Output = Value;
92
93 fn mul(self, rhs: Self) -> Self::Output {
94 match (self, rhs) {
95 (Value::Int(l), Value::Int(r)) => Value::Int(l * r),
96 (a, b) => todo!("mul {} {}", a, b),
97 }
98 }
99}
100
101impl std::ops::Div for Value {
102 type Output = Value;
103
104 fn div(self, rhs: Self) -> Self::Output {
105 match (self, rhs) {
106 (Value::Int(l), Value::Int(r)) => Value::Int(l / r),
107 (a, b) => todo!("div {} {}", a, b),
108 }
109 }
110}
111
112impl std::ops::Add<Value> for Value {
113 type Output = Value;
114
115 fn add(self, o: Value) -> Self::Output {
116 match (self, o) {
117 (Value::Int(l), Value::Int(r)) => Value::Int(l + r),
118 (a, b) => todo!("add {} {}", a, b),
119 }
120 }
121}
122
123impl std::ops::Sub<Value> for Value {
124 type Output = Value;
125 fn sub(self, o: Value) -> Self::Output {
126 match (self, o) {
127 (Value::Int(l), Value::Int(r)) => Value::Int(l - r),
128 (a, b) => todo!("sub {} {}", a, b),
129 }
130 }
131}