skeem 0.0.28 → 0.1.00

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9c6cb859a4082620c599599f02f5948ee5608d79
4
- data.tar.gz: 742acc6b351efce05a6d40f7c9b558368c734fd5
3
+ metadata.gz: c18e55326253e46eb6287437d7730b35a115ac6d
4
+ data.tar.gz: 5e868f0b8fb7fc6f0814a3dc25f7f09d1b4c542f
5
5
  SHA512:
6
- metadata.gz: fc51a07506b30450c78fd538a9127926378d6fdc3d165a1a3e075424295876a2727734bc4b969895f6f6bc76ea3f7c6a5e5ea6cdaec9495556a34b3d8e7c8c80
7
- data.tar.gz: 076b28ff2fc211ed0ae3e2bf3cdfa08f4d220f5682c72f8f59e98dfe84f2555aa9ebbb529e08d94c24349e3845aad836c64eb541c5c2f414f917678fc36f096b
6
+ metadata.gz: 192c9172702d53cbbe60475740a4cb6e95b7641a6d817287d3b446eb4d40ebc4662f3cfc2eec0e36d40717b076a08005e2e541bcd8639bdb5661e3f153a727da
7
+ data.tar.gz: c2ae96f49f854b63919966ecd1d9275f89da8a1487230c78509e1533a8748813b589f571dcca9065f3262fd51e167608e8759e0412dd1c69c43c4579af0e9305
data/CHANGELOG.md CHANGED
@@ -1,9 +1,32 @@
1
+ ## [0.1.00] - 2018-12-28
2
+ - Version bumped because lists are re-implemented in a way to closer to historical Scheme/Lisp.
3
+ - A lot of internal refactoring after list re-implementation...
4
+
5
+ ### Added
6
+ - File `primitive_builder.rb` implementation of: `pair?`, `car`, `cdr`, `cons`, `list->vectors` list procedures.
7
+ - File `primitive_builder.rb` implementation of: `vector->list` vector procedures.
8
+
9
+ ### Changed
10
+ - Class `SkmList` is now deprecated and being replaced by `SkmPair`nodes.
11
+ - Class `SkmElementVisitor` supports new visit events: `visit_empty_list` and `visit_pair`
12
+
13
+
14
+ ## [0.0.28] - 2018-12-10
15
+ - Nasty bug fix: interpreter was'nt able to retrieve data argument deep in call stack.
16
+
17
+ ### Added
18
+ - Method `Environment#inspect`
19
+
20
+ ### Fixed
21
+ - Method `SkmDefinition#call` now accepts variable references that refer to a lambda or a primitive procedure.
22
+ - Method `SkmLambda#evaluate_sequence` failed when argument value came from a caller deep in call stack?
23
+ - Added a specific test in `interpreter_spec.rb`
24
+
1
25
  ## [0.0.27] - 2018-11-25
2
26
  ### Fixed
3
27
  - The interpreter failed with second-order lambdas (lambda expression that contains another lambda)
4
28
  - Added a specific test in `interpreter_spec.rb`
5
29
 
6
-
7
30
  ## [0.0.26] - 2018-11-25
8
31
 
9
32
  ### Added
data/README.md CHANGED
@@ -178,7 +178,7 @@ This section lists the implemented standard procedures
178
178
  * Integer-level: `even?`, `odd?`
179
179
 
180
180
  #### List procedures
181
- * `list?`, `null?`, `list`, `length`
181
+ * `list?`, `null?`, `pair?`, `car`, `cdr`, `cons`, `length`, `list`, `list->vector`
182
182
 
183
183
  #### String procedures
184
184
  * `string?`, `string=?`, `string-append`, `string-length`, `string->symbol`,
@@ -187,7 +187,7 @@ This section lists the implemented standard procedures
187
187
  * `symbol?`, `symbol=?`
188
188
 
189
189
  #### Vector procedures
