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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../s_expr_nodes'
2
4
 
3
5
  module Skeem
@@ -17,7 +19,7 @@ module Skeem
17
19
  def callable?
18
20
  true
19
21
  end
20
-
22
+
21
23
  def procedure?
22
24
  true
23
25
  end
@@ -76,10 +78,8 @@ module Skeem
76
78
  if (anArity.low + 2) != count_param
77
79
  discrepancy_arity_argument_count(anArity.low, count_param, 2)
78
80
  end
79
- else # fixed arity...
80
- if (anArity.high + 1) != count_param
81
- discrepancy_arity_argument_count(anArity.high, count_param, 1)
82
- end
81
+ elsif (anArity.high + 1) != count_param # fixed arity...
82
+ discrepancy_arity_argument_count(anArity.high, count_param, 1)
83
83
  end
84
84
 
85
85
  anArity
@@ -102,10 +102,8 @@ module Skeem
102
102
  if count_actuals > arity.high
103
103
  wrong_number_arguments(arity.high, count_actuals)
104
104
  end
105
- else # fixed non-zero arity...
106
- if count_actuals != arity.high
107
- wrong_number_arguments(arity.high, count_actuals)
108
- end
105
+ elsif count_actuals != arity.high # fixed non-zero arity...
106
+ wrong_number_arguments(arity.high, count_actuals)
109
107
  end
110
108
  end
111
109
 
@@ -114,11 +112,11 @@ module Skeem
114
112
  result = code.call(aRuntime)
115
113
  elsif arity.variadic? || (arity.low < arity.high)
116
114
  if arity.low.zero?
117
- if ['and', 'or', 'append'].include? identifier
115
+ if %w[and or append].include? identifier
118
116
  # Defer the evaluation of arguments to the primitive
119
117
  result = code.call(aRuntime, operands)
120
118
  else
121
- evaluated_args = operands.map {|opernd| opernd.evaluate(aRuntime) }
119
+ evaluated_args = operands.map { |opernd| opernd.evaluate(aRuntime) }
122
120
  result = code.call(aRuntime, evaluated_args)
123
121
  end
124
122
  else
@@ -134,14 +132,13 @@ module Skeem
134
132
  # p args.inspect
135
133
  result = code.send(:call, aRuntime, *args)
136
134
  end
137
- else # Fixed arity...
138
- if identifier.value =~ /^set-[a-zA-Z]+!/ || identifier.value =~ /[a-zA-Z]+-set!/
139
- # Defer evaluation inside the primitive
140
- result = code.send(:call, aRuntime, *operands)
141
- else
142
- evaluated_args = operands.map {|opernd| opernd.evaluate(aRuntime) }
143
- result = code.send(:call, aRuntime, *evaluated_args)
144
- end
135
+ elsif identifier.value =~ /^set-[a-zA-Z]+!/ || identifier.value =~ /[a-zA-Z]+-set!/
136
+ # Fixed arity...
137
+ # Defer evaluation inside the primitive
138
+ result = code.send(:call, aRuntime, *operands)
139
+ else
140
+ evaluated_args = operands.map { |opernd| opernd.evaluate(aRuntime) }
141
+ result = code.send(:call, aRuntime, *evaluated_args)
145
142
  end
146
143
 
147
144
  result
@@ -166,4 +163,4 @@ module Skeem
166
163
  end
167
164
  end # class
168
165
  end # module
169
- end # module
166
+ end # module
data/lib/skeem/runtime.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 's_expr_nodes'
2
4
 
3
5
  module Skeem
@@ -41,13 +43,12 @@ module Skeem
41
43
  result = nil
42
44
  begin
43
45
  result = entry.evaluate(self)
44
-
45
- rescue NoMethodError => exc
46
+ rescue NoMethodError => e
46
47
  # $stderr.puts 'In rescue block'
47
48
  # $stderr.puts key_value.inspect
48
49
  # $stderr.puts entry.inspect
49
50
  # $stderr.puts entry.expression.inspect
50
- raise exc
51
+ raise e
51
52
  end
52
53
  result
53
54
  else
@@ -66,13 +67,14 @@ module Skeem
66
67
  invokation.evaluate(self)
67
68
  end
68
69
 
69
- def nest()
70
+ def nest
70
71
  nested = SkmFrame.new(environment)
71
72
  push(nested)
72
73
  end
73
74
 
74
75
  def unnest
75
76
  raise StandardError, 'Cannot unnest environment' unless environment.parent
77
+
76
78
  environment.bindings.clear
77
79
  pop
78
80
  end
@@ -90,6 +92,7 @@ module Skeem
90
92
  if env_stack.empty?
91
93
  raise StandardError, 'Skeem environment stack empty!'
92
94
  end
