@@ -32,281 +32,27 @@ pub use self::_multiply_::*;
32
32
//
33
33
// This module will hold core function and macro primitives that aren't special cases
34
34
// (like the quote macro, or let), and can't be implemented in clojure itself
35
- //
36
- #[ derive( Debug , Clone ) ]
37
- pub struct StrFn { }
38
- impl ToValue for StrFn {
39
- fn to_value ( & self ) -> Value {
40
- Value :: IFn ( Rc :: new ( self . clone ( ) ) )
41
- }
42
- }
43
- impl IFn for StrFn {
44
- fn invoke ( & self , args : Vec < Rc < Value > > ) -> Value {
45
- Value :: String (
46
- args. into_iter ( )
47
- . map ( |arg| arg. to_string ( ) )
48
- . collect :: < Vec < String > > ( )
49
- . join ( "" ) ,
50
- )
51
- }
52
- }
53
-
54
- #[ derive( Debug , Clone ) ]
55
- pub struct StringPrintFn { }
56
- impl ToValue for StringPrintFn {
57
- fn to_value ( & self ) -> Value {
58
- Value :: IFn ( Rc :: new ( self . clone ( ) ) )
59
- }
60
- }
61
- impl IFn for StringPrintFn {
62
- fn invoke ( & self , args : Vec < Rc < Value > > ) -> Value {
63
- Value :: String (
64
- args. into_iter ( )
65
- . map ( |arg| arg. to_string ( ) )
66
- . collect :: < Vec < String > > ( )
67
- . join ( "" ) ,
68
- )
69
- }
70
- }
71
-
72
- #[ derive( Debug , Clone ) ]
73
- pub struct AddFn { }
74
- impl ToValue for AddFn {
75
- fn to_value ( & self ) -> Value {
76
- Value :: IFn ( Rc :: new ( self . clone ( ) ) )
77
- }
78
- }
79
- impl IFn for AddFn {
80
- fn invoke ( & self , args : Vec < Rc < Value > > ) -> Value {
81
- args. into_iter ( ) . fold ( 0_i32 . to_value ( ) , |a, b| match a {
82
- Value :: I32 ( a_) => match * b {
83
- Value :: I32 ( b_) => Value :: I32 ( a_ + b_) ,
84
- Value :: F64 ( b_) => Value :: F64 ( a_ as f64 + b_) ,
85
- _ => Value :: Condition ( format ! ( // TODO: what error message should be returned regarding using typetags?
86
- "Type mismatch; Expecting: (i32 | i64 | f32 | f64), Found: {}" ,
87
- b. type_tag( )
88
- ) ) ,
89
- } ,
90
- Value :: F64 ( a_) => match * b {
91
- Value :: I32 ( b_) => Value :: F64 ( a_ + b_ as f64 ) ,
92
- Value :: F64 ( b_) => Value :: F64 ( a_ + b_) ,
93
- _ => Value :: Condition ( format ! ( // TODO: what error message should be returned regarding using typetags?
94
- "Type mismatch; Expecting: (i32 | i64 | f32 | f64), Found: {}" ,
95
- b. type_tag( )
96
- ) ) ,
97
- } ,
98
- _ => Value :: Condition ( format ! ( // TODO: what error message should be returned regarding using typetags?
99
- "Type mismatch: Expecting: (i32 | i64 | f32 | f64), Found: {}" ,
100
- a. type_tag( )
101
- ) ) ,
102
- } )
103
- }
104
- }
105
35
106
- #[ derive( Debug , Clone ) ]
107
- pub struct EvalFn {
108
- enclosing_environment : Rc < Environment > ,
109
- }
110
- impl EvalFn {
111
- pub fn new ( enclosing_environment : Rc < Environment > ) -> EvalFn {
112
- EvalFn {
113
- enclosing_environment,
114
- }
115
- }
116
- }
117
- impl ToValue for EvalFn {
118
- fn to_value ( & self ) -> Value {
119
- Value :: IFn ( Rc :: new ( self . clone ( ) ) )
120
- }
121
- }
122
- impl IFn for EvalFn {
123
- fn invoke ( & self , args : Vec < Rc < Value > > ) -> Value {
124
- // @TODO generalize arity exceptions, and other exceptions
125
- if args. len ( ) != 1 {
126
- return error_message:: wrong_arg_count ( 1 , args. len ( ) )
127
- }
128
- let arg = args. get ( 0 ) . unwrap ( ) ;
129
- arg. eval ( Rc :: clone ( & self . enclosing_environment ) )
130
- }
131
- }
36
+ // language core functions
37
+ pub ( crate ) mod eval;
132
38
133
- #[ derive( Debug , Clone ) ]
134
- pub struct DoFn { }
135
- impl ToValue for DoFn {
136
- fn to_value ( & self ) -> Value {
137
- Value :: IFn ( Rc :: new ( self . clone ( ) ) )
138
- }
139
- }
140
- impl IFn for DoFn {
141
- fn invoke ( & self , args : Vec < Rc < Value > > ) -> Value {
142
- // @TODO generalize arity exceptions, and other exceptions
143
- if args. is_empty ( ) {
144
- return Value :: Nil ;
145
- }
146
- ( * * args. last ( ) . unwrap ( ) ) . clone ( )
147
- }
148
- }
149
-
150
- //
151
- // Since our macros currently expand and evaluate at the same time, our `do` macro will be implemented
152
- // by expanding to a do-fn, which will just naturally evaluate all arguments, being a fn, and
153
- // return the last item
154
- // This will change when macros change
155
- //
156
- #[ derive( Debug , Clone ) ]
157
- pub struct DoMacro { }
158
- impl ToValue for DoMacro {
159
- fn to_value ( & self ) -> Value {
160
- Value :: Macro ( Rc :: new ( self . clone ( ) ) )
161
- }
162
- }
163
- impl IFn for DoMacro {
164
- fn invoke ( & self , args : Vec < Rc < Value > > ) -> Value {
165
- // @TODO generalize arity exceptions, and other exceptions
166
- if args. is_empty ( ) {
167
- return vec ! [ Symbol :: intern( "do" ) . to_rc_value( ) , Rc :: new( Value :: Nil ) ]
168
- . into_list ( )
169
- . to_value ( ) ;
170
- }
171
- // (do a b c) becomes (do-fn* a b c), so we need to copy a,b, and c for our new expression
172
- let args_for_ret_expr = args
173
- . iter ( )
174
- . map ( |arg| arg. to_rc_value ( ) )
175
- . collect :: < Vec < Rc < Value > > > ( ) ;
39
+ // macros
40
+ pub ( crate ) mod do_macro;
176
41
177
- let mut do_body = vec ! [ Symbol :: intern ( "do-fn*" ) . to_rc_value ( ) ] ;
178
- do_body . extend_from_slice ( args_for_ret_expr . get ( 0 .. ) . unwrap ( ) ) ;
42
+ // arithmetics
43
+ pub ( crate ) mod _plus_ ;
179
44
180
- do_body. into_list ( ) . to_value ( )
181
- }
182
- }
45
+ // string
46
+ pub ( crate ) mod str;
183
47
184
- #[ derive( Debug , Clone ) ]
185
- pub struct NthFn { }
186
- impl ToValue for NthFn {
187
- fn to_value ( & self ) -> Value {
188
- Value :: IFn ( Rc :: new ( self . clone ( ) ) )
189
- }
190
- }
191
- impl IFn for NthFn {
192
- fn invoke ( & self , args : Vec < Rc < Value > > ) -> Value {
193
- // @TODO generalize arity exceptions, and other exceptions
194
- if args. len ( ) != 2 {
195
- return error_message:: wrong_varg_count ( & [ 2 , 3 ] , args. len ( ) )
196
- }
197
- // @TODO change iteration to work with Value references, or even change invoke to work on Rc<..>
198
- // as we do everything else; surely we don't want to clone just to read from a collection
199
- if let Value :: I32 ( ind) = * * args. get ( 1 ) . unwrap ( ) {
200
- if ind < 0 {
201
- return error_message:: index_cannot_be_negative ( ind as usize )
202
- }
203
- let ind = ind as usize ;
48
+ // operations on collections
49
+ pub ( crate ) mod nth;
50
+ pub ( crate ) mod concat;
51
+ pub ( crate ) mod assoc;
204
52
205
- match & * * args. get ( 0 ) . unwrap ( ) {
206
- Value :: PersistentList ( Cons ( head, tail, count) ) => {
207
- let count = * count as usize ;
208
- if ind >= count {
209
- error_message:: index_out_of_bounds ( ind, count)
210
- } else if ind == 0 {
211
- head. to_value ( )
212
- } else {
213
- tail. iter ( ) . nth ( ind - 1 ) . unwrap ( ) . to_value ( )
214
- }
215
- }
216
- Value :: PersistentList ( Empty ) => error_message:: index_out_of_bounds ( ind, 0 ) ,
217
- Value :: PersistentVector ( PersistentVector { vals } ) => {
218
- if ind >= vals. len ( ) {
219
- error_message:: index_out_of_bounds ( ind, vals. len ( ) )
220
- } else {
221
- vals. get ( ind) . unwrap ( ) . to_value ( )
222
- }
223
- }
224
- _ => error_message:: type_mismatch ( TypeTag :: ISeq , & * * args. get ( 0 ) . unwrap ( ) ) ,
225
- }
226
- } else {
227
- error_message:: type_mismatch ( TypeTag :: Integer , & * * args. get ( 1 ) . unwrap ( ) )
228
- }
229
- }
230
- }
53
+ // input and output
54
+ pub ( crate ) mod print_string;
55
+ pub ( crate ) mod string_pring;
231
56
232
- #[ derive( Debug , Clone ) ]
233
- pub struct ConcatFn { }
234
- impl ToValue for ConcatFn {
235
- fn to_value ( & self ) -> Value {
236
- Value :: IFn ( Rc :: new ( self . clone ( ) ) )
237
- }
238
- }
239
- impl IFn for ConcatFn {
240
- fn invoke ( & self , args : Vec < Rc < Value > > ) -> Value {
241
- let concatted_vec = args. iter ( ) . fold ( Vec :: new ( ) , |mut sum, coll| {
242
- let coll_vec = match & * * coll {
243
- Value :: PersistentList ( plist) => {
244
- Rc :: new ( plist. clone ( ) ) . iter ( ) . collect :: < Vec < Rc < Value > > > ( )
245
- }
246
- Value :: PersistentVector ( pvector) => {
247
- Rc :: new ( pvector. clone ( ) ) . iter ( ) . collect :: < Vec < Rc < Value > > > ( )
248
- }
249
- _ => vec ! [ ] ,
250
- } ;
251
-
252
- sum. extend ( coll_vec) ;
253
- sum
254
- } ) ;
255
- Value :: PersistentList ( concatted_vec. into_iter ( ) . collect :: < PersistentList > ( ) )
256
- }
257
- }
258
-
259
- /// Primitive printing function;
260
- /// (defn print-string [string] .. prints single string .. )
261
- #[ derive( Debug , Clone ) ]
262
- pub struct PrintStringFn { }
263
- impl ToValue for PrintStringFn {
264
- fn to_value ( & self ) -> Value {
265
- Value :: IFn ( Rc :: new ( self . clone ( ) ) )
266
- }
267
- }
268
- impl IFn for PrintStringFn {
269
- fn invoke ( & self , args : Vec < Rc < Value > > ) -> Value {
270
- if args. len ( ) != 1 {
271
- return error_message:: wrong_arg_count ( 1 , args. len ( ) )
272
- }
273
- println ! ( "{}" , args. get( 0 ) . unwrap( ) . to_string( ) ) ;
274
- Value :: Nil
275
- }
276
- }
277
- // General assoc fn; however, currently just implemented
278
- // for our one map type, PersistentListMap
279
- #[ derive( Debug , Clone ) ]
280
- pub struct AssocFn { }
281
- impl ToValue for AssocFn {
282
- fn to_value ( & self ) -> Value {
283
- Value :: IFn ( Rc :: new ( self . clone ( ) ) )
284
- }
285
- }
286
- impl IFn for AssocFn {
287
- fn invoke ( & self , args : Vec < Rc < Value > > ) -> Value {
288
- // We don't want even args, because assoc works like
289
- // (assoc {} :a 1) ;; 3 args
290
- // (assoc {} :a 1 :b 2) ;; 5 args
291
- // (assoc {} :a 1 :b 2 :c 3) ;; 7 args ...
292
- if args. len ( ) < 3 || args. len ( ) . is_even ( ) {
293
- return Value :: Condition ( format ! (
294
- "Wrong number of arguments given to function (Given: {}, Expected: 3 | 5 | 7 | ..)" ,
295
- args. len( )
296
- ) ) ;
297
- }
298
-
299
- if let Value :: PersistentListMap ( pmap) = & * ( args. get ( 0 ) . unwrap ( ) . clone ( ) ) {
300
- let mut retval = pmap. clone ( ) ;
301
- for ( key_value, val_value) in args. into_iter ( ) . skip ( 1 ) . tuples ( ) {
302
- let key = key_value. to_rc_value ( ) ;
303
- let val = val_value. to_rc_value ( ) ;
304
- println ! ( "key: {:?}, val: {:?}" , key, val) ;
305
- retval = pmap. assoc ( key, val) ;
306
- }
307
- return Value :: PersistentListMap ( retval) ;
308
- }
309
-
310
- Value :: Nil
311
- }
312
- }
57
+ // other
58
+ pub ( crate ) mod slurp;
0 commit comments