skeem 0.1.01 → 0.1.02

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a601349ce09d5671ffb98d698495e52828c3c691
4
- data.tar.gz: bbb0008716eed1df4c321b5f6f6d979d5e470e41
3
+ metadata.gz: d94f383bc1d7de65f89a238b842b70e2c33d82c6
4
+ data.tar.gz: a2f2c7ee6140a51f3a5ea060d4211076c7f4b61e
5
5
  SHA512:
6
- metadata.gz: 98e38e4b05f6f448437aa0dfea2eded663408b127183aac1f2b24d6ee6b28d67fad056df6786f95b1024074b0891130d2c3e3560164c261396e314db63d9a614
7
- data.tar.gz: 4f0a1f51e6484bbcd8678dea5d136904d0ba41300296219fac36d7dc977982ee84146967deac72102bd961d792e1421c5e0e5b45431aad992d50b11fd529d4c0
6
+ metadata.gz: ca7c1d2590e6f3dec7a02345e36c8d8fe01df89aa601727e490ead32099c76e858f23a7e6caa49dd37dc144d07cc70a7a1bbe7559efdfb04437ac2e3e8fa0a81
7
+ data.tar.gz: 8cc56c1209d30ce0470f5281bad9b17cabdd8515f4126881c5bf7815f1fb94e73fc2d73ce33f84826291f0b0c8f2ac7498adfd1c7da8b879519fb0ed20b41e05
@@ -1,3 +1,17 @@
1
+ ## [0.1.02] - 2019-01-13
2
+ ### Added
3
+ - File `primitive_builder.rb` implementation of: `equal?`, `make-vector`, `symbol->string` procedures.
4
+
5
+ ### Changed
6
+ - File `.travis.yml` Added newer Ruby versions and more environments in "Allowed failures" because of Bundler issue.
7
+ - File `README.md` udpated to reflect currently implemented features.
8
+ - Class `SkmUndefined` uses now the Singleton pattern.
9
+
10
+ ### Fixed
11
+ - File `skeem.gemspec` Make dependency on Bundler gem depends on the Ruby version.
12
+ - Method `SkmElement#eqv?` was missing. Method is now implemented.
13
+ - Class `PrimitiveProcedure` was unable to cope with procedures with a bounded range of arity.
14
+
1
15
  ## [0.1.01] - 2019-01-01
2
16
  - Fixes, added 'set-car!', 'set-cdr!' standard Scheme procedures.
3
17
 
data/README.md CHANGED
@@ -167,7 +167,7 @@ __Syntax:__
167
167
  This section lists the implemented standard procedures
168
168
 
169
169
  #### Equivalence predicates
170
- * `eqv?`
170
+ * `eqv?`, `equal?`
171
171
 
172
172
  #### Boolean procedures
173
173
  * `boolean?`, `and`, `or`, `not`
@@ -181,13 +181,13 @@ This section lists the implemented standard procedures
181
181
  * `list?`, `null?`, `pair?`, `car`, `cdr`, `cons`, `length`, `list`, `list->vector`, `set-car!`, `set-cdr!`
182
182
 
183
183
  #### String procedures
184
- * `string?`, `string=?`, `string-append`, `string-length`, `string->symbol`,
184
+ * `string?`, `string=?`, `string-append`, `string-length`, `string->symbol`
185
185
 
186
186
  #### Symbol procedures
187
- * `symbol?`, `symbol=?`
187
+ * `symbol?`, `symbol=?`, `symbol->string`
188
188
 
189
189
  #### Vector procedures
190
- * `vector?`, `vector`, `vector-length`, `vector-set!`, `vector->list`
190
+ * `vector?`, `make-vector`, `vector`, `vector-length`, `vector-set!`, `vector->list`
191
191
 
192
192
  #### Input/output procedures
193
193
  * `newline`
@@ -1,27 +1,30 @@
1
1
  version: '{build}'
2
- max_jobs: 3
2
+ max_jobs: 5
3
3
  environment:
