@@ -5,6 +5,14 @@ use crate::{
5
5
utils:: { require_int_parameter, require_list_parameter, require_parameter} ,
6
6
} ;
7
7
use std:: collections:: HashMap ;
8
+ use cfg_if:: cfg_if;
9
+ cfg_if ! {
10
+ if #[ cfg( feature = "bigint" ) ] {
11
+ use num_traits:: ToPrimitive ;
12
+ } else {
13
+ use crate :: model:: IntType ;
14
+ }
15
+ }
8
16
9
17
/// Initialize an instance of `Env` with several core Lisp functions implemented
10
18
/// in Rust. **Without this, you will only have access to the functions you
@@ -18,7 +26,7 @@ pub fn default_env() -> Env {
18
26
let expr = require_parameter ( "print" , args, 0 ) ?;
19
27
20
28
println ! ( "{}" , & expr) ;
21
- return Ok ( expr. clone ( ) ) ;
29
+ Ok ( expr. clone ( ) )
22
30
} ) ,
23
31
) ;
24
32
@@ -99,7 +107,7 @@ pub fn default_env() -> Env {
99
107
Value :: NativeFunc ( |_env, args| {
100
108
let list = require_list_parameter ( "car" , args, 0 ) ?;
101
109
102
- return list. car ( ) . map ( |c| c . clone ( ) ) ;
110
+ list. car ( )
103
111
} ) ,
104
112
) ;
105
113
@@ -108,7 +116,7 @@ pub fn default_env() -> Env {
108
116
Value :: NativeFunc ( |_env, args| {
109
117
let list = require_list_parameter ( "cdr" , args, 0 ) ?;
110
118
111
- return Ok ( Value :: List ( list. cdr ( ) ) ) ;
119
+ Ok ( Value :: List ( list. cdr ( ) ) )
112
120
} ) ,
113
121
) ;
114
122
@@ -118,26 +126,33 @@ pub fn default_env() -> Env {
118
126
let car = require_parameter ( "cons" , args, 0 ) ?;
119
127
let cdr = require_list_parameter ( "cons" , args, 1 ) ?;
120
128
121
- return Ok ( Value :: List ( cdr. cons ( car. clone ( ) ) ) ) ;
129
+ Ok ( Value :: List ( cdr. cons ( car. clone ( ) ) ) )
122
130
} ) ,
123
131
) ;
124
132
125
133
entries. insert (
126
134
String :: from ( "list" ) ,
127
- Value :: NativeFunc ( |_env, args| Ok ( Value :: List ( args. into_iter ( ) . collect :: < List > ( ) ) ) ) ,
135
+ Value :: NativeFunc ( |_env, args| Ok ( Value :: List ( args. iter ( ) . collect :: < List > ( ) ) ) ) ,
128
136
) ;
129
137
130
138
entries. insert (
131
139
String :: from ( "nth" ) ,
132
140
Value :: NativeFunc ( |_env, args| {
133
- let index = require_int_parameter ( "nth" , args, 0 ) ?;
141
+ cfg_if ! {
142
+ if #[ cfg( feature = "bigint" ) ] {
143
+ let index = require_int_parameter( "nth" , args, 0 ) ?
144
+ . to_usize( )
145
+ . ok_or( RuntimeError :: new( "Failed converting `BigInt` to `usize`" ) ) ?;
146
+ } else {
147
+ let index = require_int_parameter( "nth" , args, 0 ) ? as usize ;
148
+ }
149
+ }
134
150
let list = require_list_parameter ( "nth" , args, 1 ) ?;
135
151
136
- return Ok ( list
152
+ Ok ( list
137
153
. into_iter ( )
138
- . nth ( index as usize )
139
- . map ( |v| v. clone ( ) )
140
- . unwrap_or ( Value :: NIL ) ) ;
154
+ . nth ( index)
155
+ . unwrap_or ( Value :: NIL ) )
141
156
} ) ,
142
157
) ;
143
158
@@ -150,7 +165,7 @@ pub fn default_env() -> Env {
150
165
151
166
v. sort ( ) ;
152
167
153
- return Ok ( Value :: List ( v. into_iter ( ) . collect ( ) ) ) ;
168
+ Ok ( Value :: List ( v. into_iter ( ) . collect ( ) ) )
154
169
} ) ,
155
170
) ;
156
171
@@ -163,7 +178,7 @@ pub fn default_env() -> Env {
163
178
164
179
v. reverse ( ) ;
165
180
166
- return Ok ( Value :: List ( v. into_iter ( ) . collect ( ) ) ) ;
181
+ Ok ( Value :: List ( v. into_iter ( ) . collect ( ) ) )
167
182
} ) ,
168
183
) ;
169
184
@@ -173,18 +188,19 @@ pub fn default_env() -> Env {
173
188
let func = require_parameter ( "map" , args, 0 ) ?;
174
189
let list = require_list_parameter ( "map" , args, 1 ) ?;
175
190
176
- return list
191
+ list
177
192
. into_iter ( )
178
193
. map ( |val| {
179
- let expr = lisp ! { ( { func. clone( ) } { val. clone ( ) } ) } ;
194
+ let expr = lisp ! { ( { func. clone( ) } { val} ) } ;
180
195
181
196
eval ( env. clone ( ) , & expr)
182
197
} )
183
198
. collect :: < Result < List , RuntimeError > > ( )
184
- . map ( |l| Value :: List ( l ) ) ;
199
+ . map ( Value :: List )
185
200
} ) ,
186
201
) ;
187
202
203
+ // 🦀 Oh the poor `filter`, you must feel really sad being unused.
188
204
// entries.insert(
189
205
// String::from("filter"),
190
206
// Value::NativeFunc(
@@ -208,7 +224,13 @@ pub fn default_env() -> Env {
208
224
Value :: NativeFunc ( |_env, args| {
209
225
let list = require_list_parameter ( "length" , args, 0 ) ?;
210
226
211
- return Ok ( Value :: Int ( list. into_iter ( ) . len ( ) as i32 ) ) ;
227
+ cfg_if ! {
228
+ if #[ cfg( feature = "bigint" ) ] {
229
+ Ok ( Value :: Int ( list. into_iter( ) . len( ) . into( ) ) )
230
+ } else {
231
+ Ok ( Value :: Int ( list. into_iter( ) . len( ) as IntType ) )
232
+ }
233
+ }
212
234
} ) ,
213
235
) ;
214
236
@@ -218,9 +240,24 @@ pub fn default_env() -> Env {
218
240
let start = require_int_parameter ( "range" , args, 0 ) ?;
219
241
let end = require_int_parameter ( "range" , args, 1 ) ?;
220
242
221
- Ok ( Value :: List (
222
- ( start..end) . map ( |i| Value :: Int ( i) ) . collect :: < List > ( ) ,
223
- ) )
243
+ cfg_if ! {
244
+ if #[ cfg( feature = "bigint" ) ] {
245
+ let mut i = start. clone( ) ;
246
+ let mut res = Vec :: with_capacity( ( end. clone( ) - start)
247
+ . to_usize( )
248
+ . ok_or( RuntimeError :: new( "Failed converting `BigInt` to `usize`" ) ) ?
249
+ ) ;
250
+
251
+ while i < end {
252
+ res. push( i. clone( ) ) ;
253
+ i += 1 ;
254
+ }
255
+
256
+ Ok ( Value :: List ( res. into_iter( ) . map( Value :: Int ) . collect:: <List >( ) ) )
257
+ } else {
258
+ Ok ( Value :: List ( ( start..end) . map( Value :: Int ) . collect:: <List >( ) ) )
259
+ }
260
+ }
224
261
} ) ,
225
262
) ;
226
263
@@ -230,24 +267,21 @@ pub fn default_env() -> Env {
230
267
let a = require_parameter ( "+" , args, 0 ) ?;
231
268
let b = require_parameter ( "+" , args, 1 ) ?;
232
269
233
- match ( a. as_int ( ) , b. as_int ( ) ) {
234
- ( Some ( a) , Some ( b) ) => return Ok ( Value :: Int ( a + b) ) ,
235
- _ => ( ) ,
236
- } ;
270
+ if let ( Some ( a) , Some ( b) ) = ( a. as_int ( ) , b. as_int ( ) ) {
271
+ return Ok ( Value :: Int ( a + b) )
272
+ }
237
273
238
- match ( a. as_float ( ) , b. as_float ( ) ) {
239
- ( Some ( a) , Some ( b) ) => return Ok ( Value :: Float ( a + b) ) ,
240
- _ => ( ) ,
241
- } ;
274
+ if let ( Some ( a) , Some ( b) ) = ( a. as_float ( ) , b. as_float ( ) ) {
275
+ return Ok ( Value :: Float ( a + b) )
276
+ }
242
277
243
- match ( a. as_string ( ) , b. as_string ( ) ) {
244
- ( Some ( a) , Some ( b) ) => return Ok ( Value :: String ( String :: from ( a) + b) ) ,
245
- _ => ( ) ,
246
- } ;
278
+ if let ( Some ( a) , Some ( b) ) = ( a. as_string ( ) , b. as_string ( ) ) {
279
+ return Ok ( Value :: String ( String :: from ( a) + b) )
280
+ }
247
281
248
- return Err ( RuntimeError {
282
+ Err ( RuntimeError {
249
283
msg : String :: from ( "Function \" +\" requires arguments to be numbers or strings" ) ,
250
- } ) ;
284
+ } )
251
285
} ) ,
252
286
) ;
253
287
@@ -257,19 +291,17 @@ pub fn default_env() -> Env {
257
291
let a = require_parameter ( "-" , args, 0 ) ?;
258
292
let b = require_parameter ( "-" , args, 1 ) ?;
259
293
260
- match ( a. as_int ( ) , b. as_int ( ) ) {
261
- ( Some ( a) , Some ( b) ) => return Ok ( Value :: Int ( a - b) ) ,
262
- _ => ( ) ,
263
- } ;
294
+ if let ( Some ( a) , Some ( b) ) = ( a. as_int ( ) , b. as_int ( ) ) {
295
+ return Ok ( Value :: Int ( a - b) )
296
+ }
264
297
265
- match ( a. as_float ( ) , b. as_float ( ) ) {
266
- ( Some ( a) , Some ( b) ) => return Ok ( Value :: Float ( a - b) ) ,
267
- _ => ( ) ,
268
- } ;
298
+ if let ( Some ( a) , Some ( b) ) = ( a. as_float ( ) , b. as_float ( ) ) {
299
+ return Ok ( Value :: Float ( a - b) )
300
+ }
269
301
270
- return Err ( RuntimeError {
302
+ Err ( RuntimeError {
271
303
msg : String :: from ( "Function \" -\" requires arguments to be numbers" ) ,
272
- } ) ;
304
+ } )
273
305
} ) ,
274
306
) ;
275
307
@@ -279,19 +311,17 @@ pub fn default_env() -> Env {
279
311
let a = require_parameter ( "*" , args, 0 ) ?;
280
312
let b = require_parameter ( "*" , args, 1 ) ?;
281
313
282
- match ( a. as_int ( ) , b. as_int ( ) ) {
283
- ( Some ( a) , Some ( b) ) => return Ok ( Value :: Int ( a * b) ) ,
284
- _ => ( ) ,
285
- } ;
314
+ if let ( Some ( a) , Some ( b) ) = ( a. as_int ( ) , b. as_int ( ) ) {
315
+ return Ok ( Value :: Int ( a * b) )
316
+ }
286
317
287
- match ( a. as_float ( ) , b. as_float ( ) ) {
288
- ( Some ( a) , Some ( b) ) => return Ok ( Value :: Float ( a * b) ) ,
289
- _ => ( ) ,
290
- } ;
318
+ if let ( Some ( a) , Some ( b) ) = ( a. as_float ( ) , b. as_float ( ) ) {
319
+ return Ok ( Value :: Float ( a * b) )
320
+ }
291
321
292
- return Err ( RuntimeError {
322
+ Err ( RuntimeError {
293
323
msg : String :: from ( "Function \" *\" requires arguments to be numbers" ) ,
294
- } ) ;
324
+ } )
295
325
} ) ,
296
326
) ;
297
327
@@ -301,19 +331,17 @@ pub fn default_env() -> Env {
301
331
let a = require_parameter ( "/" , args, 0 ) ?;
302
332
let b = require_parameter ( "/" , args, 1 ) ?;
303
333
304
- match ( a. as_int ( ) , b. as_int ( ) ) {
305
- ( Some ( a) , Some ( b) ) => return Ok ( Value :: Int ( a / b) ) ,
306
- _ => ( ) ,
307
- } ;
334
+ if let ( Some ( a) , Some ( b) ) = ( a. as_int ( ) , b. as_int ( ) ) {
335
+ return Ok ( Value :: Int ( a / b) )
336
+ }
308
337
309
- match ( a. as_float ( ) , b. as_float ( ) ) {
310
- ( Some ( a) , Some ( b) ) => return Ok ( Value :: Float ( a / b) ) ,
311
- _ => ( ) ,
312
- } ;
338
+ if let ( Some ( a) , Some ( b) ) = ( a. as_float ( ) , b. as_float ( ) ) {
339
+ return Ok ( Value :: Float ( a / b) )
340
+ }
313
341
314
- return Err ( RuntimeError {
342
+ Err ( RuntimeError {
315
343
msg : String :: from ( "Function \" /\" requires arguments to be numbers" ) ,
316
- } ) ;
344
+ } )
317
345
} ) ,
318
346
) ;
319
347
@@ -323,14 +351,13 @@ pub fn default_env() -> Env {
323
351
let a = require_parameter ( "truncate" , args, 0 ) ?;
324
352
let b = require_parameter ( "truncate" , args, 1 ) ?;
325
353
326
- match ( a. as_int ( ) , b. as_int ( ) ) {
327
- ( Some ( a) , Some ( b) ) => return Ok ( Value :: Int ( a / b) ) ,
328
- _ => ( ) ,
329
- } ;
354
+ if let ( Some ( a) , Some ( b) ) = ( a. as_int ( ) , b. as_int ( ) ) {
355
+ return Ok ( Value :: Int ( a / b) )
356
+ }
330
357
331
- return Err ( RuntimeError {
358
+ Err ( RuntimeError {
332
359
msg : String :: from ( "Function \" truncate\" requires arguments to be integers" ) ,
333
- } ) ;
360
+ } )
334
361
} ) ,
335
362
) ;
336
363
@@ -418,7 +445,7 @@ pub fn default_env() -> Env {
418
445
let func = require_parameter ( "apply" , args, 0 ) ?;
419
446
let params = require_list_parameter ( "apply" , args, 1 ) ?;
420
447
421
- eval ( env. clone ( ) , & Value :: List ( params. cons ( func. clone ( ) ) ) )
448
+ eval ( env, & Value :: List ( params. cons ( func. clone ( ) ) ) )
422
449
} ) ,
423
450
) ;
424
451
0 commit comments