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.
- checksums.yaml +4 -4
- data/.rubocop.yml +451 -195
- data/.travis.yml +27 -0
- data/CHANGELOG.md +35 -1
- data/Gemfile +2 -0
- data/README.md +125 -56
- data/Rakefile +2 -0
- data/appveyor.yml +3 -4
- data/bin/cubic.skm +4 -0
- data/bin/hello-world.skm +1 -0
- data/bin/skeem +72 -0
- data/lib/skeem/datum_dsl.rb +40 -30
- data/lib/skeem/element_visitor.rb +5 -2
- data/lib/skeem/grammar.rb +88 -26
- data/lib/skeem/interpreter.rb +9 -7
- data/lib/skeem/parser.rb +6 -4
- data/lib/skeem/primitive/primitive_builder.rb +148 -122
- data/lib/skeem/primitive/primitive_procedure.rb +23 -25
- data/lib/skeem/runtime.rb +17 -15
- data/lib/skeem/s_expr_builder.rb +49 -117
- 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/standard/base.skm +4 -0
- data/lib/skeem/tokenizer.rb +38 -28
- data/lib/skeem/version.rb +3 -1
- data/lib/skeem.rb +2 -0
- data/skeem.gemspec +9 -6
- 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 +84 -44
- data/spec/skeem/lambda_spec.rb +13 -11
- data/spec/skeem/parser_spec.rb +23 -19
- data/spec/skeem/primitive/primitive_builder_spec.rb +65 -48
- 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 +18 -10
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
|