4
4
  matrix:
5
- - Ruby_version: 21
6
- - Ruby_version: 21-x64
7
- - Ruby_version: 22
8
- - Ruby_version: 22-x64
9
- - Ruby_version: 23
10
- - Ruby_version: 23-x64
11
- - Ruby_version: 24
12
- - Ruby_version: 24-x64
13
- - Ruby_version: 25
14
5
  - Ruby_version: 25-x64
15
-
16
- # These are failing
17
- # - Ruby_version: 26
18
- # - Ruby_version: 26-x64
6
+ - Ruby_version: 24-x64
7
+ - Ruby_version: 23-x64
8
+ - Ruby_version: 25
9
+ - Ruby_version: 24
10
+ - Ruby_version: 23
11
+
12
+ # These are failing
13
+ # - Ruby_version: 26
14
+ # - Ruby_version: 26-x64
19
15
 
20
16
  install:
21
17
  - set PATH=C:\Ruby%Ruby_version%\bin;%PATH%
18
+ - gem update --system
19
+ - gem install bundler
22
20
  - bundle install --retry=3 --clean --force
23
21
 
24
22
  build: off
25
23
 
24
+ before_test:
25
+ - ruby -v
26
+ - gem -v
27
+ - bundle -v
28
+
26
29
  test_script:
27
30
  - bundle exec rake
@@ -53,6 +53,8 @@ module Skeem
53
53
  result = case aLiteral
54
54
  when String
55
55
  SkmString.create(aLiteral)
56
+ when SkmIdentifier
57
+ SkmString.create(aLiteral.value)
56
58
  else
57
59
  SkmString.create(aLiteral.to_s)
58
60
  end
@@ -39,6 +39,10 @@ module Skeem
39
39
  SkmArity.new(0, '*')
40
40
  end
41
41
 
42
+ def one_or_two
43
+ SkmArity.new(1, 2)
44
+ end
45
+
42
46
  def one_or_more
43
47
  SkmArity.new(1, '*')
44
48
  end
@@ -57,6 +61,7 @@ module Skeem
57
61
 
58
62
  def add_comparison(aRuntime)
59
63
  create_eqv?(aRuntime)
64
+ create_equal?(aRuntime)
60
65
  create_equal(aRuntime)
61
66
  create_lt(aRuntime)
62
67
  create_gt(aRuntime)
@@ -88,6 +93,7 @@ module Skeem
88
93
 
89
94
  def add_symbol_procedures(aRuntime)
90
95
  create_object_predicate(aRuntime, 'symbol?')
96
+ create_symbol2string(aRuntime)
91
97
  end
92
98
 
93
99
  def add_list_procedures(aRuntime)
@@ -107,6 +113,7 @@ module Skeem
107
113
  create_object_predicate(aRuntime, 'vector?')
108
114
  create_vector(aRuntime)
109
115
  create_vector_length(aRuntime)
116
+ create_make_vector(aRuntime)
110
117
  create_vector_ref(aRuntime)
111
118
  create_vector2list(aRuntime)
112
119
  end
@@ -220,12 +227,23 @@ module Skeem
220
227
  operand_1 = argument1.evaluate(runtime)
221
228
  operand_2 = argument2.evaluate(runtime)
222
229
  raw_result = operand_1.eqv?(operand_2)
223
- to_datum(raw_result)
230
+ boolean(raw_result)
224
231
  end
225
232
 
226
233
  define_primitive_proc(aRuntime, 'eqv?', binary, primitive)
227
234
  end
228
235
 
236
+ def create_equal?(aRuntime)
237
+ primitive = ->(runtime, argument1, argument2) do
238
+ operand_1 = argument1.evaluate(runtime)
239
+ operand_2 = argument2.evaluate(runtime)
240
+ raw_result = operand_1.skm_equal?(operand_2)
241
+ boolean(raw_result)
242
+ end
243
+
244
+ define_primitive_proc(aRuntime, 'equal?', binary, primitive)
245
+ end
246
+
229
247
  def create_equal(aRuntime)
