skeem 0.1.01 → 0.1.02

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
  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