skeem 0.2.16 → 0.2.20

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.
@@ -16,8 +16,13 @@ module Skeem
16
16
  # Delimiters: parentheses '(', ')'
17
17
  # Separators: comma
18
18
  class Tokenizer
19
+ # @return [StringScanner]
19
20
  attr_reader(:scanner)
21
+
22
+ # @return [Integer] Current line number
20
23
  attr_reader(:lineno)
24
+
25
+ # @return [Integer] Offset of start of current line
21
26
  attr_reader(:line_start)
22
27
 
23
28
  @@lexeme2name = {
@@ -53,7 +58,7 @@ module Skeem
53
58
  SYNTAX-RULES
54
59
  UNQUOTE
55
60
  UNQUOTE-SPLICING
56
- ].map { |x| [x, x] } .to_h
61
+ ].map { |x| [x, x.sub(/\*$/, '_STAR')] }.to_h
57
62
 
58
63
  class ScanError < StandardError; end
59
64
 
@@ -84,6 +89,8 @@ module Skeem
84
89
 
85
90
  private
86
91
 
92
+ # rubocop: disable Lint/DuplicateBranch
93
+
87
94
  def _next_token
88
95
  skip_intertoken_spaces
89
96
  curr_ch = scanner.peek(1)
@@ -109,7 +116,7 @@ module Skeem
109
116
  elsif (lexeme = scanner.scan(/[+-]?[0-9]+(?:\.[0-9]*)?(?:(?:e|E)[+-]?[0-9]+)?/))
110
117
  # Order dependency: must be tested after INTEGER case
111
118
  token = build_token('REAL', lexeme)
