skeem 0.2.10 → 0.2.11

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 482a0c8f936db1cc3099e133dda1d42d685d5e3c7fe244bf98f0062ad1470bc1
4
- data.tar.gz: e950b89cf3a4bc7971a5263e96f7a8dbb670d926b03601d2c4116ccc03b613ec
3
+ metadata.gz: c08f4d71464aad98f53e99e6f66cd18e5961dbd1930353a560844b05d824e288
4
+ data.tar.gz: f38223cedadc6689670c1d4db901a25cf18caf5b2761519e866909575228b5d9
5
5
  SHA512:
6
- metadata.gz: a8a6cde2cd049ccdf7ac4256b2313a462990f355790e6a23ab78febaa9f2377a39914f169c213e5ec1b2342e6bc611eeddae6f8f806ac3ecff713a356765403c
7
- data.tar.gz: 6b9ea76b548deb643631515a755c431a30c915ad1db1dee609ceec1c03e17380d99f0fe33d1ab80a4eda4eec9de3a4acc55e03d6f8d4ebac800f650ad9695554
6
+ metadata.gz: 6618523bb5c1a4145b625ed5d264c1879f6980677df9c18e208f9a623652329cf952b4620a8c0c15c96cc38157e75f0590e9555535fa76b63a4361c866393bfb
7
+ data.tar.gz: 2b0ce438844db721e855dc9a805a66dcacac97240895d3be96e09e9634b8d80056e7dd4cdcb9e36c98896bb536f36ef0801ae830173a8b7ff0d1f032cfd3f18f
@@ -1,3 +1,14 @@
1
+ ## [0.2.11] - 2019-06-16
2
+ - Added procedures: `gcd`, `lcm`, `numerator`, `denominator`, `floor`, `ceiling`, `truncate`,
3
+ `round`.
4
+
5
+ ### Changed
6
+ - File `interpreter_spec.rb`: Refactoring by DRYing code
7
+ - File `primitive_builder_spec.rb`: Refactoring by DRYing code
8
+ - File `base.skm` added implementation of `truncate`
9
+ - File `primitive_builder.rb` Implemented primitive procedures `gcd`, `lcm`, `numerator`, `denominator`, `floor`, `ceiling`, `round`.
10
+ - File `README.md` Added mentions to new procedures.
11
+
1
12
  ## [0.2.10] - 2019-06-15
2
13
  - Skeem now supports rational numbers (fractions)
3
14
  - Added procedures: `max`, `min`, `floor/`, `floor-quotient`, `floor-remainder`, `truncate/`, `truncate-quotient`,
@@ -15,6 +26,7 @@
15
26
  `truncate-remainder`, `quotient`, `remainder`, `modulo`
16
27
  - Class Tokenizer updated to recognize rational numbers.
17
28
  - Test suite file `base_tests.scm` expanded.
29
+ - File `README.md` Added mentions to new procedures.
18
30
 
19
31
  ### Fixed
20
32
  - File `primitive_builder.rb` Fixed and extended implementation of `/`procedure
data/README.md CHANGED
@@ -254,7 +254,7 @@ This section lists the implemented standard procedures
254
254
  * Number-level: `number?`, `complex?`, `real?`, `rational?`, `integer?`, `zero?`, `exact?`, `inexact?`, `exact-integer?` , `+`, `-`, `*`, `/`,
255
255
  `=`, `square`, `number->string`
256
256
  * Real-level: `positive?`, `negative?`, `<`, `>`, `<=`, `>=`, `abs`, `max`, `min`, `floor/`, `floor-quotient`, `floor-remainder`, `truncate/`, `truncate-quotient`,
257
- `truncate-remainder`, `quotient`, `remainder`, `modulo`
257
+ `truncate-remainder`, `quotient`, `remainder`, `modulo`, `gcd`, `lcm`, `numerator`, `denominator`, `floor`, `ceiling`, `truncate`, `round`
258
258
  * Integer-level: `even?`, `odd?`
259
259
 
260
260
  #### List procedures
@@ -29,12 +29,12 @@ module Skeem
29
29
  @parser ||= Parser.new
30
30
  @ptree = parser.parse(source)
31
31
  # $stderr.puts @ptree.root.inspect if mode.nil?
