@@ -8,21 +8,19 @@ use crate::persistent_list::{
88 PersistentList :: { Cons , Empty } ,
99 ToPersistentList , ToPersistentListIter ,
1010} ;
11+ use crate :: persistent_list_map:: IPersistentListMap ;
1112use crate :: persistent_vector:: { PersistentVector , ToPersistentVectorIter } ;
13+ use crate :: repl:: Repl ;
1214use crate :: symbol:: Symbol ;
15+ use crate :: type_tag:: TypeTag ;
1316use crate :: value:: { Evaluable , ToValue } ;
1417
15- //
16- // This module will hold the core functions and macros that Clojure will
17- // hook into; Functions / Macros like "+", "fn*", "let", "cond", etc
18- //
19- // This is still experimental, and we may instead undo this all and
20- // represent fn* and let and the like the same it is done in ClojureJVM,
21- // where I believe they are defined flat out in the Compiler class
22- //
23- // However, even in that case this may stick around to implement basic
24- // functions like "+" that usually rely on interop
25- //
18+ use itertools:: Itertools ;
19+
20+ use crate :: util:: IsEven ;
21+
22+ // This module will hold core function and macro primitives that aren't special cases
23+ // (like the quote macro, or let), and can't be implemented in clojure itself
2624
2725#[ derive( Debug , Clone ) ]
2826pub struct StrFn { }
@@ -283,3 +281,43 @@ impl IFn for PrintStringFn {
283281 Value :: Nil
284282 }
285283}
284+ // General assoc fn; however, currently just implemented
285+ // for our one map type, PersistentListMap
286+ #[ derive( Debug , Clone ) ]
287+ pub struct AssocFn { }
288+ impl ToValue for AssocFn {
289+ fn to_value ( & self ) -> Value {
290+ Value :: IFn ( Rc :: new ( self . clone ( ) ) )
291+ }
292+ }
293+ impl IFn for AssocFn {
294+ fn invoke ( & self , args : Vec < & Value > ) -> Value {
295+ // We don't want even args, because assoc works like
296+ // (assoc {} :a 1) ;; 3 args
297+ // (assoc {} :a 1 :b 2) ;; 5 args
298+ // (assoc {} :a 1 :b 2 :c 3) ;; 7 args ...
299+ if args. len ( ) < 3 || args. len ( ) . is_even ( ) {
300+ return Value :: Condition ( format ! (
301+ "Wrong number of arguments given to function (Given: {}, Expected: 3 | 5 | 7 | ..)" ,
302+ args. len( )
303+ ) ) ;
304+ }
305+
306+ if let Value :: PersistentListMap ( pmap) = args. get ( 0 ) . unwrap ( ) {
307+ let mut retval = pmap. clone ( ) ;
308+ for ( key_value, val_value) in args. into_iter ( ) . skip ( 1 ) . tuples ( ) {
309+ let key = key_value. to_rc_value ( ) ;
310+ let val = val_value. to_rc_value ( ) ;
311+ println ! ( "key: {:?}, val: {:?}" , key, val) ;
312+ retval = pmap. assoc ( key, val) ;
313+ }
314+ return Value :: PersistentListMap ( retval) ;
315+ }
316+
317+ Value :: Nil
318+ }
319+ }
320+
321+ }
322+ }
323+ }
0 commit comments