skeem 0.2.14 → 0.2.18
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/.rubocop.yml +451 -195
- data/.travis.yml +27 -0
- data/CHANGELOG.md +35 -1
- data/Gemfile +2 -0
- data/README.md +125 -56
- data/Rakefile +2 -0
- data/appveyor.yml +3 -4
- data/bin/cubic.skm +4 -0
- data/bin/hello-world.skm +1 -0
- data/bin/skeem +72 -0
- data/lib/skeem/datum_dsl.rb +40 -30
- data/lib/skeem/element_visitor.rb +5 -2
- data/lib/skeem/grammar.rb +88 -26
- data/lib/skeem/interpreter.rb +9 -7
- data/lib/skeem/parser.rb +6 -4
- data/lib/skeem/primitive/primitive_builder.rb +148 -122
- data/lib/skeem/primitive/primitive_procedure.rb +23 -25
- data/lib/skeem/runtime.rb +17 -15
- data/lib/skeem/s_expr_builder.rb +49 -117
- data/lib/skeem/s_expr_nodes.rb +147 -132
- data/lib/skeem/skeem_exception.rb +1 -0
- data/lib/skeem/skm_binding.rb +9 -11
- data/lib/skeem/skm_compound_datum.rb +9 -6
- data/lib/skeem/skm_element.rb +15 -13
- data/lib/skeem/skm_empty_list.rb +6 -4
- data/lib/skeem/skm_exception.rb +9 -0
- data/lib/skeem/skm_expression.rb +3 -1
- data/lib/skeem/skm_frame.rb +3 -2
- data/lib/skeem/skm_pair.rb +26 -18
- data/lib/skeem/skm_procedure_exec.rb +11 -6
- data/lib/skeem/skm_simple_datum.rb +23 -20
- data/lib/skeem/skm_unary_expression.rb +34 -37
- data/lib/skeem/standard/base.skm +4 -0
- data/lib/skeem/tokenizer.rb +38 -28
- data/lib/skeem/version.rb +3 -1
- data/lib/skeem.rb +2 -0
- data/skeem.gemspec +9 -6
- data/spec/skeem/add4.skm +4 -0
- data/spec/skeem/datum_dsl_spec.rb +13 -12
- data/spec/skeem/element_visitor_spec.rb +14 -10
- data/spec/skeem/interpreter_spec.rb +84 -44
- data/spec/skeem/lambda_spec.rb +13 -11
- data/spec/skeem/parser_spec.rb +23 -19
- data/spec/skeem/primitive/primitive_builder_spec.rb +65 -48
- data/spec/skeem/primitive/primitive_procedure_spec.rb +14 -12
- data/spec/skeem/runtime_spec.rb +20 -18
- data/spec/skeem/s_expr_nodes_spec.rb +8 -6
- data/spec/skeem/skm_compound_datum_spec.rb +12 -10
- data/spec/skeem/skm_element_spec.rb +7 -5
- data/spec/skeem/skm_empty_list_spec.rb +7 -5
- data/spec/skeem/skm_frame_spec.rb +5 -4
- data/spec/skeem/skm_pair_spec.rb +9 -8
- data/spec/skeem/skm_procedure_exec_spec.rb +2 -0
- data/spec/skeem/skm_simple_datum_spec.rb +24 -22
- data/spec/skeem/skm_unary_expression_spec.rb +11 -9
- data/spec/skeem/tokenizer_spec.rb +54 -43
- data/spec/skeem_spec.rb +2 -0
- data/spec/spec_helper.rb +15 -10
- metadata +18 -10
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative '../spec_helper' # Use the RSpec framework
|
2
4
|
require_relative '../../lib/skeem/tokenizer' # Load the class under test
|
3
5
|
|
@@ -12,14 +14,14 @@ module Skeem
|
|
12
14
|
end
|
13
15
|
|
14
16
|
# Assumption: subject is a Skeem::Tokenizer
|
15
|
-
|
16
|
-
|
17
|
+
def check_tokens(tokenTests, tokType)
|
18
|
+
tokenTests.each do |(input, prediction)|
|
17
19
|
subject.reinitialize(input)
|
18
20
|
token = subject.tokens.first
|
19
21
|
expect(token.terminal).to eq(tokType)
|
20
22
|
expect(token.lexeme).to eq(prediction)
|
21
|
-
|
22
|
-
|
23
|
+
end
|
24
|
+
end
|
23
25
|
|
24
26
|
def unquoted(aString)
|
25
27
|
aString.gsub(/(^")|("$)/, '')
|
@@ -46,8 +48,7 @@ module Skeem
|
|
46
48
|
terminals = tokens.map(&:terminal)
|
47
49
|
prediction = %w[LPAREN RPAREN APOSTROPHE
|
48
50
|
GRAVE_ACCENT PERIOD
|
49
|
-
COMMA COMMA_AT_SIGN
|
50
|
-
]
|
51
|
+
COMMA COMMA_AT_SIGN ]
|
51
52
|
expect(terminals).to eq(prediction)
|
52
53
|
end
|
53
54
|
end # context
|
@@ -80,7 +81,7 @@ module Skeem
|
|
80
81
|
|
81
82
|
check_tokens(tests, 'INTEGER')
|
82
83
|
end
|
83
|
-
|
84
|
+
|
84
85
|
it 'should tokenize integers with explicit radix 10' do
|
85
86
|
tests = [
|
86
87
|
# couple [raw input, expected]
|
@@ -106,7 +107,7 @@ module Skeem
|
|
106
107
|
]
|
107
108
|
|
108
109
|
check_tokens(tests, 'INTEGER')
|
109
|
-
end
|
110
|
+
end
|
110
111
|
end # context
|
111
112
|
|
112
113
|
context 'Rational literals recognition:' do
|
@@ -114,7 +115,7 @@ module Skeem
|
|
114
115
|
tests = [
|
115
116
|
# couple [raw input, expected]
|
116
117
|
['1/2', Rational(1, 2)],
|
117
|
-
['-22/7', -Rational(22, 7)]
|
118
|
+
['-22/7', -Rational(22, 7)]
|
118
119
|
]
|
119
120
|
|
120
121
|
check_tokens(tests, 'RATIONAL')
|
@@ -128,6 +129,7 @@ module Skeem
|
|
128
129
|
end # context
|
129
130
|
|
130
131
|
context 'Real number recognition:' do
|
132
|
+
# rubocop: disable Style/ExponentialNotation
|
131
133
|
it 'should tokenize real numbers' do
|
132
134
|
tests = [
|
133
135
|
# couple [raw input, expected]
|
@@ -139,15 +141,16 @@ module Skeem
|
|
139
141
|
|
140
142
|
check_tokens(tests, 'REAL')
|
141
143
|
end
|
144
|
+
# rubocop: enable Style/ExponentialNotation
|
142
145
|
end # context
|
143
146
|
|
144
147
|
context 'Character literal recognition:' do
|
145
148
|
it 'should tokenize named characters' do
|
146
149
|
tests = [
|
147
150
|
# couple [raw input, expected]
|
148
|
-
[
|
149
|
-
[
|
150
|
-
[
|
151
|
+
['#\alarm', ?\a],
|
152
|
+
['#\newline', ?\n],
|
153
|
+
['#\return', ?\r]
|
151
154
|
]
|
152
155
|
|
153
156
|
check_tokens(tests, 'CHAR')
|
@@ -156,10 +159,10 @@ module Skeem
|
|
156
159
|
it 'should tokenize escaped characters' do
|
157
160
|
tests = [
|
158
161
|
# couple [raw input, expected]
|
159
|
-
[
|
160
|
-
[
|
161
|
-
[
|
162
|
-
[
|
162
|
+
['#\a', ?a],
|
163
|
+
['#\A', ?A],
|
164
|
+
['#\(', ?(],
|
165
|
+
['#\ ', ?\s]
|
163
166
|
]
|
164
167
|
|
165
168
|
check_tokens(tests, 'CHAR')
|
@@ -168,9 +171,9 @@ module Skeem
|
|
168
171
|
it 'should tokenize hex-coded characters' do
|
169
172
|
tests = [
|
170
173
|
# couple [raw input, expected]
|
171
|
-
[
|
172
|
-
[
|
173
|
-
[
|
174
|
+
['#\x07', ?\a],
|
175
|
+
['#\x1B', ?\e],
|
176
|
+
['#\x3BB', ?\u03bb]
|
174
177
|
]
|
175
178
|
|
176
179
|
check_tokens(tests, 'CHAR')
|
@@ -201,10 +204,10 @@ module Skeem
|
|
201
204
|
# "\x03B1; is named GREEK SMALL LETTER ALPHA."
|
202
205
|
|
203
206
|
context 'Identifier recognition:' do
|
204
|
-
it 'should tokenize
|
207
|
+
it 'should tokenize identifiers' do
|
205
208
|
examples = [
|
206
209
|
# Examples taken from R7RS document
|
207
|
-
'
|
210
|
+
'+', '+soup+', '<=?',
|
208
211
|
'->string', 'a34kTMNs', 'lambda',
|
209
212
|
'list->vector', 'q', 'V17a',
|
210
213
|
'|two words|', '|two\x20;words|',
|
@@ -222,6 +225,14 @@ module Skeem
|
|
222
225
|
expect(token.lexeme).to eq(input)
|
223
226
|
end
|
224
227
|
end
|
228
|
+
|
229
|
+
it 'should recognize ellipsis' do
|
230
|
+
input = '...'
|
231
|
+
subject.reinitialize(input)
|
232
|
+
token = subject.tokens.first
|
233
|
+
expect(token.terminal).to eq('ELLIPSIS')
|
234
|
+
expect(token.lexeme).to eq(input)
|
235
|
+
end
|
225
236
|
end # context
|
226
237
|
|
227
238
|
context 'Vector recognition' do
|
@@ -233,7 +244,7 @@ module Skeem
|
|
233
244
|
['INTEGER', 0, 3],
|
234
245
|
['INTEGER', -2, 5],
|
235
246
|
['STRING_LIT', 'Sue', 8],
|
236
|
-
['RPAREN', ')', 13]
|
247
|
+
['RPAREN', ')', 13]
|
237
248
|
]
|
238
249
|
tokens = subject.tokens
|
239
250
|
predictions.each_with_index do |(pr_terminal, pr_lexeme, pr_position), i|
|
@@ -255,7 +266,7 @@ module Skeem
|
|
255
266
|
end
|
256
267
|
|
257
268
|
it 'should skip trailing comments' do
|
258
|
-
input = "
|
269
|
+
input = '"Some text"; Trailing comment'
|
259
270
|
subject.reinitialize(input)
|
260
271
|
token = subject.tokens.first
|
261
272
|
expect(token.terminal).to eq('STRING_LIT')
|
@@ -305,28 +316,28 @@ module Skeem
|
|
305
316
|
context 'Scanning Scheme sample code' do
|
306
317
|
it 'should produce a sequence of token objects' do
|
307
318
|
# Deeper tokenizer testing
|
308
|
-
source =
|
319
|
+
source = '(define circle-area (lambda (r) (* pi (* r r))))'
|
309
320
|
subject.reinitialize(source)
|
310
321
|
predicted = [
|
311
|
-
[
|
312
|
-
[
|
313
|
-
[
|
314
|
-
[
|
315
|
-
[
|
316
|
-
[
|
317
|
-
[
|
318
|
-
[
|
319
|
-
[
|
320
|
-
[
|
321
|
-
[
|
322
|
-
[
|
323
|
-
[
|
324
|
-
[
|
325
|
-
[
|
326
|
-
[
|
327
|
-
[
|
328
|
-
[
|
329
|
-
[
|
322
|
+
%w[LPAREN (],
|
323
|
+
%w[DEFINE define],
|
324
|
+
%w[IDENTIFIER circle-area],
|
325
|
+
%w[LPAREN (],
|
326
|
+
%w[LAMBDA lambda],
|
327
|
+
%w[LPAREN (],
|
328
|
+
%w[IDENTIFIER r],
|
329
|
+
%w[RPAREN )],
|
330
|
+
%w[LPAREN (],
|
331
|
+
%w[IDENTIFIER *],
|
332
|
+
%w[IDENTIFIER pi],
|
333
|
+
%w[LPAREN (],
|
334
|
+
%w[IDENTIFIER *],
|
335
|
+
%w[IDENTIFIER r],
|
336
|
+
%w[IDENTIFIER r],
|
337
|
+
%w[RPAREN )],
|
338
|
+
%w[RPAREN )],
|
339
|
+
%w[RPAREN )],
|
340
|
+
%w[RPAREN )]
|
330
341
|
]
|
331
342
|
match_expectations(subject, predicted)
|
332
343
|
end
|
data/spec/skeem_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'bundler/setup'
|
2
4
|
require 'rspec' # Use the RSpec framework
|
3
5
|
require_relative '../lib/skeem'
|
@@ -15,26 +17,29 @@ RSpec.configure do |config|
|
|
15
17
|
config.full_backtrace = true
|
16
18
|
end
|
17
19
|
|
20
|
+
|
18
21
|
module InterpreterSpec
|
19
22
|
def expect_expr(aSkeemExpr)
|
20
23
|
result = subject.run(aSkeemExpr)
|
21
24
|
expect(result)
|
22
25
|
end
|
23
26
|
|
27
|
+
# rubocop: disable Lint/RescueException
|
28
|
+
|
24
29
|
# This method assumes that 'subject' is a Skeem::Interpreter instance.
|
25
30
|
def compare_to_predicted(arrActualsPredictions)
|
26
31
|
arrActualsPredictions.each_with_index do |(source, predicted), index|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
expect(result).to eq(predicted)
|
33
|
-
end
|
34
|
-
rescue Exception => exc
|
35
|
-
$stderr.puts "Row #{index + 1} failed."
|
36
|
-
throw exc
|
32
|
+
result = subject.run(source)
|
33
|
+
if block_given?
|
34
|
+
yield result, predicted
|
35
|
+
else
|
36
|
+
expect(result).to eq(predicted)
|
37
37
|
end
|
38
|
+
|
39
|
+
rescue Exception => e
|
40
|
+
$stderr.puts "Row #{index + 1} failed."
|
41
|
+
throw e
|
38
42
|
end
|
39
43
|
end
|
44
|
+
# rubocop: enable Lint/RescueException
|
40
45
|
end
|
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.18
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dimitri Geshef
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-08-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rley
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 0.8.03
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 0.8.03
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -69,13 +69,15 @@ dependencies:
|
|
69
69
|
description: " Skeem is a Scheme language interpreter implemented in Ruby.\n"
|
70
70
|
email:
|
71
71
|
- famished.tiger@yahoo.com
|
72
|
-
executables:
|
72
|
+
executables:
|
73
|
+
- skeem
|
73
74
|
extensions: []
|
74
75
|
extra_rdoc_files:
|
75
76
|
- README.md
|
76
77
|
files:
|
77
78
|
- ".rspec"
|
78
79
|
- ".rubocop.yml"
|
80
|
+
- ".travis.yml"
|
79
81
|
- ".yardopts"
|
80
82
|
- CHANGELOG.md
|
81
83
|
- Gemfile
|
@@ -83,6 +85,9 @@ files:
|
|
83
85
|
- README.md
|
84
86
|
- Rakefile
|
85
87
|
- appveyor.yml
|
88
|
+
- bin/cubic.skm
|
89
|
+
- bin/hello-world.skm
|
90
|
+
- bin/skeem
|
86
91
|
- lib/skeem.rb
|
87
92
|
- lib/skeem/datum_dsl.rb
|
88
93
|
- lib/skeem/element_visitor.rb
|
@@ -94,10 +99,12 @@ files:
|
|
94
99
|
- lib/skeem/runtime.rb
|
95
100
|
- lib/skeem/s_expr_builder.rb
|
96
101
|
- lib/skeem/s_expr_nodes.rb
|
102
|
+
- lib/skeem/skeem_exception.rb
|
97
103
|
- lib/skeem/skm_binding.rb
|
98
104
|
- lib/skeem/skm_compound_datum.rb
|
99
105
|
- lib/skeem/skm_element.rb
|
100
106
|
- lib/skeem/skm_empty_list.rb
|
107
|
+
- lib/skeem/skm_exception.rb
|
101
108
|
- lib/skeem/skm_expression.rb
|
102
109
|
- lib/skeem/skm_frame.rb
|
103
110
|
- lib/skeem/skm_pair.rb
|
@@ -108,6 +115,7 @@ files:
|
|
108
115
|
- lib/skeem/tokenizer.rb
|
109
116
|
- lib/skeem/version.rb
|
110
117
|
- skeem.gemspec
|
118
|
+
- spec/skeem/add4.skm
|
111
119
|
- spec/skeem/datum_dsl_spec.rb
|
112
120
|
- spec/skeem/element_visitor_spec.rb
|
113
121
|
- spec/skeem/interpreter_spec.rb
|
@@ -132,7 +140,7 @@ homepage: https://github.com/famished-tiger/Skeem
|
|
132
140
|
licenses:
|
133
141
|
- MIT
|
134
142
|
metadata: {}
|
135
|
-
post_install_message:
|
143
|
+
post_install_message:
|
136
144
|
rdoc_options:
|
137
145
|
- --charset=UTF-8 --exclude="examples|spec"
|
138
146
|
require_paths:
|
@@ -141,15 +149,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
141
149
|
requirements:
|
142
150
|
- - ">="
|
143
151
|
- !ruby/object:Gem::Version
|
144
|
-
version:
|
152
|
+
version: 2.5.0
|
145
153
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
154
|
requirements:
|
147
155
|
- - ">="
|
148
156
|
- !ruby/object:Gem::Version
|
149
157
|
version: '0'
|
150
158
|
requirements: []
|
151
|
-
rubygems_version: 3.
|
152
|
-
signing_key:
|
159
|
+
rubygems_version: 3.1.4
|
160
|
+
signing_key:
|
153
161
|
specification_version: 4
|
154
162
|
summary: Skeem is an interpreter of a subset of the Scheme programming language. Scheme
|
155
163
|
is a descendent of the Lisp language.
|