32
- # require 'debug' unless mode.nil?
32
+ # require 'debug' unless mode.nil?
33
33
  end
34
-
34
+
35
35
  def run(source, mode = nil)
36
36
  parse(source, mode)
37
- # require 'debug' unless mode.nil?
37
+ # require 'debug' unless mode.nil?
38
38
  @ptree.root.evaluate(runtime)
39
39
  end
40
40
 
@@ -53,6 +53,13 @@ module Skeem
53
53
  create_divide(aRuntime)
54
54
  create_floor_slash(aRuntime)
55
55
  create_truncate_slash(aRuntime)
56
+ create_gcd(aRuntime)
57
+ create_lcm(aRuntime)
58
+ create_numerator(aRuntime)
59
+ create_denominator(aRuntime)
60
+ create_floor(aRuntime)
61
+ create_ceiling(aRuntime)
62
+ create_round(aRuntime)
56
63
  end
57
64
 
58
65
  def add_comparison(aRuntime)
@@ -252,6 +259,94 @@ module Skeem
252
259
  define_primitive_proc(aRuntime, 'truncate/', binary, primitive)
253
260
  end
254
261
 
262
+ def create_gcd(aRuntime)
263
+ primitive = ->(_runtime, arglist) do
264
+ if arglist.empty?
265
+ integer(0)
266
+ else
267
+ first_one = arglist.shift
268
+ divisor = first_one.value
269
+
270
+ arglist.each do |elem|
271
+ divisor = divisor.gcd(elem.value)
272
+ break if divisor == 1
273
+ end
274
+
275
+ to_datum(divisor)
276
+ end
277
+ end
278
+ define_primitive_proc(aRuntime, 'gcd', zero_or_more, primitive)
279
+ end
280
+
281
+ def create_lcm(aRuntime)
282
+ primitive = ->(_runtime, arglist) do
283
+ if arglist.empty?
284
+ integer(1)
285
+ else
286
+ values = arglist.map(&:value)
287
+ multiple = values.reduce(1, :lcm)
288
+
289
+ to_datum(multiple)
290
+ end
291
+ end
292
+ define_primitive_proc(aRuntime, 'lcm', zero_or_more, primitive)
293
+ end
294
+
295
+ def create_numerator(aRuntime)
296
+ primitive = ->(_runtime, arg_evaluated) do
297
+ case arg_evaluated
298
+ when SkmInteger
299
+ result = arg_evaluated
300
+ when SkmRational, SkmReal
301
+ result = integer(arg_evaluated.value.numerator)
302
+ end
303
+ result
304
+ end
305
+
306
+ define_primitive_proc(aRuntime, 'numerator', unary, primitive)
307
+ end
308
+
309
+ def create_denominator(aRuntime)
310
+ primitive = ->(_runtime, arg_evaluated) do
311
+ case arg_evaluated
312
+ when SkmInteger
313
+ result = 1
314
+ when SkmRational, SkmReal
315
+ result = arg_evaluated.value.denominator
316
+ end
317
+ integer(result)
318
+ end
319
+
320
+ define_primitive_proc(aRuntime, 'denominator', unary, primitive)
321
+ end
322
+
323
+ def create_floor(aRuntime)
324
+ primitive = ->(_runtime, arg_evaluated) do
325
+ result = arg_evaluated.value.floor
326
+ integer(result)
327
+ end
328
+
329
+ define_primitive_proc(aRuntime, 'floor', unary, primitive)
330
+ end
331
+
332
+ def create_ceiling(aRuntime)
333
+ primitive = ->(_runtime, arg_evaluated) do
334
+ result = arg_evaluated.value.ceil
335
+ integer(result)
336
+ end
337
+
338
+ define_primitive_proc(aRuntime, 'ceiling', unary, primitive)
339
+ end
340
+
341
+ def create_round(aRuntime)
342
+ primitive = ->(_runtime, arg_evaluated) do
343
+ result = arg_evaluated.value.round
344
+ integer(result)
345
+ end
346
+
347
+ define_primitive_proc(aRuntime, 'round', unary, primitive)
348
+ end
349
+
255
350
  def core_eqv?(eval_arg1, eval_arg2)
