skeem 0.2.14 → 0.2.18

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