@@ -54,18 +54,16 @@ pub enum Value {
5454 DefMacro ,
5555 FnMacro ,
5656 LetMacro ,
57+ IfMacro ,
5758
5859 String ( std:: string:: String ) ,
5960 Nil ,
6061}
6162use crate :: value:: Value :: * ;
6263
63- // @TODO since I have already manually defined hash, surely this should just be defined
64- // in terms of that?
6564impl PartialEq for Value {
66- // @TODO derive from Hash in some way? Note; can't derive with derive because of
67- // our trait objects in IFn and Macro
6865 // @TODO implement our generic IFns some other way? After all, again, this isn't Java
66+ // @TODO improve this? This is a hack
6967 fn eq ( & self , other : & Value ) -> bool {
7068 //
7169 if let I32 ( i) = self {
@@ -146,6 +144,11 @@ impl PartialEq for Value {
146144 return true ;
147145 }
148146 }
147+ if let IfMacro = self {
148+ if let IfMacro = other {
149+ return true ;
150+ }
151+ }
149152
150153 if let String ( string) = self {
151154 if let String ( string2) = other {
@@ -172,6 +175,7 @@ enum ValueHash {
172175 DefmacroMacro ,
173176 DefMacro ,
174177 FnMacro ,
178+ IfMacro ,
175179 LetMacro ,
176180 Nil ,
177181}
@@ -204,6 +208,7 @@ impl Hash for Value {
204208 DefMacro => ValueHash :: DefMacro . hash ( state) ,
205209 FnMacro => ValueHash :: FnMacro . hash ( state) ,
206210 LetMacro => ValueHash :: LetMacro . hash ( state) ,
211+ IfMacro => ValueHash :: IfMacro . hash ( state) ,
207212
208213 String ( string) => string. hash ( state) ,
209214 Nil => ValueHash :: Nil . hash ( state) ,
@@ -229,6 +234,7 @@ impl fmt::Display for Value {
229234 DefMacro => std:: string:: String :: from ( "#macro[def*]" ) ,
230235 DefmacroMacro => std:: string:: String :: from ( "#macro[defmacro*]" ) ,
231236 FnMacro => std:: string:: String :: from ( "#macro[fn*]" ) ,
237+ IfMacro => std:: string:: String :: from ( "#macro[if*]" ) ,
232238 LetMacro => std:: string:: String :: from ( "#macro[let*]" ) ,
233239 Value :: String ( string) => string. clone ( ) ,
234240 Nil => std:: string:: String :: from ( "nil" ) ,
@@ -270,6 +276,7 @@ impl Value {
270276 Value :: DefmacroMacro => TypeTag :: Macro ,
271277 Value :: LetMacro => TypeTag :: Macro ,
272278 Value :: FnMacro => TypeTag :: Macro ,
279+ Value :: IfMacro => TypeTag :: Macro ,
273280 Value :: String ( _) => TypeTag :: String ,
274281 Value :: Nil => TypeTag :: Nil ,
275282 }
@@ -558,7 +565,23 @@ impl Value {
558565 ) ) ) ) ,
559566 Ordering :: Equal => Some ( args. nth ( 0 ) ) ,
560567 }
561- }
568+ } ,
569+ IfMacro => {
570+ if args. len ( ) != 2 && args. len ( ) != 3 {
571+ return Some ( Rc :: new ( Value :: Condition ( format ! (
572+ "Wrong number of arguments (Given: {}, Expected: 2 or 3)" ,
573+ args. len( )
574+ ) ) ) )
575+ }
576+ let arg_refs = PersistentList :: iter ( args) . collect :: < Vec < Rc < Value > > > ( ) ;
577+ let condition = arg_refs. get ( 0 ) . unwrap ( ) . eval ( Rc :: clone ( environment) ) ;
578+
579+ if condition. is_truthy ( ) {
580+ Some ( arg_refs. get ( 1 ) . unwrap ( ) . eval_to_rc ( Rc :: clone ( environment) ) )
581+ } else {
582+ Some ( arg_refs. get ( 2 ) . unwrap_or ( & Rc :: new ( Value :: Nil ) ) . eval_to_rc ( Rc :: clone ( environment) ) )
583+ }
584+ }
562585 //
563586 // If we're not a valid IFn
564587 //
@@ -568,6 +591,12 @@ impl Value {
568591 ////////////////////////////////////////////////////////////////////////////////////////////////////
569592 // Eval Helper
570593 ////////////////////////////////////////////////////////////////////////////////////////////////////
594+ fn is_truthy ( & self ) -> bool {
595+ if let Value :: Nil = self {
596+ return false ;
597+ }
598+ true
599+ }
571600}
572601pub trait ToValue {
573602 fn to_value ( & self ) -> Value ;
0 commit comments