skeem 0.2.15 → 0.2.16

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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +17 -11
  3. data/CHANGELOG.md +5 -0
  4. data/Gemfile +2 -0
  5. data/README.md +3 -2
  6. data/Rakefile +2 -0
  7. data/appveyor.yml +3 -4
  8. data/bin/skeem +15 -15
  9. data/lib/skeem.rb +2 -0
  10. data/lib/skeem/datum_dsl.rb +12 -3
  11. data/lib/skeem/element_visitor.rb +5 -2
  12. data/lib/skeem/grammar.rb +86 -24
  13. data/lib/skeem/interpreter.rb +5 -3
  14. data/lib/skeem/parser.rb +6 -4
  15. data/lib/skeem/primitive/primitive_builder.rb +128 -115
  16. data/lib/skeem/primitive/primitive_procedure.rb +17 -20
  17. data/lib/skeem/runtime.rb +9 -5
  18. data/lib/skeem/s_expr_builder.rb +46 -104
  19. data/lib/skeem/s_expr_nodes.rb +116 -90
  20. data/lib/skeem/skeem_exception.rb +0 -0
  21. data/lib/skeem/skm_binding.rb +6 -7
  22. data/lib/skeem/skm_compound_datum.rb +8 -4
  23. data/lib/skeem/skm_element.rb +14 -12
  24. data/lib/skeem/skm_empty_list.rb +6 -4
  25. data/lib/skeem/skm_exception.rb +9 -0
  26. data/lib/skeem/skm_expression.rb +3 -1
  27. data/lib/skeem/skm_frame.rb +3 -2
  28. data/lib/skeem/skm_pair.rb +23 -18
  29. data/lib/skeem/skm_procedure_exec.rb +8 -6
  30. data/lib/skeem/skm_simple_datum.rb +13 -12
  31. data/lib/skeem/skm_unary_expression.rb +15 -17
  32. data/lib/skeem/tokenizer.rb +32 -25
  33. data/lib/skeem/version.rb +3 -1
  34. data/skeem.gemspec +6 -4
  35. data/spec/skeem/add4.skm +4 -0
  36. data/spec/skeem/datum_dsl_spec.rb +13 -12
  37. data/spec/skeem/element_visitor_spec.rb +12 -10
  38. data/spec/skeem/interpreter_spec.rb +74 -46
  39. data/spec/skeem/lambda_spec.rb +9 -7
  40. data/spec/skeem/parser_spec.rb +21 -19
  41. data/spec/skeem/primitive/primitive_builder_spec.rb +57 -48
  42. data/spec/skeem/primitive/primitive_procedure_spec.rb +15 -13
  43. data/spec/skeem/runtime_spec.rb +18 -16
  44. data/spec/skeem/s_expr_nodes_spec.rb +8 -6
  45. data/spec/skeem/skm_compound_datum_spec.rb +11 -9
  46. data/spec/skeem/skm_element_spec.rb +7 -5
  47. data/spec/skeem/skm_empty_list_spec.rb +7 -5
  48. data/spec/skeem/skm_frame_spec.rb +5 -4
  49. data/spec/skeem/skm_pair_spec.rb +4 -3
  50. data/spec/skeem/skm_procedure_exec_spec.rb +2 -0
  51. data/spec/skeem/skm_simple_datum_spec.rb +24 -22
  52. data/spec/skeem/skm_unary_expression_spec.rb +11 -9
  53. data/spec/skeem/tokenizer_spec.rb +53 -44
  54. data/spec/skeem_spec.rb +2 -0
  55. data/spec/spec_helper.rb +4 -2
  56. metadata +7 -4
File without changes
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'skm_element'
2
4
 
3
5
  module Skeem
4
-
5
6
  # An identifier that is not a syntactic keyword can be used as a variable.
6
7
  # A variable may give a name to value that is bound (i.e. associated)
7
8
  # to that variable.
@@ -56,26 +57,24 @@ module Skeem
56
57
 
57
58
  result
58
59
  end
59
-
60
60
  end # class
61
61
 
62
62
 
63
63
  class SkmUpdateBinding < SkmBinding
64
-
65
64
  protected
66
65
 
67
66
  def binding_action(aRuntime, anIdentifier, anExpression)
68
67
  aRuntime.update_binding(anIdentifier, anExpression)
69
68
  end
70
69
  end # class
