skeem 0.2.05 → 0.2.06
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 +19 -0
- data/README.md +32 -2
- data/lib/skeem/grammar.rb +13 -3
- data/lib/skeem/primitive/primitive_builder.rb +5 -1
- data/lib/skeem/s_expr_builder.rb +56 -17
- data/lib/skeem/s_expr_nodes.rb +56 -2
- data/lib/skeem/tokenizer.rb +4 -1
- data/lib/skeem/version.rb +1 -1
- data/spec/skeem/interpreter_spec.rb +62 -1
- data/spec/skeem/primitive/primitive_builder_spec.rb +10 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f14377aa793138a9eb14281b8f72ea29a8008da684b5d462c0060f635b2b5a9b
|
4
|
+
data.tar.gz: 2e37d741b3a156c4dabf20138cc604db4e9fb59dd78e2a8b518ad59566c2ecb5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 45a19a92c4c3e9b7033edebb197af870b20cd139db4246d14c6e9d9520105f6057435a60bdef2ad39466fa86b5179404cd19b79a604f70ea7d30abfc6ea80803
|
7
|
+
data.tar.gz: 5ecb615aef9290a912919272c6f47f372b2b9b990a3867f66205fcc2cf21005c2b0d7cfc38479dad9137c142969d36b7b856ded9cd297a426a0c6ba1f8ea0e64
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
## [0.2.06] - 2019-05-30
|
2
|
+
- NEW Special `cond` (= condional) form implemented. Supports `else` alternative and arrow (=>) syntax.
|
3
|
+
- FIX Corner case in procedure `append`.
|
4
|
+
|
5
|
+
### Added
|
6
|
+
- Class `SkmConditional`. Internal representation of `cond`forms.
|
7
|
+
|
8
|
+
### Changed
|
9
|
+
- Class `Skeem::Tokenizer`. Added keywords `cond`, `else` and `=>` separator.
|
10
|
+
- Method `Tokenizer#_next_token` updated to accept new keywords and arrows `=>`
|
11
|
+
- File `grammar.rb`: Added new terminals and new production rules for parsing the `cond` form
|
12
|
+
- File `s_expr_builder.rb`: Added new methods for building parse tree of `cond` forms
|
13
|
+
- File `interpreter_spec.rb`: Added tests for `cond`form.
|
14
|
+
- File `README.md` Updated for `cond` form. Added fifth example illustrating the `cond` form.
|
15
|
+
|
16
|
+
### Fixed
|
17
|
+
- Method `Primitive#create_append`: test case (append '() 'a)) failed to return a (as identifier)
|
18
|
+
|
19
|
+
|
1
20
|
## [0.2.05] - 2019-05-26
|
2
21
|
- Passing more standard Scheme tests, `append` procedure implemented.
|
3
22
|
|
data/README.md
CHANGED
@@ -80,7 +80,7 @@ Here are a few pointers for the Scheme programming language:
|
|
80
80
|
|
81
81
|
scheme_code =<<-SKEEM
|
82
82
|
; Let's implement the 'min' function
|
83
|
-
(define min (lambda(x y) (if (< x y) x y)))
|
83
|
+
(define min (lambda (x y) (if (< x y) x y)))
|
84
84
|
|
85
85
|
; What is the minimum of 2 and 3?
|
86
86
|
(min 2 3)
|
@@ -142,6 +142,30 @@ Here are a few pointers for the Scheme programming language:
|
|
142
142
|
puts result.last.value # => 3
|
143
143
|
```
|
144
144
|
|
145
|
+
### Example 5 (Conditional branching)
|
146
|
+
|
147
|
+
```ruby
|
148
|
+
require 'skeem'
|
149
|
+
|
150
|
+
schemer = Skeem::Interpreter.new
|
151
|
+
|
152
|
+
scheme_code =<<-SKEEM
|
153
|
+
; Let's implement the 'signum' function
|
154
|
+
(define signum (lambda (x)
|
155
|
+
(cond
|
156
|
+
((positive? x) 1)
|
157
|
+
((zero? x) 0)
|
158
|
+
(else -1))))
|
159
|
+
|
160
|
+
(signum -3)
|
161
|
+
SKEEM
|
162
|
+
|
163
|
+
# Ask Ruby to execute Scheme code
|
164
|
+
result = schemer.run(scheme_code)
|
165
|
+
puts result.value # => -1
|
166
|
+
```
|
167
|
+
|
168
|
+
|
145
169
|
## Currently implemented R7RS features
|
146
170
|
### Data type literals
|
147
171
|
- Booleans: `#t`, `#true`, `#f`, `#false`
|
@@ -160,7 +184,7 @@ Here are a few pointers for the Scheme programming language:
|
|
160
184
|
- Variable references
|
161
185
|
- Procedure calls
|
162
186
|
- Lambda expressions
|
163
|
-
-
|
187
|
+
- Conditionals (if, cond)
|
164
188
|
- Definitions
|
165
189
|
- Assignments
|
166
190
|
|
@@ -195,6 +219,12 @@ __Syntax:__
|
|
195
219
|
* (set! <identifier\> <expression\>)
|
196
220
|
|
197
221
|
### Derived expressions
|
222
|
+
#### cond
|
223
|
+
__Purpose:__ Define one or more branchings.
|
224
|
+
__Syntax:__
|
225
|
+
* (cond (<test\> <consequent\>)\+)
|
226
|
+
* (cond (<test\><consequent\>)* (else <alternate\>))
|
227
|
+
|
198
228
|
#### let
|
199
229
|
__Purpose:__ Define one or more variable local to the block.
|
200
230
|
__Syntax:__
|
data/lib/skeem/grammar.rb
CHANGED
@@ -11,7 +11,7 @@ module Skeem
|
|
11
11
|
# Delimiters, separators...
|
12
12
|
add_terminals('APOSTROPHE', 'COMMA', 'COMMA_AT_SIGN')
|
13
13
|
add_terminals('GRAVE_ACCENT', 'LPAREN', 'RPAREN')
|
14
|
-
add_terminals('PERIOD')
|
14
|
+
add_terminals('PERIOD', 'ARROW')
|
15
15
|
add_terminals('VECTOR_BEGIN')
|
16
16
|
|
17
17
|
# Literal values...
|
@@ -19,8 +19,8 @@ module Skeem
|
|
19
19
|
add_terminals('STRING_LIT', 'IDENTIFIER')
|
20
20
|
|
21
21
|
# Keywords...
|
22
|
-
add_terminals('BEGIN', '
|
23
|
-
add_terminals('LET', 'LET*')
|
22
|
+
add_terminals('BEGIN', 'COND', 'DEFINE', 'ELSE')
|
23
|
+
add_terminals('IF', 'LAMBDA', 'LET', 'LET*')
|
24
24
|
add_terminals('QUOTE', 'QUASIQUOTE', 'SET!')
|
25
25
|
add_terminals('UNQUOTE', 'UNQUOTE-SPLICING')
|
26
26
|
|
@@ -95,6 +95,8 @@ module Skeem
|
|
95
95
|
rule 'number' => 'INTEGER'
|
96
96
|
rule 'number' => 'REAL'
|
97
97
|
rule('assignment' => 'LPAREN SET! IDENTIFIER expression RPAREN').as 'assignment'
|
98
|
+
rule('derived_expression' => 'LPAREN COND cond_clause_plus RPAREN').as 'cond_form'
|
99
|
+
rule('derived_expression' => 'LPAREN COND cond_clause_star LPAREN ELSE sequence RPAREN RPAREN').as 'cond_else_form'
|
98
100
|
rule('derived_expression' => 'LPAREN LET LPAREN binding_spec_star RPAREN body RPAREN').as 'short_let_form'
|
99
101
|
rule('derived_expression' => 'LPAREN LET* LPAREN binding_spec_star RPAREN body RPAREN').as 'let_star_form'
|
100
102
|
|
@@ -102,6 +104,14 @@ module Skeem
|
|
102
104
|
# the next rule was made more general than its standard counterpart
|
103
105
|
rule('derived_expression' => 'LPAREN BEGIN body RPAREN').as 'begin_expression'
|
104
106
|
rule 'derived_expression' => 'quasiquotation'
|
107
|
+
rule('cond_clause_plus' => 'cond_clause_plus cond_clause').as 'multiple_cond_clauses'
|
108
|
+
rule('cond_clause_plus' => 'cond_clause').as 'last_cond_clauses'
|
109
|
+
rule('cond_clause_star' => 'cond_clause_star cond_clause').as 'cond_clauses_star'
|
110
|
+
rule('cond_clause_star' => []).as 'last_cond_clauses_star'
|
111
|
+
rule('cond_clause' => 'LPAREN test sequence RPAREN').as 'cond_clause'
|
112
|
+
rule('cond_clause' => 'LPAREN test RPAREN')
|
113
|
+
rule('cond_clause' => 'LPAREN test ARROW recipient RPAREN').as 'cond_arrow_clause'
|
114
|
+
rule('recipient' => 'expression')
|
105
115
|
rule('quasiquotation' => 'LPAREN QUASIQUOTE qq_template RPAREN').as 'quasiquotation'
|
106
116
|
rule('quasiquotation' => 'GRAVE_ACCENT qq_template').as 'quasiquotation_short'
|
107
117
|
rule('binding_spec_star' => 'binding_spec_star binding_spec').as 'multiple_binding_specs'
|
data/lib/skeem/s_expr_builder.rb
CHANGED
@@ -56,13 +56,13 @@ module Skeem
|
|
56
56
|
|
57
57
|
# rule('cmd_or_def_plus' => 'cmd_or_def').as 'last_cmd_def'
|
58
58
|
def reduce_last_cmd_def(_production, _range, _tokens, theChildren)
|
59
|
-
SkmPair.
|
59
|
+
SkmPair.new(theChildren.last, SkmEmptyList.instance)
|
60
60
|
end
|
61
|
-
|
61
|
+
|
62
62
|
# rule('cmd_or_def' => 'LPAREN BEGIN cmd_or_def_plus RPAREN').as 'begin_cmd'
|
63
63
|
def reduce_begin_cmd(_production, _range, _tokens, theChildren)
|
64
|
-
SkmSequencingBlock.new(theChildren[2])
|
65
|
-
end
|
64
|
+
SkmSequencingBlock.new(theChildren[2])
|
65
|
+
end
|
66
66
|
|
67
67
|
# rule('definition' => 'LPAREN DEFINE IDENTIFIER expression RPAREN')
|
68
68
|
# .as 'definition'
|
@@ -77,10 +77,10 @@ module Skeem
|
|
77
77
|
# $stderr.puts lmbd.inspect
|
78
78
|
SkmBinding.new(theChildren[3], lmbd)
|
79
79
|
end
|
80
|
-
|
80
|
+
|
81
81
|
# rule('definition' => 'LPAREN BEGIN definition_star RPAREN').as 'definitions_within_begin'
|
82
82
|
def reduce_definitions_within_begin(_production, aRange, _tokens, theChildren)
|
83
|
-
SkmSequencingBlock.new(SkmPair.create_from_a(theChildren[2]))
|
83
|
+
SkmSequencingBlock.new(SkmPair.create_from_a(theChildren[2]))
|
84
84
|
end
|
85
85
|
|
86
86
|
# rule('expression' => 'IDENTIFIER').as 'variable_reference'
|
@@ -236,22 +236,21 @@ module Skeem
|
|
236
236
|
definitions = theChildren[0].nil? ? [] : theChildren[0]
|
237
237
|
{ defs: definitions, sequence: theChildren[1] }
|
238
238
|
end
|
239
|
-
|
239
|
+
|
240
240
|
# rule('definition_star' => 'definition_star definition').as 'definition_star'
|
241
241
|
def reduce_definition_star(_production, _range, _tokens, theChildren)
|
242
242
|
theChildren[0] << theChildren[1]
|
243
243
|
end
|
244
|
-
|
245
|
-
|
246
|
-
# rule('definition_star' => []).as 'no_definition_yet'
|
244
|
+
|
245
|
+
|
246
|
+
# rule('definition_star' => []).as 'no_definition_yet'
|
247
247
|
def reduce_no_definition_yet(_production, _range, _tokens, theChildren)
|
248
248
|
[]
|
249
|
-
end
|
249
|
+
end
|
250
250
|
|
251
251
|
# rule('sequence' => 'command_star expression').as 'sequence'
|
252
252
|
def reduce_sequence(_production, _range, _tokens, theChildren)
|
253
253
|
SkmPair.create_from_a(theChildren[0] << theChildren[1])
|
254
|
-
|
255
254
|
end
|
256
255
|
|
257
256
|
# rule('command_star' => 'command_star command').as 'multiple_commands'
|
@@ -274,20 +273,60 @@ module Skeem
|
|
274
273
|
SkmUpdateBinding.new(theChildren[2], theChildren[3])
|
275
274
|
end
|
276
275
|
|
276
|
+
# rule('derived_expression' => 'LPAREN COND cond_clause_plus RPAREN').as 'cond_form'
|
277
|
+
def reduce_cond_form(_production, aRange, _tokens, theChildren)
|
278
|
+
SkmConditional.new(aRange.low, theChildren[2], nil)
|
279
|
+
end
|
280
|
+
|
281
|
+
# rule('derived_expression' => 'LPAREN COND cond_clause_star LPAREN ELSE sequence RPAREN RPAREN').as 'cond_else_form'
|
282
|
+
def reduce_cond_else_form(_production, aRange, _tokens, theChildren)
|
283
|
+
SkmConditional.new(aRange.low, theChildren[2], SkmSequencingBlock.new(theChildren[5]))
|
284
|
+
end
|
285
|
+
|
277
286
|
# rule('derived_expression' => 'LPAREN LET LPAREN binding_spec_star RPAREN body RPAREN').as 'short_let_form'
|
278
287
|
def reduce_short_let_form(_production, aRange, _tokens, theChildren)
|
279
288
|
SkmBindingBlock.new(:let, theChildren[3], theChildren[5])
|
280
289
|
end
|
281
|
-
|
290
|
+
|
282
291
|
# rule('derived_expression' => 'LPAREN LET* LPAREN binding_spec_star RPAREN body RPAREN').as 'let_star_form'
|
283
|
-
def reduce_let_star_form(_production,
|
292
|
+
def reduce_let_star_form(_production, _range, _tokens, theChildren)
|
284
293
|
SkmBindingBlock.new(:let_star, theChildren[3], theChildren[5])
|
285
294
|
end
|
286
295
|
|
287
296
|
# rule('derived_expression' => 'LPAREN BEGIN body RPAREN').as 'begin_expression'
|
288
|
-
def reduce_begin_expression(_production,
|
289
|
-
SkmSequencingBlock.new(theChildren[2])
|
290
|
-
end
|
297
|
+
def reduce_begin_expression(_production, _range, _tokens, theChildren)
|
298
|
+
SkmSequencingBlock.new(theChildren[2])
|
299
|
+
end
|
300
|
+
|
301
|
+
# rule('cond_clause_plus' => 'cond_clause_plus cond_clause').as 'multiple_cond_clauses'
|
302
|
+
def reduce_multiple_cond_clauses(_production, _range, _tokens, theChildren)
|
303
|
+
theChildren[0] << theChildren[1]
|
304
|
+
end
|
305
|
+
|
306
|
+
# rule('cond_clause_plus' => 'cond_clause').as 'last_cond_clauses'
|
307
|
+
def reduce_last_cond_clauses(_production, _range, _tokens, theChildren)
|
308
|
+
[theChildren[0]]
|
309
|
+
end
|
310
|
+
|
311
|
+
# rule('cond_clause_star' => 'cond_clause_star cond_clause').as 'cond_clauses_star'
|
312
|
+
def reduce_cond_clauses_star(_production, _range, _tokens, theChildren)
|
313
|
+
theChildren[0] << theChildren[1]
|
314
|
+
end
|
315
|
+
|
316
|
+
# rule('cond_clause_star' => []).as 'last_cond_clauses_star'
|
317
|
+
def reduce_last_cond_clauses_star(_production, _range, _tokens, _children)
|
318
|
+
[]
|
319
|
+
end
|
320
|
+
|
321
|
+
# rule('cond_clause' => 'LPAREN test sequence RPAREN').as 'cond_clause'
|
322
|
+
def reduce_cond_clause(_production, _range, _tokens, theChildren)
|
323
|
+
[theChildren[1], SkmSequencingBlock.new(SkmPair.create_from_a(theChildren[2]))]
|
324
|
+
end
|
325
|
+
|
326
|
+
# rule('cond_clause' => 'LPAREN test ARROW recipient RPAREN').as 'cond_arrow_clause'
|
327
|
+
def reduce_cond_arrow_clause(_production, _range, _tokens, theChildren)
|
328
|
+
[theChildren[1], theChildren[3]]
|
329
|
+
end
|
291
330
|
|
292
331
|
# rule('quasiquotation' => 'LPAREN QUASIQUOTE qq_template RPAREN').as 'quasiquotation'
|
293
332
|
def reduce_quasiquotation(_production, aRange, _tokens, theChildren)
|
data/lib/skeem/s_expr_nodes.rb
CHANGED
@@ -233,6 +233,60 @@ module Skeem
|
|
233
233
|
end
|
234
234
|
end # class
|
235
235
|
|
236
|
+
|
237
|
+
class SkmConditional < SkmMultiExpression
|
238
|
+
# An array of couples [test, sequence]
|
239
|
+
attr_reader :clauses
|
240
|
+
attr_reader :alternate
|
241
|
+
|
242
|
+
def initialize(aPosition, theClauses, anAlternate)
|
243
|
+
super(aPosition)
|
244
|
+
@clauses = theClauses
|
245
|
+
@alternate = anAlternate
|
246
|
+
end
|
247
|
+
|
248
|
+
def evaluate(aRuntime)
|
249
|
+
clause_matching = false
|
250
|
+
result = nil
|
251
|
+
|
252
|
+
clauses.each do |(test, consequent)|
|
253
|
+
test_result = test.evaluate(aRuntime)
|
254
|
+
next if test_result.boolean? && test_result.value == false
|
255
|
+
|
256
|
+
clause_matching = true
|
257
|
+
result = consequent.evaluate(aRuntime)
|
258
|
+
break
|
259
|
+
end
|
260
|
+
|
261
|
+
unless clause_matching
|
262
|
+
result = alternate ? alternate.evaluate(aRuntime) : SkmUndefined.instance
|
263
|
+
end
|
264
|
+
|
265
|
+
result
|
266
|
+
end
|
267
|
+
|
268
|
+
def quasiquote(aRuntime)
|
269
|
+
quasi_clauses = clauses.map do |(test, consequent)|
|
270
|
+
test_qq = test.quasiquote(aRuntime)
|
271
|
+
consequent_qq = consequent.quasiquote(aRuntime)
|
272
|
+
[test_qq, consequent_qq]
|
273
|
+
end
|
274
|
+
quasi_alternate = alternate ? alternate.quasiquote(aRuntime) : nil
|
275
|
+
|
276
|
+
self.class.new(position, quasi_clauses, quasi_alternate)
|
277
|
+
end
|
278
|
+
|
279
|
+
def inspect
|
280
|
+
result = inspect_prefix + '@test ' + test.inspect + ', '
|
281
|
+
result << "@clauses \n"
|
282
|
+
clauses.each do |(test, consequent)|
|
283
|
+
result << ' ' << test.inspect << ' ' << consequent.inspect << "\n"
|
284
|
+
end
|
285
|
+
result << '@alternate ' + alternate.inspect + inspect_suffix
|
286
|
+
result
|
287
|
+
end
|
288
|
+
end # class
|
289
|
+
|
236
290
|
SkmArity = Struct.new(:low, :high) do
|
237
291
|
def nullary?
|
238
292
|
low.zero? && high == 0
|
@@ -466,8 +520,8 @@ require_relative 'skm_procedure_exec'
|
|
466
520
|
extend Forwardable
|
467
521
|
|
468
522
|
attr_reader :representation
|
469
|
-
attr_reader :environment
|
470
|
-
|
523
|
+
attr_reader :environment
|
524
|
+
|
471
525
|
def_delegators(:@representation, :formals, :definitions, :sequence)
|
472
526
|
|
473
527
|
def initialize(aRepresentation, aRuntime)
|
data/lib/skeem/tokenizer.rb
CHANGED
@@ -20,6 +20,7 @@ module Skeem
|
|
20
20
|
|
21
21
|
@@lexeme2name = {
|
22
22
|
"'" => 'APOSTROPHE',
|
23
|
+
'=>' => 'ARROW',
|
23
24
|
'`' => 'GRAVE_ACCENT',
|
24
25
|
'(' => 'LPAREN',
|
25
26
|
')' => 'RPAREN',
|
@@ -32,7 +33,9 @@ module Skeem
|
|
32
33
|
# Here are all the implemented Scheme keywords (in uppercase)
|
33
34
|
@@keywords = %w[
|
34
35
|
BEGIN
|
36
|
+
COND
|
35
37
|
DEFINE
|
38
|
+
ELSE
|
36
39
|
IF
|
37
40
|
LAMBDA
|
38
41
|
LET
|
@@ -86,7 +89,7 @@ module Skeem
|
|
86
89
|
token = build_token(@@lexeme2name[curr_ch], scanner.getch)
|
87
90
|
elsif (lexeme = scanner.scan(/(?:\.)(?=\s)/)) # Single char occurring alone
|
88
91
|
token = build_token('PERIOD', lexeme)
|
89
|
-
elsif (lexeme = scanner.scan(
|
92
|
+
elsif (lexeme = scanner.scan(/(?:,@?)|(?:=>)/))
|
90
93
|
token = build_token(@@lexeme2name[lexeme], lexeme)
|
91
94
|
elsif (lexeme = scanner.scan(/#(?:(?:true)|(?:false)|(?:u8)|[\\\(tfeiodx]|(?:\d+[=#]))/))
|
92
95
|
token = cardinal_token(lexeme)
|
data/lib/skeem/version.rb
CHANGED
@@ -156,6 +156,66 @@ SKEEM
|
|
156
156
|
result = subject.run(source)
|
157
157
|
expect(result).to eq(1)
|
158
158
|
end
|
159
|
+
|
160
|
+
it 'should implement the cond form' do
|
161
|
+
source = <<-SKEEM
|
162
|
+
(define signum (lambda (x)
|
163
|
+
(cond
|
164
|
+
((> x 0) 1)
|
165
|
+
((= x 0) 0)
|
166
|
+
((< x 0) -1)
|
167
|
+
)))
|
168
|
+
SKEEM
|
169
|
+
result = subject.run(source)
|
170
|
+
result = subject.run('(signum 3)')
|
171
|
+
expect(result).to eq(1)
|
172
|
+
|
173
|
+
result = subject.run('(signum 0)')
|
174
|
+
expect(result).to eq(0)
|
175
|
+
|
176
|
+
result = subject.run('(signum -3)')
|
177
|
+
expect(result).to eq(-1)
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'should implement the cond form with arrows' do
|
181
|
+
source = <<-SKEEM
|
182
|
+
(define signum (lambda (x)
|
183
|
+
(cond
|
184
|
+
((> x 0) => 1)
|
185
|
+
((= x 0) => 0)
|
186
|
+
((< x 0) => -1)
|
187
|
+
)))
|
188
|
+
SKEEM
|
189
|
+
result = subject.run(source)
|
190
|
+
result = subject.run('(signum 3)')
|
191
|
+
expect(result).to eq(1)
|
192
|
+
|
193
|
+
result = subject.run('(signum 0)')
|
194
|
+
expect(result).to eq(0)
|
195
|
+
|
196
|
+
result = subject.run('(signum -3)')
|
197
|
+
expect(result).to eq(-1)
|
198
|
+
end
|
199
|
+
|
200
|
+
it 'should implement the cond ... else form' do
|
201
|
+
source = <<-SKEEM
|
202
|
+
(define signum (lambda (x)
|
203
|
+
(cond
|
204
|
+
((> x 0) 1)
|
205
|
+
((= x 0) 0)
|
206
|
+
(else -1)
|
207
|
+
)))
|
208
|
+
SKEEM
|
209
|
+
result = subject.run(source)
|
210
|
+
result = subject.run('(signum 3)')
|
211
|
+
expect(result).to eq(1)
|
212
|
+
|
213
|
+
result = subject.run('(signum 0)')
|
214
|
+
expect(result).to eq(0)
|
215
|
+
|
216
|
+
result = subject.run('(signum -3)')
|
217
|
+
expect(result).to eq(-1)
|
218
|
+
end
|
159
219
|
|
160
220
|
it 'should implement the quotation of constant literals' do
|
161
221
|
checks = [
|
@@ -718,7 +778,8 @@ SKEEM
|
|
718
778
|
checks = [
|
719
779
|
['(list)', []],
|
720
780
|
['(list 1)', [1]],
|
721
|
-
['(list 1 2 3 4)', [1, 2, 3, 4]]
|
781
|
+
['(list 1 2 3 4)', [1, 2, 3, 4]],
|
782
|
+
["(list 'a (+ 3 4) 'c)", [identifier('a'), 7, identifier('c')]]
|
722
783
|
]
|
723
784
|
checks.each do |(skeem_expr, expectation)|
|
724
785
|
result = subject.run(skeem_expr)
|
@@ -558,8 +558,10 @@ SKEEM
|
|
558
558
|
["(length '())", 0],
|
559
559
|
["(length '(1))", 1],
|
560
560
|
["(length '(1 2))", 2],
|
561
|
-
["(length '(1 2 3))", 3]
|
561
|
+
["(length '(1 2 3))", 3],
|
562
|
+
["(length '(a (b) (c d e)))", 3]
|
562
563
|
]
|
564
|
+
|
563
565
|
checks.each do |(skeem_expr, expectation)|
|
564
566
|
result = subject.run(skeem_expr)
|
565
567
|
expect(result).to eq(expectation)
|
@@ -580,11 +582,16 @@ SKEEM
|
|
580
582
|
["(append '(a b) '(c) 'd)", array2list_ids(['a', 'b', 'c', 'd'])],
|
581
583
|
["(append '(a (b)) '((c)))", [SkmIdentifier.create('a'),
|
582
584
|
SkmPair.create_from_a(array2list_ids(['b'])),
|
583
|
-
SkmPair.create_from_a(array2list_ids(['c']))]]
|
585
|
+
SkmPair.create_from_a(array2list_ids(['c']))]],
|
586
|
+
[ "(append '() 'a)", SkmIdentifier.create('a')]
|
584
587
|
]
|
585
588
|
checks.each do |(skeem_expr, expectation)|
|
586
589
|
result = subject.run(skeem_expr)
|
587
|
-
|
590
|
+
if result.kind_of?(SkmPair)
|
591
|
+
expect(result.to_a).to eq(expectation)
|
592
|
+
else
|
593
|
+
expect(result).to eq(expectation)
|
594
|
+
end
|
588
595
|
end
|
589
596
|
end
|
590
597
|
|
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.2.
|
4
|
+
version: 0.2.06
|
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-05-
|
11
|
+
date: 2019-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rley
|