230
248
  primitive = ->(runtime, first_operand, arglist) do
231
249
  first_one = first_operand.evaluate(runtime)
@@ -423,12 +441,14 @@ module Skeem
423
441
  define_primitive_proc(aRuntime, 'string->symbol', unary, primitive)
424
442
  end
425
443
 
426
- def create_cons(aRuntime)
427
- primitive = ->(runtime, obj1, obj2) do
428
- SkmPair.new(obj1.evaluate(aRuntime), obj2.evaluate(aRuntime))
444
+ def create_symbol2string(aRuntime)
445
+ primitive = ->(runtime, arg) do
446
+ arg_evaluated = arg.evaluate(runtime)
447
+ check_argtype(arg_evaluated, SkmIdentifier, 'symbol', 'symbol->string')
448
+ string(arg_evaluated)
429
449
  end
430
450
 
431
- define_primitive_proc(aRuntime, 'cons', binary, primitive)
451
+ define_primitive_proc(aRuntime, 'symbol->string', unary, primitive)
432
452
  end
433
453
 
434
454
  def create_car(aRuntime)
@@ -451,6 +471,14 @@ module Skeem
451
471
  define_primitive_proc(aRuntime, 'cdr', unary, primitive)
452
472
  end
453
473
 
474
+ def create_cons(aRuntime)
475
+ primitive = ->(runtime, obj1, obj2) do
476
+ SkmPair.new(obj1.evaluate(aRuntime), obj2.evaluate(aRuntime))
477
+ end
478
+
479
+ define_primitive_proc(aRuntime, 'cons', binary, primitive)
480
+ end
481
+
454
482
  def create_length(aRuntime)
455
483
  primitive = ->(runtime, arg) do
456
484
  arg_evaluated = arg.evaluate(runtime)
@@ -542,6 +570,23 @@ module Skeem
542
570
 
543
571
  define_primitive_proc(aRuntime, 'vector-length', unary, primitive)
544
572
  end
573
+
574
+ def create_make_vector(aRuntime)
575
+ primitive = ->(runtime, count_arg, arglist) do
576
+ count = count_arg.evaluate(runtime)
577
+ check_argtype(count, SkmInteger, 'integer', 'make_vector')
578
+ if arglist.empty?
579
+ filler = SkmUndefined.instance
580
+ else
581
+ filler = arglist.car.evaluate(runtime)
582
+ end
583
+ elements = Array.new(count.value, filler)
584
+
585
+ vector(elements)
586
+ end
587
+
588
+ define_primitive_proc(aRuntime, 'make-vector', one_or_two, primitive)
589
+ end
545
590
 
546
591
  def create_vector_ref(aRuntime)
547
592
  # argument 1: a vector, argument 2: an index(integer)
@@ -21,6 +21,10 @@ module Skeem
21
21
  aProcedureCall.operands_consumed = true
22
22
  do_call(aRuntime, actuals)
23
23
  end
24
+
25
+ def skm_equal?(other)
26
+ equal?(other)
27
+ end
24
28
 
25
29
  private
26
30
 
@@ -61,6 +65,13 @@ module Skeem
61
65
  if count_actuals < arity.low
62
66
  wrong_number_arguments(arity.low, count_actuals)
63
67
  end
68
+ elsif arity.low < arity.high # Arity range
69
+ if count_actuals < arity.low
70
+ wrong_number_arguments(arity.low, count_actuals)
71
+ end
72
+ if count_actuals > arity.high
73
+ wrong_number_arguments(arity.high, count_actuals)
74
+ end
64
75
  else # fixed non-zero arity...
65
76
  if count_actuals != arity.high
66
77
  wrong_number_arguments(arity.high, count_actuals)
@@ -71,7 +82,7 @@ module Skeem
71
82
  def do_call(aRuntime, operands)
72
83
  if arity.nullary?
73
84
  result = code.call(aRuntime)
