skeem 0.2.17 → 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.
@@ -138,7 +138,7 @@ module Skeem
138
138
  end
139
139
 
140
140
  def inspect_specific
141
- raise NotImplementedError, "Missing #{self.class.to_s + '#' + 'inspect_specific'}"
141
+ raise NotImplementedError, "Missing #{self.class}#inspect_specific"
142
142
  end
143
143
  end # struct
144
144
  end # module
@@ -4,7 +4,10 @@ require_relative 'skm_empty_list'
4
4
 
5
5
  module Skeem
6
6
  class SkmPair < SkmElement
7
+ # @return [SkmElement]
7
8
  attr_accessor :car
9
+
10
+ # @return [SkmElement]
8
11
  attr_accessor :cdr
9
12
 
10
13
  alias first car
@@ -168,8 +171,8 @@ module Skeem
168
171
  begin
169
172
  result = clone_evaluate(aRuntime)
170
173
  rescue NoMethodError => e
171
- $stderr.puts 'SkmPair#evaluate: ' + inspect
172
- $stderr.puts 'SkmPair as Array: ' + to_a.inspect
174
+ $stderr.puts "SkmPair#evaluate: #{inspect}"
175
+ $stderr.puts "SkmPair as Array: #{to_a.inspect}"
173
176
  raise e
174
177
  end
175
178
  end
@@ -4,7 +4,10 @@ require_relative 'runtime'
4
4
 
5
5
  module Skeem
6
6
  class SkmProcedureExec
7
+ # @return [SkmFrame]
7
8
  attr_reader :frame
9
+
10
+ # @return [SkmLambda]
8
11
  attr_reader :definition
9
12
 
10
13
  def initialize(aLambda)
@@ -6,7 +6,10 @@ module Skeem
6
6
  # Abstract class. Root of class hierarchy needed for Interpreter
7
7
  # design pattern
8
8
  class SkmSimpleDatum < SkmElement
9
+ # @return [Rley::Syntax::Token] token object corresponding to Skeem element
9
10
  attr_reader :token
11
+
12
+ # @return [Object]
10
13
  attr_reader :value
11
14
 
12
15
  def initialize(aToken, aPosition)
@@ -37,13 +40,11 @@ module Skeem
37
40
  def ==(other)
38
41
  return true if equal?(other)
39
42
 
40
- result = if other.kind_of?(SkmSimpleDatum)
41
- value == other.value
42
- else
43
- value == other
44
- end
45
-
46
- result
43
+ if other.kind_of?(SkmSimpleDatum)
44
+ value == other.value
45
+ else
46
+ value == other
47
+ end
47
48
  end
48
49
 
49
50
  alias eqv? ==
@@ -104,10 +105,12 @@ module Skeem
104
105
  false
105
106
  end
106
107
 
108
+ # rubocop: disable Style/NegatedIfElseCondition
109
+
107
110
  def eqv?(other)
108
111
  return true if equal?(other)
109
112
 
110
- result = if other.kind_of?(SkmNumber)
113
+ if other.kind_of?(SkmNumber)
111
114
  if exact? != other.exact?
112
115
  false
113
116
  else
@@ -116,9 +119,8 @@ module Skeem
116
119
  else
117
120
  value == other
118
121
  end
119
-
120
- result
121
122
  end
123
+ # rubocop: enable Style/NegatedIfElseCondition
122
124
  end # class
123
125
 
124
126
  class SkmReal < SkmNumber
@@ -76,8 +76,7 @@ module Skeem
76
76
  end
77
77
 
78
78
  def quasiquote(aRuntime)
79
- result = evaluate(aRuntime)
80
- result
79
+ evaluate(aRuntime)
81
80
  end
82
81
 
83
82
  protected
@@ -115,7 +114,10 @@ module Skeem
115
114
  class SkmBindingBlock < SkmUnaryExpression
116
115
  alias body child
117
116
 
117
+ # @return [Symbol] One of: :let, :let_star
118
118
  attr_reader :kind
119
+
120
+ # @return [Array<SkmBinding>]
119
121
  attr_reader :bindings
120
122
 
121
123
  def initialize(theKind, theBindings, aBody)
@@ -126,14 +128,15 @@ module Skeem
126
128
 
127
129
  def evaluate(aRuntime)
128
130
  aRuntime.push(SkmFrame.new(aRuntime.environment))
129
- if kind == :let
131
+ case kind
132
+ when :let
130
133
  locals = bindings.map do |bnd|
131
134
  SkmBinding.new(bnd.variable, bnd.value.evaluate(aRuntime))
132
135
  end
133
136
  locals.each do |bnd|
134
137
  aRuntime.add_binding(bnd.variable.evaluate(aRuntime), bnd.value)
135
138
  end
