add string keys to dicts
This commit is contained in:
parent
d334e483a5
commit
659fdd3506
38
src/base.rs
38
src/base.rs
|
@ -60,7 +60,15 @@ pub fn doc(f: &Value) -> Value {
|
|||
|
||||
pub fn assoc(dict: &Value, key: &Value, value: &Value) -> Value {
|
||||
match (dict, key) {
|
||||
(Value::Dict(d), Value::Keyword(k)) => Value::Dict(Box::new(d.update(k, value.clone()))),
|
||||
(Value::Dict(d), Value::Keyword(k)) => {
|
||||
Value::Dict(Box::new(d.update(Key::Keyword(k), value.clone())))
|
||||
}
|
||||
(Value::Dict(d), Value::Interned(k)) => {
|
||||
Value::Dict(Box::new(d.update(Key::Interned(k), value.clone())))
|
||||
}
|
||||
(Value::Dict(d), Value::String(s)) => {
|
||||
Value::Dict(Box::new(d.update(Key::String(s.clone()), value.clone())))
|
||||
}
|
||||
_ => unreachable!("internal Ludus error calling assoc with ({dict}, {key}, {value})"),
|
||||
}
|
||||
}
|
||||
|
@ -175,7 +183,17 @@ pub fn dissoc(dict: &Value, key: &Value) -> Value {
|
|||
match (dict, key) {
|
||||
(Value::Dict(dict), Value::Keyword(key)) => {
|
||||
let mut new = dict.clone();
|
||||
new.remove(key);
|
||||
new.remove(&Key::Keyword(key));
|
||||
Value::Dict(new)
|
||||
}
|
||||
(Value::Dict(dict), Value::Interned(key)) => {
|
||||
let mut new = dict.clone();
|
||||
new.remove(&Key::Interned(key));
|
||||
Value::Dict(new)
|
||||
}
|
||||
(Value::Dict(dict), Value::String(key)) => {
|
||||
let mut new = dict.clone();
|
||||
new.remove(&Key::String(key.clone()));
|
||||
Value::Dict(new)
|
||||
}
|
||||
_ => unreachable!("internal Ludus error"),
|
||||
|
@ -220,7 +238,15 @@ pub fn at(ordered: &Value, i: &Value) -> Value {
|
|||
|
||||
pub fn get(dict: &Value, key: &Value) -> Value {
|
||||
match (dict, key) {
|
||||
(Value::Dict(dict), Value::Keyword(key)) => match dict.get(key) {
|
||||
(Value::Dict(dict), Value::Keyword(key)) => match dict.get(&Key::Keyword(key)) {
|
||||
Some(x) => x.clone(),
|
||||
None => Value::Nil,
|
||||
},
|
||||
(Value::Dict(dict), Value::Interned(key)) => match dict.get(&Key::Interned(key)) {
|
||||
Some(x) => x.clone(),
|
||||
None => Value::Nil,
|
||||
},
|
||||
(Value::Dict(dict), Value::String(key)) => match dict.get(&Key::String(key.clone())) {
|
||||
Some(x) => x.clone(),
|
||||
None => Value::Nil,
|
||||
},
|
||||
|
@ -344,7 +370,7 @@ pub fn list(x: &Value) -> Value {
|
|||
let kvs = d.iter();
|
||||
let mut list = vector![];
|
||||
for (key, value) in kvs {
|
||||
let kv = Value::Tuple(Rc::new(vec![Value::Keyword(key), value.clone()]));
|
||||
let kv = Value::Tuple(Rc::new(vec![key.to_value(), value.clone()]));
|
||||
list.push_back(kv);
|
||||
}
|
||||
Value::List(Box::new(list))
|
||||
|
@ -645,5 +671,9 @@ pub fn make_base() -> Value {
|
|||
("unbox", Value::BaseFn(BaseFn::Unary("unbox", unbox))),
|
||||
("upcase", Value::BaseFn(BaseFn::Unary("upcase", upcase))),
|
||||
];
|
||||
let members = members
|
||||
.iter()
|
||||
.map(|(name, bfn)| (Key::Keyword(name), bfn.clone()))
|
||||
.collect::<Vec<_>>();
|
||||
Value::Dict(Box::new(HashMap::from(members)))
|
||||
}
|
||||
|
|
62
src/value.rs
62
src/value.rs
|
@ -112,6 +112,42 @@ pub struct Partial {
|
|||
pub function: Value,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum Key {
|
||||
Keyword(&'static str),
|
||||
Interned(&'static str),
|
||||
String(Rc<String>),
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Key {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
Key::Keyword(s) => write!(f, ":{s}"),
|
||||
Key::Interned(s) => write!(f, "\"{s}\""),
|
||||
Key::String(s) => write!(f, "\"{s}\""),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Key {
|
||||
pub fn to_value(&self) -> Value {
|
||||
match self {
|
||||
Key::Keyword(s) => Value::Keyword(s),
|
||||
Key::Interned(s) => Value::Interned(s),
|
||||
Key::String(s) => Value::String(s.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_value(value: Value) -> Key {
|
||||
match value {
|
||||
Value::Keyword(s) => Key::Keyword(s),
|
||||
Value::Interned(s) => Key::Keyword(s),
|
||||
Value::String(s) => Key::String(s.clone()),
|
||||
_ => unreachable!("dict keys must be keywords or strings"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Value {
|
||||
Nothing,
|
||||
|
@ -124,7 +160,7 @@ pub enum Value {
|
|||
Number(f64),
|
||||
Tuple(Rc<Vec<Value>>),
|
||||
List(Box<Vector<Value>>),
|
||||
Dict(Box<HashMap<&'static str, Value>>),
|
||||
Dict(Box<HashMap<Key, Value>>),
|
||||
Box(Rc<RefCell<Value>>),
|
||||
Fn(Rc<LFn>),
|
||||
BaseFn(BaseFn),
|
||||
|
@ -234,9 +270,8 @@ impl Value {
|
|||
let members = d
|
||||
.iter()
|
||||
.map(|(k, v)| {
|
||||
let key_show = Value::Keyword(k).show();
|
||||
let value_show = v.show();
|
||||
format!("{key_show} {value_show}")
|
||||
format!("{k} {value_show}")
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
|
@ -338,9 +373,8 @@ impl Value {
|
|||
let members = d
|
||||
.iter()
|
||||
.map(|(k, v)| {
|
||||
let key_show = Value::Keyword(k).stringify();
|
||||
let value_show = v.stringify();
|
||||
format!("{key_show} {value_show}")
|
||||
format!("{k} {value_show}")
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
|
@ -437,13 +471,13 @@ impl Value {
|
|||
Value::Tuple(Rc::new(vec))
|
||||
}
|
||||
|
||||
pub fn get_shared_box(&self, name: &'static str) -> Value {
|
||||
match self {
|
||||
Value::Dict(dict) => dict
|
||||
.get(name)
|
||||
.expect("expected dict to have requested value")
|
||||
.clone(),
|
||||
_ => unreachable!("expected dict"),
|
||||
}
|
||||
}
|
||||
// pub fn get_shared_box(&self, name: &'static str) -> Value {
|
||||
// match self {
|
||||
// Value::Dict(dict) => dict
|
||||
// .get(name)
|
||||
// .expect("expected dict to have requested value")
|
||||
// .clone(),
|
||||
// _ => unreachable!("expected dict"),
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user