256
351
  raw_result = eval_arg1.eqv?(eval_arg2)
257
352
  boolean(raw_result)
@@ -3,9 +3,9 @@
3
3
  ;; (exact-integer? z)
4
4
  (define exact-integer?
5
5
  (lambda (z)
6
- (and
6
+ (and
7
7
  (exact? z)
8
- (integer? z))))
8
+ (integer? z))))
9
9
 
10
10
  ;; (zero? z)
11
11
  ;; Returns true iff z is zero
@@ -15,7 +15,7 @@
15
15
  #t
16
16
  #f)))
17
17
 
18
- ; (positive? x)
18
+ ; (positive? x)
19
19
  ; Return true if x greater than zero; false otherwise
20
20
  (define positive?
21
21
  (lambda (x)
@@ -24,7 +24,7 @@
24
24
  #f)))
25
25
 
26
26
  ; (negative? x)
27
- ; Returns true iff x < 0
27
+ ; Returns true iff x < 0
28
28
  (define negative?
29
29
  (lambda (x)
30
30
  (if (< x 0)
@@ -32,11 +32,11 @@
32
32
  #f)))
33
33
 
34
34
  ; (inexact? z)
35
- ; Returns true iff z is not an exact number
35
+ ; Returns true iff z is not an exact number
36
36
  (define inexact?
37
- (lambda (z)
37
+ (lambda (z)
38
38
  (not (exact? z))))
39
-
39
+
40
40
  (define floor-quotient
41
41
  (lambda (n1 n2)
42
42
  (car (floor/ n1 n2))))
@@ -44,7 +44,7 @@
44
44
  (define floor-remainder
45
45
  (lambda (n1 n2)
46
46
  (cdr (floor/ n1 n2))))
47
-
47
+
48
48
  (define truncate-quotient
49
49
  (lambda (n1 n2)
50
50
  (car (truncate/ n1 n2))))
@@ -57,17 +57,24 @@
57
57
  (define quotient
58
58
  (lambda (x y)
59
59
  (truncate-quotient x y)))
60
-
60
+
61
61
  ; For R5RS compatibility
62
62
  (define remainder
63
63
  (lambda (x y)
64
64
  (truncate-remainder x y)))
65
-
65
+
66
66
  ; For R5RS compatibility
67
67
  (define modulo
68
68
  (lambda (x y)
69
69
  (floor-remainder x y)))
70
70
 
71
+ (define truncate
72
+ (lambda (x)
73
+ (if (positive? x)
74
+ (floor x)
75
+ (ceiling x)
76
+ )))
77
+
71
78
  ; (odd? n)
72
79
  ; Returns true iff n is odd
73
80
  (define odd?
@@ -102,47 +109,47 @@
102
109
  (if obj #f #t))
103
110
 
104
111
  ; (list arg ...)
105
- ; Allocates and returns a new list from its arguments
112
+ ; Allocates and returns a new list from its arguments
106
113
  (define list
107
114
  (lambda args args))
108
-
109
- (define caar
115
+
116
+ (define caar
110
117
  (lambda (x)
111
118
  (car (car x))))
112
119
 
113
- (define cadr
114
- (lambda (x)
120
+ (define cadr
121
+ (lambda (x)
115
122
  (car (cdr x))))
116
123
 
117
- (define cdar
124
+ (define cdar
118
125
  (lambda(x)
119
126
  (cdr (car x))))
120
127
 
121
- (define cddr
122
- (lambda (x)
128
+ (define cddr
129
+ (lambda (x)
123
130
  (cdr (cdr x))))
124
131
 
125
- ;; (list-ref list n)
132
+ ;; (list-ref list n)
126
133
  ;; Return the nth (sero-based) element of list
127
134
  ;; n must be a nonnegative integer
128
135
  ;(define list-ref
129
136
  ; (lambda (ls n)
130
137
  ; (if (= n 0)
131
138
  ; (car ls)
132
- ; (list-ref (cdr ls) (- n 1)))))
133
-
139
+ ; (list-ref (cdr ls) (- n 1)))))
140
+
134
141
  (define symbol=? string=?)
135
142
 
136
143
  ;; Test the equivalence (with eqv? predicate) between an expected value and
137
144
  ;; an expression
138
145
  ;; (test-eqv expected test-expr)
139
- (define test-eqv
140
- (lambda (x y)
146
+ (define test-eqv
147
+ (lambda (x y)
141
148
  (test-assert (eqv? x y))))
142
149
 
143
150
  ;; Test the equality (with equal? predicate) between an expected value and
144
151
  ;; an expression
145
152
  ;; (test-equal expected test-expr)
146
- (define test-equal
147
- (lambda (x y)
153
+ (define test-equal
154
+ (lambda (x y)
148
155
  (test-assert (equal? x y))))
@@ -1,3 +1,3 @@
1
1
  module Skeem
2
- VERSION = '0.2.10'.freeze
2
+ VERSION = '0.2.11'.freeze
3
3
  end
@@ -5,6 +5,7 @@ require_relative '../../lib/skeem/interpreter' # Load the class under test
5
5
 
6
6
  module Skeem
7
7
  describe Interpreter do
8
+ include InterpreterSpec
8
9
  include DatumDSL
9
10
 
10
11
  context 'Initialization:' do
@@ -39,13 +40,12 @@ module Skeem
39
40
  context 'Interpreting self-evaluating expressions' do
40
41
  it 'should evaluate isolated booleans' do
41
42
  samples = [
42
- ['#f', false],
43
- ['#false', false],
44
- ['#t', true],
45
- ['#true', true]
46
- ]
47
- samples.each do |source, predicted|
48
- result = subject.run(source)
43
+ ['#f', false],
44
+ ['#false', false],
45
+ ['#t', true],
46
+ ['#true', true]
47
+ ]
48
+ compare_to_predicted(samples) do |result, predicted|
49
49
  expect(result).to be_kind_of(SkmBoolean)
50
50
  expect(result).to eq(predicted)
51
51
  end
@@ -59,8 +59,7 @@ module Skeem
59
59
  ['+12345', 12345],
60
60
  ['-12345', -12345]
61
61
  ]
62
- samples.each do |source, predicted|
63
- result = subject.run(source)
62
+ compare_to_predicted(samples) do |result, predicted|
64
63
  expect(result).to be_kind_of(SkmInteger)
65
64
  expect(result).to eq(predicted)
66
65
  end
@@ -74,8 +73,7 @@ module Skeem
74
73
  ['+123e+45', 123e+45],
75
74
  ['-123e-45', -123e-45]
76
75
  ]
77
- samples.each do |source, predicted|
78
- result = subject.run(source)
76
+ compare_to_predicted(samples) do |result, predicted|
79
77
  expect(result).to be_kind_of(SkmReal)
80
78
  expect(result).to eq(predicted)
81
79
  end
@@ -83,10 +81,9 @@ module Skeem
83
81
 
84
82
  it 'should evaluate isolated strings' do
85
83
  samples = [
86
- ['"Hello, world"', 'Hello, world']
87
- ]
88
- samples.each do |source, predicted|
89
- result = subject.run(source)
84
+ ['"Hello, world"', 'Hello, world']
85
+ ]
86
+ compare_to_predicted(samples) do |result, predicted|
90
87
  expect(result).to be_kind_of(SkmString)
91
88
  expect(result).to eq(predicted)
92
89
  end
@@ -132,10 +129,7 @@ SKEEM
132
129
  ['(if (> 3 2) "yes")', 'yes'],
133
130
  ['(if (> 2 3) "yes")', SkmUndefined.instance]
134
131
  ]
135
- checks.each do |(skeem_expr, expectation)|
136
- result = subject.run(skeem_expr)
137
- expect(result).to eq(expectation)
138
- end
132
+ compare_to_predicted(checks)
139
133
  end
140
134
 
141
135
  it 'should implement the complete conditional form' do
@@ -143,10 +137,7 @@ SKEEM
143
137
  ['(if (> 3 2) "yes" "no")', 'yes'],
144
138
  ['(if (> 2 3) "yes" "no")', 'no']
145
139
  ]
146
- checks.each do |(skeem_expr, expectation)|
147
- result = subject.run(skeem_expr)
148
- expect(result).to eq(expectation)
149
- end
140
+ compare_to_predicted(checks)
150
141
  source = <<-SKEEM
151
142
  ; Example from R7RS section 4.1.5
152
143
  (if (> 3 2)
@@ -156,7 +147,7 @@ SKEEM
156
147
  result = subject.run(source)
157
148
  expect(result).to eq(1)
158
149
  end
159
-
150
+
160
151
  it 'should implement the cond form' do
161
152
  source = <<-SKEEM
162
153
  (define signum (lambda (x)
@@ -166,17 +157,15 @@ SKEEM
166
157
  ((< x 0) -1)
167
158
  )))
168
159
  SKEEM
169
- result = subject.run(source)
170
- result = subject.run('(signum 3)')
171
- expect(result).to eq(1)
172
-
173
- result = subject.run('(signum 0)')
174
- expect(result).to eq(0)
175
-
176
- result = subject.run('(signum -3)')
177
- expect(result).to eq(-1)
160
+ result = subject.run(source)
161
+ checks = [
162
+ ['(signum 3)', 1],
163
+ ['(signum 0)', 0],
164
+ ['(signum -3)', -1]
165
+ ]
166
+ compare_to_predicted(checks)
178
167
  end
179
-
168
+
180
169
  it 'should implement the cond form with arrows' do
181
170
  source = <<-SKEEM
182
171
  (define signum (lambda (x)
@@ -186,16 +175,14 @@ SKEEM
186
175
  ((< x 0) => -1)
187
176
  )))
188
177
  SKEEM
189
- result = subject.run(source)
190
- result = subject.run('(signum 3)')
191
- expect(result).to eq(1)
192
-
193
- result = subject.run('(signum 0)')
194
- expect(result).to eq(0)
195
-
196
- result = subject.run('(signum -3)')
197
- expect(result).to eq(-1)
198
- end
178
+ result = subject.run(source)
179
+ checks = [
180
+ ['(signum 3)', 1],
181
+ ['(signum 0)', 0],
182
+ ['(signum -3)', -1]
183
+ ]
184
+ compare_to_predicted(checks)
185
+ end
199
186
 
200
187
  it 'should implement the cond ... else form' do
201
188
  source = <<-SKEEM
@@ -206,16 +193,22 @@ SKEEM
206
193
  (else -1)
207
194
  )))
208
195
  SKEEM
209
- result = subject.run(source)
210
- result = subject.run('(signum 3)')
211
- expect(result).to eq(1)
212
-
213
- result = subject.run('(signum 0)')
214
- expect(result).to eq(0)
196
+ result = subject.run(source)
197
+ checks = [
198
+ ['(signum 3)', 1],
199
+ ['(signum 0)', 0],
200
+ ['(signum -3)', -1]
201
+ ]
202
+ compare_to_predicted(checks)
203
+ end
215
204
 
216
- result = subject.run('(signum -3)')
217
- expect(result).to eq(-1)
218
- end
205
+ it 'should implement the truncate procedure' do
206
+ checks = [
207
+ ['(truncate -4.3)', -4],
208
+ ['(truncate 3.5)', 3]
209
+ ]
210
+ compare_to_predicted(checks)
211
+ end
219
212
 
220
213
  it 'should implement the quotation of constant literals' do
221
214
  checks = [
@@ -228,10 +221,7 @@ SKEEM
228
221
  ["'\"abc\"", 'abc'],
229
222
  ["'#t", true]
230
223
  ]
231
- checks.each do |(skeem_expr, expectation)|
232
- result = subject.run(skeem_expr)
233
- expect(result).to eq(expectation)
234
- end
224
+ compare_to_predicted(checks)
235
225
  end
236
226
 
237
227
  it 'should implement the quotation of vectors' do
@@ -280,12 +270,12 @@ SKEEM
280
270
  subject.run(source)
281
271
  procedure = subject.fetch('abs')
282
272
  expect(procedure.arity).to eq(1)
283
- result = subject.run('(abs -3)')
284
- expect(result).to eq(3)
285
- result = subject.run('(abs 0)')
286
- expect(result).to eq(0)
287
- result = subject.run('(abs 3)')
288
- expect(result).to eq(3)
273
+ checks = [
274
+ ['(abs -3)', 3],
275
+ ['(abs 0)', 0],
276
+ ['(abs 3)', 3]
277
+ ]
278
+ compare_to_predicted(checks)
289
279
  end
290
280
 
291
281
  it 'should implement the lambda function with two args' do
@@ -298,12 +288,12 @@ SKEEM
298
288
  subject.run(source)
299
289
  procedure = subject.fetch('min')
300
290
  expect(procedure.arity).to eq(2)
301
- result = subject.run('(min 1 2)')
302
- expect(result).to eq(1)
303
- result = subject.run('(min 2 1)')
304
- expect(result).to eq(1)
305
- result = subject.run('(min 2 2)')
306
- expect(result).to eq(2)
291
+ checks = [
292
+ ['(min 1 2)', 1],
293
+ ['(min 2 1)', 1],
294
+ ['(min 2 2)', 2]
295
+ ]
296
+ compare_to_predicted(checks)
307
297
  end
308
298
 
309
299
  it 'should implement recursive functions' do
@@ -377,8 +367,8 @@ SKEEM
377
367
  result = subject.run(source)
378
368
  expect(result.last.value).to eq(20)
379
369
  end
380
-
381
-
370
+
371
+
382
372
  end # context
383
373
 
384
374
  context 'Binding constructs:' do
@@ -412,8 +402,7 @@ SKEEM
412
402
  (z (+ x y)))
413
403
  (* z x)))
414
404
  SKEEM
415
- result = subject.run(source)
416
- expect(result).to eq(35)
405
+ expect_expr(source).to eq(35)
417
406
  end
418
407
 
419
408
  it 'should support the nesting of a lambda in a let expression' do
@@ -444,8 +433,7 @@ SKEEM
444
433
  (z (+ x y)))
445
434
  (* z x)))