95
+
93
96
  env_stack.pop
94
97
  end
95
98
 
@@ -110,6 +113,7 @@ module Skeem
110
113
  if call_stack.empty?
111
114
  raise StandardError, 'Skeem call stack empty!'
112
115
  end
116
+
113
117
  call_stack.pop
114
118
  end
115
119
 
@@ -132,4 +136,4 @@ module Skeem
132
136
  result
133
137
  end
134
138
  end # class
135
- end # module
139
+ end # module
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'stringio'
2
4
  require_relative 'skm_pair'
3
5
  require_relative 'skm_binding'
@@ -43,11 +45,23 @@ module Skeem
43
45
  def reduce_main(_production, _range, _tokens, theChildren)
44
46
  last_child = theChildren.last
45
47
  # $stderr.puts last_child.inspect
46
- result = if last_child.length == 1
47
- last_child.car
48
- else
49
- last_child
50
- end
48
+ if last_child.length == 1
49
+ last_child.car
50
+ else
51
+ last_child
52
+ end
53
+ end
54
+
55
+ # Default semantic action for rules of the form:
56
+ # rule 'some_symbol_star' => 'some_symbol_star some_symbol'
57
+ def reduce_star_default(_production, _range, _tokens, theChildren)
58
+ theChildren[0] << theChildren[1]
59
+ end
60
+
61
+ # Default semantic action for rules of the form:
62
+ # rule 'some_symbol_star' => []
63
+ def reduce_star_base(_production, _range, _tokens, _children)
64
+ []
51
65
  end
52
66
 
53
67
  # rule('cmd_or_def_plus' => 'cmd_or_def_plus cmd_or_def').as 'multiple_cmd_def'
@@ -81,7 +95,7 @@ module Skeem
81
95
  end
82
96
 
83
97
  # rule('definition' => 'LPAREN BEGIN definition_star RPAREN').as 'definitions_within_begin'
84
- def reduce_definitions_within_begin(_production, aRange, _tokens, theChildren)
98
+ def reduce_definitions_within_begin(_production, _range, _tokens, theChildren)
85
99
  SkmSequencingBlock.new(SkmPair.create_from_a(theChildren[2]))
86
100
  end
87
101
 
@@ -135,20 +149,10 @@ module Skeem
135
149
  end
136
150
 
137
151
  # rule('vector' => 'VECTOR_BEGIN datum_star RPAREN').as 'vector'
138
- def reduce_vector(_production, aRange, _tokens, theChildren)
152
+ def reduce_vector(_production, _range, _tokens, theChildren)
139
153
  SkmVector.new(theChildren[1])
140
154
  end
141
155
 
142
- # rule('datum_star' => 'datum_star datum').as 'datum_star'
143
- def reduce_datum_star(_production, aRange, _tokens, theChildren)
144
- theChildren[0] << theChildren[1]
145
- end
146
-
147
- # rule('datum_star' => []).as 'no_datum_yet'
148
- def reduce_no_datum_yet(_production, aRange, _tokens, theChildren)
149
- []
150
- end
151
-
152
156
  # rule('procedure_call' => 'LPAREN operator RPAREN').as 'proc_call_nullary'
153
157
  def reduce_proc_call_nullary(_production, aRange, _tokens, theChildren)
154
158
  ProcedureCall.new(aRange, theChildren[1], [])
@@ -174,11 +178,6 @@ module Skeem
174
178
  [theChildren.last]
175
179
  end
176
180
 
177
- # rule('operand_plus' => 'operand').as 'last_operand'
178
- def reduce_last_operand(_production, _range, _tokens, theChildren)
179
- [theChildren.last]
180
- end
181
-
182
181
  # rule('def_formals' => 'identifier_star').as 'def_formals'
183
182
  def reduce_def_formals(_production, _range, _tokens, theChildren)
184
183
  SkmFormals.new(theChildren[0], :fixed)
@@ -213,16 +212,6 @@ module Skeem
213
212
  SkmFormals.new(formals, :variadic)
214
213
  end
215
214
 
216
- # rule('identifier_star' => 'identifier_star IDENTIFIER').as 'identifier_star'
217
- def reduce_identifier_star(_production, _range, _tokens, theChildren)
218
- theChildren[0] << theChildren[1]
219
- end
220
-
221
- # rule('identifier_star' => []).as 'no_identifier_yet'
222
- def reduce_no_identifier_yet(_production, _range, _tokens, theChildren)
223
- []
224
- end
225
-
226
215
  # rule('identifier_plus' => 'identifier_plus IDENTIFIER').as 'multiple_identifiers'
227
216
  def reduce_multiple_identifiers(_production, _range, _tokens, theChildren)
228
217
  theChildren[0] << theChildren[1]
