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
@@ -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