71
-
70
+
72
71
  class SkmDelayedUpdateBinding < SkmBinding
73
72
  attr_reader :new_val
74
-
73
+
75
74
  def initialize(anIdentifier, aValue)
76
75
  super(anIdentifier, aValue)
77
76
  end
78
-
77
+
79
78
  def do_it!(aRuntime)
80
79
  aRuntime.update_binding(variable, new_val)
81
80
  end
@@ -85,5 +84,5 @@ module Skeem
85
84
  def binding_action(_runtime, _identifier, anExpression)
86
85
  @new_val = anExpression
87
86
  end
88
- end # class
87
+ end # class
89
88
  end # module
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'forwardable'
2
4
  require_relative 'skm_element'
3
5
 
@@ -18,13 +20,15 @@ module Skeem
18
20
  end
19
21
 
20
22
  def ==(other)
21
- return true if self.equal?(other)
23
+ return true if equal?(other)
24
+
22
25
  result = case other
23
26
  when SkmCompoundDatum
24
- self.class == other.class && self.members == other.members
27
+ self.class == other.class && members == other.members
25
28
  when Array
26
29
  members == other
27
30
  end
31
+ result
28
32
  end
29
33
 
30
34
  alias eqv? equal?
@@ -65,7 +69,7 @@ module Skeem
65
69
  protected
66
70
 
67
71
  def inspect_specific
68
- result = ''
72
+ result = +''
69
73
  members.each { |elem| result << elem.inspect + ', ' }
70
74
  result.sub!(/, $/, '')
71
75
  result
@@ -77,4 +81,4 @@ module Skeem
77
81
  true
78
82
  end
79
83
  end # class
80
- end # module
84
+ end # module
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Skeem
2
4
  # Abstract class. Generalization of any S-expr element.
3
5
  SkmElement = Struct.new(:position) do
4
6
  def initialize(aPosition)
5
7
  self.position = aPosition
6
8
  end
7
-
9
+
8
10
  def callable?
9
11
  false
10
12
  end
@@ -12,15 +14,15 @@ module Skeem
12
14
  def number?
13
15
  false
14
16
  end
15
-
17
+
16
18
  def complex?
17
19
  false
18
- end
20
+ end
19
21
 
20
22
  def real?
21
23
  false
22
24
  end
23
-
25
+
24
26
  def rational?
25
27
  false
26
28
  end
@@ -32,7 +34,7 @@ module Skeem
32
34
  def boolean?
33
35
  false
34
36
  end
35
-
37
+
36
38
  def char?
37
39
  false
38
40
  end
@@ -56,7 +58,7 @@ module Skeem
56
58
  def pair?
57
59
  false
58
60
  end
59
-
61
+
60
62
  def procedure?
61
63
  false
62
64
  end
@@ -73,11 +75,11 @@ module Skeem
73
75
  msg = "Missing implementation of method #{self.class.name}##{__method__}"
74
76
  raise NotImplementedError, msg
75
77
  end
76
-
78
+
77
79
  def skm_eq?(other)
78
80
  # Default implementation, to override when necessary
79
- self.eqv?(other)
80
- end
81
+ eqv?(other)
82
+ end
81
83
 
82
84
  # @return [TrueClass, FalseClass] true if quoted element is identical to itself
83
85
  def verbatim?
@@ -117,8 +119,8 @@ module Skeem
117
119
  # Do nothing
118
120
  end
119
121
 
120
- def inspect
121
- result = inspect_prefix
122
+ def inspect
123
+ result = inspect_prefix.dup
122
124
  result << inspect_specific
123
125
  result << inspect_suffix
124
126
 
@@ -139,4 +141,4 @@ module Skeem
139
141
  raise NotImplementedError, "Missing #{self.class.to_s + '#' + 'inspect_specific'}"
140
142
  end
141
143
  end # struct
142
- end # module
144
+ end # module
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'singleton'
2
4
  require_relative 'skm_element'
3
5
 
@@ -42,7 +44,7 @@ module Skeem
42
44
  def klone
43
45
  self
44
46
  end
45
-
47
+
46
48
  def append_list(aList)
47
49
  aList
48
50
  end
@@ -64,14 +66,14 @@ module Skeem
64
66
  protected
65
67
 
66
68
  def inspect_specific
67
- '()'
69
+ +'()'
68
70
  end
69
71
 
70
72
  private
