skeem 0.0.22 → 0.0.23
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 +10 -1
- data/README.md +11 -4
- data/lib/skeem/convertible.rb +4 -0
- data/lib/skeem/primitive/primitive_builder.rb +65 -4
- data/lib/skeem/version.rb +1 -1
- data/spec/skeem/primitive/primitive_builder_spec.rb +88 -28
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46a43c0a96d793c7f042976ec034e9e261fe8198
|
4
|
+
data.tar.gz: 381a4e60b09bc4ffe797dce9ed62a40b53ec1225
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e7dc6aa941a1e5fc4940b4d35df274ac08cf3064990dd033af703d3e72afc59f7abfd19249c24574162fdac5e72fb74425e54303780df215764fb800d19b4cb6
|
7
|
+
data.tar.gz: a716f8595373f25da0796eb58c07f53d47bb83db183fe0d969226ff3216993198f5c9a47cb6bea7e3e578e539eb1760c9effbf8426483b59fcd34058be5c362a
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
## [0.0.23] - 2018-10-24
|
2
|
+
### Added
|
3
|
+
- File `primitive_builder.rb` implementation of: standard `or`, `string->symbol`, `number->string`, `string-append` procedures.
|
4
|
+
|
5
|
+
### Changed
|
6
|
+
- File `README.md` udpated to reflect currently implemented features.
|
7
|
+
|
8
|
+
### Fixed
|
9
|
+
- Method `Convertible#to_skm` Now converts String argument into `SkmString` and raises an exception when unable to convert.
|
10
|
+
|
1
11
|
## [0.0.22] - 2018-10-23
|
2
12
|
### Added
|
3
13
|
- Class `SkmBuilder`added support for list datum.
|
@@ -6,7 +16,6 @@
|
|
6
16
|
### Fixed
|
7
17
|
- File `interpreter_spec.rb` Added test example of list quotation.
|
8
18
|
|
9
|
-
|
10
19
|
## [0.0.21] - 2018-10-22
|
11
20
|
### Added
|
12
21
|
- Added support for alternative `define` syntax.
|
data/README.md
CHANGED
@@ -125,6 +125,8 @@ Here are a few other ones:
|
|
125
125
|
- Vectors: `#(1 2 "three")`
|
126
126
|
|
127
127
|
### Scheme Expressions
|
128
|
+
- Constant literals
|
129
|
+
- Quotations
|
128
130
|
- Variable references
|
129
131
|
- Procedure calls
|
130
132
|
- Lambda expressions
|
@@ -145,20 +147,25 @@ __Syntax:__
|
|
145
147
|
* (if <test\> <consequent\> <alternate\>)
|
146
148
|
|
147
149
|
|
148
|
-
|
149
150
|
#### lambda
|
150
151
|
__Purpose:__ Definition of a procedure.
|
151
152
|
__Syntax:__
|
152
153
|
* (lambda <formals\> <body\>)
|
153
154
|
|
155
|
+
#### quote
|
156
|
+
__Purpose:__ Quoting an expression (leave it unevaluated).
|
157
|
+
__Syntax:__
|
158
|
+
* (quote <datum\>)
|
159
|
+
* '<datum\>
|
160
|
+
|
154
161
|
### Standard library
|
155
162
|
This section lists the implemented standard procedures
|
156
163
|
|
157
164
|
#### Boolean procedures
|
158
|
-
* `boolean?`, `not`
|
165
|
+
* `boolean?`, `and`, `or`, `not`
|
159
166
|
|
160
167
|
#### Numerical operations
|
161
|
-
* Number-level: `number?`, `real?`, `integer?`, `zero?`, `+`, `-`, `*`, `/`, `=`, `square`
|
168
|
+
* Number-level: `number?`, `real?`, `integer?`, `zero?`, `+`, `-`, `*`, `/`, `=`, `square`, `number->string`
|
162
169
|
* Real-level: `positive?`, `negative?`, `<`, `>`, `<=`, `>=`, `abs`, `floor-remainder`
|
163
170
|
* Integer-level: `even?`, `odd?`
|
164
171
|
|
@@ -166,7 +173,7 @@ This section lists the implemented standard procedures
|
|
166
173
|
* `list?`, `null?`, `list`, `length`
|
167
174
|
|
168
175
|
#### String procedures
|
169
|
-
* `string
|
176
|
+
* `string?`, `string-append`, `string->symbol`,
|
170
177
|
|
171
178
|
#### Symbol procedures
|
172
179
|
* `symbol?`
|
data/lib/skeem/convertible.rb
CHANGED
@@ -8,7 +8,7 @@ module Skeem
|
|
8
8
|
def add_primitives(aRuntime)
|
9
9
|
add_arithmetic(aRuntime)
|
10
10
|
add_comparison(aRuntime)
|
11
|
-
|
11
|
+
add_number_procedures(aRuntime)
|
12
12
|
add_boolean_procedures(aRuntime)
|
13
13
|
add_string_procedures(aRuntime)
|
14
14
|
add_symbol_procedures(aRuntime)
|
@@ -56,20 +56,24 @@ module Skeem
|
|
56
56
|
create_gte(aRuntime)
|
57
57
|
end
|
58
58
|
|
59
|
-
def
|
59
|
+
def add_number_procedures(aRuntime)
|
60
60
|
create_object_predicate(aRuntime, 'number?')
|
61
61
|
create_object_predicate(aRuntime, 'real?')
|
62
62
|
create_object_predicate(aRuntime, 'integer?')
|
63
|
+
create_number2string(aRuntime)
|
63
64
|
end
|
64
65
|
|
65
66
|
def add_boolean_procedures(aRuntime)
|
66
67
|
create_not(aRuntime)
|
67
68
|
create_and(aRuntime)
|
69
|
+
create_or(aRuntime)
|
68
70
|
create_object_predicate(aRuntime, 'boolean?')
|
69
71
|
end
|
70
72
|
|
71
73
|
def add_string_procedures(aRuntime)
|
72
74
|
create_object_predicate(aRuntime, 'string?')
|
75
|
+
create_string_append(aRuntime)
|
76
|
+
create_string2symbol(aRuntime)
|
73
77
|
end
|
74
78
|
|
75
79
|
def add_symbol_procedures(aRuntime)
|
@@ -267,6 +271,17 @@ module Skeem
|
|
267
271
|
define_primitive_proc(aRuntime, '>=', one_or_more, primitive)
|
268
272
|
end
|
269
273
|
|
274
|
+
def create_number2string(aRuntime)
|
275
|
+
# TODO: add support for radix argument
|
276
|
+
primitive = ->(runtime, arg) do
|
277
|
+
arg_evaluated = arg.evaluate(runtime)
|
278
|
+
check_argtype(arg_evaluated, SkmNumber, 'number', 'number->string')
|
279
|
+
to_skm(arg_evaluated.value.to_s)
|
280
|
+
end
|
281
|
+
|
282
|
+
define_primitive_proc(aRuntime, 'number->string', unary, primitive)
|
283
|
+
end
|
284
|
+
|
270
285
|
def create_not(aRuntime)
|
271
286
|
primitive = ->(runtime, arg) do
|
272
287
|
arg_evaluated = arg.evaluate(runtime)
|
@@ -279,7 +294,7 @@ module Skeem
|
|
279
294
|
|
280
295
|
define_primitive_proc(aRuntime, 'not', unary, primitive)
|
281
296
|
end
|
282
|
-
|
297
|
+
|
283
298
|
def create_and(aRuntime)
|
284
299
|
# arglist should be a Ruby Array
|
285
300
|
primitive = ->(runtime, arglist) do
|
@@ -298,7 +313,53 @@ module Skeem
|
|
298
313
|
to_skm(raw_result)
|
299
314
|
end
|
300
315
|
end
|
301
|
-
define_primitive_proc(aRuntime, 'and', zero_or_more, primitive)
|
316
|
+
define_primitive_proc(aRuntime, 'and', zero_or_more, primitive)
|
317
|
+
end
|
318
|
+
|
319
|
+
def create_or(aRuntime)
|
320
|
+
# arglist should be a Ruby Array
|
321
|
+
primitive = ->(runtime, arglist) do
|
322
|
+
if arglist.empty?
|
323
|
+
to_skm(false) # in conformance with 4.2.1
|
324
|
+
else
|
325
|
+
raw_result = false
|
326
|
+
last_result = nil
|
327
|
+
arglist.each do |raw_arg|
|
328
|
+
argument = raw_arg.evaluate(aRuntime)
|
329
|
+
last_result = argument
|
330
|
+
raw_result ||= (!argument.boolean? || argument.value)
|
331
|
+
break if raw_result
|
332
|
+
end
|
333
|
+
raw_result = last_result if raw_result
|
334
|
+
to_skm(raw_result)
|
335
|
+
end
|
336
|
+
end
|
337
|
+
define_primitive_proc(aRuntime, 'or', zero_or_more, primitive)
|
338
|
+
end
|
339
|
+
|
340
|
+
def create_string_append(aRuntime)
|
341
|
+
primitive = ->(runtime, arglist) do
|
342
|
+
if arglist.empty?
|
343
|
+
value = ''
|
344
|
+
else
|
345
|
+
parts = evaluate_array(arglist, aRuntime)
|
346
|
+
value = parts.reduce('') { |interim, substr| interim << substr.value }
|
347
|
+
end
|
348
|
+
|
349
|
+
SkmString.create(value)
|
350
|
+
end
|
351
|
+
|
352
|
+
define_primitive_proc(aRuntime, 'string-append', zero_or_more, primitive)
|
353
|
+
end
|
354
|
+
|
355
|
+
def create_string2symbol(aRuntime)
|
356
|
+
primitive = ->(runtime, arg) do
|
357
|
+
arg_evaluated = arg.evaluate(runtime)
|
358
|
+
check_argtype(arg_evaluated, SkmString, 'string', 'string->symbol')
|
359
|
+
SkmIdentifier.create(arg_evaluated.value)
|
360
|
+
end
|
361
|
+
|
362
|
+
define_primitive_proc(aRuntime, 'string->symbol', unary, primitive)
|
302
363
|
end
|
303
364
|
|
304
365
|
def create_length(aRuntime)
|
data/lib/skeem/version.rb
CHANGED
@@ -148,7 +148,7 @@ module Skeem
|
|
148
148
|
end
|
149
149
|
end # context
|
150
150
|
|
151
|
-
context 'Number
|
151
|
+
context 'Number procedures:' do
|
152
152
|
it 'should implement the number? predicate' do
|
153
153
|
checks = [
|
154
154
|
['(number? 3.1)', true],
|
@@ -161,7 +161,7 @@ module Skeem
|
|
161
161
|
expect(result.value).to eq(expectation)
|
162
162
|
end
|
163
163
|
end
|
164
|
-
|
164
|
+
|
165
165
|
it 'should implement the real? predicate' do
|
166
166
|
checks = [
|
167
167
|
['(real? 3.1)', true],
|
@@ -188,8 +188,21 @@ module Skeem
|
|
188
188
|
expect(result.value).to eq(expectation)
|
189
189
|
end
|
190
190
|
end
|
191
|
+
|
192
|
+
it 'should implement the number->string procedure' do
|
193
|
+
checks = [
|
194
|
+
['(number->string 3.4)', '3.4'],
|
195
|
+
['(number->string 1e2)', '100.0'],
|
196
|
+
['(number->string 1e-23)', '1.0e-23'],
|
197
|
+
['(number->string -7)', '-7']
|
198
|
+
]
|
199
|
+
checks.each do |(skeem_expr, expectation)|
|
200
|
+
result = subject.run(skeem_expr)
|
201
|
+
expect(result.value).to eq(expectation)
|
202
|
+
end
|
203
|
+
end
|
191
204
|
end # context
|
192
|
-
|
205
|
+
|
193
206
|
context 'Boolean procedures:' do
|
194
207
|
it 'should implement the not procedure' do
|
195
208
|
checks = [
|
@@ -202,7 +215,7 @@ module Skeem
|
|
202
215
|
expect(result.value).to eq(expectation)
|
203
216
|
end
|
204
217
|
end
|
205
|
-
|
218
|
+
|
206
219
|
it 'should implement the and procedure' do
|
207
220
|
checks = [
|
208
221
|
['(and (= 2 2) (> 2 1))', true],
|
@@ -213,14 +226,39 @@ module Skeem
|
|
213
226
|
result = subject.run(skeem_expr)
|
214
227
|
expect(result.value).to eq(expectation)
|
215
228
|
end
|
216
|
-
|
229
|
+
|
217
230
|
# If all the expressions evaluate to true values,
|
218
231
|
# the values of the last expression are returned.
|
219
232
|
source = "(and 1 2 'c '(f g))"
|
220
233
|
result = subject.run(source)
|
221
|
-
|
222
|
-
|
223
|
-
|
234
|
+
expect(result).to be_kind_of(SkmList)
|
235
|
+
expect(result.head.value).to eq('f')
|
236
|
+
expect(result.last.value).to eq('g')
|
237
|
+
end
|
238
|
+
|
239
|
+
it 'should implement the or procedure' do
|
240
|
+
checks = [
|
241
|
+
['(or (= 2 2) (> 2 1))', true],
|
242
|
+
['(or (= 2 2) (< 2 1))', true],
|
243
|
+
['(or)', false],
|
244
|
+
['(or #f)', false],
|
245
|
+
['(or #f #t)', true],
|
246
|
+
['(or #f #f #f)', false],
|
247
|
+
|
248
|
+
]
|
249
|
+
checks.each do |(skeem_expr, expectation)|
|
250
|
+
result = subject.run(skeem_expr)
|
251
|
+
expect(result.value).to eq(expectation)
|
252
|
+
end
|
253
|
+
|
254
|
+
# When an expression evaluates to true value,
|
255
|
+
# the values of the this expression is returned.
|
256
|
+
source = "(or #f 'a #f)"
|
257
|
+
result = subject.run(source)
|
258
|
+
expect(result).to be_kind_of(SkmIdentifier)
|
259
|
+
expect(result.value).to eq('a')
|
260
|
+
end
|
261
|
+
|
224
262
|
it 'should implement the boolean? procedure' do
|
225
263
|
checks = [
|
226
264
|
['(boolean? #f)', true],
|
@@ -230,9 +268,9 @@ module Skeem
|
|
230
268
|
result = subject.run(skeem_expr)
|
231
269
|
expect(result.value).to eq(expectation)
|
232
270
|
end
|
233
|
-
end
|
271
|
+
end
|
234
272
|
end # context
|
235
|
-
|
273
|
+
|
236
274
|
context 'String procedures:' do
|
237
275
|
it 'should implement the string? procedure' do
|
238
276
|
checks = [
|
@@ -244,10 +282,32 @@ module Skeem
|
|
244
282
|
result = subject.run(skeem_expr)
|
245
283
|
expect(result.value).to eq(expectation)
|
246
284
|
end
|
247
|
-
end
|
285
|
+
end
|
286
|
+
|
287
|
+
it 'should implement the string->symbol procedure' do
|
288
|
+
checks = [
|
289
|
+
['(string->symbol "mISSISSIppi")', 'mISSISSIppi']
|
290
|
+
]
|
291
|
+
checks.each do |(skeem_expr, expectation)|
|
292
|
+
result = subject.run(skeem_expr)
|
293
|
+
expect(result.value).to eq(expectation)
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
it 'should implement the string-append procedure' do
|
298
|
+
checks = [
|
299
|
+
['(string-append)', ''],
|
300
|
+
['(string-append "abc" "def")', 'abcdef'],
|
301
|
+
['(string-append "Hey " "you " "there!")', 'Hey you there!']
|
302
|
+
]
|
303
|
+
checks.each do |(skeem_expr, expectation)|
|
304
|
+
result = subject.run(skeem_expr)
|
305
|
+
expect(result.value).to eq(expectation)
|
306
|
+
end
|
307
|
+
end
|
248
308
|
end # context
|
249
|
-
|
250
|
-
context 'Symbol procedures:' do
|
309
|
+
|
310
|
+
context 'Symbol procedures:' do
|
251
311
|
it 'should implement the symbol? procedure' do
|
252
312
|
checks = [
|
253
313
|
['(symbol? #f)', false],
|
@@ -259,8 +319,8 @@ module Skeem
|
|
259
319
|
end
|
260
320
|
end
|
261
321
|
end # context
|
262
|
-
|
263
|
-
context 'List procedures:' do
|
322
|
+
|
323
|
+
context 'List procedures:' do
|
264
324
|
it 'should implement the list? procedure' do
|
265
325
|
checks = [
|
266
326
|
['(list? #f)', false],
|
@@ -274,7 +334,7 @@ module Skeem
|
|
274
334
|
expect(result.value).to eq(expectation)
|
275
335
|
end
|
276
336
|
end
|
277
|
-
|
337
|
+
|
278
338
|
it 'should implement the null? procedure' do
|
279
339
|
checks = [
|
280
340
|
['(null? #f)', false],
|
@@ -289,7 +349,7 @@ module Skeem
|
|
289
349
|
result = subject.run(skeem_expr)
|
290
350
|
expect(result.value).to eq(expectation)
|
291
351
|
end
|
292
|
-
end
|
352
|
+
end
|
293
353
|
|
294
354
|
it 'should implement the length procedure' do
|
295
355
|
checks = [
|
@@ -302,10 +362,10 @@ module Skeem
|
|
302
362
|
result = subject.run(skeem_expr)
|
303
363
|
expect(result.value).to eq(expectation)
|
304
364
|
end
|
305
|
-
end
|
306
|
-
end # context
|
365
|
+
end
|
366
|
+
end # context
|
307
367
|
|
308
|
-
context 'Vector procedures:' do
|
368
|
+
context 'Vector procedures:' do
|
309
369
|
it 'should implement the vector? procedure' do
|
310
370
|
checks = [
|
311
371
|
['(vector? #f)', false],
|
@@ -319,13 +379,13 @@ module Skeem
|
|
319
379
|
expect(result.value).to eq(expectation)
|
320
380
|
end
|
321
381
|
end
|
322
|
-
|
382
|
+
|
323
383
|
it 'should implement the vector procedure' do
|
324
384
|
source = '(vector)'
|
325
385
|
result = subject.run(source)
|
326
386
|
expect(result).to be_kind_of(SkmVector)
|
327
387
|
expect(result).to be_empty
|
328
|
-
|
388
|
+
|
329
389
|
source = '(vector 1 2 3)'
|
330
390
|
result = subject.run(source)
|
331
391
|
expect(result).to be_kind_of(SkmVector)
|
@@ -346,17 +406,17 @@ module Skeem
|
|
346
406
|
result = subject.run(skeem_expr)
|
347
407
|
expect(result.value).to eq(expectation)
|
348
408
|
end
|
349
|
-
end
|
409
|
+
end
|
350
410
|
|
351
411
|
it 'should implement the vector-ref procedure' do
|
352
412
|
source = "(vector-ref '#(1 1 2 3 5 8 13 21) 5)"
|
353
413
|
result = subject.run(source)
|
354
414
|
expect(result).to be_kind_of(SkmInteger)
|
355
|
-
expect(result.value).to eq(8)
|
356
|
-
end
|
357
|
-
end # context
|
358
|
-
|
359
|
-
context 'IO procedures:' do
|
415
|
+
expect(result.value).to eq(8)
|
416
|
+
end
|
417
|
+
end # context
|
418
|
+
|
419
|
+
context 'IO procedures:' do
|
360
420
|
it 'should implement the newline procedure' do
|
361
421
|
default_stdout = $stdout
|
362
422
|
$stdout = StringIO.new()
|
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.0.
|
4
|
+
version: 0.0.23
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dimitri Geshef
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-10-
|
11
|
+
date: 2018-10-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rley
|