skeem 0.0.20 → 0.0.21
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 +12 -0
- data/README.md +24 -17
- data/lib/skeem/convertible.rb +2 -0
- data/lib/skeem/grammar.rb +2 -2
- data/lib/skeem/interpreter.rb +4 -3
- data/lib/skeem/primitive/primitive_builder.rb +1 -1
- data/lib/skeem/s_expr_builder.rb +12 -0
- data/lib/skeem/s_expr_nodes.rb +18 -3
- data/lib/skeem/version.rb +1 -1
- data/spec/skeem/interpreter_spec.rb +19 -10
- data/spec/skeem/primitive/primitive_builder_spec.rb +6 -6
- 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: 848f771b4fb717e1c491f6afae9a88a9c34e5302
|
4
|
+
data.tar.gz: 349587e3837e36893a5aaaad4a32986708d24979
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 89778cee179ca6cd65a5f45804471637d31a0db36f094cbedadc8ef72cb46cc3b0c75193e4b458b16091388a2a02db8c13e27444b7642da56ffc899504d451ce
|
7
|
+
data.tar.gz: cecc4f9aca3391d4abf695b593822988b49145e6bf55e66ed468cb10bda9e4fca5f9ad569c2c9e3de1d6220943437eabbd88067b3a5282abeea3bee2d2764679
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
## [0.0.21] - 2018-10-22
|
2
|
+
### Added
|
3
|
+
- Added support for alternative `define` syntax.
|
4
|
+
- File `primitive_builder.rb` implementation of: standard `vector-ref` procedure.
|
5
|
+
- Added `SkmQuotation#inspect`, `SkmVector#inspect` method
|
6
|
+
|
7
|
+
### Changed
|
8
|
+
- File `README.md` added sub-section with links for Scheme language.
|
9
|
+
|
10
|
+
### Fixed
|
11
|
+
- Method `Convertible#to_skm` now returns a SkmElement-like object without attempting a convertion.
|
12
|
+
|
1
13
|
## [0.0.20] - 2018-10-21
|
2
14
|
### Added
|
3
15
|
- Added support for quotation: (quote foo) or 'foo
|
data/README.md
CHANGED
@@ -23,10 +23,27 @@ Or install it yourself as:
|
|
23
23
|
|
24
24
|
$ gem install skeem
|
25
25
|
|
26
|
-
## Usage
|
27
26
|
|
28
|
-
The __Skeem__ project has
|
29
|
-
|
27
|
+
The __Skeem__ project has started recently and at this stage, the gem supports a small Scheme subset.
|
28
|
+
|
29
|
+
## About Scheme
|
30
|
+
|
31
|
+
The Scheme programming language is a Lisp dialect that supports multiple paradigms, including functional programming and imperative programming.
|
32
|
+
|
33
|
+
### Resources on Scheme
|
34
|
+
Here are a few pointers for the Scheme programming language:
|
35
|
+
- Wikipedia article on [Scheme](https://en.m.wikipedia.org/wiki/Scheme_\(programming_language\))
|
36
|
+
- Latest official Scheme standard: [R7RS](https://bitbucket.org/cowan/r7rs-wg1-infra/src/default/R7RSHomePage.md)
|
37
|
+
#### Online tutorials and books:
|
38
|
+
- [The Scheme Programming Language, 4th Edition](https://www.scheme.com/tspl4/) by Kent Dybvig. An complete, introductory textbook on Scheme based on the older R5RS standard.
|
39
|
+
- [Teach Yourself Scheme in Fixnum Days](http://ds26gte.github.io/tyscheme/index.html) by Dorai Sitaram
|
40
|
+
|
41
|
+
## Other similar Ruby projects
|
42
|
+
__Skeem__ isn't the sole implementation of the Scheme language in Ruby.
|
43
|
+
Here are a few other ones:
|
44
|
+
- [Heist gem](https://rubygems.org/gems/heist) -- Probably one of best Scheme implementation in Ruby. Really worth a try. Alas, the [project](https://github.com/jcoglan/heist) seems to be dormant for several years.
|
45
|
+
|
46
|
+
## Usage
|
30
47
|
|
31
48
|
### Example 1 (Variable definition)
|
32
49
|
|
@@ -116,14 +133,17 @@ At this stage, the gem consists of a bare-bones interpreter.
|
|
116
133
|
#### define
|
117
134
|
__Purpose:__ Create a new variable and bind an expression/value to it.
|
118
135
|
__Syntax:__
|
119
|
-
* (define <identifier\> <expression\>)
|
136
|
+
* (define <identifier\> <expression\>)
|
137
|
+
* (define (<variable\> <formals\>) <body\>)
|
120
138
|
|
121
139
|
#### if
|
122
140
|
__Purpose:__ Conditional evaluation based on a test expression.
|
123
141
|
__Syntax:__
|
142
|
+
* (if <test\> <consequent\>)
|
124
143
|
* (if <test\> <consequent\> <alternate\>)
|
125
144
|
|
126
145
|
|
146
|
+
|
127
147
|
#### lambda
|
128
148
|
__Purpose:__ Definition of a procedure.
|
129
149
|
__Syntax:__
|
@@ -164,19 +184,6 @@ Roadmap:
|
|
164
184
|
- Extend the language in order to support [Minikanren](https://github.com/TheReasonedSchemer2ndEd/CodeFromTheReasonedSchemer2ndEd)
|
165
185
|
- Make it pass all examples from the [Reasoned Schemer](https://mitpress.mit.edu/books/reasoned-schemer-second-edition) book.
|
166
186
|
|
167
|
-
|
168
|
-
Good to know:
|
169
|
-
Online book: [The Scheme Programming Language (4th Ed.)](https://www.scheme.com/tspl4/). Remark: covers an older version of Scheme.
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
## Other similar Ruby projects
|
176
|
-
__Skeem__ isn't the sole implementation of the Scheme language in Ruby.
|
177
|
-
Here are a few other ones:
|
178
|
-
- [Heist gem](https://rubygems.org/gems/heist) -- Probably one of best Scheme implementation in Ruby. Really worth a try. Alas, the [project](https://github.com/jcoglan/heist) seems to be dormant for several years.
|
179
|
-
|
180
187
|
## Contributing
|
181
188
|
|
182
189
|
Bug reports and pull requests are welcome on GitHub at https://github.com/famished-tiger/Skeem.
|
data/lib/skeem/convertible.rb
CHANGED
data/lib/skeem/grammar.rb
CHANGED
@@ -65,8 +65,8 @@ module Skeem
|
|
65
65
|
rule('operand_plus' => 'operand').as 'last_operand'
|
66
66
|
rule 'operator' => 'expression'
|
67
67
|
rule 'operand' => 'expression'
|
68
|
-
rule
|
69
|
-
|
68
|
+
rule('def_formals' => 'identifier_star').as 'def_formals'
|
69
|
+
rule('def_formals' => 'identifier_star PERIOD IDENTIFIER').as 'pair_formals'
|
70
70
|
rule('lambda_expression' => 'LPAREN LAMBDA formals body RPAREN').as 'lambda_expression'
|
71
71
|
rule('formals' => 'LPAREN identifier_star RPAREN').as 'fixed_arity_formals'
|
72
72
|
rule('formals' => 'IDENTIFIER').as 'variadic_formals'
|
data/lib/skeem/interpreter.rb
CHANGED
@@ -15,10 +15,11 @@ module Skeem
|
|
15
15
|
add_standard(runtime)
|
16
16
|
end
|
17
17
|
|
18
|
-
def run(source)
|
18
|
+
def run(source, mode = nil)
|
19
19
|
@parser ||= Parser.new
|
20
20
|
@ptree = parser.parse(source)
|
21
|
-
# $stderr.puts @ptree.root.inspect
|
21
|
+
# $stderr.puts @ptree.root.inspect if mode.nil?
|
22
|
+
# require 'debug' if mode.nil?
|
22
23
|
return @ptree.root.evaluate(runtime)
|
23
24
|
end
|
24
25
|
|
@@ -37,7 +38,7 @@ module Skeem
|
|
37
38
|
lib_source = nil
|
38
39
|
File.open(aPathname, 'r') do |lib|
|
39
40
|
lib_source = lib.read
|
40
|
-
run(lib_source)
|
41
|
+
run(lib_source, :silent)
|
41
42
|
end
|
42
43
|
end
|
43
44
|
end # class
|
data/lib/skeem/s_expr_builder.rb
CHANGED
@@ -66,6 +66,7 @@ module Skeem
|
|
66
66
|
# Equivalent to: (define IDENTIFIER (lambda (formals) body))
|
67
67
|
def reduce_alt_definition(_production, aRange, _tokens, theChildren)
|
68
68
|
lmbd = SkmLambda.new(aRange, theChildren[4], theChildren[6])
|
69
|
+
# $stderr.puts lmbd.inspect
|
69
70
|
SkmDefinition.new(aRange, theChildren[3], lmbd)
|
70
71
|
end
|
71
72
|
|
@@ -124,6 +125,17 @@ module Skeem
|
|
124
125
|
[theChildren.last]
|
125
126
|
end
|
126
127
|
|
128
|
+
# rule('def_formals' => 'identifier_star').as 'def_formals'
|
129
|
+
def reduce_def_formals(_production, _range, _tokens, theChildren)
|
130
|
+
SkmFormals.new(theChildren[0], :fixed)
|
131
|
+
end
|
132
|
+
|
133
|
+
# rule('def_formals' => 'identifier_star PERIOD identifier').as 'pair_formals'
|
134
|
+
def reduce_pair_formals(_production, _range, _tokens, theChildren)
|
135
|
+
formals = theChildren[0] << theChildren[2]
|
136
|
+
SkmFormals.new(formals, :variadic)
|
137
|
+
end
|
138
|
+
|
127
139
|
# rule('lambda_expression' => 'LPAREN LAMBDA formals body RPAREN').as 'lambda_expression'
|
128
140
|
def reduce_lambda_expression(_production, aRange, _tokens, theChildren)
|
129
141
|
lmbd = SkmLambda.new(aRange, theChildren[2], theChildren[3])
|
data/lib/skeem/s_expr_nodes.rb
CHANGED
@@ -68,8 +68,8 @@ module Skeem
|
|
68
68
|
raise NotImplementedError
|
69
69
|
end
|
70
70
|
|
71
|
-
def inspect
|
72
|
-
raise NotImplementedError
|
71
|
+
def inspect
|
72
|
+
raise NotImplementedError, "Missing #{self.class}#inspect method."
|
73
73
|
end
|
74
74
|
|
75
75
|
protected
|
@@ -270,7 +270,15 @@ module Skeem
|
|
270
270
|
def evaluate(aRuntime)
|
271
271
|
elements_evaluated = elements.map { |elem| elem.evaluate(aRuntime) }
|
272
272
|
SkmVector.new(elements_evaluated)
|
273
|
-
end
|
273
|
+
end
|
274
|
+
|
275
|
+
def inspect()
|
276
|
+
result = inspect_prefix
|
277
|
+
elements.each { |elem| result << elem.inspect + ', ' }
|
278
|
+
result.sub!(/, $/, '')
|
279
|
+
result << inspect_suffix
|
280
|
+
result
|
281
|
+
end
|
274
282
|
|
275
283
|
end # class
|
276
284
|
|
@@ -286,6 +294,13 @@ module Skeem
|
|
286
294
|
def evaluate(aRuntime)
|
287
295
|
datum
|
288
296
|
end
|
297
|
+
|
298
|
+
def inspect
|
299
|
+
result = inspect_prefix
|
300
|
+
result << datum.inspect
|
301
|
+
result << inspect_suffix
|
302
|
+
result
|
303
|
+
end
|
289
304
|
end # class
|
290
305
|
|
291
306
|
class SkmDefinition < SkmElement
|
data/lib/skeem/version.rb
CHANGED
@@ -83,7 +83,7 @@ module Skeem
|
|
83
83
|
expect(result.value).to eq(predicted)
|
84
84
|
end
|
85
85
|
end
|
86
|
-
|
86
|
+
|
87
87
|
it 'should evaluate vector of constants' do
|
88
88
|
source = '#(2018 10 20 "Sat")'
|
89
89
|
result = subject.run(source)
|
@@ -97,7 +97,7 @@ module Skeem
|
|
97
97
|
predictions.each_with_index do |(type, value), index|
|
98
98
|
expect(result.elements[index]).to be_kind_of(type)
|
99
99
|
expect(result.elements[index].value).to eq(value)
|
100
|
-
end
|
100
|
+
end
|
101
101
|
end
|
102
102
|
end # context
|
103
103
|
|
@@ -158,7 +158,7 @@ SKEEM
|
|
158
158
|
["'a", 'a'],
|
159
159
|
["'145932", 145932],
|
160
160
|
["'\"abc\"", 'abc'],
|
161
|
-
["'#t", true]
|
161
|
+
["'#t", true]
|
162
162
|
]
|
163
163
|
checks.each do |(skeem_expr, expectation)|
|
164
164
|
result = subject.run(skeem_expr)
|
@@ -178,9 +178,9 @@ SKEEM
|
|
178
178
|
predictions.each_with_index do |(type, value), index|
|
179
179
|
expect(result.elements[index]).to be_kind_of(type)
|
180
180
|
expect(result.elements[index].value).to eq(value)
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
184
|
|
185
185
|
it 'should implement the lambda function with one arg' do
|
186
186
|
source = <<-SKEEM
|
@@ -237,7 +237,6 @@ SKEEM
|
|
237
237
|
expect(result.value).to eq(8)
|
238
238
|
end
|
239
239
|
|
240
|
-
|
241
240
|
it 'should support procedures with variable number of arguments' do
|
242
241
|
# Example from R7RS section 4.1.4
|
243
242
|
source = '((lambda x x) 3 4 5 6)'
|
@@ -255,7 +254,7 @@ SKEEM
|
|
255
254
|
expect(result.head.value).to eq(5)
|
256
255
|
expect(result.last.value).to eq(6)
|
257
256
|
end
|
258
|
-
|
257
|
+
|
259
258
|
it 'should implement the compact define + lambda syntax' do
|
260
259
|
source = <<-SKEEM
|
261
260
|
; Alternative syntax to: (define f (lambda x (+ x 42)))
|
@@ -264,9 +263,19 @@ SKEEM
|
|
264
263
|
(f 23)
|
265
264
|
SKEEM
|
266
265
|
result = subject.run(source)
|
267
|
-
expect(result.value).to eq(65)
|
266
|
+
expect(result.last.value).to eq(65)
|
267
|
+
end
|
268
|
+
|
269
|
+
it 'should implement the compact define + pair syntax' do
|
270
|
+
source = <<-SKEEM
|
271
|
+
; Alternative syntax to: (define nlist (lambda args args))
|
272
|
+
(define (nlist . args)
|
273
|
+
args)
|
274
|
+
(nlist 0 1 2 3 4)
|
275
|
+
SKEEM
|
276
|
+
result = subject.run(source)
|
277
|
+
expect(result.last.last.value).to eq(4)
|
268
278
|
end
|
269
|
-
=end
|
270
279
|
end # context
|
271
280
|
|
272
281
|
context 'Built-in primitive procedures' do
|
@@ -330,12 +330,12 @@ module Skeem
|
|
330
330
|
end
|
331
331
|
end
|
332
332
|
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
333
|
+
it 'should implement the vector-ref procedure' do
|
334
|
+
source = "(vector-ref '#(1 1 2 3 5 8 13 21) 5)"
|
335
|
+
result = subject.run(source)
|
336
|
+
expect(result).to be_kind_of(SkmInteger)
|
337
|
+
expect(result.value).to eq(8)
|
338
|
+
end
|
339
339
|
end # context
|
340
340
|
|
341
341
|
context 'IO procedures:' do
|
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.21
|
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-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rley
|