skeem 0.0.28 → 0.1.00

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