71
73
 
72
- def initialize()
74
+ def initialize
73
75
  super(0)
74
- self.freeze
76
+ freeze
75
77
  end
76
78
  end # class
77
79
  end # module
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Skeem
4
+ class SkmException < RuntimeError
5
+ end # class
6
+
7
+ class SkmError < SkmException
8
+ end # class
9
+ end # module
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'skm_element'
2
4
 
3
5
  module Skeem
4
6
  # Abstract class.
5
7
  class SkmExpression < SkmElement
6
8
  end # class
7
- end # module
9
+ end # module
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'skm_simple_datum'
2
4
 
3
5
  module Skeem
@@ -139,6 +141,5 @@ module Skeem
139
141
  # Notify the value that it is bound to a variable from this frame.
140
142
  anExpression.bound!(self)
141
143
  end
142
-
143
144
  end # class
144
- end # module
145
+ end # module
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'skm_empty_list'
2
4
 
3
5
  module Skeem
@@ -41,11 +43,12 @@ module Skeem
41
43
  def self.create_from_a(anArray)
42
44
  current = nil
43
45
  return SkmEmptyList.instance if anArray.empty?
46
+
44
47
  anArray.reverse_each do |elem|
45
48
  if current.nil?
46
- current = self.new(elem, SkmEmptyList.instance)
49
+ current = new(elem, SkmEmptyList.instance)
47
50
  else
48
- current = self.new(elem, current)
51
+ current = new(elem, current)
49
52
  end
50
53
  end
51
54
 
@@ -54,6 +57,7 @@ module Skeem
54
57
 
55
58
  def empty?
56
59
  return false if car
60
+
57
61
  if [SkmPair, SkmEmptyList].include? cdr.class
58
62
  cdr.empty?
59
63
  else
@@ -92,20 +96,20 @@ module Skeem
92
96
  end
93
97
 
94
98
  def last_pair
95
- if cdr.nil? || (cdr == SkmEmptyList.instance) || (!cdr.kind_of?(SkmPair))
99
+ if cdr.nil? || (cdr == SkmEmptyList.instance) || !cdr.kind_of?(SkmPair)
96
100
  self
97
101
  else
98
102
  cdr.last_pair
99
103
  end
100
104
  end
101
-
105
+
102
106
  def proper?
103
- last_node = self.last_pair
107
+ last_node = last_pair
104
108
  last_node.cdr.nil? || (last_node.cdr == SkmEmptyList.instance)
105
109
  end
106
110
 
107
111
  def last
108
- self.to_a.last
112
+ to_a.last
109
113
  end
110
114
 
111
115
  def eqv?(_other)
@@ -138,7 +142,7 @@ module Skeem
138
142
  end
139
143
 
140
144
  def append(anElement)
141
- last_one = self.last_pair
145
+ last_one = last_pair
142
146
  if last_one.cdr.nil? || last_one.cdr.kind_of?(SkmEmptyList)
143
147
  last_one.cdr = SkmPair.new(anElement, SkmEmptyList.instance)
144
148
  else
@@ -147,7 +151,7 @@ module Skeem
147
151
  end
148
152
 
149
153
  def append_list(aList)
150
- last_one = self.last_pair
154
+ last_one = last_pair
151
155
  if last_one.cdr.nil? || last_one.cdr.kind_of?(SkmEmptyList)
152
156
  last_one.cdr = aList
153
157
  else
@@ -157,22 +161,23 @@ module Skeem
157
161
 
158
162
  def evaluate(aRuntime)
159
163
  return SkmEmptyList.instance if empty?
164
+
160
165
  if car.kind_of?(SkmIdentifier) && car.is_var_name
161
166
  result = aRuntime.evaluate_form(self)
162
167
  else
163
168
  begin
164
169
  result = clone_evaluate(aRuntime)
165
- rescue NoMethodError => exc
166
- $stderr.puts 'SkmPair#evaluate: ' + self.inspect
167
- $stderr.puts 'SkmPair as Array: ' + self.to_a.inspect
168
- raise exc
170
+ rescue NoMethodError => e
171
+ $stderr.puts 'SkmPair#evaluate: ' + inspect
172
+ $stderr.puts 'SkmPair as Array: ' + to_a.inspect
173
+ raise e
169
174
  end
170
175
  end
171
176
  result
172
177
  end
173
178
 