446
435
  SKEEM
447
- result = subject.run(source)
448
- expect(result).to eq(70)
436
+ expect_expr(source).to eq(70)
449
437
  end
450
438
  end # context
451
439
 
@@ -470,7 +458,7 @@ SKEEM
470
458
  result = subject.run(source)
471
459
  expect(result).to eq(7)
472
460
  end
473
-
461
+
474
462
  it 'should support begin as lambda body' do
475
463
  source = <<-SKEEM
476
464
  (define kube (lambda (x)
@@ -484,7 +472,7 @@ SKEEM
484
472
  SKEEM
485
473
  result = subject.run(source)
486
474
  expect(result.last).to eq(64)
487
- end
475
+ end
488
476
  end # context
489
477
 
490
478
  context 'Quasiquotation:' do
@@ -499,10 +487,7 @@ SKEEM
499
487
  ['`"abc"', 'abc'],
500
488
  ['`#t', true]
501
489
  ]
502
- checks.each do |(skeem_expr, expectation)|
503
- result = subject.run(skeem_expr)
504
- expect(result).to eq(expectation)
505
- end
490
+ compare_to_predicted(checks)
506
491
  end
507
492
 
508
493
  it 'should implement the quasiquotation of vectors' do
@@ -654,10 +639,7 @@ SKEEM
654
639
  ['(zero? 3)', false],
655
640
  ['(zero? -3)', false]
656
641
  ]