74
- elsif arity.variadic?
85
+ elsif arity.variadic? || (arity.low < arity.high)
75
86
  if arity.low.zero?
76
87
  result = code.call(aRuntime, operands)
77
88
  else
@@ -83,8 +94,8 @@ module Skeem
83
94
  #p count_delta
84
95
  #p arguments.inspect
85
96
  result = code.send(:call, aRuntime, *arguments.flatten)
86
- end
87
- else
97
+ end
98
+ else # Fixed arity...
88
99
  result = code.send(:call, aRuntime, *operands)
89
100
  end
90
101
 
@@ -1,11 +1,14 @@
1
1
  # Classes that implement nodes of Abstract Syntax Trees (AST) representing
2
2
  # Skeem parse results.
3
+ require 'singleton'
3
4
 
4
5
  require_relative 'datum_dsl'
5
6
  require_relative 'skm_unary_expression'
6
7
 
7
8
  module Skeem
8
9
  class SkmUndefined
10
+ include Singleton
11
+
9
12
  def value
10
13
  :UNDEFINED
11
14
  end
@@ -22,6 +25,12 @@ module Skeem
22
25
  raise StandardError, other.inspect
23
26
  end
24
27
  end
28
+
29
+ private
30
+
31
+ def initialize
32
+ self.freeze
33
+ end
25
34
  end # class
26
35
 
27
36
  class SkmMultiExpression < SkmExpression
@@ -227,7 +236,7 @@ module Skeem
227
236
  condition_result = nil
228
237
  if test_result.boolean? && test_result.value == false
229
238
  # Only #f is considered as false, everything else is true
230
- condition_result = alternate ? alternate.evaluate(aRuntime) : SkmUndefined.new
239
+ condition_result = alternate ? alternate.evaluate(aRuntime) : SkmUndefined.instance
231
240
  else
232
241
  condition_result = consequent.evaluate(aRuntime)
233
242
  end
@@ -374,6 +383,7 @@ module Skeem
374
383
  end
375
384
 
376
385
  alias eqv? equal?
386
+ alias skm_equal? equal?
377
387
 
378
388
  def inspect
379
389
  result = inspect_prefix + '@formals ' + formals.inspect + ', '
@@ -28,7 +28,8 @@ module Skeem
28
28
  end
29
29
 
30
30
  alias eqv? equal?
31
-
31
+ alias skm_equal? ==
32
+
32
33
  def verbatim?
33
34
  found = members.find_index { |elem| !elem.verbatim? }
34
35
  found ? false : true
@@ -46,14 +47,14 @@ module Skeem
46
47
  quasi_members = members.map { |elem| elem.quasiquote(aRuntime) }
47
48
  self.class.new(quasi_members)
48
49
  end
49
-
50
+
50
51
  def quoted!
51
52
  members.each(&:quoted!)
52
53
  end
53
-
54
+
54
55
  def unquoted!
55
56
  members.each(&:unquoted!)
56
- end
57
+ end
57
58
 
58
59
  # Part of the 'visitee' role in Visitor design pattern.
59
60
  # @param aVisitor [SkmElementVisitor] the visitor
@@ -45,6 +45,15 @@ module Skeem
45
45
  false
46
46
  end
47
47
 
48
+ def eqv?(other)
49
+ equal?(other)
50
+ end
51
+
52
+ def skm_equal?(_other)
53
+ msg = "Missing implementation of method #{self.class.name}##{__method__}"
54
+ raise NotImplementedError, msg
55
+ end
56
+
48
57
  # @return [TrueClass, FalseClass] true if quoted element is identical to itself
49
58
  def verbatim?
50
59
  false
@@ -31,6 +31,10 @@ module Skeem
31
31
  true
32
32
  end
33
33
 
34
+ def skm_equal?(other)
35
+ equal?(other)
36
+ end
37
+
34
38
  def to_a
35
39
  []
36
40
  end
@@ -59,6 +63,7 @@ module Skeem
59
63
 
60
64
  def initialize()
