skeem 0.2.15 → 0.2.16

Sign up to get free protection for your applications and to get access to all the features.
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