174
179
  def quasiquote(aRuntime)
175
- members_eval = self.to_a.map { |elem| elem.quasiquote(aRuntime) }
180
+ members_eval = to_a.map { |elem| elem.quasiquote(aRuntime) }
176
181
  self.class.create_from_a(members_eval)
177
182
  end
178
183
 
@@ -184,16 +189,17 @@ module Skeem
184
189
 
185
190
  def quoted!
186
191
  car.quoted!
187
- cdr.quoted! if cdr
192
+ cdr&.quoted!
188
193
  end
189
194
 
190
195
  def unquoted!
191
196
  car.unquoted!
192
- cdr.unquoted! if cdr
197
+ cdr&.unquoted!
193
198
  end
194
199
 
195
- def verbatim?()
200
+ def verbatim?
196
201
  return false unless car.verbatim?
202
+
197
203
  if cdr.nil?
198
204
  true
199
205
  else
@@ -211,6 +217,5 @@ module Skeem
211
217
 
212
218
  result
213
219
  end
214
-
215
220
  end # class
216
- end # module
221
+ end # module
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'runtime'
2
4
 
3
5
  module Skeem
@@ -27,18 +29,18 @@ module Skeem
27
29
  result = definition.evaluate_sequence(runtime)
28
30
  runtime.pop
29
31
  # $stderr.puts "Lambda result: #{result.object_id.to_s(16)}" if result.kind_of?(SkmLambda)
30
-
32
+
31
33
  result
32
34
  end
33
-
35
+
34
36
  private
35
-
37
+
36
38
  def evaluate_defs(aRuntime)
37
39
  definition.definitions.each do |bndng|
38
- val = bndng.value.evaluate(aRuntime)
40
+ val = bndng.value.evaluate(aRuntime)
39
41
  var = bndng.variable.evaluate(aRuntime)
40
42
  frame.add_binding(var, val)
41
- end
43
+ end
42
44
  end
43
45
  end # class
44
- end # module
46
+ end # module
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'skm_element'
2
4
 
3
5
  module Skeem
@@ -14,7 +16,7 @@ module Skeem
14
16
  end
15
17
 
16
18
  def self.create(aValue)
17
- lightweight = self.allocate
19
+ lightweight = allocate
18
20
  lightweight.init_value(aValue)
19
21
  return lightweight
20
22
  end
@@ -33,12 +35,12 @@ module Skeem
33
35
  # @param other [SkmSimpleDatum, Object] object to compare with.
34
36
  # @return [TrueClass, FalseClass]
35
37
  def ==(other)
36
- return true if self.equal?(other)
38
+ return true if equal?(other)
37
39
 
38
40
  result = if other.kind_of?(SkmSimpleDatum)
39
- self.value == other.value
41
+ value == other.value
40
42
  else
41
- self.value == other
43
+ value == other
42
44
  end
43
45
 
44
46
  result
@@ -51,7 +53,7 @@ module Skeem
51
53
  true
52
54
  end
53
55
 
54
- def done!()
56
+ def done!
55
57
  # Do nothing
56
58
  end
57
59
 
@@ -103,16 +105,16 @@ module Skeem
103
105
  end
104
106
 
105
107
  def eqv?(other)
106
- return true if self.equal?(other)
108
+ return true if equal?(other)
107
109
 
108
110
  result = if other.kind_of?(SkmNumber)
109
- if self.exact? != other.exact?
111
+ if exact? != other.exact?
110
112
  false
111
113
  else
112
- self.value == other.value
114
+ value == other.value
113
115
  end
114
116
  else
115
- self.value == other
117
+ value == other
116
118
  end
117
119
 
118
120
  result
@@ -159,7 +161,6 @@ module Skeem
159
161
  char_value = int_value < 0xff ? int_value.chr : [int_value].pack('U')
160
162
  create(char_value)
161
163
  end
162
-
163
164
  end # class
164
165
 
165
166
  class SkmString < SkmSimpleDatum
@@ -199,7 +200,7 @@ module Skeem
199
200
  end
200
201
 
201
202
  def verbatim?
202
- not is_var_name
203
+ !is_var_name
203
204
  end
204
205
 
205
206
  def quoted!
@@ -213,4 +214,4 @@ module Skeem
213
214
 
214
215
  class SkmReserved < SkmIdentifier
215
216
  end # class
216
- end # module
217
+ end # module