skeem 0.2.14 → 0.2.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +451 -195
  3. data/.travis.yml +27 -0
  4. data/CHANGELOG.md +35 -1
  5. data/Gemfile +2 -0
  6. data/README.md +125 -56
  7. data/Rakefile +2 -0
  8. data/appveyor.yml +3 -4
  9. data/bin/cubic.skm +4 -0
  10. data/bin/hello-world.skm +1 -0
  11. data/bin/skeem +72 -0
  12. data/lib/skeem/datum_dsl.rb +40 -30
  13. data/lib/skeem/element_visitor.rb +5 -2
  14. data/lib/skeem/grammar.rb +88 -26
  15. data/lib/skeem/interpreter.rb +9 -7
  16. data/lib/skeem/parser.rb +6 -4
  17. data/lib/skeem/primitive/primitive_builder.rb +148 -122
  18. data/lib/skeem/primitive/primitive_procedure.rb +23 -25
  19. data/lib/skeem/runtime.rb +17 -15
  20. data/lib/skeem/s_expr_builder.rb +49 -117
  21. data/lib/skeem/s_expr_nodes.rb +147 -132
  22. data/lib/skeem/skeem_exception.rb +1 -0
  23. data/lib/skeem/skm_binding.rb +9 -11
  24. data/lib/skeem/skm_compound_datum.rb +9 -6
  25. data/lib/skeem/skm_element.rb +15 -13
  26. data/lib/skeem/skm_empty_list.rb +6 -4
  27. data/lib/skeem/skm_exception.rb +9 -0
  28. data/lib/skeem/skm_expression.rb +3 -1
  29. data/lib/skeem/skm_frame.rb +3 -2
  30. data/lib/skeem/skm_pair.rb +26 -18
  31. data/lib/skeem/skm_procedure_exec.rb +11 -6
  32. data/lib/skeem/skm_simple_datum.rb +23 -20
  33. data/lib/skeem/skm_unary_expression.rb +34 -37
  34. data/lib/skeem/standard/base.skm +4 -0
  35. data/lib/skeem/tokenizer.rb +38 -28
  36. data/lib/skeem/version.rb +3 -1
  37. data/lib/skeem.rb +2 -0
  38. data/skeem.gemspec +9 -6
  39. data/spec/skeem/add4.skm +4 -0
  40. data/spec/skeem/datum_dsl_spec.rb +13 -12
  41. data/spec/skeem/element_visitor_spec.rb +14 -10
  42. data/spec/skeem/interpreter_spec.rb +84 -44
  43. data/spec/skeem/lambda_spec.rb +13 -11
  44. data/spec/skeem/parser_spec.rb +23 -19
  45. data/spec/skeem/primitive/primitive_builder_spec.rb +65 -48
  46. data/spec/skeem/primitive/primitive_procedure_spec.rb +14 -12
  47. data/spec/skeem/runtime_spec.rb +20 -18
  48. data/spec/skeem/s_expr_nodes_spec.rb +8 -6
  49. data/spec/skeem/skm_compound_datum_spec.rb +12 -10
  50. data/spec/skeem/skm_element_spec.rb +7 -5
  51. data/spec/skeem/skm_empty_list_spec.rb +7 -5
  52. data/spec/skeem/skm_frame_spec.rb +5 -4
  53. data/spec/skeem/skm_pair_spec.rb +9 -8
  54. data/spec/skeem/skm_procedure_exec_spec.rb +2 -0
  55. data/spec/skeem/skm_simple_datum_spec.rb +24 -22
  56. data/spec/skeem/skm_unary_expression_spec.rb +11 -9
  57. data/spec/skeem/tokenizer_spec.rb +54 -43
  58. data/spec/skeem_spec.rb +2 -0
  59. data/spec/spec_helper.rb +15 -10
  60. metadata +18 -10