@@ -239,32 +228,11 @@ module Skeem
239
228
  { defs: definitions, sequence: theChildren[1] }
240
229
  end
241
230
 
242
- # rule('definition_star' => 'definition_star definition').as 'definition_star'
243
- def reduce_definition_star(_production, _range, _tokens, theChildren)
244
- theChildren[0] << theChildren[1]
245
- end
246
-
247
-
248
- # rule('definition_star' => []).as 'no_definition_yet'
249
- def reduce_no_definition_yet(_production, _range, _tokens, theChildren)
250
- []
251
- end
252
-
253
231
  # rule('sequence' => 'command_star expression').as 'sequence'
254
232
  def reduce_sequence(_production, _range, _tokens, theChildren)
255
233
  SkmPair.create_from_a(theChildren[0] << theChildren[1])
256
234
  end
257
235
 
258
- # rule('command_star' => 'command_star command').as 'multiple_commands'
259
- def reduce_multiple_commands(_production, _range, _tokens, theChildren)
260
- theChildren[0] << theChildren[1]
261
- end
262
-
263
- # rule('command_star' => []).as 'no_command_yet'
264
- def reduce_no_command_yet(_production, _range, _tokens, theChildren)
265
- []
266
- end
267
-
268
236
  # rule('conditional' => 'LPAREN IF test consequent alternate RPAREN').as 'conditional'
269
237
  def reduce_conditional(_production, aRange, _tokens, theChildren)
270
238
  SkmCondition.new(aRange, theChildren[2], theChildren[3], theChildren[4])
@@ -286,7 +254,7 @@ module Skeem
286
254
  end
287
255
 
288
256
  # rule('derived_expression' => 'LPAREN LET LPAREN binding_spec_star RPAREN body RPAREN').as 'short_let_form'
289
- def reduce_short_let_form(_production, aRange, _tokens, theChildren)
257
+ def reduce_short_let_form(_production, _range, _tokens, theChildren)
290
258
  SkmBindingBlock.new(:let, theChildren[3], theChildren[5])
291
259
  end
292
260
 
@@ -309,9 +277,9 @@ module Skeem
309
277
 
310
278
  # We reky on utility 'builder' object
311
279
  worker = SkmDoExprBuilder.new(theChildren[3], theChildren[6],
312
- theChildren[7], theChildren[9])
280
+ theChildren[7], theChildren[9])
313
281
  do_expression = worker.do_expression
314
- body = { :defs => [], :sequence => do_expression }
282
+ body = { defs: [], sequence: do_expression }
315
283
  SkmBindingBlock.new(:let_star, worker.bindings, body)
316
284
  end
317
285
 
@@ -325,16 +293,6 @@ module Skeem
325
293
  [theChildren[0]]
326
294
  end
327
295
 
328
- # rule('cond_clause_star' => 'cond_clause_star cond_clause').as 'cond_clauses_star'
329
- def reduce_cond_clauses_star(_production, _range, _tokens, theChildren)
330
- theChildren[0] << theChildren[1]
331
- end
332
-
333
- # rule('cond_clause_star' => []).as 'last_cond_clauses_star'
334
- def reduce_last_cond_clauses_star(_production, _range, _tokens, _children)
335
- []
336
- end
337
-
338
296
  # rule('cond_clause' => 'LPAREN test sequence RPAREN').as 'cond_clause'
339
297
  def reduce_cond_clause(_production, _range, _tokens, theChildren)
340
298
  [theChildren[1], SkmSequencingBlock.new(SkmPair.create_from_a(theChildren[2]))]
@@ -346,40 +304,20 @@ module Skeem
346
304
  end
347
305
 
348
306
  # rule('quasiquotation' => 'LPAREN QUASIQUOTE qq_template RPAREN').as 'quasiquotation'
349
- def reduce_quasiquotation(_production, aRange, _tokens, theChildren)
307
+ def reduce_quasiquotation(_production, _range, _tokens, theChildren)
350
308
  SkmQuasiquotation.new(theChildren[2])
351
309
  end
352
310
 
353
311
  # rule('quasiquotation' => 'GRAVE_ACCENT qq_template').as 'quasiquotation_short'
354
- def reduce_quasiquotation_short(_production, aRange, _tokens, theChildren)
312
+ def reduce_quasiquotation_short(_production, _range, _tokens, theChildren)
355
313
  SkmQuasiquotation.new(theChildren[1])
356
314
  end
357
315
 
358
- # rule('binding_spec_star' => 'binding_spec_star binding_spec').as 'multiple_binding_specs'
359
- def reduce_multiple_binding_specs(_production, aRange, _tokens, theChildren)
360
- theChildren[0] << theChildren[1]
361
- end
362
-
363
- # rule('binding_spec_star' => []).as 'no_binding_spec_yet'
364
- def reduce_no_binding_spec_yet(_production, aRange, _tokens, _children)
365
- []
366
- end
367
-
368
316
  # rule('binding_spec' => 'LPAREN IDENTIFIER expression RPAREN').as 'binding_spec'
