@@ -4,25 +4,6 @@ use std::fmt;
4
4
use std:: fmt:: Formatter ;
5
5
use std:: cmp:: Ordering ;
6
6
7
- #[ derive( Debug , Clone ) ]
8
- pub enum LValue {
9
- StringValue ( String ) ,
10
- NumericalValue ( f64 ) ,
11
- BooleanValue ( bool ) ,
12
- Quoted ( Box < Expression > ) ,
13
- }
14
-
15
- impl fmt:: Display for LValue {
16
- fn fmt ( & self , f : & mut Formatter ) -> fmt:: Result {
17
- match * self {
18
- LValue :: StringValue ( ref s) => write ! ( f, "\" {}\" " , s) ,
19
- LValue :: NumericalValue ( v) => write ! ( f, "{}" , v) ,
20
- LValue :: BooleanValue ( v) => if v { write ! ( f, "#t" ) } else { write ! ( f, "#f" ) } ,
21
- LValue :: Quoted ( ref e) => write ! ( f, "#<expression>:{:?}" , e) ,
22
- }
23
- }
24
- }
25
-
26
7
#[ derive( Debug , Clone ) ]
27
8
pub enum Procedure {
28
9
UserDefined {
@@ -62,49 +43,45 @@ impl fmt::Display for Procedure {
62
43
}
63
44
64
45
#[ derive( Debug , Clone ) ]
65
- pub enum LResult {
66
- Value ( LValue ) ,
46
+ pub enum LValue {
47
+ StringValue ( String ) ,
48
+ NumericalValue ( f64 ) ,
49
+ BooleanValue ( bool ) ,
50
+ Quoted ( Box < Expression > ) ,
67
51
Procedure ( Procedure ) ,
68
52
Undefined ,
69
53
}
70
54
71
- impl fmt:: Display for LResult {
55
+ impl fmt:: Display for LValue {
72
56
fn fmt ( & self , f : & mut Formatter ) -> fmt:: Result {
73
57
match * self {
74
- LResult :: Value ( ref v) => write ! ( f, "{}" , v) ,
75
- LResult :: Procedure ( ref p) => write ! ( f, "{}" , p) ,
76
- LResult :: Undefined => write ! ( f, "#<undefined>" ) ,
58
+ LValue :: StringValue ( ref s) => write ! ( f, "\" {}\" " , s) ,
59
+ LValue :: NumericalValue ( v) => write ! ( f, "{}" , v) ,
60
+ LValue :: BooleanValue ( v) => if v { write ! ( f, "#t" ) } else { write ! ( f, "#f" ) } ,
61
+ LValue :: Quoted ( ref e) => write ! ( f, "#<expression>:{:?}" , e) ,
62
+ LValue :: Procedure ( ref p) => write ! ( f, "{}" , p) ,
63
+ LValue :: Undefined => write ! ( f, "#<undefined>" ) ,
77
64
}
78
65
}
79
66
}
80
67
81
- impl LResult {
82
- pub fn compare ( & self , v : & LResult ) -> Result < Ordering , String > {
83
- let lhs: LValue ;
84
- let rhs: LValue ;
68
+ impl LValue {
69
+ pub fn compare ( & self , rhs : & LValue ) -> Result < Ordering , String > {
85
70
match * self {
86
- LResult :: Value ( ref lv) => lhs = lv. clone ( ) ,
87
- _ => return Err ( "Can't compare procedures or undefined results." . to_string ( ) ) ,
88
- }
89
- match * v {
90
- LResult :: Value ( ref lv) => rhs = lv. clone ( ) ,
91
- _ => return Err ( "Can't compare procedures or undefined results." . to_string ( ) ) ,
92
- }
93
- match lhs {
94
71
LValue :: StringValue ( ref s1) => {
95
- match rhs {
72
+ match * rhs {
96
73
LValue :: StringValue ( ref s2) => Ok ( s1. cmp ( s2) ) ,
97
74
_ => Err ( "Expected string expression as the second argument." . to_string ( ) ) ,
98
75
}
99
76
}
100
77
LValue :: BooleanValue ( b1) => {
101
- match rhs {
78
+ match * rhs {
102
79
LValue :: BooleanValue ( b2) => Ok ( b1. cmp ( & b2) ) ,
103
80
_ => Err ( "Expected boolean expression as the second argument." . to_string ( ) ) ,
104
81
}
105
82
}
106
83
LValue :: NumericalValue ( x1) => {
107
- match rhs {
84
+ match * rhs {
108
85
LValue :: NumericalValue ( x2) => {
109
86
Ok ( if x1 > x2 {
110
87
Ordering :: Greater
@@ -118,30 +95,26 @@ impl LResult {
118
95
}
119
96
}
120
97
LValue :: Quoted ( _) => Err ( "Can't compare quoted expressions." . to_string ( ) ) ,
98
+ LValue :: Procedure ( _) => Err ( "Can't compare procedures." . to_string ( ) ) ,
99
+ LValue :: Undefined => Err ( "Can't compare #<undefined>'s." . to_string ( ) ) ,
121
100
}
122
101
}
123
102
124
103
pub fn to_boolean ( & self ) -> Result < bool , String > {
125
104
match * self {
126
- LResult :: Value ( ref lv) => {
127
- match * lv {
128
- LValue :: NumericalValue ( x) => Ok ( x >= 0.0 ) ,
129
- LValue :: BooleanValue ( b) => Ok ( b) ,
130
- LValue :: StringValue ( _) => Ok ( true ) ,
131
- LValue :: Quoted ( _) => Ok ( true ) ,
132
- }
133
- }
105
+ LValue :: NumericalValue ( x) => Ok ( x >= 0.0 ) ,
106
+ LValue :: BooleanValue ( b) => Ok ( b) ,
107
+ LValue :: StringValue ( _) => Ok ( true ) ,
108
+ LValue :: Quoted ( _) => Ok ( true ) ,
134
109
_ => Err ( "Can't convert procedures and #undefined's to booleans." . to_string ( ) ) ,
135
110
}
136
111
}
137
112
}
138
113
139
114
#[ derive( Debug , Clone ) ]
140
115
pub enum Expression {
141
- Call {
142
- fun : Box < Expression > ,
143
- arguments : Vec < Expression > ,
144
- } ,
116
+ List ( Vec < Expression > ) ,
117
+ Eval ( Box < Expression > ) ,
145
118
Definition {
146
119
name : String ,
147
120
value : Box < Expression > ,
@@ -167,6 +140,9 @@ impl Expression {
167
140
let newv = ( * v) . clone ( ) ;
168
141
return Expression :: process_quote ( & ListNode :: Node ( false , newv) ) ;
169
142
}
143
+ if v. len ( ) == 0 {
144
+ return Ok ( Expression :: List ( Vec :: new ( ) ) ) ;
145
+ }
170
146
match v[ 0 ] {
171
147
ListNode :: Identifier ( _, ref s) => {
172
148
match s. as_str ( ) {
@@ -181,10 +157,18 @@ impl Expression {
181
157
Expression :: process_quote ( & v[ 1 ] )
182
158
}
183
159
}
184
- _ => Expression :: process_call ( & v) ,
160
+ "eval" => {
161
+ if v. len ( ) != 2 {
162
+ Err ( "Eval expression must contain exactly one expression."
163
+ . to_string ( ) )
164
+ } else {
165
+ Expression :: process_eval ( & v[ 1 ] )
166
+ }
167
+ }
168
+ _ => Expression :: process_list ( & v) ,
185
169
}
186
170
}
187
- _ => Expression :: process_call ( & v) ,
171
+ _ => Expression :: process_list ( & v) ,
188
172
}
189
173
}
190
174
ListNode :: Identifier ( quoted, ref s) => {
@@ -292,22 +276,21 @@ impl Expression {
292
276
}
293
277
}
294
278
295
- fn process_call ( params : & [ ListNode ] ) -> Result < Expression , String > {
296
- let mut args: Vec < Expression > = Vec :: new ( ) ;
297
- for node in & params[ 1 ..] {
298
- match Expression :: from_list ( node) {
299
- Ok ( e) => args. push ( e) ,
300
- Err ( s) => return Err ( s) ,
301
- }
279
+ fn process_eval ( n : & ListNode ) -> Result < Expression , String > {
280
+ match Expression :: from_list ( n) {
281
+ Ok ( e) => Ok ( Expression :: Eval ( Box :: new ( e) ) ) ,
282
+ Err ( s) => Err ( s) ,
302
283
}
303
- match Expression :: from_list ( & params[ 0 ] ) {
304
- Ok ( e) => {
305
- Ok ( Expression :: Call {
306
- fun : Box :: new ( e) ,
307
- arguments : args,
308
- } )
284
+ }
285
+
286
+ fn process_list ( elements : & [ ListNode ] ) -> Result < Expression , String > {
287
+ let mut children: Vec < Expression > = Vec :: new ( ) ;
288
+ for e in elements {
289
+ match Expression :: from_list ( e) {
290
+ Ok ( expr) => children. push ( expr) ,
291
+ Err ( s) => return Err ( s) ,
309
292
}
310
- Err ( s) => Err ( s) ,
311
293
}
294
+ Ok ( Expression :: List ( children) )
312
295
}
313
296
}
0 commit comments