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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 91492f1d990da9deecf2146b21c13a5721cbf327
4
- data.tar.gz: 06355e700c51894615aea3c34c7f26794a2482b4
3
+ metadata.gz: 848f771b4fb717e1c491f6afae9a88a9c34e5302
4
+ data.tar.gz: 349587e3837e36893a5aaaad4a32986708d24979
5
5
  SHA512:
6
- metadata.gz: eb0d9f83f9816fbc881fef46b75e9587111539e3f4254772478e3e05bcb1c4fcd26d6dc16d83053f41c2fab55fe96e1d5d4cc1b02a7fc120218d09dcaa000088
7
- data.tar.gz: cad77c7dab37087ff75202d2429d5213dd1ccf04e04d6a45993f41f9dc7ef587b897e2c677e10f1eb3d800c46f47a742f2378d95b2c020edb0f2d2da34d5171f
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 just started.
29
- At this stage, the gem consists of a bare-bones interpreter.
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.
@@ -4,6 +4,8 @@ module Skeem
4
4
  module Convertible
5
5
  # Convert Ruby object into its Skeem counterpart
6
6
  def to_skm(native_obj)
7
+ return native_obj if native_obj.kind_of?(SkmElement)
8
+
7
9
  case native_obj
8
10
  when TrueClass, FalseClass
9
11
  SkmBoolean.create(native_obj)
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 'def_formals' => 'identifier_star'
69
- # rule('def_formals' => 'identifier_star period identifier').as 'OTHER_NAME_formals'
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'
@@ -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
@@ -85,7 +85,7 @@ module Skeem
85
85
  create_object_predicate(aRuntime, 'vector?')
86
86
  create_vector(aRuntime)
87
87
  create_vector_length(aRuntime)
88
- # create_vector_ref(aRuntime)
88
+ create_vector_ref(aRuntime)
89
89
  end
90
90
 
91
91
  def add_io_procedures(aRuntime)(aRuntime)
@@ -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])
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Skeem
2
- VERSION = '0.0.20'.freeze
2
+ VERSION = '0.0.21'.freeze
3
3
  end
@@ -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
- =begin
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
- # 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
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.20
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-20 00:00:00.000000000 Z
11
+ date: 2018-10-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rley