Skip to content

Commit 127b4f6

Browse files
committed
Merge branch 'master' into feature/count
2 parents aee2ec4 + ae6a4a0 commit 127b4f6

File tree

4 files changed

+79
-28
lines changed

4 files changed

+79
-28
lines changed

src/persistent_list_map.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,11 @@ macro_rules! persistent_list_map {
6363
}
6464
};
6565
}
66-
67-
/// merge!(base_meta(name, ns), map_entry!("key1", "value1"), map_entry!("key2", "value2"));
66+
/// Just like conj in Clojure, conj allows you to conjoin a new mapentry onto a map
67+
/// although currently, that is all it allows
68+
/// conj!(base_meta(name, ns), map_entry!("key1", "value1"), map_entry!("key2", "value2"));
6869
#[macro_export]
69-
macro_rules! merge {
70+
macro_rules! conj {
7071
( $plistmap:expr, $($kv:expr), *) => {
7172
{
7273
let mut temp_plistmap_as_vec = $plistmap.clone().iter().collect::<Vec<MapEntry>>();
@@ -78,14 +79,18 @@ macro_rules! merge {
7879
};
7980
}
8081

81-
/// merge!(base_meta(name, ns), map_entry!("key1", "value1"), map_entry!("key2", "value2"));
82+
/// merge!(persistent_list_map!{"a" => 1 "b" => 2}
83+
/// persistent_list_map!{"b" => 3}
84+
/// persistent_list_map!{"d" => 5 "e" => 7}
85+
/// ), ;
8286
#[macro_export]
83-
macro_rules! merge_maps {
84-
( $plistmap:expr, $($kv:expr), *) => {
87+
macro_rules! merge {
88+
( $plistmap:expr, $($map:expr), *) => {
8589
{
8690
let mut temp_plistmap_as_vec = $plistmap.clone().iter().collect::<Vec<MapEntry>>();
8791
$(
88-
temp_plistmap_as_vec.push($kv);
92+
let next_map_as_vec = $map.clone().iter().collect::<Vec<MapEntry>>();
93+
temp_plistmap_as_vec.extend_from_slice(&next_map_as_vec);
8994
)*
9095
temp_plistmap_as_vec.into_iter().collect::<PersistentListMap>()
9196
}

src/reader.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use crate::value::{ToValue, Value};
2727
use std::rc::Rc;
2828
use crate::protocols;
2929
use crate::traits::IObj;
30+
use crate::traits::IMeta;
3031
use std::io::BufRead;
3132
//
3233
// Note; the difference between ours 'parsers'
@@ -512,11 +513,12 @@ pub fn try_read_meta(input: &str) -> IResult<&str, Value> {
512513
let column = 1;
513514
// @TODO merge the meta iobj_value *already* has
514515
// @TODO define some better macros and / or functions for map handling
515-
meta = merge!(
516+
meta = conj!(
516517
meta,
517518
map_entry!("line",line),
518519
map_entry!("column",column)
519520
);
521+
meta = merge!(meta,iobj_value.meta());
520522
Ok((rest_input,iobj_value.with_meta(meta).unwrap().to_value()))
521523
}
522524
else {
@@ -990,6 +992,17 @@ mod tests {
990992
}
991993
}
992994
#[test]
995+
fn try_read_multiple_meta_keyword() {
996+
let with_meta = "^:cat ^:dog a";
997+
match try_read(with_meta).ok().unwrap().1 {
998+
Value::Symbol(symbol) => {
999+
assert!(symbol.meta().contains_key(&Keyword::intern("cat").to_rc_value()));
1000+
assert!(symbol.meta().contains_key(&Keyword::intern("dog").to_rc_value()));
1001+
},
1002+
_ => panic!("try_read_meta \"^:cat a\" should return a symbol")
1003+
}
1004+
}
1005+
#[test]
9931006
fn try_read_meta_keyword() {
9941007
let with_meta = "^:cat a";
9951008
match try_read(with_meta).ok().unwrap().1 {

src/symbol.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,15 +197,15 @@ mod tests {
197197
"namespace",
198198
"name"
199199
).with_meta(
200-
merge!(
200+
conj!(
201201
PersistentListMap::Empty,
202202
map_entry!("key", "value")
203203
)
204204
),
205205
Symbol {
206206
ns: String::from("namespace"),
207207
name: String::from("name"),
208-
meta: merge!(
208+
meta: conj!(
209209
PersistentListMap::Empty,
210210
map_entry!("key", "value")
211211
)

src/value.rs

Lines changed: 51 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -349,24 +349,17 @@ impl Value {
349349
match &**defname {
350350
Value::Symbol(sym) => {
351351
println!("Def: meta on sym is {}",sym.meta());
352-
// TODO: environment.insert with meta?
353-
let s = if doc_string != Value::Nil {
354-
let ss = Symbol::intern_with_ns(
355-
&sym.ns,
356-
&sym.name
357-
// merge!(
358-
// meta::base_meta(&sym.ns, &sym.name),
359-
// map_entry!("doc", doc_string)
360-
// ),
361-
);
362-
ss.clone()
363-
} else {
364-
sym.clone()
365-
};
366-
environment.insert(s.to_owned(), defval);
367-
// @TODO return var. For now, however, we only have symbols
368-
// @TODO intern from environment, don't make new sym ?
369-
Some(s.to_rc_value())
352+
353+
let mut meta = sym.meta();
354+
355+
if doc_string != Value::Nil {
356+
meta = conj!(meta,map_entry!("doc",doc_string));
357+
}
358+
359+
let sym = sym.with_meta(meta);
360+
environment.insert(sym.clone(), defval);
361+
// @TODO return var
362+
Some(sym.to_rc_value())
370363
}
371364
_ => Some(Rc::new(Value::Condition(std::string::String::from(
372365
"First argument to def must be a symbol",
@@ -778,3 +771,43 @@ impl Evaluable for Value {
778771
self.to_rc_value().eval_to_rc(environment)
779772
}
780773
}
774+
mod tests {
775+
use crate::keyword::Keyword;
776+
use crate::symbol::Symbol;
777+
use crate::protocols;
778+
use crate::value::Value;
779+
use crate::value::ToValue;
780+
use crate::traits::IMeta;
781+
use std::rc::Rc;
782+
use crate::environment::Environment;
783+
use crate::persistent_list_map::PersistentListMap;
784+
use crate::persistent_list_map::IPersistentMap;
785+
use crate::maps::MapEntry;
786+
use crate::protocol::ProtocolCastable;
787+
// (def ^{:cat 1 :dog 2} a "Docstring" 1)
788+
// ==>
789+
// a with meta of {:cat 1 :dog 2 :doc "Docstring"} ?
790+
#[test]
791+
fn def_with_docstring() {
792+
let sym_meta = persistent_list_map!{
793+
"cat" => 1,
794+
"dog" => 2
795+
};
796+
let a = sym!("a").with_meta(sym_meta);
797+
let result = Value::DefMacro.apply_to_persistent_list(
798+
&Rc::new(Environment::new_main_environment()),
799+
&Rc::new(list!(a "Docstring" 1))
800+
);
801+
802+
let final_sym_meta =
803+
result
804+
.unwrap()
805+
.as_protocol::<protocols::IMeta>()
806+
.meta();
807+
808+
assert_eq!(Value::I32(1),*final_sym_meta.get(&Keyword::intern("cat").to_rc_value()));
809+
assert_eq!(Value::I32(2),*final_sym_meta.get(&Keyword::intern("dog").to_rc_value()));
810+
assert_eq!(Value::String("Docstring".to_string()),*final_sym_meta.get(&Keyword::intern("doc").to_rc_value()));
811+
812+
}
813+
}

0 commit comments

Comments
 (0)