skeem 0.0.20 → 0.0.21
Sign up to get free protection for your applications and to get access to all the features.
- 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
|