@@ -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,19 +97,19 @@ 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
103
- result = inspect_prefix + operator.inspect + ', '
104
- result << '@operands ' + operands.inspect + inspect_suffix
106
+ result = +"#{inspect_prefix}#{operator.inspect}, "
107
+ result << "@operands #{operands.inspect}#{inspect_suffix}"
105
108
  result
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,14 +124,13 @@ 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
- when Primitive::PrimitiveProcedure
130
+ when Primitive::PrimitiveProcedure, SkmLambda
127
131
  callee = operator
128
132
  when SkmLambdaRep
129
133
  callee = operator.evaluate(aRuntime)
130
- when SkmLambda
131
- callee = operator
132
134
  else
133
135
  result = operator.evaluate(aRuntime)
134
136
  if result.kind_of?(Primitive::PrimitiveProcedure)
@@ -144,14 +146,14 @@ module Skeem
144
146
  def fetch_callee(aRuntime, var_key)
145
147
  begin
146
148
  aRuntime.include?(var_key.value)
147
- rescue NoMethodError => exc
149
+ rescue NoMethodError => e
148
150
  # $stderr.puts "VVVVVVVVVVVVVVV"
149
151
  # $stderr.puts 'var_key: ' + var_key.inspect
150
152
  # $stderr.puts 'operator: ' + operator.inspect
151
153
  # $stderr.puts 'operands: ' + operands.inspect
152
154
  # $stderr.puts 'operands_consumed: ' + operands_consumed.inspect
153
155
  # $stderr.puts "^^^^^^^^^^^^^^^"
154
- raise exc
156
+ raise e
155
157
  end
156
158
  unless aRuntime.include?(var_key.value)
157
159
  err = StandardError
@@ -172,6 +174,7 @@ module Skeem
172
174
 
173
175
  def transform_operands(aRuntime)
174
176
  return [] if operands == SkmEmptyList.instance
177
+
175
178
  actuals = operands.to_a
176
179
 
177
180
  result = actuals.map do |actual|
@@ -185,9 +188,6 @@ module Skeem
185
188
 
186
189
  result.nil? ? [] : result
187
190
  end
188
-
189
-
190
-
191
191
  end # class
192
192
 
193
193
  class SkmCondition < SkmMultiExpression
@@ -211,6 +211,7 @@ module Skeem
211
211
  else
212
212
  condition_result = consequent.evaluate(aRuntime)
213
213
  end
214
+ condition_result
214
215
  end
215
216
 
216
217
  def quasiquote(aRuntime)
@@ -218,22 +219,21 @@ module Skeem
218
219
  quasi_consequent = consequent.quasiquote(aRuntime)
219
220
  quasi_alternate = alternate.quasiquote(aRuntime)
220
221
 
221
- self.class.new(position, quasi_test, quasi_consequent, quasi_alternate)
222
+ self.class.new(position, quasi_test, quasi_consequent, quasi_alternate)
222
223
  end
223
224
 
224
225
  def inspect
225
- result = inspect_prefix + '@test ' + test.inspect + ', '
226
- result << '@consequent ' + consequent.inspect + ', '
227
- result << '@alternate ' + alternate.inspect + inspect_suffix
226
+ result = +"#{inspect_prefix}@test #{test.inspect}, "
227
+ result << "@consequent #{consequent.inspect}, "
228
+ result << "@alternate #{alternate.inspect}#{inspect_suffix}"
228
229
  result
229
230
  end
230
231
 
231
232
  def associations
232
- [:test, :consequent, :alternate]
233
+ %i[test consequent alternate]
233
234
  end
234
235
  end # class
235
236
 
236
-
237
237
  class SkmConditional < SkmMultiExpression
238
238
  # An array of couples [test, sequence]
239
239
  attr_reader :clauses
@@ -266,7 +266,7 @@ module Skeem
266
266
  end
267
267
 
268
268
  def quasiquote(aRuntime)
269
- quasi_clauses = clauses.map do |(test, consequent)|
269
+ quasi_clauses = clauses.map do |(test, consequent)|
270
270
  test_qq = test.quasiquote(aRuntime)
271
271
  consequent_qq = consequent.quasiquote(aRuntime)