369
- def reduce_binding_spec(production, _range, _tokens, theChildren)
317
+ def reduce_binding_spec(_production, _range, _tokens, theChildren)
370
318
  SkmBinding.new(theChildren[1], theChildren[2])
371
319
  end
372
320
 
373
- # rule('iteration_spec_star' => 'iteration_spec_star iteration_spec').as 'multiple_iter_specs'
374
- def reduce_multiple_iter_specs(_production, _range, _tokens, theChildren)
375
- theChildren[0] << theChildren[1]
376
- end
377
-
378
- # rule('iteration_spec_star' => []).as 'no_iter_spec_yet'
379
- def reduce_no_iter_spec_yet(_production, _range, _tokens, _children)
380
- []
381
- end
382
-
383
321
  # rule('iteration_spec' => 'LPAREN IDENTIFIER init step RPAREN').as 'iteration_spec_long'
384
322
  def reduce_iteration_spec_long(_production, _range, _tokens, theChildren)
385
323
  SkmIterationSpec.new(theChildren[1], theChildren[2], theChildren[3])
@@ -391,10 +329,26 @@ module Skeem
391
329
  end
392
330
 
393
331
  # rule('do_result' => []).as 'empty_do_result'
394
- def reduce_empty_do_result(_production, _range, _tokens, theChildren)
332
+ def reduce_empty_do_result(_production, _range, _tokens, _children)
395
333
  SkmEmptyList.instance
396
334
  end
397
335
 
336
+ # rule('includer' => 'LPAREN INCLUDE string_plus RPAREN').as 'include'
337
+ def reduce_include(_production, _range, _tokens, theChildren)
338
+ includer = SkmIncluder.new(theChildren[2])
339
+ includer.build
340
+ end
341
+
342
+ # rule('string_plus' => 'string_plus STRING_LIT').as 'multiple_string'
343
+ def reduce_multiple_string(_production, _range, _tokens, theChildren)
344
+ theChildren[0] << theChildren[1]
345
+ end
346
+
347
+ # rule('string_plus' => 'STRING_LIT').as 'last_single_string'
348
+ def reduce_last_single_string(_production, _range, _tokens, theChildren)
349
+ [theChildren[0]]
350
+ end
351
+
398
352
  # rule('list_qq_template' => 'LPAREN qq_template_or_splice_star RPAREN').as 'list_qq'
399
353
  def reduce_list_qq(_production, _range, _tokens, theChildren)
400
354
  SkmPair.create_from_a(theChildren[1])
@@ -406,21 +360,9 @@ module Skeem
406
360
  end
407
361
 
408
362
  # rule('unquotation' => 'COMMA qq_template').as 'unquotation_short'
409
- def reduce_unquotation_short(_production, aRange, _tokens, theChildren)
363
+ def reduce_unquotation_short(_production, _range, _tokens, theChildren)
410
364
  SkmUnquotation.new(theChildren[1])
411
365
  end
412
-
413
- # rule('qq_template_or_splice_star' => 'qq_template_or_splice_star qq_template_or_splice').as 'multiple_template_splice'
414
- def reduce_multiple_template_splice(_production, _range, _tokens, theChildren)
415
- theChildren[0] << theChildren[1]
416
- end
417
-
418
- # rule('qq_template_or_splice_star' => []).as 'no_template_splice_yet'
419
- def reduce_no_template_splice_yet(_production, _range, _tokens, theChildren)
420
- []
421
- end
422
-
423
-
424
366
  end # class
425
367
  end # module
426
- # End of file
368
+ # End of file
@@ -1,9 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Classes that implement nodes of Abstract Syntax Trees (AST) representing
2
4
  # Skeem parse results.
5
+ require 'forwardable'
3
6
  require 'singleton'
4
7
 
5
8
  require_relative 'datum_dsl'
6
9
  require_relative 'skm_unary_expression'
10
+ require_relative 'skm_procedure_exec'
7
11
 
8
12
  module Skeem
9
13
  class SkmUndefined
@@ -20,7 +24,7 @@ module Skeem
20
24
  private
21
25
 
22
26
  def initialize
23
- self.freeze
27
+ freeze
24
28
  end
25
29
  end # class
26
30
 
@@ -63,11 +67,11 @@ module Skeem
63
67
  end
64
68
 
65
69
  def evaluate(aRuntime)
66
- frame_change = false
67
70
  aRuntime.push_call(self)