657
- checks.each do |(skeem_expr, expectation)|
658
- result = subject.run(skeem_expr)
659
- expect(result).to eq(expectation)
660
- end
642
+ compare_to_predicted(checks)
661
643
  end
662
644
 
663
645
  it 'should implement the positive? predicate' do
@@ -669,10 +651,7 @@ SKEEM
669
651
  ['(positive? 3)', true],
670
652
  ['(positive? -3)', false]
671
653
  ]
672
- checks.each do |(skeem_expr, expectation)|
673
- result = subject.run(skeem_expr)
674
- expect(result).to eq(expectation)
675
- end
654
+ compare_to_predicted(checks)
676
655
  end
677
656
 
678
657
  it 'should implement the negative? predicate' do
@@ -684,10 +663,7 @@ SKEEM
684
663
  ['(negative? 3)', false],
685
664
  ['(negative? -3)', true]
686
665
  ]
687
- checks.each do |(skeem_expr, expectation)|
688
- result = subject.run(skeem_expr)
689
- expect(result).to eq(expectation)
690
- end
666
+ compare_to_predicted(checks)
691
667
  end
692
668
 
693
669
  it 'should implement the even? predicate' do
@@ -697,10 +673,7 @@ SKEEM
697
673
  ['(even? 2.0)', true],
