@@ -54,18 +54,16 @@ pub enum Value {
54
54
DefMacro ,
55
55
FnMacro ,
56
56
LetMacro ,
57
+ IfMacro ,
57
58
58
59
String ( std:: string:: String ) ,
59
60
Nil ,
60
61
}
61
62
use crate :: value:: Value :: * ;
62
63
63
- // @TODO since I have already manually defined hash, surely this should just be defined
64
- // in terms of that?
65
64
impl 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
68
65
// @TODO implement our generic IFns some other way? After all, again, this isn't Java
66
+ // @TODO improve this? This is a hack
69
67
fn eq ( & self , other : & Value ) -> bool {
70
68
//
71
69
if let I32 ( i) = self {
@@ -146,6 +144,11 @@ impl PartialEq for Value {
146
144
return true ;
147
145
}
148
146
}
147
+ if let IfMacro = self {
148
+ if let IfMacro = other {
149
+ return true ;
150
+ }
151
+ }
149
152
150
153
if let String ( string) = self {
151
154
if let String ( string2) = other {
@@ -172,6 +175,7 @@ enum ValueHash {
172
175
DefmacroMacro ,
173
176
DefMacro ,
174
177
FnMacro ,
178
+ IfMacro ,
175
179
LetMacro ,
176
180
Nil ,
177
181
}
@@ -204,6 +208,7 @@ impl Hash for Value {
204
208
DefMacro => ValueHash :: DefMacro . hash ( state) ,
205
209
FnMacro => ValueHash :: FnMacro . hash ( state) ,
206
210
LetMacro => ValueHash :: LetMacro . hash ( state) ,
211
+ IfMacro => ValueHash :: IfMacro . hash ( state) ,
207
212
208
213
String ( string) => string. hash ( state) ,
209
214
Nil => ValueHash :: Nil . hash ( state) ,
@@ -229,6 +234,7 @@ impl fmt::Display for Value {
229
234
DefMacro => std:: string:: String :: from ( "#macro[def*]" ) ,
230
235
DefmacroMacro => std:: string:: String :: from ( "#macro[defmacro*]" ) ,
231
236
FnMacro => std:: string:: String :: from ( "#macro[fn*]" ) ,
237
+ IfMacro => std:: string:: String :: from ( "#macro[if*]" ) ,
232
238
LetMacro => std:: string:: String :: from ( "#macro[let*]" ) ,
233
239
Value :: String ( string) => string. clone ( ) ,
234
240
Nil => std:: string:: String :: from ( "nil" ) ,
@@ -270,6 +276,7 @@ impl Value {
270
276
Value :: DefmacroMacro => TypeTag :: Macro ,
271
277
Value :: LetMacro => TypeTag :: Macro ,
272
278
Value :: FnMacro => TypeTag :: Macro ,
279
+ Value :: IfMacro => TypeTag :: Macro ,
273
280
Value :: String ( _) => TypeTag :: String ,
274
281
Value :: Nil => TypeTag :: Nil ,
275
282
}
@@ -558,7 +565,23 @@ impl Value {
558
565
) ) ) ) ,
559
566
Ordering :: Equal => Some ( args. nth ( 0 ) ) ,
560
567
}
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
+ }
562
585
//
563
586
// If we're not a valid IFn
564
587
//
@@ -568,6 +591,12 @@ impl Value {
568
591
////////////////////////////////////////////////////////////////////////////////////////////////////
569
592
// Eval Helper
570
593
////////////////////////////////////////////////////////////////////////////////////////////////////
594
+ fn is_truthy ( & self ) -> bool {
595
+ if let Value :: Nil = self {
596
+ return false ;
597
+ }
598
+ true
599
+ }
571
600
}
572
601
pub trait ToValue {
573
602
fn to_value ( & self ) -> Value ;
0 commit comments