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