698
674
  ['(even? -120762398465)', false]
699
675
  ]
700
- checks.each do |(skeem_expr, expectation)|
701
- result = subject.run(skeem_expr)
702
- expect(result).to eq(expectation)
703
- end
676
+ compare_to_predicted(checks)
704
677
  end
705
678
 
706
679
  it 'should implement the odd? predicate' do
@@ -710,10 +683,7 @@ SKEEM
710
683
  ['(odd? 2.0)', false],
711
684
  ['(odd? -120762398465)', true]
712
685
  ]
713
- checks.each do |(skeem_expr, expectation)|
714
- result = subject.run(skeem_expr)
715
- expect(result).to eq(expectation)
716
- end
686
+ compare_to_predicted(checks)
717
687
  end
718
688
 
719
689
  it 'should implement the abs function' do
@@ -725,10 +695,7 @@ SKEEM
725
695
  ['(abs 3)', 3],
726
696
  ['(abs -7)', 7]
727
697
  ]
728
- checks.each do |(skeem_expr, expectation)|
729
- result = subject.run(skeem_expr)
730
- expect(result).to eq(expectation)
731
- end
698
+ compare_to_predicted(checks)
732
699
  end
733
700
 
734
701
  it 'should implement the square function' do
@@ -737,10 +704,7 @@ SKEEM
737
704
  ['(square 2.0)', 4.0],