190
- * `vector?`, `vector`, `vector-length`, `vector-set!`
190
+ * `vector?`, `vector`, `vector-length`, `vector-set!`, `vector->list`
191
191
 
192
192
  #### Input/output procedures
193
193
  * `newline`
@@ -204,7 +204,7 @@ Roadmap:
204
204
  - Extend the language in order to support [Minikanren](https://github.com/TheReasonedSchemer2ndEd/CodeFromTheReasonedSchemer2ndEd)
205
205
  - Make it pass all examples from the [Reasoned Schemer](https://mitpress.mit.edu/books/reasoned-schemer-second-edition) book.
206
206
 
207
- ## Other Scheme implementation in Ruby
207
+ ## Other Scheme implementations in Ruby
208
208
  __Skeem__ isn't the sole implementation of the Scheme language in Ruby.
209
209
  Here are a few other ones:
210
210
  - [Heist gem](https://rubygems.org/gems/heist) -- Probably one of best Scheme implementation in Ruby. Really worth a try. Alas, the [project](https://github.com/jcoglan/heist) seems to be dormant for several years.
@@ -1,5 +1,6 @@
1
1
  require_relative 'skm_simple_datum'
2
2
  require_relative 'skm_compound_datum'
3
+ require_relative 'skm_pair'
3
4
 
4
5
  module Skeem
5
6
  # Mixin module that provides factory methods that ease the conversion of
@@ -75,16 +76,16 @@ module Skeem
75
76
  def list(aLiteral)
76
77
  result = case aLiteral
77
78
  when Array
78
- SkmList.new(to_datum(aLiteral))
79
- when SkmList
80
- SkmList.new(to_datum(aLiteral.members))
79
+ SkmPair.create_from_a(to_datum(aLiteral))
80
+ when SkmPair
81
+ SkmPair.create_from_a(to_datum(aLiteral.to_a))
81
82
  else
82
- SkmList.new([to_datum(aLiteral)])
83
+ SkmPair.new(to_datum(aLiteral), SkmEmptyList.instance)
83
84
  end
84
85
 
85
86
  result
86
87
  end
87
-
88
+
88
89
  def vector(aLiteral)
89
90
  result = case aLiteral
90
91
  when Array
@@ -96,8 +97,9 @@ module Skeem
96
97
  end
97
98
 
98
99
  result
99
- end
100
+ end
100
101
 
102
+ # Conversion from Ruby object value to Skeem datum
101
103
  def to_datum(aLiteral)
102
104
  return aLiteral if aLiteral.kind_of?(SkmSimpleDatum)
103
105
  return list(aLiteral.members) if aLiteral.kind_of?(SkmList)
@@ -114,6 +116,9 @@ module Skeem
114
116
  SkmBoolean.create(aLiteral)
115
117
  when String
116
118
  parse_literal(aLiteral)
119
+ when SkmPair # Special case: not a PORO literal
120
+ # One assumes that a Skeem list contains only Skeem datum objects
121
+ SkmPair.create_from_a(aLiteral.to_a)
117
122
  else
118
123
  raise StandardError, aLiteral.inspect
119
124
  end
@@ -49,8 +49,21 @@ module Skeem
49
49
  broadcast(:after_compound_datum, aCompoundDatum)
50
50
  end
51
51
 
52
+ # Visit event. The visitor is visiting the
53
+ # given empty list object.
54
+ # @param anEmptyList [SkmEmptyList] the empty list object to visit.
55
+ def visit_empty_list(anEmptyList)
56
+ broadcast(:before_empty_list, anEmptyList)
57
+ broadcast(:after_empty_list, anEmptyList)
58
+ end
52
59
 
53
60
 
61
+ def visit_pair(aPair)
62
+ broadcast(:before_pair, aPair)
63
+ traverse_car_cdr(aPair)
64
+ broadcast(:after_pair, aPair)
65
+ end
66
+
54
67
  =begin
55
68
  # Visit event. The visitor is about to visit the given non terminal node.
56
69
  # @param aNonTerminalNode [NonTerminalNode] the node to visit.
@@ -78,6 +91,19 @@ module Skeem
78
91
  broadcast(:after_children, aParent, children)
79
92
  end
80
93
 
94
+ def traverse_car_cdr(aPair)
95
+ if aPair.car
96
+ broadcast(:before_car, aPair, aPair.car)
97
+ aPair.car.accept(self)
98
+ broadcast(:after_car, aPair, aPair.car)
99
+ end
100
+ if aPair.cdr
101
+ broadcast(:before_cdr, aPair, aPair.cdr)
102
+ aPair.cdr.accept(self)
103
+ broadcast(:after_cdr, aPair, aPair.cdr)
104
+ end
105
+ end
106
+
81
107
  # Send a notification to all subscribers.
82
108
  # @param msg [Symbol] event to notify
83
109
  # @param args [Array] arguments of the notification.
data/lib/skeem/grammar.rb CHANGED
@@ -54,7 +54,7 @@ module Skeem
54
54
  rule 'compound_datum' => 'list'
55
55
  rule 'compound_datum' => 'vector'
56
56
  rule('list' => 'LPAREN datum_star RPAREN').as 'list'
57
- rule 'list' => 'LPAREN datum_plus PERIOD datum RPAREN'
57
+ rule('list' => 'LPAREN datum_plus PERIOD datum RPAREN').as 'dotted_list'
58
58
  rule('vector' => 'VECTOR_BEGIN datum_star RPAREN').as 'vector'
59
59
  rule('datum_plus' => 'datum_plus datum').as 'multiple_datums'
60
60
  rule('datum_plus' => 'datum').as 'last_datum'
@@ -1,5 +1,6 @@
1
1
  require_relative 'primitive_procedure'
2
2
  require_relative '../datum_dsl'
3
+ require_relative '../skm_pair'
3
4
  # require_relative '../s_expr_nodes'
4
5
 
5
6
  module Skeem
@@ -92,7 +93,12 @@ module Skeem
92
93
  def add_list_procedures(aRuntime)
93
94
  create_object_predicate(aRuntime, 'list?')
94
95
  create_object_predicate(aRuntime, 'null?')
96
+ create_object_predicate(aRuntime, 'pair?')
97
+ create_cons(aRuntime)
98
+ create_car(aRuntime)
99
+ create_cdr(aRuntime)
95
100
  create_length(aRuntime)
101
+ create_list2vector(aRuntime)
96
102
  end
97
103
 
98
104
  def add_vector_procedures(aRuntime)
@@ -100,6 +106,7 @@ module Skeem
100
106
  create_vector(aRuntime)
101
107
  create_vector_length(aRuntime)
102
108
  create_vector_ref(aRuntime)
109
+ create_vector2list(aRuntime)
103
110
  end
104
111
 
105
112
  def add_io_procedures(aRuntime)(aRuntime)
@@ -132,7 +139,7 @@ module Skeem
132
139
  else
133
140
  first_one = arglist.first.evaluate(runtime)
134
141
  raw_result = first_one.value
135
- operands = evaluate_tail(arglist, runtime)
142
+ operands = remaining_args(arglist, runtime)
136
143
  operands.each { |elem| raw_result += elem.value }
137
144
  to_datum(raw_result)
138
145
  end
@@ -147,7 +154,7 @@ module Skeem
147
154
  if arglist.empty?
148
155
  raw_result = -raw_result
149
156
  else
150
- operands = evaluate_array(arglist, runtime)
157
+ operands = arglist.evaluate(runtime).to_a
151
158
  operands.each { |elem| raw_result -= elem.value }
152
159
  end
153
160
  to_datum(raw_result)
@@ -163,15 +170,8 @@ module Skeem
163
170
  else
164
171
  first_one = arglist.first.evaluate(runtime)
165
172
  raw_result = first_one.value
166
- operands = evaluate_tail(arglist, runtime)
167
- begin
173
+ operands = remaining_args(arglist, runtime)
168
174
  operands.each { |elem| raw_result *= elem.value }
169
- rescue NoMethodError => exc
170
- # $stderr.puts aRuntime.environment.inspect
171
- # $stderr.puts first_one.inspect
172
- # $stderr.puts operands.inspect
173
- raise exc
174
- end
175
175
  to_datum(raw_result)
176
176
  end
177
177
  end
@@ -186,7 +186,7 @@ module Skeem
186
186
  if arglist.empty?
187
187
  raw_result = 1 / raw_result.to_f
188
188
  else
189
- operands = evaluate_array(arglist, runtime)
189
+ operands = arglist.evaluate(runtime).to_a
190
190
  operands.each do |elem|
191
191
  if raw_result > elem.value && raw_result.modulo(elem.value).zero?
192
192
  raw_result /= elem.value
@@ -212,7 +212,7 @@ module Skeem
212
212
 
213
213
  define_primitive_proc(aRuntime, 'floor-remainder', binary, primitive)
214
214
  end
215
-
215
+
216
216
  def create_eqv?(aRuntime)
217
217
  primitive = ->(runtime, argument1, argument2) do
218
218
  operand_1 = argument1.evaluate(runtime)
@@ -221,7 +221,7 @@ module Skeem
221
221
  to_datum(raw_result)
222
222
  end
223
223
 
224
- define_primitive_proc(aRuntime, 'eqv?', binary, primitive)
224
+ define_primitive_proc(aRuntime, 'eqv?', binary, primitive)
225
225
  end
226
226
 
227
227
  def create_equal(aRuntime)
@@ -230,7 +230,7 @@ module Skeem
230
230
  if arglist.empty?
231
231
  boolean(true)
232
232
  else
233
- operands = evaluate_array(arglist, runtime)
233
+ operands = arglist.evaluate(runtime).to_a
234
234
  first_value = first_one.value
235
235
  all_equal = operands.all? { |elem| first_value == elem.value }
236
236
  boolean(all_equal)
@@ -246,7 +246,7 @@ module Skeem
246
246
  boolean(false)
247
247
  else
248
248
  operands = [first_operand.evaluate(runtime)]
249
- operands.concat(evaluate_array(arglist, runtime))
249
+ operands.concat(arglist.evaluate(runtime).to_a)
250
250
  result = true
251
251
  operands.each_cons(2) do |(elem1, elem2)|
252
252
  result &&= elem1.value < elem2.value
@@ -264,7 +264,7 @@ module Skeem
264
264
  boolean(false)
265
265
  else
266
266
  operands = [first_operand.evaluate(runtime)]
267
- operands.concat(evaluate_array(arglist, runtime))
267
+ operands.concat(arglist.evaluate(runtime).to_a)
268
268
  result = true
269
269
  operands.each_cons(2) do |(elem1, elem2)|
270
270
  result &&= elem1.value > elem2.value
@@ -282,7 +282,7 @@ module Skeem
282
282
  boolean(true)
283
283
  else
284
284
  operands = [first_operand.evaluate(runtime)]
285
- operands.concat(evaluate_array(arglist, runtime))
285
+ operands.concat(arglist.evaluate(runtime).to_a)
286
286
  result = true
287
287
  operands.each_cons(2) do |(elem1, elem2)|
288
288
  result &&= elem1.value <= elem2.value
@@ -300,11 +300,12 @@ module Skeem
300
300
  boolean(true)
301
301
  else
302
302
  operands = [first_operand.evaluate(runtime)]
303
- operands.concat(evaluate_array(arglist, runtime))
303
+ operands.concat(arglist.evaluate(runtime).to_a)
304
304
  result = true
305
305
  operands.each_cons(2) do |(elem1, elem2)|
306
306
  result &&= elem1.value >= elem2.value
307
307
  end
308
+
308
309
  boolean(result)
309
310
  end
310
311
  end
@@ -331,6 +332,7 @@ module Skeem
331
332
  else
332
333
  raw_result = true
333
334
  last_result = nil
335
+ # $stderr.puts arglist.inspect
334
336
  arglist.each do |raw_arg|
335
337
  argument = raw_arg.evaluate(aRuntime)
336
338
  last_result = argument
@@ -338,6 +340,9 @@ module Skeem
338
340
  break unless raw_result
339
341
  end
340
342
  raw_result = last_result if raw_result
343
+ # $stderr.puts raw_result.inspect
344
+ # $stderr.puts raw_result.cdr.inspect if raw_result.kind_of?(SkmPair)
345
+ # $stderr.puts to_datum(raw_result).inspect
341
346
  to_datum(raw_result)
342
347
  end
343
348
  end
@@ -371,7 +376,7 @@ module Skeem
371
376
  if arglist.empty?
372
377
  boolean(true)
373
378
  else
374
- operands = evaluate_array(arglist, runtime)
379
+ operands = evaluate_arguments(arglist, runtime)
375
380
  first_value = first_one.value
376
381
  all_equal = operands.all? { |elem| first_value == elem.value }
377
382
  boolean(all_equal)
@@ -386,7 +391,7 @@ module Skeem
386
391
  if arglist.empty?
387
392
  value = ''
388
393
  else
389
- parts = evaluate_array(arglist, aRuntime)
394
+ parts = evaluate_arguments(arglist, aRuntime)
390
395
  value = parts.reduce('') { |interim, substr| interim << substr.value }
391
396
  end
392
397
 
@@ -416,22 +421,60 @@ module Skeem
416
421
  define_primitive_proc(aRuntime, 'string->symbol', unary, primitive)
417
422
  end
418
423
 
424
+ def create_cons(aRuntime)
425
+ primitive = ->(runtime, obj1, obj2) do
426
+ SkmPair.new(obj1.evaluate(aRuntime), obj2.evaluate(aRuntime))
427
+ end
428
+
429
+ define_primitive_proc(aRuntime, 'cons', binary, primitive)
430
+ end
431
+
432
+ def create_car(aRuntime)
433
+ primitive = ->(runtime, arg) do
434
+ arg_evaluated = arg.evaluate(runtime)
435
+ check_argtype(arg_evaluated, SkmPair, 'pair', 'car')
436
+ arg_evaluated.car
437
+ end
438
+
439
+ define_primitive_proc(aRuntime, 'car', unary, primitive)
440
+ end
441
+
442
+ def create_cdr(aRuntime)
443
+ primitive = ->(runtime, arg) do
444
+ arg_evaluated = arg.evaluate(runtime)
445
+ check_argtype(arg_evaluated, SkmPair, 'pair', 'cdr')
446
+ arg_evaluated.cdr
447
+ end
448
+
449
+ define_primitive_proc(aRuntime, 'cdr', unary, primitive)
450
+ end
451
+
419
452
  def create_length(aRuntime)
420
453
  primitive = ->(runtime, arg) do
421
454
  arg_evaluated = arg.evaluate(runtime)
422
- check_argtype(arg_evaluated, SkmList, 'list', 'length')
455
+ check_argtype(arg_evaluated, [SkmPair, SkmEmptyList], 'list', 'length')
423
456
  integer(arg_evaluated.length)
424
457
  end
425
458
 
426
459
  define_primitive_proc(aRuntime, 'length', unary, primitive)
427
460
  end
428
461
 
462
+ def create_list2vector(aRuntime)
463
+ primitive = ->(runtime, arg) do
464
+ arg_evaluated = arg.evaluate(runtime)
465
+ check_argtype(arg_evaluated, [SkmPair, SkmEmptyList], 'list', 'list->vector')
466
+ vector(arg_evaluated.to_a)
467
+ end
468
+
469
+ define_primitive_proc(aRuntime, 'list->vector', unary, primitive)
470
+ end
471
+
429
472
  def create_vector(aRuntime)
430
473
  primitive = ->(runtime, arglist) do
431
474
  if arglist.empty?
432
475
  elements = []
433
476
  else
434
- elements = evaluate_array(arglist, aRuntime)
477
+ elements = evaluate_arguments(arglist, aRuntime)
435
478
  end
436
479
 
437
480
  vector(elements)
@@ -465,6 +508,16 @@ module Skeem
465
508
  define_primitive_proc(aRuntime, 'vector-ref', binary, primitive)
466
509
  end
467
510
 
511
+ def create_vector2list(aRuntime)
512
+ primitive = ->(runtime, arg) do
513
+ arg_evaluated = arg.evaluate(runtime)
514
+ check_argtype(arg_evaluated, SkmVector, 'vector', 'vector->list')
515
+ SkmPair.create_from_a(arg_evaluated.members)
516
+ end
517
+
518
+ define_primitive_proc(aRuntime, 'vector->list', unary, primitive)
519
+ end
520
+
468
521
  def create_newline(aRuntime)
469
522
  primitive = ->(runtime) do
470
523
  # @TODO: make output stream configurable
@@ -473,13 +526,13 @@ module Skeem
473
526
 
474
527
  define_primitive_proc(aRuntime, 'newline', nullary, primitive)
475
528
  end
476
-
529
+
477
530
  def create_assert(aRuntime)
478
531
  primitive = ->(runtime, arg) do
479
532
  arg_evaluated = arg.evaluate(runtime)
480
533
  if arg_evaluated.boolean? && arg_evaluated.value == false
481
534
  assert_call = aRuntime.caller
482
- pos = assert_call.call_site
535
+ pos = assert_call.call_site
483
536
  # Error: assertion failed: (> 1 2)
484
537
  msg = "assertion failed on line #{pos.line}, column #{pos.column}"
485
538
  raise StandardError, 'Error: ' + msg
@@ -525,20 +578,45 @@ module Skeem
525
578
  aRuntime.define(aKey, anEntry)
526
579
  end
527
580
 
528
- def evaluate_array(anArray, aRuntime)
529
- anArray.map { |elem| elem.evaluate(aRuntime) }
530
- end
531
-
532
- def evaluate_tail(anArray, aRuntime)
533
- evaluate_array(anArray.drop(1), aRuntime)
581
+ def evaluate_arguments(arglist, aRuntime)
582
+ case arglist
583
+ when Array
584
+ arglist.map { |elem| elem.evaluate(aRuntime) }
585
+ when SkmPair
586
+ arglist.evaluate(aRuntime).to_a
587
+ end
534
588
  end
535
589
 
536
590
  def check_argtype(argument, requiredRubyClass, requiredSkmType, aProcName)
591
+ if requiredRubyClass.kind_of?(Array)
592
+ unless requiredRubyClass.include?(argument.class)
593
+ type_error(argument, requiredSkmType, aProcName)
594
+ end
595
+ else
537
596
  unless argument.kind_of?(requiredRubyClass)
538
- msg1 = "Procedure '#{aProcName}': #{requiredSkmType} argument required,"
539
- msg2 = "but got #{argument.value}"
540
- raise StandardError, msg1 + ' ' + msg2
597
+ type_error(argument, requiredSkmType, aProcName)
541
598
  end
599
+ end
600
+ end
601
+
602
+ def type_error(argument, requiredSkmType, aProcName)
603
+ msg1 = "Procedure '#{aProcName}': #{requiredSkmType} argument required,"
604
+ if argument.respond_to?(:value)
605
+ msg2 = "but got #{argument.value}"
606
+ else
607
+ msg2 = "but got #{argument.class}"
608
+ end
609
+ raise StandardError, msg1 + ' ' + msg2
610
+ end
611
+
612
+ def remaining_args(arglist, aRuntime)
613
+ case arglist
614
+ when Array
615
+ raw_arg = arglist[1..-1]
616
+ when SkmPair
617
+ raw_arg = arglist.cdr.to_a
618
+ end
619
+ raw_arg.map { |arg| arg.evaluate(aRuntime) }
542
620
  end
543
621
  end # module
544
622
  end # module
@@ -16,9 +16,10 @@ module Skeem
16
16
 
17
17
  # Arguments are positional in a primitive procedure.
18
18
  def call(aRuntime, aProcedureCall)
19
- check_actual_count(aProcedureCall)
19
+ actuals = aProcedureCall.operands.to_a
20
+ check_actual_count(actuals)
20
21
  aProcedureCall.operands_consumed = true
21
- do_call(aRuntime, aProcedureCall.operands.to_a)
22
+ do_call(aRuntime, actuals)
22
23
  end
23
24
 
24
25
  private
@@ -50,8 +51,8 @@ module Skeem
50
51
  anArity
51
52
  end
52
53
 
53
- def check_actual_count(aProcedureCall)
54
- count_actuals = aProcedureCall.operands.size
54
+ def check_actual_count(actuals)
55
+ count_actuals = actuals.size
55
56
  if arity.nullary?
56
57
  unless count_actuals.zero?
57
58
  wrong_number_arguments(arity.high, count_actuals)
@@ -77,7 +78,7 @@ module Skeem
77
78
  arguments = []
78
79
  arguments << operands.take(arity.low).flatten
79
80
  count_delta = operands.size - arity.low
80
- arguments << SkmList.new(operands.slice(-count_delta, count_delta))
81
+ arguments << SkmPair.create_from_a(operands.slice(-count_delta, count_delta))
81
82
  #p operands.size
82
83
  #p count_delta
83
84
  #p arguments.inspect
data/lib/skeem/runtime.rb CHANGED
@@ -57,11 +57,11 @@ module Skeem
57
57
  end
58
58
  end
59
59
 
60
- # @param aList[SkmList] first member is an identifier.
60
+ # @param aList[SkmPair] first member is an identifier.
61
61
  def evaluate_form(aList)
62
62
  # TODO: manage the cases where first_member is a keyword
63
- first_member = aList.first
64
- invokation = ProcedureCall.new(nil, first_member, aList.tail.members)
63
+ first_member = aList.car
64
+ invokation = ProcedureCall.new(nil, first_member, aList.cdr.to_a)
65
65
  invokation.evaluate(self)
66
66
  end
67
67
 
@@ -98,9 +98,9 @@ module Skeem
98
98
  raise StandardError, "Invalid call object #{aProcCall.inspect}"
99
99
  end
100
100
  # $stderr.puts 'CALL STACK vvvv'
101
- call_stack.each do |proc_call|
101
+ # call_stack.each do |proc_call|
102
102
  # $stderr.puts proc_call.inspect
103
- end
103
+ # end
104
104
  # $stderr.puts 'CALL STACK ^^^^'
105
105
  end
106
106
 
@@ -1,4 +1,5 @@
1
1
  require 'stringio'
2
+ require_relative 'skm_pair'
2
3
  require_relative 's_expr_nodes'
3
4
 
4
5
  module Skeem
@@ -38,8 +39,9 @@ module Skeem
38
39
  # rule('program' => 'cmd_or_def_plus').as 'main'
39
40
  def reduce_main(_production, _range, _tokens, theChildren)
40
41
  last_child = theChildren.last
41
- result = if last_child.members.size == 1
42
- last_child.members[0]
42
+ # $stderr.puts last_child.inspect
43
+ result = if last_child.length == 1
44
+ last_child.car
43
45
  else
44
46
  last_child
45
47
  end
@@ -47,13 +49,13 @@ module Skeem
47
49
 
48
50
  # rule('cmd_or_def_plus' => 'cmd_or_def_plus cmd_or_def').as 'multiple_cmd_def'
49
51
  def reduce_multiple_cmd_def(_production, _range, _tokens, theChildren)
50
- theChildren[0].members << theChildren[1]
52
+ theChildren[0].append(theChildren[1])
51
53
  theChildren[0]
52
54
  end
53
55
 
54
56
  # rule('cmd_or_def_plus' => 'cmd_or_def').as 'last_cmd_def'
55
57
  def reduce_last_cmd_def(_production, _range, _tokens, theChildren)
56
- SkmList.new([theChildren.last])
58
+ SkmPair.create_from_a([theChildren.last])
57
59
  end
58
60
 
59
61
  # rule('definition' => 'LPAREN DEFINE IDENTIFIER expression RPAREN')
@@ -86,9 +88,24 @@ module Skeem
86
88
  end
87
89
 
88
90
  # rule('list' => 'LPAREN datum_star RPAREN').as 'list'
89
- def reduce_list(_production, aRange, _tokens, theChildren)
90
- SkmList.new(theChildren[1])
91
+ def reduce_list(_production, _range, _tokens, theChildren)
92
+ SkmPair.create_from_a(theChildren[1])
91
93
  end
94
+
95
+ # rule('list' => 'LPAREN datum_plus PERIOD datum RPAREN').as 'dotted_list'
96
+ def reduce_dotted_list(_production, _range, _tokens, theChildren)
97
+ # if theChildren[1].kind_of?(Array)
98
+ # if theChildren[1].size == 1
99
+ # car_arg = theChildren[1].first
100
+ # else
101
+ # car_arg = SkmPair.create_from_a(theChildren[1])
102
+ # end
103
+ # else
104
+ # car_arg = theChildren[1]
105
+ # end
106
+
107
+ SkmPair.new(theChildren[1], theChildren[3])
108
+ end
92
109
 
93
110
  # rule('vector' => 'VECTOR_BEGIN datum_star RPAREN').as 'vector'
94
111
  def reduce_vector(_production, aRange, _tokens, theChildren)
@@ -197,7 +214,7 @@ module Skeem
197
214
 
198
215
  # rule('sequence' => 'command_star expression').as 'sequence'
199
216
  def reduce_sequence(_production, _range, _tokens, theChildren)
200
- SkmList.new(theChildren[0] << theChildren[1])
217
+ SkmPair.create_from_a(theChildren[0] << theChildren[1])
201
218
  end
202
219
 
203
220
  # rule('command_star' => 'command_star command').as 'multiple_commands'
@@ -225,22 +242,21 @@ module Skeem
225
242
  # $stderr.puts theChildren[1].inspect
226
243
  SkmQuasiquotation.new(theChildren[1])
227
244
  end
228
-
245
+
229
246
  # rule('list_qq_template' => 'LPAREN qq_template_or_splice_star RPAREN').as 'list_qq'
230
247
  def reduce_list_qq(_production, _range, _tokens, theChildren)
231
- SkmList.new(theChildren[1])
232
- end
248
+ SkmPair.create_from_a(theChildren[1])
249
+ end
233
250
 
234
251
  # rule('vector_qq_template' => 'VECTOR_BEGIN qq_template_or_splice_star RPAREN').as 'vector_qq'
235
252
  def reduce_vector_qq(_production, _range, _tokens, theChildren)
236
253
  SkmVector.new(theChildren[1])
237
254
  end
238
-
255
+
239
256
  # rule('unquotation' => 'COMMA qq_template').as 'unquotation_short'
240
257
  def reduce_unquotation_short(_production, aRange, _tokens, theChildren)
241
258
  SkmUnquotation.new(theChildren[1])
242
259
  end
243
-
244
260
 
245
261
  # rule('qq_template_or_splice_star' => 'qq_template_or_splice_star qq_template_or_splice').as 'multiple_template_splice'
246
262
  def reduce_multiple_template_splice(_production, _range, _tokens, theChildren)