61
65
  super(0)
66
+ self.freeze
62
67
  end
63
68
  end # class
64
69
  end # module
@@ -86,6 +86,30 @@ module Skeem
86
86
  self.to_a.last
87
87
  end
88
88
 
89
+ def eqv?(_other)
90
+ false
91
+ end
92
+
93
+ def skm_equal?(other)
94
+ return true if equal?(other)
95
+
96
+ equal = true
97
+ if car.nil?
98
+ equal = other.car.nil?
99
+ else
100
+ equal &&= car.skm_equal?(other.car)
101
+ end
102
+ return false unless equal
103
+
104
+ if cdr.nil?
105
+ equal &&= other.cdr.nil?
106
+ else
107
+ equal &&= cdr.skm_equal?(other.cdr)
108
+ end
109
+
110
+ equal
111
+ end
112
+
89
113
  def each(&aBlock)
90
114
  aBlock.call(car)
91
115
  cdr.each(&aBlock) if cdr && !cdr.null?
@@ -45,6 +45,7 @@ module Skeem
45
45
  end
46
46
 
47
47
  alias eqv? ==
48
+ alias skm_equal? eqv?
48
49
 
49
50
  def verbatim?
50
51
  true
@@ -1,3 +1,3 @@
1
1
  module Skeem
2
- VERSION = '0.1.01'.freeze
2
+ VERSION = '0.1.02'.freeze
3
3
  end
@@ -58,7 +58,11 @@ SUMMARY
58
58
  spec.add_dependency 'rley', '~> 0.7'
59
59
 
60
60
  # Development dependencies
61
+ if RUBY_VERSION <= '2.2'
61
62
  spec.add_development_dependency 'bundler', '~> 1.16'
63
+ else
64
+ spec.add_development_dependency 'bundler', '~> 2.0'
65
+ end
62
66
  spec.add_development_dependency 'rake', '~> 10.0'
63
67
  spec.add_development_dependency 'rspec', '~> 3.0'
64
68
  end
@@ -98,13 +98,53 @@ SKEEM
98
98
  ['(eqv? 2 2)', true],
99
99
  ['(eqv? 2 2.0)', false],
100
100
  ['(eqv? 3 2)', false],
101
+ ["(eqv? '() '())", true],
101
102
  ['(eqv? 100000000 100000000)', true],
102
103
  ['(eqv? "a" "a")', false],
103
- ['(eqv? "a" "b")', false]
104
+ ['(eqv? "a" "b")', false],
105
+ ['(eqv? (cons 1 2) (cons 1 2))', false],
106
+ ['(eqv? (lambda () 1) (lambda () 2))', false],
107
+ ['(define p (lambda (x) x)) (eqv? p p)', true],
108
+ ["(eqv? #f 'nil)", false]
104
109
  ]
105
110
  checks.each do |(skeem_expr, expectation)|
106
111
  result = subject.run(skeem_expr)
107
- expect(result).to eq(expectation)
112
+ if result.length > 1
113
+ expect(result.last).to eq(expectation)
114
+ else
115
+ expect(result).to eq(expectation)
116
+ end
117
+ end
118
+ end
119
+
120
+ it 'should implement the equal? procedure' do
121
+ checks = [
122
+ ['(equal? #f #f)', true],
123
+ ['(equal? #t #t)', true],
124
+ ['(equal? #f #t)', false],
125
+ ["(equal? 'a 'a)", true],
126
+ ["(equal? 'a 'b)", false],
127
+ ["(equal? '(a) '(a))", true],
128
+ ["(equal? '(a) '(b))", false],
129
+ ["(equal? '(a (b) c) '(a (b) c))", true],
130
+ ["(equal? (cdr '(a)) '())", true],
131
+ ['(equal? "abc" "abc")', true],
132
+ ['(equal? "abc" "acb")', false],
133
+ ['(equal? 2 2)', true],
134
+ ["(equal? '#(a) '#(b))", false],
135
+ ["(equal? '#(a) '#(a))", true],
136
+ ["(equal? (make-vector 5 'a) (make-vector 5 'a))", true],
137
+ ['(equal? car car)', true],
138
+ ['(equal? car cdr)', false],
139
+ ['(equal? (lambda (x) x) (lambda (y) y))', false],
140
+ ]
141
+ checks.each do |(skeem_expr, expectation)|
142
+ result = subject.run(skeem_expr)
143
+ if result.length > 1
144
+ expect(result.last).to eq(expectation)
145
+ else
146
+ expect(result).to eq(expectation)
147
+ end
108
148
  end