112
- elsif (lexeme = scanner.scan(/#(?:(?:true)|(?:false)|(?:u8)|[\\\(tfeiodx]|(?:\d+[=#]))/))
119
+ elsif (lexeme = scanner.scan(/#(?:(?:true)|(?:false)|(?:u8)|[\\(tfeiodx]|(?:\d+[=#]))/))
113
120
  token = cardinal_token(lexeme)
114
121
  elsif (lexeme = scanner.scan(/"(?:\\"|[^"])*"/)) # Double quotes literal?
115
122
  token = build_token('STRING_LIT', lexeme)
@@ -119,7 +126,7 @@ module Skeem
119
126
  token = build_token(tok_type, lexeme)
120
127
  elsif (lexeme = scanner.scan(/\|(?:[^|])*\|/)) # Vertical bar delimited
121
128
  token = build_token('IDENTIFIER', lexeme)
122
- elsif (lexeme = scanner.scan(/([\+\-])((?=\s|[|()";])|$)/))
129
+ elsif (lexeme = scanner.scan(/([+\-])((?=\s|[|()";])|$)/))
123
130
  # # R7RS peculiar identifiers case 1: isolated plus and minus as identifiers
124
131
  token = build_token('IDENTIFIER', lexeme)
125
132
  elsif (lexeme = scanner.scan(/[+-][a-zA-Z!$%&*\/:<=>?@^_~+-@][a-zA-Z0-9!$%&*+-.\/:<=>?@^_~+-]*/))
@@ -138,6 +145,8 @@ module Skeem
138
145
  return token
139
146
  end
140
147
 
148
+ # rubocop: enable Lint/DuplicateBranch
149
+
141
150
  =begin
142
151
  #u8( This introduces a bytevector constant (section 6.9).
143
152
  Bytevector constants are terminated by ) .
@@ -162,11 +171,10 @@ other literal data (section 2.4).
162
171
  if (lexeme = scanner.scan(/#\\/))
163
172
  if (lexeme = scanner.scan(/(?:alarm|backspace|delete|escape|newline|null|return|space|tab)/))
164
173
  token = build_token('CHAR', lexeme, :name)
165
- elsif (lexeme = scanner.scan(/[^x]/))
166
- token = build_token('CHAR', lexeme, :escaped)
167
174
  elsif (lexeme = scanner.scan(/x[0-9a-fA-F]+/))
168
175
  token = build_token('CHAR', lexeme, :hex_value)
169
- elsif (lexeme = scanner.scan(/x/))
176
+ else
177
+ lexeme = scanner.getch
170
178
  token = build_token('CHAR', lexeme, :escaped)
171
179
  end
172
180
  end
@@ -352,7 +360,6 @@ other literal data (section 2.4).
352
360
  end
353
361
 
354
362
  def skip_block_comment
355
- # require 'debug'
356
363
  scanner.skip(/#\|/)
357
364
  nesting_level = 1
358
365
  loop do
data/lib/skeem/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Skeem
4
- VERSION = '0.2.16'
4
+ VERSION = '0.2.20'
5
5
  end
data/skeem.gemspec CHANGED
@@ -10,6 +10,7 @@ module PkgExtending
10
10
  file_list = Dir[
11
11
  '.rubocop.yml',
12
12
  '.rspec',
13
+ '.travis.yml',
13
14
  '.yardopts',
14
15
  'appveyor.yml',
15
16
  'Gemfile',
@@ -23,7 +24,8 @@ module PkgExtending
23
24
  'lib/**/*.rb',
24
25
  'lib/**/*.skm',
25
26
  'spec/**/*.rb',
26
- 'spec/**/*.skm'
27
+ 'spec/**/*.skm',
28
+ 'spec/**/*.yml'
27
29
  ]
28
30
  aPackage.files = file_list
29
31
  aPackage.test_files = Dir['spec/**/*_spec.rb']
@@ -52,7 +54,7 @@ DESCR
52
54
  SUMMARY
53
55
  spec.homepage = 'https://github.com/famished-tiger/Skeem'
54
56
  spec.license = 'MIT'
55
- spec.required_ruby_version = '>= 2.3.0'
57
+ spec.required_ruby_version = '>= 2.5.0'
56
58
 
57
59
  spec.bindir = 'bin'
58
60
  spec.executables << 'skeem'
@@ -60,12 +62,10 @@ SUMMARY
60
62
  PkgExtending.pkg_files(spec)
61
63
  PkgExtending.pkg_documentation(spec)
62
64
  # Runtime dependencies
63
- spec.add_dependency 'rley', '~> 0.7'
65
+ spec.add_dependency 'rley', '~> 0.8.08'
64
66
 
65
67
  # Development dependencies
66
68
  spec.add_development_dependency 'bundler', '~> 2.0'
67
69
  spec.add_development_dependency 'rake', '~> 12.0'
68
70
  spec.add_development_dependency 'rspec', '~> 3.0'
69
-
70
-
71
71
  end
@@ -12,7 +12,9 @@ module Skeem
12
12
  let(:simple_datum) { integer 42 }
13
13
  let(:listener) do
14
14
  fake = double('fake-subscriber')
15
- fake.define_singleton_method(:accept_all) {}
15
+ fake.define_singleton_method(:accept_all) do
16
+ # Dummy block
17
+ end
16
18
  fake
17
19
  end
18
20
 
@@ -16,7 +16,7 @@ module Skeem
16
16
  end
17
17
 
18
18
  it 'could be initialized with a block argument' do
19
- expect { Interpreter.new { |interp| } }.not_to raise_error
19
+ expect { Interpreter.new(&:runtime) }.not_to raise_error
20
20
  end
21
21
 
22
22
  it 'should have a parser' do
@@ -67,6 +67,7 @@ module Skeem
67
67
  end
68
68
  end
69
69
 
70
+ # rubocop: disable Style/ExponentialNotation
70
71
  it 'should evaluate isolated real numbers' do
71
72
  samples = [
72
73
  ['0.0', 0.0],
@@ -80,6 +81,7 @@ module Skeem
80
81
  expect(result).to eq(predicted)
81
82
  end
82
83
  end
84
+ # rubocop: enable Style/ExponentialNotation
83
85
 
84
86
  it 'should evaluate isolated strings' do
85
87
  samples = [
@@ -31,7 +31,7 @@ SKEEM
31
31
 
32
32
  context 'Defining compound procedures:' do
33
33
  it 'should accept the definition of simple procedure with arity 1' do
34
- source = definition_set + "\n" + 'square'
34
+ source = "#{definition_set}\nsquare"
35
35
  result = subject.run(source)
36
36
 
37
37
  square = result.last
@@ -41,7 +41,7 @@ SKEEM
41
41
  end
42
42
 
43
43
  it 'should accept the definition of simple procedure with arity 2' do
44
- source = definition_set + "\n" + 'sum-of-squares'
44
+ source = "#{definition_set}\nsum-of-squares"
45
45
  result = subject.run(source)
46
46
 
47
47
  square = result.last
@@ -65,14 +65,14 @@ SKEEM
65
65
  end
66
66
 
67
67
  it 'should support the call to a simple procedure with arity 2' do
68
- source = definition_set + "\n" + '(sum-of-squares 3 4)'
68
+ source = "#{definition_set}\n(sum-of-squares 3 4)"
69
69
  result = subject.run(source)
70
70
 
71
71
  expect(result.last).to eq(25)
72
72
  end
73
73
 
74
74
  it 'should support the call to a nested lambda procedure' do
75
- source = definition_set + "\n" + '(f 5)'
75
+ source = "#{definition_set}\n(f 5)"
76
76
  result = subject.run(source)
77
77
 
78
78
  expect(result.last).to eq(136)
@@ -45,6 +45,7 @@ module Skeem
45
45
  end
46
46
  end
47
47
 
48
+ # rubocop: disable Style/ExponentialNotation
48
49
  it 'should parse isolated real numbers' do
49
50
  samples = [
50
51
  ['0.0', 0.0],
@@ -59,6 +60,7 @@ module Skeem
59
60
  expect(ptree.root.value).to eq(predicted)
60
61
  end
61
62
  end
63
+ # rubocop: enable Style/ExponentialNotation
62
64
 
63
65
  it 'should parse isolated strings' do
64
66
  samples = [
@@ -654,8 +654,8 @@ SKEEM
654
654
  ["(append '(a b) '(c d))", array2list_ids(%w[a b c d])],
655
655
  ["(append '(a b) '(c) 'd)", array2list_ids(%w[a b c d])],
656
656
  ["(append '(a (b)) '((c)))", [SkmIdentifier.create('a'),
657
- SkmPair.create_from_a(array2list_ids(['b'])),
658
- SkmPair.create_from_a(array2list_ids(['c']))]],
657
+ SkmPair.create_from_a(array2list_ids(['b'])),
658
+ SkmPair.create_from_a(array2list_ids(['c']))]],
659
659
  ["(append '() 'a)", SkmIdentifier.create('a')]
660
660
  ]
661
661
  compare_to_predicted(checks) do |result, expectation|
@@ -919,8 +919,8 @@ SKEEM
919
919
  result = subject.run(source)
920
920
  expect(result).to be_kind_of(SkmVector)
921
921
  expectation = [SkmInteger.create(0),
922
- SkmPair.new(SkmString.create('Sue'), SkmPair.new(SkmString.create('Sue'), SkmEmptyList.instance)),
923
- SkmString.create('Anna')]
922
+ SkmPair.new(SkmString.create('Sue'), SkmPair.new(SkmString.create('Sue'), SkmEmptyList.instance)),
923
+ SkmString.create('Anna')]
924
924
  expect(result).to eq(expectation)
925
925
 
926
926
  source = <<-SKEEM
@@ -1010,7 +1010,7 @@ SKEEM
1010
1010
  err = StandardError
1011
1011
  msg1 = 'Error: assertion failed on line 3, column 4'
1012
1012
  msg2 = 'with <Skeem::SkmBoolean: false>'
1013
- expect { subject.run(source) }.to raise_error(err, msg1 + ', ' + msg2)
1013
+ expect { subject.run(source) }.to raise_error(err, "#{msg1}, #{msg2}")
1014
1014
  end
1015
1015
  end # context
1016
1016
  end # describe
@@ -149,7 +149,7 @@ module Skeem
149
149
  expect(pproc.call(rtime, no_arg)).to eq(0)
150
150
 
151
151
  many = [SkmString.create('foo'), SkmString.create('bar'),
152
- SkmString.create('quux')]
152
+ SkmString.create('quux')]
153
153
  expect(pproc.call(rtime, many)).to eq(3)
154
154
  end
155
155
  end # context
@@ -96,11 +96,11 @@ module Skeem
96
96
 
97
97
  it 'should push a call to the stack call' do
98
98
  expect { subject.push_call(sample_call) }.not_to raise_error
99
- expect(subject.call_stack.size). to eq(1)
99
+ expect(subject.call_stack.size).to eq(1)
100
100
  expect(subject.caller).to eq(sample_call)
101
101
 
102
102
  subject.push_call(sample_call.clone)
103
- expect(subject.call_stack.size). to eq(2)
103
+ expect(subject.call_stack.size).to eq(2)
104
104
  end
105
105
 
106
106
  it 'should pop a call from the call stack' do
@@ -50,7 +50,7 @@ module Skeem
50
50
  it 'should return its text representation' do
51
51
  txt1 = '<Skeem::SkmCompoundDatum: <Skeem::SkmInteger: 1>,'
52
52
  txt2 = '<Skeem::SkmInteger: 2>, <Skeem::SkmInteger: 3>>'
53
- expect(subject.inspect).to eq(txt1 + ' ' + txt2)
53
+ expect(subject.inspect).to eq("#{txt1} #{txt2}")
54
54
  end
55
55
  end # context
56
56
 
@@ -37,7 +37,7 @@ module Skeem
37
37
 
38
38
  context 'Provided services:' do
39
39
  let(:runtime) { Runtime.new(SkmFrame.new) }
40
- let(:list_length_2) { SkmPair.new(integer(10), subject) }
40
+ let(:list_length2) { SkmPair.new(integer(10), subject) }
41
41
  let(:quirk_element) { double('three') }
42
42
  let(:quirk_members) { [integer(10), quirk_element] }
43
43
 
@@ -71,7 +71,7 @@ module Skeem
71
71
  expect(subject.length).to eq(1)
72
72
 
73
73
  # Use a list of length 2
74
- expect(list_length_2.length).to eq(2)
74
+ expect(list_length2.length).to eq(2)
75
75
  end
76
76
 
77
77
  it 'should respond false to `eqv?` message' do
@@ -113,7 +113,7 @@ module Skeem
113
113
  expect(subject.to_a).to eq([sample_car])
114
114
 
115
115
  # Use a list of length 2
116
- expect(list_length_2.to_a).to eq([integer(10), sample_car])
116
+ expect(list_length2.to_a).to eq([integer(10), sample_car])
117
117
  end
118
118
 
119
119
  it 'should return the last pair of a proper list' do
@@ -133,7 +133,7 @@ module Skeem
133
133
 
134
134
  it 'should return the last element of a list' do
135
135
  expect(subject.last).to eq(sample_car)
136
- expect(list_length_2.last).to eq(sample_car)
136
+ expect(list_length2.last).to eq(sample_car)
137
137
  end
138
138
 
139
139
  it 'should append a new element to a list' do
@@ -227,7 +227,7 @@ module Skeem
227
227
  expect(subject.inspect).to eq(predicted)
228
228
 
229
229
  predicted = '<Skeem::SkmPair: <Skeem::SkmInteger: 10>, <Skeem::SkmInteger: 3>>'
230
- expect(list_length_2.inspect).to eq(predicted)
230
+ expect(list_length2.inspect).to eq(predicted)
231
231
  end
232
232
  end # context
233
233
  end # describe
@@ -47,8 +47,8 @@ module Skeem
47
47
  tokens.each { |token| expect(token).to be_kind_of(Rley::Lexical::Token) }
48
48
  terminals = tokens.map(&:terminal)
49
49
  prediction = %w[LPAREN RPAREN APOSTROPHE
50
- GRAVE_ACCENT PERIOD
51
- COMMA COMMA_AT_SIGN ]
50
+ GRAVE_ACCENT PERIOD
51
+ COMMA COMMA_AT_SIGN ]
52
52
  expect(terminals).to eq(prediction)
53
53
  end
54
54
  end # context
@@ -129,6 +129,7 @@ module Skeem
129
129
  end # context
130
130
 
131
131
  context 'Real number recognition:' do
132
+ # rubocop: disable Style/ExponentialNotation
132
133
  it 'should tokenize real numbers' do
133
134
  tests = [
134
135
  # couple [raw input, expected]
@@ -140,6 +141,7 @@ module Skeem
140
141
 
141
142
  check_tokens(tests, 'REAL')
142
143
  end
144
+ # rubocop: enable Style/ExponentialNotation
143
145
  end # context
144
146
 
145
147
  context 'Character literal recognition:' do
data/spec/spec_helper.rb CHANGED
@@ -17,26 +17,29 @@ RSpec.configure do |config|
17
17
  config.full_backtrace = true
18
18
  end
19
19
 
20
+
20
21
  module InterpreterSpec
21
22
  def expect_expr(aSkeemExpr)
22
23
  result = subject.run(aSkeemExpr)
23
24
  expect(result)
24
25
  end
25
26
 
27
+ # rubocop: disable Lint/RescueException
28
+
26
29
  # This method assumes that 'subject' is a Skeem::Interpreter instance.
27
30
  def compare_to_predicted(arrActualsPredictions)
28
31
  arrActualsPredictions.each_with_index do |(source, predicted), index|
29
- begin
30
- result = subject.run(source)
31
- if block_given?
32
- yield result, predicted
33
- else
34
- expect(result).to eq(predicted)
35
- end
36
- rescue Exception => e
37
- $stderr.puts "Row #{index + 1} failed."
38
- throw e
32
+ result = subject.run(source)
33
+ if block_given?
34
+ yield result, predicted
35
+ else
36
+ expect(result).to eq(predicted)
39
37
  end
38
+
39
+ rescue Exception => e
40
+ $stderr.puts "Row #{index + 1} failed."
41
+ throw e
40
42
  end
41
43
  end
44
+ # rubocop: enable Lint/RescueException
42
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.16
4
+ version: 0.2.20
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: 2019-08-18 00:00:00.000000000 Z
11
+ date: 2021-11-01 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: '0.7'
19
+ version: 0.8.08
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: '0.7'
26
+ version: 0.8.08
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -77,6 +77,7 @@ extra_rdoc_files:
77
77
  files:
78
78
  - ".rspec"
79
79
  - ".rubocop.yml"
80
+ - ".travis.yml"
80
81
  - ".yardopts"
81
82
  - CHANGELOG.md
82
83
  - Gemfile
@@ -139,7 +140,7 @@ homepage: https://github.com/famished-tiger/Skeem
139
140
  licenses:
140
141
  - MIT
141
142
  metadata: {}
142
- post_install_message:
143
+ post_install_message:
143
144
  rdoc_options:
144
145
  - --charset=UTF-8 --exclude="examples|spec"
145
146
  require_paths:
@@ -148,15 +149,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
148
149
  requirements:
149
150
  - - ">="
150
151
  - !ruby/object:Gem::Version
151
- version: 2.3.0
152
+ version: 2.5.0
152
153
  required_rubygems_version: !ruby/object:Gem::Requirement
153
154
  requirements:
154
155
  - - ">="
155
156
  - !ruby/object:Gem::Version
156
157
  version: '0'
157
158
  requirements: []
158
- rubygems_version: 3.0.3
159
- signing_key:
159
+ rubygems_version: 3.1.4
160
+ signing_key:
160
161
  specification_version: 4
161
162
  summary: Skeem is an interpreter of a subset of the Scheme programming language. Scheme
162
163
  is a descendent of the Lisp language.