272
272
  [test_qq, consequent_qq]
@@ -277,27 +277,31 @@ module Skeem
277
277
  end
278
278
 
279
279
  def inspect
280
- result = inspect_prefix + '@test ' + test.inspect + ', '
280
+ result = "#{inspect_prefix}@test #{test.inspect} , "
281
281
  result << "@clauses \n"
282
282
  clauses.each do |(test, consequent)|
283
- result << ' ' << test.inspect << ' ' << consequent.inspect << "\n"
283
+ result << ' ' << test.inspect << ' ' << consequent.inspect << "\n"
284
284
  end
285
- result << '@alternate ' + alternate.inspect + inspect_suffix
285
+ result << "@alternate #{alternate.inspect}#{inspect_suffix}"
286
286
  result
287
287
  end
288
288
  end # class
289
289
 
290
290
  SkmArity = Struct.new(:low, :high) do
291
+ # rubocop: disable Style/NumericPredicate
292
+
291
293
  def nullary?
292
294
  low.zero? && high == 0
293
295
  end
296
+ # rubocop: enable Style/NumericPredicate
294
297
 
295
298
  def variadic?
296
299
  high == '*'
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
@@ -442,6 +446,7 @@ end # class
442
446
  attr_reader :update_steps
443
447
 
444
448
  def initialize(aTest, doResult, theCommands, theUpdates)
449
+ super(nil)
445
450
  @test = aTest
446
451
  @do_result = doResult
447
452
  @commands = theCommands
@@ -454,12 +459,12 @@ end # class
454
459
  test_result = test.evaluate(aRuntime)
455
460
  if test_result.boolean? && test_result.value == false
456
461
  # Only #f is considered as false, everything else is true
457
- commands.evaluate(aRuntime) if commands
462
+ commands&.evaluate(aRuntime)
458
463
  if update_steps
459
464
  update_steps.evaluate(aRuntime)
460
465
  case update_steps
461
466
  when SkmEmptyList.instance
462
- ; Do nothing
467
+ # Do nothing
463
468
  when SkmPair
464
469
  arr = update_steps.to_a
465
470
  arr.each { |delayed_binding| delayed_binding.do_it!(aRuntime) }
@@ -476,6 +481,31 @@ end # class
476
481
  end
477
482
  end # class
478
483
 
484
+ class SkmIncluder
485
+ attr_reader :filenames
486
+
487
+ def initialize(theFilenames)
488
+ @filenames = theFilenames
489
+ end
490
+
491
+ def build
492
+ parser = Skeem::Parser.new
493
+ parse_results = filenames.map do |fname|
494
+ f_source = File.read(fname.value)
495
+ ptree = parser.parse(f_source)
496
+ ptree.root
497
+ end
498
+
499
+ if parse_results.size == 1
500
+ result = parse_results[0]
501
+ else
502
+ sequence = SkmPair.create_from_a(parse_results)
503
+ result = SkmSequencingBlock.new(sequence)
504
+ end
505
+ result
506
+ end
507
+ end # class
508
+
479
509
  class SkmFormals
480
510
  attr_reader :formals
481
511
  attr_reader :arity
@@ -509,17 +539,14 @@ end # class
509
539
 
510
540
  if arityKind == :fixed
511
541
  @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
542
+ elsif formals.empty? # :variadic
543
+ raise StandardError, 'Internal error: inconsistent arity'
544
+ else
545
+ @arity = SkmArity.new(fixed_arity - 1, '*')
518
546
  end
519
547
  end
520
548
  end # class
521
549
 
522
-
523
550
  # Parse tree representation of a Lambda
524
551
  # - Not bound to a frame (aka environment)
525
552
  # - Knows the parse representation of its embedded definitions
@@ -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,20 +616,20 @@ 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)
601
630
  variadic_part = variadic_part_raw.map do |actual|
602
631
  case actual
603
- when ProcedureCall
604
- actual.evaluate(aRuntime)
605
- when SkmQuotation
632
+ when ProcedureCall, SkmQuotation
606
633
  actual.evaluate(aRuntime)