109
149
  end
110
150
 
@@ -362,10 +402,25 @@ SKEEM
362
402
  context 'Symbol procedures:' do
363
403
  it 'should implement the symbol? procedure' do
364
404
  checks = [
365
- ['(symbol? #f)', false],
405
+ ["(symbol? 'foo)", true],
406
+ ["(symbol? (car '(a b)))", true],
366
407
  ['(symbol? "bar")', false],
408
+ ["(symbol? 'nil)", true],
367
409
  ["(symbol? '())", false],
368
- ["(symbol? 'foo)", true],
410
+ ['(symbol? #f)', false]
411
+ ]
412
+ checks.each do |(skeem_expr, expectation)|
413
+ result = subject.run(skeem_expr)
414
+ expect(result).to eq(expectation)
415
+ end
416
+ end
417
+
418
+ it 'should implement the symbol->string procedure' do
419
+ checks = [
420
+ ["(equal? (symbol->string 'Hi) \"Hi\")", true],
421
+ ["(equal? (symbol->string 'flying-fish) \"flying-fish\")", true],
422
+ ["(equal? (symbol->string 'Martin) \"Martin\")", true],
423
+ ['(equal? (symbol->string (string->symbol "Malvina")) "Malvina")', true]
369
424
  ]
370
425
  checks.each do |(skeem_expr, expectation)|
371
426
  result = subject.run(skeem_expr)
@@ -378,9 +433,9 @@ SKEEM
378
433
  it 'should implement the pair? procedure' do
379
434
  checks = [
380
435
  ["(pair? '(a . b))", true],
381
- #["(pair? '(a b c))", true],
382
- #["(pair? '())", false],
383
- #["(pair? '#(a b))", false]
436
+ ["(pair? '(a b c))", true],
437
+ ["(pair? '())", false],
438
+ ["(pair? '#(a b))", false]
384
439
  ]
385
440
  checks.each do |(skeem_expr, expectation)|
386
441
  result = subject.run(skeem_expr)
@@ -468,9 +523,9 @@ SKEEM
468
523
  expect(result.length).to eq(1)
469
524
  expect(result.car).to eq('a')
470
525
 
471
- # example = "(car '(1 . 2))" # => 1 # FAILURE
472
- # result = subject.run(example)
473
- # expect(result.car).to eq(1)
526
+ example = "(car '(1 . 2))"
527
+ result = subject.run(example)
528
+ expect(result).to eq(1)
474
529
 
475
530
  example = "(car '())" # => error
476
531
  expect { subject.run(example) }.to raise_error(StandardError)
@@ -483,9 +538,9 @@ SKEEM
483
538
  expect(result.length).to eq(3)
484
539
  expect(result.to_a).to eq(['b', 'c', 'd'])
485
540
 
486
- # example = "(cdr '(1 . 2))" # => 2 # PARSER FAILURE
487
- # result = subject.run(example)
488
- # expect(result.cdr).to eq(2)
541
+ example = "(cdr '(1 . 2))"
542
+ result = subject.run(example)
543
+ expect(result).to eq(2)
489
544
 
490
545
  example = "(cdr '())" # => error
491
546
  expect { subject.run(example) }.to raise_error(StandardError)
@@ -514,7 +569,7 @@ SKEEM
514
569
  expect(result.to_a).to eq(expectation)
515
570
  end
516
571
  end