71
+ # frame_change = false
68
72
  # $stderr.puts "\n Start of ProcedureCall#evaluate #{object_id.to_s(16)}"
69
73
  # $stderr.puts " environment: #{aRuntime.environment.object_id.to_s(16)}, "
70
- if aRuntime.environment && aRuntime.environment.parent
74
+ if aRuntime.environment&.parent
71
75
  # $stderr.puts "Parent environment #{aRuntime.environment.parent.object_id.to_s(16)}, "
72
76
  # $stderr.puts aRuntime.environment.inspect
73
77
  end
@@ -84,7 +88,6 @@ module Skeem
84
88
  # end
85
89
  # $stderr.puts ' callee: ' + callee.inspect
86
90
  result = callee.call(aRuntime, actuals)
87
- operands_consumed = true
88
91
  # aRuntime.pop if frame_change
89
92
  end
90
93
  aRuntime.pop_call
@@ -94,9 +97,9 @@ module Skeem
94
97
 
95
98
  def quasiquote(aRuntime)
96
99
  quasi_operator = operator.quasiquote(aRuntime)
97
- quasi_operands = operands.map { |oper | oper.quasiquote(aRuntime) }
100
+ quasi_operands = operands.map { |oper| oper.quasiquote(aRuntime) }
98
101
 
99
- self.class.new(position, quasi_operator, quasi_operands)
102
+ self.class.new(position, quasi_operator, quasi_operands)
100
103
  end
101
104
 
102
105
  def inspect
@@ -106,7 +109,7 @@ module Skeem
106
109
  end
107
110
 
108
111
  def associations
109
- [:operator, :operands]
112
+ %i[operator operands]
110
113
  end
111
114
 
112
115
  alias children operands
@@ -121,6 +124,7 @@ module Skeem
121
124
  result = operator.evaluate(aRuntime)
122
125
  # If child proc call consumes the parent's operand, then we're done
123
126
  return [:result, result] unless result.callable? # if operands_consumed
127
+
124
128
  callee = result
125
129
  # callee = fetch_callee(aRuntime, result)
126
130
  when Primitive::PrimitiveProcedure
@@ -144,14 +148,14 @@ module Skeem
144
148
  def fetch_callee(aRuntime, var_key)
145
149
  begin
146
150
  aRuntime.include?(var_key.value)
147
- rescue NoMethodError => exc
151
+ rescue NoMethodError => e
148
152
  # $stderr.puts "VVVVVVVVVVVVVVV"
149
153
  # $stderr.puts 'var_key: ' + var_key.inspect
150
154
  # $stderr.puts 'operator: ' + operator.inspect
151
155
  # $stderr.puts 'operands: ' + operands.inspect
152
156
  # $stderr.puts 'operands_consumed: ' + operands_consumed.inspect
153
157
  # $stderr.puts "^^^^^^^^^^^^^^^"
154
- raise exc
158
+ raise e
155
159
  end
156
160
  unless aRuntime.include?(var_key.value)
157
161
  err = StandardError
@@ -172,6 +176,7 @@ module Skeem
172
176
 
173
177
  def transform_operands(aRuntime)
174
178
  return [] if operands == SkmEmptyList.instance
179
+
175
180
  actuals = operands.to_a
176
181
 
177
182
  result = actuals.map do |actual|
@@ -185,9 +190,6 @@ module Skeem
185
190
 
186
191
  result.nil? ? [] : result
187
192
  end
188
-
189
-
190
-
191
193
  end # class
192
194
 
193
195
  class SkmCondition < SkmMultiExpression
@@ -211,6 +213,7 @@ module Skeem
211
213
  else
212
214
  condition_result = consequent.evaluate(aRuntime)
213
215
  end
216
+ condition_result
214
217
  end
215
218
 
216
219
  def quasiquote(aRuntime)
@@ -218,7 +221,7 @@ module Skeem
218
221
  quasi_consequent = consequent.quasiquote(aRuntime)
219
222
  quasi_alternate = alternate.quasiquote(aRuntime)
220
223
 
221
- self.class.new(position, quasi_test, quasi_consequent, quasi_alternate)
224
+ self.class.new(position, quasi_test, quasi_consequent, quasi_alternate)
222
225
  end
223
226
 
224
227
  def inspect
@@ -229,7 +232,7 @@ module Skeem
229
232
  end
230
233
 
231
234
  def associations
232
- [:test, :consequent, :alternate]
235
+ %i[test consequent alternate]
233
236
  end
234
237
  end # class
235
238
 
@@ -266,7 +269,7 @@ module Skeem
266
269
  end
267
270
 
268
271
  def quasiquote(aRuntime)
269
- quasi_clauses = clauses.map do |(test, consequent)|
272
+ quasi_clauses = clauses.map do |(test, consequent)|
270
273
  test_qq = test.quasiquote(aRuntime)
