skeem 0.2.15 → 0.2.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +451 -195
- data/.travis.yml +27 -0
- data/CHANGELOG.md +26 -0
- data/Gemfile +2 -0
- data/README.md +3 -2
- data/Rakefile +2 -0
- data/appveyor.yml +3 -4
- data/bin/skeem +15 -15
- data/lib/skeem/datum_dsl.rb +40 -30
- data/lib/skeem/element_visitor.rb +5 -2
- data/lib/skeem/grammar.rb +77 -54
- data/lib/skeem/interpreter.rb +9 -7
- data/lib/skeem/parser.rb +6 -4
- data/lib/skeem/primitive/primitive_builder.rb +130 -122
- data/lib/skeem/primitive/primitive_procedure.rb +23 -25
- data/lib/skeem/runtime.rb +17 -15
- data/lib/skeem/s_expr_builder.rb +39 -147
- data/lib/skeem/s_expr_nodes.rb +147 -132
- data/lib/skeem/skeem_exception.rb +1 -0
- data/lib/skeem/skm_binding.rb +9 -11
- data/lib/skeem/skm_compound_datum.rb +9 -6
- data/lib/skeem/skm_element.rb +15 -13
- data/lib/skeem/skm_empty_list.rb +6 -4
- data/lib/skeem/skm_exception.rb +9 -0
- data/lib/skeem/skm_expression.rb +3 -1
- data/lib/skeem/skm_frame.rb +3 -2
- data/lib/skeem/skm_pair.rb +26 -18
- data/lib/skeem/skm_procedure_exec.rb +11 -6
- data/lib/skeem/skm_simple_datum.rb +23 -20
- data/lib/skeem/skm_unary_expression.rb +34 -37
- data/lib/skeem/tokenizer.rb +40 -30
- data/lib/skeem/version.rb +3 -1
- data/lib/skeem.rb +2 -0
- data/skeem.gemspec +7 -5
- data/spec/skeem/add4.skm +4 -0
- data/spec/skeem/datum_dsl_spec.rb +13 -12
- data/spec/skeem/element_visitor_spec.rb +14 -10
- data/spec/skeem/interpreter_spec.rb +76 -46
- data/spec/skeem/lambda_spec.rb +13 -11
- data/spec/skeem/parser_spec.rb +23 -19
- data/spec/skeem/primitive/primitive_builder_spec.rb +55 -46
- data/spec/skeem/primitive/primitive_procedure_spec.rb +14 -12
- data/spec/skeem/runtime_spec.rb +20 -18
- data/spec/skeem/s_expr_nodes_spec.rb +8 -6
- data/spec/skeem/skm_compound_datum_spec.rb +12 -10
- data/spec/skeem/skm_element_spec.rb +7 -5
- data/spec/skeem/skm_empty_list_spec.rb +7 -5
- data/spec/skeem/skm_frame_spec.rb +5 -4
- data/spec/skeem/skm_pair_spec.rb +9 -8
- data/spec/skeem/skm_procedure_exec_spec.rb +2 -0
- data/spec/skeem/skm_simple_datum_spec.rb +24 -22
- data/spec/skeem/skm_unary_expression_spec.rb +11 -9
- data/spec/skeem/tokenizer_spec.rb +54 -43
- data/spec/skeem_spec.rb +2 -0
- data/spec/spec_helper.rb +15 -10
- metadata +13 -9
data/lib/skeem/s_expr_nodes.rb
CHANGED
@@ -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
|
-
|
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
|
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
|
100
|
+
quasi_operands = operands.map { |oper| oper.quasiquote(aRuntime) }
|
98
101
|
|
99
|
-
|
102
|
+
self.class.new(position, quasi_operator, quasi_operands)
|
100
103
|
end
|
101
104
|
|
102
105
|
def inspect
|
103
|
-
result = inspect_prefix
|
104
|
-
result <<
|
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
|
-
[
|
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 =>
|
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
|
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
|
-
|
222
|
+
self.class.new(position, quasi_test, quasi_consequent, quasi_alternate)
|
222
223
|
end
|
223
224
|
|
224
225
|
def inspect
|
225
|
-
result = inspect_prefix
|
226
|
-
result <<
|
227
|
-
result <<
|
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
|
-
[
|
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
|
-
|
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
|
280
|
+
result = "#{inspect_prefix}@test #{test.inspect} , "
|
281
281
|
result << "@clauses \n"
|
282
282
|
clauses.each do |(test, consequent)|
|
283
|
-
result << ' '
|
283
|
+
result << ' ' << test.inspect << ' ' << consequent.inspect << "\n"
|
284
284
|
end
|
285
|
-
result <<
|
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
|
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
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
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
|
-
|
339
|
+
# 3 => iteration_spec_star, 6 => test, 7 => do_result, 9 => command_star
|
336
340
|
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
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
|
-
|
345
|
-
|
346
|
-
|
348
|
+
def do_expression
|
349
|
+
DoExpression.new(test, do_result, commands, update_steps)
|
350
|
+
end
|
347
351
|
|
348
|
-
|
352
|
+
private
|
349
353
|
|
350
|
-
|
351
|
-
|
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
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
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 =
|
372
|
+
@update_steps = SkmEmptyList.instance
|
366
373
|
end
|
367
|
-
else
|
368
|
-
@update_steps = SkmEmptyList.instance
|
369
374
|
end
|
370
|
-
end
|
371
375
|
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
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
|
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
|
-
|
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
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
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
|
-
[
|
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
|
-
|
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 =
|
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 <<
|
672
|
-
result <<
|
673
|
-
result <<
|
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(
|
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
|
-
[
|
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
|
-
|
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
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
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
|
-
|
832
|
+
self
|
815
833
|
else
|
816
|
-
twin =
|
834
|
+
twin = dup
|
817
835
|
twin.set_cond_environment(aRuntime.environment)
|
818
|
-
|
836
|
+
twin
|
819
837
|
end
|
820
|
-
|
821
|
-
result
|
822
838
|
end
|
823
839
|
|
824
840
|
def doppelganger(aRuntime)
|
825
|
-
twin =
|
841
|
+
twin = dup
|
826
842
|
twin.set_cond_environment(aRuntime.environment.dup)
|
827
|
-
|
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
|
-
|
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 =
|
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
|
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 <<
|
896
|
-
result <<
|
897
|
-
result <<
|
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
|