517
-
572
+
518
573
  it 'should implement the set-car! procedure' do
519
574
  source =<<-SKEEM
520
575
  (define x '(a b c))
@@ -533,7 +588,7 @@ SKEEM
533
588
  SKEEM
534
589
  result = subject.run(source)
535
590
  expect(result.last.cdr).to eq(1)
536
- end
591
+ end
537
592
  end # context
538
593
 
539
594
  context 'Vector procedures:' do
@@ -579,6 +634,18 @@ SKEEM
579
634
  end
580
635
  end
581
636
 
637
+ it 'should implement the make-vector procedure' do
638
+ checks = [
639
+ ['(vector-length (make-vector 0))', 0],
640
+ ["(vector-length (make-vector 0 'a))", 0],
641
+ ["(equal? (make-vector 5 'a) '#(a a a a a))", true],
642
+ ]
643
+ checks.each do |(skeem_expr, expectation)|
644
+ result = subject.run(skeem_expr)
645
+ expect(result).to eq(expectation)
646
+ end
647
+ end
648
+
582
649
  it 'should implement the vector-ref procedure' do
583
650
  source = "(vector-ref '#(1 1 2 3 5 8 13 21) 5)"
584
651
  result = subject.run(source)
@@ -586,7 +653,7 @@ SKEEM
586
653
  expect(result).to eq(8)
587
654
  end
588
655
 
589
- it 'should implement the vector-> procedure' do
656
+ it 'should implement the vector->list procedure' do
590
657
  checks = [
591
658
  ["(vector->list #())", []],
592
659
  ["(vector->list '#(a b c))", ['a', 'b', 'c']]
@@ -35,6 +35,11 @@ module Skeem
35
35
  let(:runtime) { double('fake-runtime') }
36
36
  let(:visitor) { double('fake-visitor') }
37
37
  let(:not_implemented) { NotImplementedError }
38
+
39
+ it 'should be equivalent to itself' do
40
+ expect(subject).to be_eqv(subject)
41
+ expect(subject).not_to be_eqv(subject.clone)
42
+ end
38
43
 
39
44
  it "should ignore the 'done!' message" do
40
45
  expect { subject.done! }.not_to raise_error
@@ -47,6 +52,11 @@ module Skeem
47
52
  it "should ignore the 'unquoted!' message" do
48
53
  expect { subject.unquoted! }.not_to raise_error
49
54
  end
55
+
56
+ it "should complain when receiving 'skm_equal?' message" do
57
+ msg = 'Missing implementation of method Skeem::SkmElement#skm_equal?'
58
+ expect { subject.skm_equal?('omg') }.to raise_error(NotImplementedError, msg)
59
+ end
50
60
 
51
61
  it "should complain when receiving 'evaluate' message" do
52
62
  expect { subject.evaluate(runtime) }.to raise_error(not_implemented)
@@ -20,6 +20,11 @@ module Skeem
20
20
 
21
21
  context 'Provided services:' do
22
22
  let(:runtime) { double('fake-runtime') }
23
+
24
+ it 'should be equivalent to itself' do
25
+ expect(subject).to be_eqv(SkmEmptyList.instance)
26
+ expect(subject).not_to be_eqv("()")
27
+ end
23
28
 
24
29
  it "should return itself when receiving 'evaluate' message" do
25
30
  expect(subject.evaluate(runtime)).to eq(subject)
@@ -45,18 +45,37 @@ module Skeem
45
45
  # Use a list of length 2
46
46
  expect(list_length_2.length).to eq(2)
47
47
  end
48
-
48
+
49
+ it 'should respond false to `eqv?` message' do
50
+ expect(subject.eqv?(subject)).to eq(false)
51
+ end
52
+
53
+ it 'should be Skeem equal to itself' do
54
+ expect(subject.skm_equal?(subject)).to eq(true)
55
+ end
56
+
57
+
58
+ it 'should be equal to other pair when their car and cdr match' do
59
+ instance = SkmPair.new(sample_car, sample_cdr)
60
+ expect(subject.skm_equal?(instance)).to eq(true)
61
+ instance.car = integer(4)
62
+ expect(subject.skm_equal?(instance)).to eq(false)
63
+ instance.car = sample_car
64
+ instance.cdr = subject
65
+ expect(subject.skm_equal?(instance)).to eq(false)
66
+ end
67
+
49
68
  it 'should clone itself after member evaluation' do
50
69
  # subject contains self-evaluating members
51
70
  expect(subject.clone_evaluate(runtime)).to eq(subject)
52
-
71
+
53
72
  # Make pair improper...
54
73
  subject.cdr = nil
55
74
  expect(subject.clone_evaluate(runtime)).to eq(subject)
56
-
75
+
57
76
  subject.cdr = integer(4)
58
77
  expect(subject.clone_evaluate(runtime)).to eq(subject)
59
-
78
+
60
79
  successor = SkmPair.new(string('Hi'), boolean(false))
61
80
  subject.cdr = successor
62
81
  expect(subject.clone_evaluate(runtime)).to eq(subject)
@@ -68,12 +87,12 @@ module Skeem
68
87
  # Use a list of length 2
69
88
  expect(list_length_2.to_a).to eq([integer(10), sample_car])
70
89
  end
71
-
90
+
72
91
  it 'should return the last element of a list' do
73
92
  expect(subject.last).to eq(sample_car)
74
93
  expect(list_length_2.last).to eq(sample_car)
75
94
  end
76
-
95
+
77
96
  it 'should append a new element to a list' do
78
97
  subject.append(integer(4))
79
98
  expect(subject.length).to eq(2)
@@ -86,8 +105,8 @@ module Skeem
86
105
  list = SkmPair.create_from_a(array0)
87
106
  expect(list).to be_list # It's a proper list...
88
107
  expect(list.length).to eq(0)
89
- expect(list.to_a).to eq(array0)
90
-
108
+ expect(list.to_a).to eq(array0)
109
+
91
110
  # List of length 1
92
111
  array1 = [boolean(false)]
93
112
  list = SkmPair.create_from_a(array1)
@@ -109,14 +128,14 @@ module Skeem
109
128
  expect(list.length).to eq(3)
110
129
  expect(list.to_a).to eq([4, 5, 6])
111
130
  end
112
-
131
+
113
132
  it 'should support the each method' do
114
133
  my_list = SkmPair.new('w', SkmPair.new('o', SkmPair.new('w', SkmEmptyList.instance)))
115
134
  text = ''
116
135
  my_list.each { |ch| text << ch.upcase }
117
136
  expect(text).to eq('WOW')
118
137
  end
119
-
138
+
120
139
  it 'should implement the verbatim predicate' do
121
140
  expect(subject).to be_verbatim
122
141
  subject.cdr = nil
@@ -56,6 +56,24 @@ module Skeem
56
56
  expect(instance).to eq(3)
57
57
  expect(instance).not_to eq('foo')
58
58
  end
59
+
60
+ it 'should be equivalent to itself' do
61
+ expect(subject).to be_eqv(subject)
62
+ end
63
+
64
+ it 'should be equivalent by value' do
65
+ same = SkmSimpleDatum.create(3)
66
+ expect(instance).to be_eqv(same)
67
+ end
68
+
69
+ it 'should be Skeem equal to itself' do
70
+ expect(subject).to be_skm_equal(subject)
71
+ end
72
+
73
+ it 'should be Skeem equal by value' do
74
+ same = SkmSimpleDatum.create(3)
75
+ expect(instance).to be_skm_equal(same)
76
+ end
59
77
 
60
78
  it 'should be self-evaluating' do
61
79
  expect(subject.evaluate(runtime)).to be_equal(subject)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: skeem
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.01
4
+ version: 0.1.02
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimitri Geshef
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-01 00:00:00.000000000 Z
11
+ date: 2019-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rley
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.16'
33
+ version: '2.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.16'
40
+ version: '2.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement