@@ -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,15 +188,15 @@ 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
@@ -208,7 +223,13 @@ pub fn default_env() -> Env {
208
223
Value :: NativeFunc ( |_env, args| {
209
224
let list = require_list_parameter ( "length" , args, 0 ) ?;
210
225
211
- return Ok ( Value :: Int ( list. into_iter ( ) . len ( ) as i32 ) ) ;
226
+ cfg_if ! {
227
+ if #[ cfg( feature = "bigint" ) ] {
228
+ Ok ( Value :: Int ( list. into_iter( ) . len( ) . into( ) ) )
229
+ } else {
230
+ Ok ( Value :: Int ( list. into_iter( ) . len( ) as IntType ) )
231
+ }
232
+ }
212
233
} ) ,
213
234
) ;
214
235
@@ -218,9 +239,24 @@ pub fn default_env() -> Env {
218
239
let start = require_int_parameter ( "range" , args, 0 ) ?;
219
240
let end = require_int_parameter ( "range" , args, 1 ) ?;
220
241
221
- Ok ( Value :: List (
222
- ( start..end) . map ( |i| Value :: Int ( i) ) . collect :: < List > ( ) ,
223
- ) )
242
+ cfg_if ! {
243
+ if #[ cfg( feature = "bigint" ) ] {
244
+ let mut i = start. clone( ) ;
245
+ let mut res = Vec :: with_capacity( ( end. clone( ) - start)
246
+ . to_usize( )
247
+ . ok_or( RuntimeError :: new( "Failed converting `BigInt` to `usize`" ) ) ?
248
+ ) ;
249
+
250
+ while i <= end {
251
+ res. push( i. clone( ) ) ;
252
+ i += 1 ;
253
+ }
254
+
255
+ Ok ( Value :: List ( res. into_iter( ) . map( Value :: Int ) . collect:: <List >( ) ) )
256
+ } else {
257
+ Ok ( Value :: List ( ( start..=end) . map( Value :: Int ) . collect:: <List >( ) ) )
258
+ }
259
+ }
224
260
} ) ,
225
261
) ;
226
262
@@ -230,24 +266,21 @@ pub fn default_env() -> Env {
230
266
let a = require_parameter ( "+" , args, 0 ) ?;
231
267
let b = require_parameter ( "+" , args, 1 ) ?;
232
268
233
- match ( a. as_int ( ) , b. as_int ( ) ) {
234
- ( Some ( a) , Some ( b) ) => return Ok ( Value :: Int ( a + b) ) ,
235
- _ => ( ) ,
236
- } ;
269
+ if let ( Some ( a) , Some ( b) ) = ( a. as_int ( ) , b. as_int ( ) ) {
270
+ return Ok ( Value :: Int ( a + b) )
271
+ }
237
272
238
- match ( a. as_float ( ) , b. as_float ( ) ) {
239
- ( Some ( a) , Some ( b) ) => return Ok ( Value :: Float ( a + b) ) ,
240
- _ => ( ) ,
241
- } ;
273
+ if let ( Some ( a) , Some ( b) ) = ( a. as_float ( ) , b. as_float ( ) ) {
274
+ return Ok ( Value :: Float ( a + b) )
275
+ }
242
276
243
- match ( a. as_string ( ) , b. as_string ( ) ) {
244
- ( Some ( a) , Some ( b) ) => return Ok ( Value :: String ( String :: from ( a) + b) ) ,
245
- _ => ( ) ,
246
- } ;
277
+ if let ( Some ( a) , Some ( b) ) = ( a. as_string ( ) , b. as_string ( ) ) {
278
+ return Ok ( Value :: String ( String :: from ( a) + b) )
279
+ }
247
280
248
- return Err ( RuntimeError {
281
+ Err ( RuntimeError {
249
282
msg : String :: from ( "Function \" +\" requires arguments to be numbers or strings" ) ,
250
- } ) ;
283
+ } )
251
284
} ) ,
252
285
) ;
253
286
@@ -257,19 +290,17 @@ pub fn default_env() -> Env {
257
290
let a = require_parameter ( "-" , args, 0 ) ?;
258
291
let b = require_parameter ( "-" , args, 1 ) ?;
259
292
260
- match ( a. as_int ( ) , b. as_int ( ) ) {
261
- ( Some ( a) , Some ( b) ) => return Ok ( Value :: Int ( a - b) ) ,
262
- _ => ( ) ,
263
- } ;
293
+ if let ( Some ( a) , Some ( b) ) = ( a. as_int ( ) , b. as_int ( ) ) {
294
+ return Ok ( Value :: Int ( a - b) )
295
+ }
264
296
265
- match ( a. as_float ( ) , b. as_float ( ) ) {
266
- ( Some ( a) , Some ( b) ) => return Ok ( Value :: Float ( a - b) ) ,
267
- _ => ( ) ,
268
- } ;
297
+ if let ( Some ( a) , Some ( b) ) = ( a. as_float ( ) , b. as_float ( ) ) {
298
+ return Ok ( Value :: Float ( a - b) )
299
+ }
269
300
270
- return Err ( RuntimeError {
301
+ Err ( RuntimeError {
271
302
msg : String :: from ( "Function \" -\" requires arguments to be numbers" ) ,
272
- } ) ;
303
+ } )
273
304
} ) ,
274
305
) ;
275
306
@@ -279,19 +310,17 @@ pub fn default_env() -> Env {
279
310
let a = require_parameter ( "*" , args, 0 ) ?;
280
311
let b = require_parameter ( "*" , args, 1 ) ?;
281
312
282
- match ( a. as_int ( ) , b. as_int ( ) ) {
283
- ( Some ( a) , Some ( b) ) => return Ok ( Value :: Int ( a * b) ) ,
284
- _ => ( ) ,
285
- } ;
313
+ if let ( Some ( a) , Some ( b) ) = ( a. as_int ( ) , b. as_int ( ) ) {
314
+ return Ok ( Value :: Int ( a * b) )
315
+ }
286
316
287
- match ( a. as_float ( ) , b. as_float ( ) ) {
288
- ( Some ( a) , Some ( b) ) => return Ok ( Value :: Float ( a * b) ) ,
289
- _ => ( ) ,
290
- } ;
317
+ if let ( Some ( a) , Some ( b) ) = ( a. as_float ( ) , b. as_float ( ) ) {
318
+ return Ok ( Value :: Float ( a * b) )
319
+ }
291
320
292
- return Err ( RuntimeError {
321
+ Err ( RuntimeError {
293
322
msg : String :: from ( "Function \" *\" requires arguments to be numbers" ) ,
294
- } ) ;
323
+ } )
295
324
} ) ,
296
325
) ;
297
326
@@ -301,19 +330,17 @@ pub fn default_env() -> Env {
301
330
let a = require_parameter ( "/" , args, 0 ) ?;
302
331
let b = require_parameter ( "/" , args, 1 ) ?;
303
332
304
- match ( a. as_int ( ) , b. as_int ( ) ) {
305
- ( Some ( a) , Some ( b) ) => return Ok ( Value :: Int ( a / b) ) ,
306
- _ => ( ) ,
307
- } ;
333
+ if let ( Some ( a) , Some ( b) ) = ( a. as_int ( ) , b. as_int ( ) ) {
334
+ return Ok ( Value :: Int ( a / b) )
335
+ }
308
336
309
- match ( a. as_float ( ) , b. as_float ( ) ) {
310
- ( Some ( a) , Some ( b) ) => return Ok ( Value :: Float ( a / b) ) ,
311
- _ => ( ) ,
312
- } ;
337
+ if let ( Some ( a) , Some ( b) ) = ( a. as_float ( ) , b. as_float ( ) ) {
338
+ return Ok ( Value :: Float ( a / b) )
339
+ }
313
340
314
- return Err ( RuntimeError {
341
+ Err ( RuntimeError {
315
342
msg : String :: from ( "Function \" /\" requires arguments to be numbers" ) ,
316
- } ) ;
343
+ } )
317
344
} ) ,
318
345
) ;
319
346
@@ -323,14 +350,13 @@ pub fn default_env() -> Env {
323
350
let a = require_parameter ( "truncate" , args, 0 ) ?;
324
351
let b = require_parameter ( "truncate" , args, 1 ) ?;
325
352
326
- match ( a. as_int ( ) , b. as_int ( ) ) {
327
- ( Some ( a) , Some ( b) ) => return Ok ( Value :: Int ( a / b) ) ,
328
- _ => ( ) ,
329
- } ;
353
+ if let ( Some ( a) , Some ( b) ) = ( a. as_int ( ) , b. as_int ( ) ) {
354
+ return Ok ( Value :: Int ( a / b) )
355
+ }
330
356
331
- return Err ( RuntimeError {
357
+ Err ( RuntimeError {
332
358
msg : String :: from ( "Function \" truncate\" requires arguments to be integers" ) ,
333
- } ) ;
359
+ } )
334
360
} ) ,
335
361
) ;
336
362
@@ -418,7 +444,7 @@ pub fn default_env() -> Env {
418
444
let func = require_parameter ( "apply" , args, 0 ) ?;
419
445
let params = require_list_parameter ( "apply" , args, 1 ) ?;
420
446
421
- eval ( env. clone ( ) , & Value :: List ( params. cons ( func. clone ( ) ) ) )
447
+ eval ( env, & Value :: List ( params. cons ( func. clone ( ) ) ) )
422
448
} ) ,
423
449
) ;
424
450
0 commit comments