136
- elsif kind == :let_star
139
+ when :let_star
137
140
  bindings.each do |bnd|
138
141
  val = bnd.value.evaluate(aRuntime)
139
142
  aRuntime.add_binding(bnd.variable.evaluate(aRuntime), val)
@@ -186,18 +189,16 @@ module Skeem
186
189
  def eval_pair(aRuntime)
187
190
  result = nil
188
191
  sequence.to_a.each do |cmd|
189
- begin
190
- if cmd.kind_of?(SkmLambda)
191
- result = cmd.dup_cond(aRuntime)
192
- else
193
- result = cmd.evaluate(aRuntime)
194
- end
195
- rescue NoMethodError => e
196
- $stderr.puts inspect
197
- $stderr.puts sequence.inspect
198
- $stderr.puts cmd.inspect
199
- raise e
192
+ if cmd.kind_of?(SkmLambda)
193
+ result = cmd.dup_cond(aRuntime)
194
+ else
195
+ result = cmd.evaluate(aRuntime)
200
196
  end
197
+ rescue NoMethodError => e
198
+ $stderr.puts inspect
199
+ $stderr.puts sequence.inspect
200
+ $stderr.puts cmd.inspect
201
+ raise e
201
202
  end
202
203
 
203
204
  result
@@ -215,18 +216,16 @@ module Skeem
215
216
 
216
217
  if sequence[:sequence].kind_of?(SkmPair)
217
218
  sequence[:sequence].to_a.each do |cmd|
218
- begin
219
- if cmd.kind_of?(SkmLambda)
220
- result = cmd.dup_cond(aRuntime)
221
- else
222
- result = cmd.evaluate(aRuntime)
223
- end
224
- rescue NoMethodError => e
225
- $stderr.puts inspect
226
- $stderr.puts sequence[:sequence].inspect
227
- $stderr.puts cmd.inspect
228
- raise e
219
+ if cmd.kind_of?(SkmLambda)
220
+ result = cmd.dup_cond(aRuntime)
221
+ else
222
+ result = cmd.evaluate(aRuntime)
229
223
  end
224
+ rescue NoMethodError => e
225
+ $stderr.puts inspect
226
+ $stderr.puts sequence[:sequence].inspect
227
+ $stderr.puts cmd.inspect
228
+ raise e
230
229
  end
231
230
  else
232
231
  result = sequence.evaluate(aRuntime)
@@ -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
 
@@ -162,11 +167,10 @@ other literal data (section 2.4).
162
167
  if (lexeme = scanner.scan(/#\\/))
163
168
  if (lexeme = scanner.scan(/(?:alarm|backspace|delete|escape|newline|null|return|space|tab)/))
164
169
  token = build_token('CHAR', lexeme, :name)
165
- elsif (lexeme = scanner.scan(/[^x]/))
166
- token = build_token('CHAR', lexeme, :escaped)
167
170
  elsif (lexeme = scanner.scan(/x[0-9a-fA-F]+/))
168
171
  token = build_token('CHAR', lexeme, :hex_value)
169
- elsif (lexeme = scanner.scan(/x/))
172
+ else
173
+ lexeme = scanner.getch
170
174
  token = build_token('CHAR', lexeme, :escaped)
171
175
  end
172
176
  end
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.17'
4
+ VERSION = '0.2.18'
5
5
  end
data/skeem.gemspec CHANGED
@@ -24,7 +24,8 @@ module PkgExtending
24
24
  'lib/**/*.rb',
25
25
  'lib/**/*.skm',
26
26
  'spec/**/*.rb',
27
- 'spec/**/*.skm'
27
+ 'spec/**/*.skm',
28
+ 'spec/**/*.yml'
28
29
  ]
29
30
  aPackage.files = file_list
30
31
  aPackage.test_files = Dir['spec/**/*_spec.rb']
@@ -53,7 +54,7 @@ DESCR
53
54
  SUMMARY
54
55
  spec.homepage = 'https://github.com/famished-tiger/Skeem'
55
56
  spec.license = 'MIT'
56
- spec.required_ruby_version = '>= 2.3.0'
57
+ spec.required_ruby_version = '>= 2.5.0'
57
58
 
58
59
  spec.bindir = 'bin'
59
60
  spec.executables << 'skeem'
@@ -61,7 +62,7 @@ SUMMARY
61
62
  PkgExtending.pkg_files(spec)
62
63
  PkgExtending.pkg_documentation(spec)
63
64
  # Runtime dependencies
64
- spec.add_dependency 'rley', '~> 0.7'
65
+ spec.add_dependency 'rley', '~> 0.8.03'
65
66
 
66
67
  # Development dependencies
67
68
  spec.add_development_dependency 'bundler', '~> 2.0'
@@ -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
@@ -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