271
274
  consequent_qq = consequent.quasiquote(aRuntime)
272
275
  [test_qq, consequent_qq]
@@ -280,7 +283,7 @@ module Skeem
280
283
  result = inspect_prefix + '@test ' + test.inspect + ', '
281
284
  result << "@clauses \n"
282
285
  clauses.each do |(test, consequent)|
283
- result << ' ' << test.inspect << ' ' << consequent.inspect << "\n"
286
+ result << ' ' << test.inspect << ' ' << consequent.inspect << "\n"
284
287
  end
285
288
  result << '@alternate ' + alternate.inspect + inspect_suffix
286
289
  result
@@ -297,7 +300,8 @@ module Skeem
297
300
  end
298
301
 
299
302
  def ==(other)
300
- return true if self.object_id == other.object_id
303
+ return true if object_id == other.object_id
304
+
301
305
  result = false
302
306
 
303
307
  case other
@@ -325,61 +329,61 @@ module Skeem
325
329
  end
326
330
  end # class
327
331
 
328
- class SkmDoExprBuilder
329
- attr_reader :bindings
330
- attr_reader :update_steps
331
- attr_reader :test
332
- attr_reader :do_result
333
- attr_reader :commands
332
+ class SkmDoExprBuilder
333
+ attr_reader :bindings
334
+ attr_reader :update_steps
335
+ attr_reader :test
336
+ attr_reader :do_result
337
+ attr_reader :commands
334
338
 
335
- # 3 => iteration_spec_star, 6 => test, 7 => do_result, 9 => command_star
339
+ # 3 => iteration_spec_star, 6 => test, 7 => do_result, 9 => command_star
336
340
 
337
- def initialize(iterSpecs, aTest, doResult, theCommands)
338
- iteration_specs_set(iterSpecs)
339
- @test = aTest
340
- @do_result = doResult
341
- commands_set(theCommands)
342
- end
341
+ def initialize(iterSpecs, aTest, doResult, theCommands)
342
+ iteration_specs_set(iterSpecs)
343
+ @test = aTest
344
+ @do_result = doResult
345
+ commands_set(theCommands)
346
+ end
343
347
 
344
- def do_expression
345
- DoExpression.new(test, do_result, commands, update_steps)
346
- end
348
+ def do_expression
349
+ DoExpression.new(test, do_result, commands, update_steps)
350
+ end
347
351
 
348
- private
352
+ private
349
353
 
350
- def iteration_specs_set(iterSpecs)
351
- @bindings = iterSpecs.map do |iter_spec|
354
+ def iteration_specs_set(iterSpecs)
355
+ @bindings = iterSpecs.map do |iter_spec|
352
356
  var = iter_spec.variable
353
357
  val = iter_spec.init_expr
354
358
  SkmBinding.new(var, val)
355
359
  end
356
360
 
357
- to_update = iterSpecs.select { |iter_spec| iter_spec.step_expr }
358
- if to_update
359
- steps = to_update.map do |iter_spec|
360
- SkmDelayedUpdateBinding.new(iter_spec.variable, iter_spec.step_expr)
361
- end
362
- if steps.size == 1
363
- @update_steps = steps[0]
361
+ to_update = iterSpecs.select(&:step_expr)
362
+ if to_update
363
+ steps = to_update.map do |iter_spec|
364
+ SkmDelayedUpdateBinding.new(iter_spec.variable, iter_spec.step_expr)
365
+ end
366
+ if steps.size == 1
367
+ @update_steps = steps[0]
368
+ else
369
+ @update_steps = SkmPair.create_from_a(steps)
370
+ end
364
371
  else
365
- @update_steps = SkmPair.create_from_a(steps)
372
+ @update_steps = SkmEmptyList.instance
366
373
  end
367
- else
368
- @update_steps = SkmEmptyList.instance
369
374
  end
370
- end
371
375
 
372
- def commands_set(theCommands)
373
- case theCommands.size
374
- when 0
375
- @commands = SkmEmptyList.instance
376
- when 1
377
- @commands = theCommands[0]
378
- else
379
- @commands = SkmSequencingBlock.new(SkmPair.create_from_a(theCommands))
376
+ def commands_set(theCommands)
377
+ case theCommands.size
378
+ when 0
379
+ @commands = SkmEmptyList.instance
380
+ when 1
381
+ @commands = theCommands[0]
382
+ else
383
+ @commands = SkmSequencingBlock.new(SkmPair.create_from_a(theCommands))
384
+ end
380
385
  end
381
- end
382
- end # class
386
+ end # class
383
387
 
384
388
  # Syntax outline:
385
389
  # LPAREN DO LPAREN iteration_spec_star RPAREN
