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 +4 -4
- data/CHANGELOG.md +14 -0
- data/README.md +4 -4
- data/appveyor.yml +17 -14
- data/lib/skeem/datum_dsl.rb +2 -0
- data/lib/skeem/primitive/primitive_builder.rb +50 -5
- data/lib/skeem/primitive/primitive_procedure.rb +14 -3
- data/lib/skeem/s_expr_nodes.rb +11 -1
- data/lib/skeem/skm_compound_datum.rb +5 -4
- data/lib/skeem/skm_element.rb +9 -0
- data/lib/skeem/skm_empty_list.rb +5 -0
- data/lib/skeem/skm_pair.rb +24 -0
- data/lib/skeem/skm_simple_datum.rb +1 -0
- data/lib/skeem/version.rb +1 -1
- data/skeem.gemspec +4 -0
- data/spec/skeem/primitive/primitive_builder_spec.rb +83 -16
- data/spec/skeem/skm_element_spec.rb +10 -0
- data/spec/skeem/skm_empty_list_spec.rb +5 -0
- data/spec/skeem/skm_pair_spec.rb +29 -10
- data/spec/skeem/skm_simple_datum_spec.rb +18 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d94f383bc1d7de65f89a238b842b70e2c33d82c6
|
4
|
+
data.tar.gz: a2f2c7ee6140a51f3a5ea060d4211076c7f4b61e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ca7c1d2590e6f3dec7a02345e36c8d8fe01df89aa601727e490ead32099c76e858f23a7e6caa49dd37dc144d07cc70a7a1bbe7559efdfb04437ac2e3e8fa0a81
|
7
|
+
data.tar.gz: 8cc56c1209d30ce0470f5281bad9b17cabdd8515f4126881c5bf7815f1fb94e73fc2d73ce33f84826291f0b0c8f2ac7498adfd1c7da8b879519fb0ed20b41e05
|
data/CHANGELOG.md
CHANGED
@@ -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`
|
data/appveyor.yml
CHANGED
@@ -1,27 +1,30 @@
|
|
1
1
|
version: '{build}'
|
2
|
-
max_jobs:
|
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
|
-
|
17
|
-
|
18
|
-
|
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
|
data/lib/skeem/datum_dsl.rb
CHANGED
@@ -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
|
-
|
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
|
427
|
-
primitive = ->(runtime,
|
428
|
-
|
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, '
|
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
|
|
data/lib/skeem/s_expr_nodes.rb
CHANGED
@@ -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.
|
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
|
data/lib/skeem/skm_element.rb
CHANGED
@@ -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
|
data/lib/skeem/skm_empty_list.rb
CHANGED
data/lib/skeem/skm_pair.rb
CHANGED
@@ -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?
|
data/lib/skeem/version.rb
CHANGED
data/skeem.gemspec
CHANGED
@@ -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
|
-
|
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
|
-
[
|
405
|
+
["(symbol? 'foo)", true],
|
406
|
+
["(symbol? (car '(a b)))", true],
|
366
407
|
['(symbol? "bar")', false],
|
408
|
+
["(symbol? 'nil)", true],
|
367
409
|
["(symbol? '())", false],
|
368
|
-
[
|
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
|
-
|
382
|
-
|
383
|
-
|
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
|
-
|
472
|
-
|
473
|
-
|
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
|
-
|
487
|
-
|
488
|
-
|
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)
|
data/spec/skeem/skm_pair_spec.rb
CHANGED
@@ -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.
|
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-
|
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: '
|
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: '
|
40
|
+
version: '2.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|