738
705
  ['(square -7)', 49]
739
706
  ]
740
- checks.each do |(skeem_expr, expectation)|
741
- result = subject.run(skeem_expr)
742
- expect(result).to eq(expectation)
743
- end
707
+ compare_to_predicted(checks)
744
708
  end
745
709
 
746
710
  it 'should implement the not procedure' do
@@ -753,10 +717,7 @@ SKEEM
753
717
  ['(not (list))', false],
754
718
  ["(not 'nil)", false]
755
719
  ]
756
- checks.each do |(skeem_expr, expectation)|
757
- result = subject.run(skeem_expr)
758
- expect(result).to eq(expectation)
759
- end
720
+ compare_to_predicted(checks)
760
721
  end
761
722
 
762
723
  it 'should implement the list procedure' do
@@ -766,8 +727,7 @@ SKEEM
766
727
  ['(list 1 2 3 4)', [1, 2, 3, 4]],
767
728
  ["(list 'a (+ 3 4) 'c)", [identifier('a'), 7, identifier('c')]]
768
729
  ]
769
- checks.each do |(skeem_expr, expectation)|
770
- result = subject.run(skeem_expr)
730
+ compare_to_predicted(checks) do |result, expectation|
771
731
  expect(result.to_a).to eq(expectation)
772
732
  end
773
733
  end
@@ -777,10 +737,7 @@ SKEEM
777
737
  ["(caar '((a)))", 'a'],
778
738
  ["(caar '((1 2) 3 4))", 1]
779
739
  ]
780
- checks.each do |(skeem_expr, expectation)|
781
- result = subject.run(skeem_expr)
782
- expect(result).to eq(expectation)
783
- end
740
+ compare_to_predicted(checks)
784
741
  end
785
742
 
786
743
  it 'should implement the cadr procedure' do
@@ -788,18 +745,14 @@ SKEEM
788
745
  ["(cadr '(a b c))", 'b'],
789
746
  ["(cadr '((1 2) 3 4))", 3]
790
747
  ]
791
- checks.each do |(skeem_expr, expectation)|
792
- result = subject.run(skeem_expr)
793
- expect(result).to eq(expectation)
794
- end
748
+ compare_to_predicted(checks)
795
749
  end
796
750
 
797
751
  it 'should implement the cdar procedure' do
798
752
  checks = [
799
753
  ["(cdar '((7 6 5 4 3 2 1) 8 9))", [6, 5, 4, 3, 2, 1]]
800
754
  ]