@@ -454,12 +458,12 @@ end # class
454
458
  test_result = test.evaluate(aRuntime)
455
459
  if test_result.boolean? && test_result.value == false
456
460
  # Only #f is considered as false, everything else is true
457
- commands.evaluate(aRuntime) if commands
461
+ commands&.evaluate(aRuntime)
458
462
  if update_steps
459
463
  update_steps.evaluate(aRuntime)
460
464
  case update_steps
461
465
  when SkmEmptyList.instance
462
- ; Do nothing
466
+ # Do nothing
463
467
  when SkmPair
464
468
  arr = update_steps.to_a
465
469
  arr.each { |delayed_binding| delayed_binding.do_it!(aRuntime) }
@@ -476,6 +480,31 @@ end # class
476
480
  end
477
481
  end # class
478
482
 
483
+ class SkmIncluder
484
+ attr_reader :filenames
485
+
486
+ def initialize(theFilenames)
487
+ @filenames = theFilenames
488
+ end
489
+
490
+ def build
491
+ parser = Skeem::Parser.new
492
+ parse_results = filenames.map do |fname|
493
+ f_source = File.read(fname.value)
494
+ ptree = parser.parse(f_source)
495
+ ptree.root
496
+ end
497
+
498
+ if parse_results.size == 1
499
+ result = parse_results[0]
500
+ else
501
+ sequence = SkmPair.create_from_a(parse_results)
502
+ result = SkmSequencingBlock.new(sequence)
503
+ end
504
+ result
505
+ end
506
+ end # class
507
+
479
508
  class SkmFormals
480
509
  attr_reader :formals
481
510
  attr_reader :arity
@@ -509,12 +538,10 @@ end # class
509
538
 
510
539
  if arityKind == :fixed
511
540
  @arity = SkmArity.new(fixed_arity, fixed_arity)
512
- else # :variadic
513
- if formals.empty?
514
- raise StandardError, 'Internal error: inconsistent arity'
515
- else
516
- @arity = SkmArity.new(fixed_arity - 1, '*')
517
- end
541
+ elsif formals.empty? # :variadic
542
+ raise StandardError, 'Internal error: inconsistent arity'
543
+ else
544
+ @arity = SkmArity.new(fixed_arity - 1, '*')
518
545
  end
519
546
  end
520
547
  end # class
@@ -581,7 +608,7 @@ end # class
581
608
  end
582
609
 
583
610
  def associations
584
- [:formals, :definitions, :sequence]
611
+ %i[formals definitions sequence]
585
612
  end
586
613
 
587
614
  def bind_locals(aRuntime, theActuals)
@@ -589,12 +616,14 @@ end # class
589
616
  count_actuals = actuals.size
590
617
 
591
618
  if (count_actuals < required_arity) ||
592
- ((count_actuals > required_arity) && !formals.variadic?)
619
+ ((count_actuals > required_arity) &&
620
+ !formals.variadic?)
593
621
  # $stderr.puts "Error"
594
622
  # $stderr.puts self.inspect
595
623
  raise StandardError, msg_arity_mismatch(theActuals)
596
624
  end
597
625
  return if count_actuals.zero? && !formals.variadic?
626
+
598
627
  bind_required_locals(aRuntime, theActuals)
599
628
  if formals.variadic?
600
629
  variadic_part_raw = actuals.drop(required_arity)
@@ -619,7 +648,7 @@ end # class
619
648
  # $stderr.puts "Tef #{aProcedureCall.inspect}"
620
649
  # a_def.evaluate(aRuntime)
621
650
  end
622
- #aProcedureCall.operands_consumed = true
651
+ # aProcedureCall.operands_consumed = true
623
652
  end
624
653
 
625
654
  private
@@ -660,14 +689,14 @@ end # class
660
689
 
661
690
  def msg_arity_mismatch(actuals)
662
691
  # *** ERROR: wrong number of arguments for #<closure morph> (required 2, got 1)
663
- msg1 = "Wrong number of arguments for procedure "
692
+ msg1 = 'Wrong number of arguments for procedure '
664
693
  count_actuals = actuals.size
665
694
  msg2 = "(required #{required_arity}, got #{count_actuals})"
666
695
  msg1 + msg2
667
696
  end
668
697
 
669
698
  def inspect_specific
670
- result = ''
699
+ result = +''
671
700
  result << '@formals ' + formals.inspect + ', '
672
701
  result << '@definitions ' + definitions.inspect + ', '
673
702
  result << '@sequence ' + sequence.inspect + inspect_suffix
@@ -676,12 +705,6 @@ end # class
676
705
  end
677
706
  end # class
678
707
 