607
634
  else
608
635
  to_datum(actual)
@@ -619,7 +646,7 @@ end # class
619
646
  # $stderr.puts "Tef #{aProcedureCall.inspect}"
620
647
  # a_def.evaluate(aRuntime)
621
648
  end
622
- #aProcedureCall.operands_consumed = true
649
+ # aProcedureCall.operands_consumed = true
623
650
  end
624
651
 
625
652
  private
@@ -660,28 +687,22 @@ end # class
660
687
 
661
688
  def msg_arity_mismatch(actuals)
662
689
  # *** ERROR: wrong number of arguments for #<closure morph> (required 2, got 1)
663
- msg1 = "Wrong number of arguments for procedure "
690
+ msg1 = 'Wrong number of arguments for procedure '
664
691
  count_actuals = actuals.size
665
692
  msg2 = "(required #{required_arity}, got #{count_actuals})"
666
693
  msg1 + msg2
667
694
  end
668
695
 
669
696
  def inspect_specific
670
- result = ''
671
- result << '@formals ' + formals.inspect + ', '
672
- result << '@definitions ' + definitions.inspect + ', '
673
- result << '@sequence ' + sequence.inspect + inspect_suffix
697
+ result = +''
698
+ result << "@formals #{formals.inspect}, "
699
+ result << "@definitions #{definitions.inspect}, "
700
+ result << "@sequence #{sequence.inspect}#{inspect_suffix}"
674
701
 
675
702
  result
676
703
  end
677
704
  end # class
678
705
 
679
-
680
-
681
-
682
- require 'forwardable'
683
- require_relative 'skm_procedure_exec'
684
-
685
706
  class SkmLambda < SkmMultiExpression
686
707
  include DatumDSL
687
708
  extend Forwardable
@@ -692,11 +713,12 @@ require_relative 'skm_procedure_exec'
692
713
  def_delegators(:@representation, :formals, :definitions, :sequence)
693
714
 
694
715
  def initialize(aRepresentation, aRuntime)
716
+ super(nil)
695
717
  @representation = aRepresentation
696
718
  @environment = aRuntime.environment
697
719
  end
698
720
 
699
- def evaluate(aRuntime)
721
+ def evaluate(_runtime)
700
722
  self
701
723
  end
702
724
 
@@ -746,7 +768,7 @@ require_relative 'skm_procedure_exec'
746
768
  end
747
769
 
748
770
  def associations
749
- [:formals, :definitions, :sequence]
771
+ %i[formals definitions sequence]
750
772
  end
751
773
 
752
774
  def bind_locals(aRuntime, theActuals)
@@ -754,20 +776,20 @@ require_relative 'skm_procedure_exec'
754
776
  count_actuals = actuals.size
755
777
 
756
778
  if (count_actuals < required_arity) ||
757
- ((count_actuals > required_arity) && !formals.variadic?)
779
+ ((count_actuals > required_arity) &&
780
+ !formals.variadic?)
758
781
  # $stderr.puts "Error"
759
782
  # $stderr.puts self.inspect
760
783
  raise StandardError, msg_arity_mismatch(theActuals)
761
784
  end
762
785
  return if count_actuals.zero? && !formals.variadic?
786
+
763
787
  bind_required_locals(aRuntime, theActuals)
764
788
  if formals.variadic?
765
789
  variadic_part_raw = actuals.drop(required_arity)
766
790
  variadic_part = variadic_part_raw.map do |actual|
767
791
  case actual
768
- when ProcedureCall
769
- actual.evaluate(aRuntime)
770
- when SkmQuotation
792
+ when ProcedureCall, SkmQuotation
771
793
  actual.evaluate(aRuntime)
772
794
  else
773
795
  to_datum(actual)
@@ -784,26 +806,22 @@ require_relative 'skm_procedure_exec'
784
806
  # $stderr.puts "Tef #{aProcedureCall.inspect}"