801
- checks.each do |(skeem_expr, expectation)|
802
- result = subject.run(skeem_expr)
755
+ compare_to_predicted(checks) do |result, expectation|
803
756
  expect(result.to_a).to eq(expectation)
804
757
  end
805
758
  end
@@ -808,8 +761,7 @@ SKEEM
808
761
  checks = [
809
762
  ["(cddr '(2 1))", []]
810
763
  ]
811
- checks.each do |(skeem_expr, expectation)|
812
- result = subject.run(skeem_expr)
764
+ compare_to_predicted(checks) do |result, expectation|
813
765
  expect(result.to_a).to eq(expectation)
814
766
  end
815
767
  end
@@ -820,10 +772,7 @@ SKEEM
820
772
  ["(symbol=? 'a (string->symbol \"a\"))", true],
821
773
  ["(symbol=? 'a 'b)", false]
822
774
  ]
823
- checks.each do |(skeem_expr, expectation)|
824
- result = subject.run(skeem_expr)
825
- expect(result).to eq(expectation)
826
- end
775
+ compare_to_predicted(checks)
827
776
  end
828
777
 
829
778
  it 'should implement the floor-quotient procedure' do
@@ -833,12 +782,9 @@ SKEEM
833
782
  ['(floor-quotient 5 -2)', -3],
834
783
  ['(floor-quotient -5 -2)', 2]
835
784
  ]
836
- checks.each do |(skeem_expr, expectation)|
837
- result = subject.run(skeem_expr)
838
- expect(result).to eq(expectation)
839
- end
785
+ compare_to_predicted(checks)
840
786
  end
841
-
787
+
842
788
  it 'should implement the floor-remainder (modulo) procedure' do
843
789
  checks = [
844
790
  ['(floor-remainder 16 4)', 0],
@@ -850,14 +796,11 @@ SKEEM
850
796
  ['(modulo 5 2)', 1],
851
797
  ['(modulo -45.0 7)', 4.0],
852
798
  ['(modulo 10.0 -3.0)', -2.0],
853
- ['(modulo -17 -9)', -8]
799
+ ['(modulo -17 -9)', -8]
854
800
  ]
855
- checks.each do |(skeem_expr, expectation)|
856
- result = subject.run(skeem_expr)
857
- expect(result).to eq(expectation)
858
- end
801
+ compare_to_predicted(checks)
859
802
  end
860
-
803
+
861
804
  it 'should implement the truncate-quotient procedure' do
862
805
  checks = [
863
806
  ['(truncate-quotient 5 2)', 2],
@@ -867,12 +810,9 @@ SKEEM
867
810
  ['(quotient 5 2)', 2],
868
811
  ['(quotient -5 2)', -2],
869
812
  ['(quotient 5 -2)', -2],
870
- ['(quotient -5 -2)', 2]
813
+ ['(quotient -5 -2)', 2]
871
814
  ]
872
- checks.each do |(skeem_expr, expectation)|
873
- result = subject.run(skeem_expr)
874
- expect(result).to eq(expectation)
875
- end
815
+ compare_to_predicted(checks)
876
816
  end
877
817
 
878
818
  it 'should implement the truncate-remainder procedure' do
@@ -884,23 +824,17 @@ SKEEM
884
824
  ['(remainder 5 2)', 1],
885
825
  ['(remainder -5 2)', -1],
886
826
  ['(remainder 5 -2)', 1],
887
- ['(remainder -5 -2)', -1]
827
+ ['(remainder -5 -2)', -1]
888
828
  ]
889
- checks.each do |(skeem_expr, expectation)|
890
- result = subject.run(skeem_expr)
891
- expect(result).to eq(expectation)
892
- end
829
+ compare_to_predicted(checks)
893
830
  end
894
-
831
+
895
832
  it 'should implement the test-equal procedure' do
896
833
  checks = [
897
834
  ["(test-equal (cons 1 2) (cons 1 2))", true]
898
835
  ]
899
- checks.each do |(skeem_expr, expectation)|
900
- result = subject.run(skeem_expr)
901
- expect(result).to eq(expectation)
902
- end
903
- end
836
+ compare_to_predicted(checks)
837
+ end
904
838
  end # context
905
839
 
906
840
  context 'Second-order functions' do