679
-
680
-
681
-
682
- require 'forwardable'
683
- require_relative 'skm_procedure_exec'
684
-
685
708
  class SkmLambda < SkmMultiExpression
686
709
  include DatumDSL
687
710
  extend Forwardable
@@ -696,7 +719,7 @@ require_relative 'skm_procedure_exec'
696
719
  @environment = aRuntime.environment
697
720
  end
698
721
 
699
- def evaluate(aRuntime)
722
+ def evaluate(_runtime)
700
723
  self
701
724
  end
702
725
 
@@ -746,7 +769,7 @@ require_relative 'skm_procedure_exec'
746
769
  end
747
770
 
748
771
  def associations
749
- [:formals, :definitions, :sequence]
772
+ %i[formals definitions sequence]
750
773
  end
751
774
 
752
775
  def bind_locals(aRuntime, theActuals)
@@ -754,12 +777,14 @@ require_relative 'skm_procedure_exec'
754
777
  count_actuals = actuals.size
755
778
 
756
779
  if (count_actuals < required_arity) ||
757
- ((count_actuals > required_arity) && !formals.variadic?)
780
+ ((count_actuals > required_arity) &&
781
+ !formals.variadic?)
758
782
  # $stderr.puts "Error"
759
783
  # $stderr.puts self.inspect
760
784
  raise StandardError, msg_arity_mismatch(theActuals)
761
785
  end
762
786
  return if count_actuals.zero? && !formals.variadic?
787
+
763
788
  bind_required_locals(aRuntime, theActuals)
764
789
  if formals.variadic?
765
790
  variadic_part_raw = actuals.drop(required_arity)
@@ -784,7 +809,7 @@ require_relative 'skm_procedure_exec'
784
809
  # $stderr.puts "Tef #{aProcedureCall.inspect}"
785
810
  # a_def.evaluate(aRuntime)
786
811
  end
787
- #aProcedureCall.operands_consumed = true
812
+ # aProcedureCall.operands_consumed = true
788
813
  end
789
814
 
790
815
  def evaluate_sequence(aRuntime)
@@ -797,11 +822,11 @@ require_relative 'skm_procedure_exec'
797
822
  else
798
823
  result = cmd.evaluate(aRuntime)
799
824
  end
800
- rescue NoMethodError => exc
801
- $stderr.puts self.inspect
825
+ rescue NoMethodError => e
826
+ $stderr.puts inspect
802
827
  $stderr.puts sequence.inspect
803
828
  $stderr.puts cmd.inspect
804
- raise exc
829
+ raise e
805
830
  end
806
831
  end
807
832
  end
@@ -813,7 +838,7 @@ require_relative 'skm_procedure_exec'
813
838
  if environment
814
839
  result = self
815
840
  else
816
- twin = self.dup
841
+ twin = dup
817
842
  twin.set_cond_environment(aRuntime.environment)
818
843
  result = twin
819
844
  end
@@ -822,7 +847,7 @@ require_relative 'skm_procedure_exec'
822
847
  end
823
848
 
824
849
  def doppelganger(aRuntime)
825
- twin = self.dup
850
+ twin = dup
826
851
  twin.set_cond_environment(aRuntime.environment.dup)
827
852
  result = twin
828
853
 
@@ -834,9 +859,10 @@ require_relative 'skm_procedure_exec'
834
859
  # $stderr.puts " Runtime environment: #{theFrame.object_id.to_s(16)}"
835
860
  # $stderr.puts " Called from #{caller(1, 1)}"
836
861
  raise StandardError unless theFrame.kind_of?(SkmFrame)
862
+
837
863
  unless environment
838
864
  @environment = theFrame
839
- self.freeze
865
+ freeze
840
866
  # $stderr.puts " Lambda's environment updated!"
841
867
  end
842
868
  end
@@ -879,16 +905,16 @@ require_relative 'skm_procedure_exec'
879
905
 
880
906
  def msg_arity_mismatch(actuals)
881
907
  # *** ERROR: wrong number of arguments for #<closure morph> (required 2, got 1)
882
- msg1 = "Wrong number of arguments for procedure "
908
+ msg1 = 'Wrong number of arguments for procedure '
883
909
  count_actuals = actuals.size
884
910
  msg2 = "(required #{required_arity}, got #{count_actuals})"
885
911
  msg1 + msg2
886
912
  end
887
913
 
888
914
  def inspect_specific
889
- #result = "@environment #{environment.object_id.to_s(16)}, "
890
- result = ''
891
- if environment && environment.parent
915
+ # result = "@environment #{environment.object_id.to_s(16)}, "
916
+ result = +''
917
+ if environment&.parent
892
918
  result << "Parent environment #{environment.parent.object_id.to_s(16)}, "
893
919
  result << environment.inspect
894
920
  end