785
807
  # a_def.evaluate(aRuntime)
786
808
  end
787
- #aProcedureCall.operands_consumed = true
809
+ # aProcedureCall.operands_consumed = true
788
810
  end
789
811
 
790
812
  def evaluate_sequence(aRuntime)
791
813
  result = nil
792
- if sequence
793
- sequence.each do |cmd|
794
- begin
795
- if cmd.kind_of?(SkmLambda)
796
- result = cmd.dup_cond(aRuntime)
797
- else
798
- result = cmd.evaluate(aRuntime)
799
- end
800
- rescue NoMethodError => exc
801
- $stderr.puts self.inspect
802
- $stderr.puts sequence.inspect
803
- $stderr.puts cmd.inspect
804
- raise exc
805
- end
814
+ sequence&.each do |cmd|
815
+ if cmd.kind_of?(SkmLambda)
816
+ result = cmd.dup_cond(aRuntime)
817
+ else
818
+ result = cmd.evaluate(aRuntime)
806
819
  end
820
+ rescue NoMethodError => e
821
+ $stderr.puts inspect
822
+ $stderr.puts sequence.inspect
823
+ $stderr.puts cmd.inspect
824
+ raise e
807
825
  end
808
826
 
809
827
  result
@@ -811,22 +829,18 @@ require_relative 'skm_procedure_exec'
811
829
 
812
830
  def dup_cond(aRuntime)
813
831
  if environment
814
- result = self
832
+ self
815
833
  else
816
- twin = self.dup
834
+ twin = dup
817
835
  twin.set_cond_environment(aRuntime.environment)
818
- result = twin
836
+ twin
819
837
  end
820
-
821
- result
822
838
  end
823
839
 
824
840
  def doppelganger(aRuntime)
825
- twin = self.dup
841
+ twin = dup
826
842
  twin.set_cond_environment(aRuntime.environment.dup)
827
- result = twin
828
-
829
- result
843
+ twin
830
844
  end
831
845
 
832
846
  def set_cond_environment(theFrame)
@@ -834,9 +848,10 @@ require_relative 'skm_procedure_exec'
834
848
  # $stderr.puts " Runtime environment: #{theFrame.object_id.to_s(16)}"
835
849
  # $stderr.puts " Called from #{caller(1, 1)}"
836
850
  raise StandardError unless theFrame.kind_of?(SkmFrame)
851
+
837
852
  unless environment
838
853
  @environment = theFrame
839
- self.freeze
854
+ freeze
840
855
  # $stderr.puts " Lambda's environment updated!"
841
856
  end
842
857
  end
@@ -879,22 +894,22 @@ require_relative 'skm_procedure_exec'
879
894
 
880
895
  def msg_arity_mismatch(actuals)
881
896
  # *** ERROR: wrong number of arguments for #<closure morph> (required 2, got 1)
882
- msg1 = "Wrong number of arguments for procedure "
897
+ msg1 = 'Wrong number of arguments for procedure '
883
898
  count_actuals = actuals.size
884
899
  msg2 = "(required #{required_arity}, got #{count_actuals})"
885
900
  msg1 + msg2
886
901
  end
887
902
 
888
903
  def inspect_specific
889
- #result = "@environment #{environment.object_id.to_s(16)}, "
890
- result = ''
891
- if environment && environment.parent
904
+ # result = "@environment #{environment.object_id.to_s(16)}, "
905
+ result = +''
906
+ if environment&.parent
892
907
  result << "Parent environment #{environment.parent.object_id.to_s(16)}, "
893
908
  result << environment.inspect
894
909
  end
895
- result << '@formals ' + formals.inspect + ', '
896
- result << '@definitions ' + definitions.inspect + ', '
897
- result << '@sequence ' + sequence.inspect + inspect_suffix
910
+ result << "@formals #{formals.inspect}, "
911
+ result << "@definitions #{definitions.inspect}, "
912
+ result << "@sequence #{sequence.inspect}#{inspect_suffix}"
898
913
 
899
914
  result
900
915
  end