skeem 0.2.15 → 0.2.16

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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +17 -11
  3. data/CHANGELOG.md +5 -0
  4. data/Gemfile +2 -0
  5. data/README.md +3 -2
  6. data/Rakefile +2 -0
  7. data/appveyor.yml +3 -4
  8. data/bin/skeem +15 -15
  9. data/lib/skeem.rb +2 -0
  10. data/lib/skeem/datum_dsl.rb +12 -3
  11. data/lib/skeem/element_visitor.rb +5 -2
  12. data/lib/skeem/grammar.rb +86 -24
  13. data/lib/skeem/interpreter.rb +5 -3
  14. data/lib/skeem/parser.rb +6 -4
  15. data/lib/skeem/primitive/primitive_builder.rb +128 -115
  16. data/lib/skeem/primitive/primitive_procedure.rb +17 -20
  17. data/lib/skeem/runtime.rb +9 -5
  18. data/lib/skeem/s_expr_builder.rb +46 -104
  19. data/lib/skeem/s_expr_nodes.rb +116 -90
  20. data/lib/skeem/skeem_exception.rb +0 -0
  21. data/lib/skeem/skm_binding.rb +6 -7
  22. data/lib/skeem/skm_compound_datum.rb +8 -4
  23. data/lib/skeem/skm_element.rb +14 -12
  24. data/lib/skeem/skm_empty_list.rb +6 -4
  25. data/lib/skeem/skm_exception.rb +9 -0
  26. data/lib/skeem/skm_expression.rb +3 -1
  27. data/lib/skeem/skm_frame.rb +3 -2
  28. data/lib/skeem/skm_pair.rb +23 -18
  29. data/lib/skeem/skm_procedure_exec.rb +8 -6
  30. data/lib/skeem/skm_simple_datum.rb +13 -12
  31. data/lib/skeem/skm_unary_expression.rb +15 -17
  32. data/lib/skeem/tokenizer.rb +32 -25
  33. data/lib/skeem/version.rb +3 -1
  34. data/skeem.gemspec +6 -4
  35. data/spec/skeem/add4.skm +4 -0
  36. data/spec/skeem/datum_dsl_spec.rb +13 -12
  37. data/spec/skeem/element_visitor_spec.rb +12 -10
  38. data/spec/skeem/interpreter_spec.rb +74 -46
  39. data/spec/skeem/lambda_spec.rb +9 -7
  40. data/spec/skeem/parser_spec.rb +21 -19
  41. data/spec/skeem/primitive/primitive_builder_spec.rb +57 -48
  42. data/spec/skeem/primitive/primitive_procedure_spec.rb +15 -13
  43. data/spec/skeem/runtime_spec.rb +18 -16
  44. data/spec/skeem/s_expr_nodes_spec.rb +8 -6
  45. data/spec/skeem/skm_compound_datum_spec.rb +11 -9
  46. data/spec/skeem/skm_element_spec.rb +7 -5
  47. data/spec/skeem/skm_empty_list_spec.rb +7 -5
  48. data/spec/skeem/skm_frame_spec.rb +5 -4
  49. data/spec/skeem/skm_pair_spec.rb +4 -3
  50. data/spec/skeem/skm_procedure_exec_spec.rb +2 -0
  51. data/spec/skeem/skm_simple_datum_spec.rb +24 -22
  52. data/spec/skeem/skm_unary_expression_spec.rb +11 -9
  53. data/spec/skeem/tokenizer_spec.rb +53 -44
  54. data/spec/skeem_spec.rb +2 -0
  55. data/spec/spec_helper.rb +4 -2
  56. metadata +7 -4
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'parser'
2
4
  require_relative 'skm_frame'
3
5
  require_relative 'runtime'
@@ -9,7 +11,7 @@ module Skeem
9
11
  attr_reader(:parser)
10
12
  attr_reader(:runtime)
11
13
 
12
- def initialize(&aBlock)
14
+ def initialize
13
15
  @runtime = Runtime.new(SkmFrame.new)
14
16
  @parser = Parser.new
15
17
 
@@ -20,7 +22,7 @@ module Skeem
20
22
  end
21
23
  end
22
24
 
23
- def add_default_procedures()
25
+ def add_default_procedures
24
26
  add_primitives(runtime)
25
27
  add_standard(runtime)
26
28
  end
@@ -57,4 +59,4 @@ module Skeem
57
59
  end
58
60
  end
59
61
  end # class
60
- end # module
62
+ end # module
data/lib/skeem/parser.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'tokenizer'
2
4
  require_relative 'grammar'
3
5
  require_relative 's_expr_builder'
@@ -5,10 +7,10 @@ require_relative 's_expr_builder'
5
7
  module Skeem
6
8
  class Parser
7
9
  attr_reader(:engine)
8
-
9
- def initialize()
10
+
11
+ def initialize
10
12
  # Create a Rley facade object
11
- @engine = Rley::Engine.new do |cfg|
13
+ @engine = Rley::Engine.new do |cfg|
12
14
  cfg.diagnose = true
13
15
  cfg.repr_builder = SkmBuilder
14
16
  end
@@ -16,7 +18,7 @@ module Skeem
16
18
  # Step 1. Load Skeem grammar
17
19
  @engine.use_grammar(Skeem::Grammar)
18
20
  end
19
-
21
+
20
22
  # Parse the given Skeem expression into a parse tree.
21
23
  # @param source [String] Skeem expression to parse
22
24
  # @return [ParseTree] A regexp object equivalent to the Skeem expression.
@@ -1,5 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'primitive_procedure'
2
4
  require_relative '../datum_dsl'
5
+ require_relative '../skm_exception'
3
6
  require_relative '../skm_pair'
4
7
 
5
8
  module Skeem
@@ -34,7 +37,7 @@ module Skeem
34
37
  def binary
35
38
  SkmArity.new(2, 2)
36
39
  end
37
-
40
+
38
41
  def ternary
39
42
  SkmArity.new(3, 3)
40
43
  end
@@ -158,11 +161,12 @@ module Skeem
158
161
  create_map(aRuntime)
159
162
  end
160
163
 
161
- def add_io_procedures(aRuntime)(aRuntime)
164
+ def add_io_procedures(aRuntime)
162
165
  create_display(aRuntime)
163
166
  end
164
167
 
165
168
  def add_special_procedures(aRuntime)
169
+ create_error(aRuntime)
166
170
  create_test_assert(aRuntime)
167
171
  create_debug(aRuntime)
168
172
  create_inspect(aRuntime)
@@ -170,7 +174,7 @@ module Skeem
170
174
 
171
175
  def create_plus(aRuntime)
172
176
  # arglist should be a Ruby Array
173
- primitive = ->(_runtime, arglist) do
177
+ primitive = lambda do |_runtime, arglist|
174
178
  if arglist.empty?
175
179
  integer(0)
176
180
  else
@@ -184,7 +188,7 @@ module Skeem
184
188
  end
185
189
 
186
190
  def create_minus(aRuntime)
187
- primitive = ->(_runtime, first_operand, arglist) do
191
+ primitive = lambda do |_runtime, first_operand, arglist|
188
192
  raw_result = first_operand.value
189
193
  if arglist.empty?
190
194
  raw_result = -raw_result
@@ -198,7 +202,7 @@ module Skeem
198
202
  end
199
203
 
200
204
  def create_multiply(aRuntime)
201
- primitive = ->(_runtime, arglist) do
205
+ primitive = lambda do |_runtime, arglist|
202
206
  if arglist.empty?
203
207
  integer(1)
204
208
  else
@@ -212,7 +216,6 @@ module Skeem
212
216
  end
213
217
 
214
218
  def reciprocal(aLiteral)
215
-
216
219
  case aLiteral
217
220
  when Integer
218
221
  result = Rational(1, aLiteral)
@@ -226,29 +229,29 @@ module Skeem
226
229
  end
227
230
 
228
231
  def create_divide(aRuntime)
229
- primitive = ->(_runtime, first_operand, arglist) do
232
+ primitive = lambda do |_runtime, first_operand, arglist|
230
233
  raw_result = first_operand.value
231
234
  if arglist.empty?
232
235
  raw_result = reciprocal(raw_result)
233
236
  else
234
237
  # Ugly: Ruby version dependency: Rubies older than 2.4 have class Fixnum instead of Integer
235
- int_class = (RUBY_VERSION[0..2] < "2.4") ? Fixnum : Integer
238
+ int_class = (RUBY_VERSION[0..2] < '2.4') ? Fixnum : Integer
236
239
 
237
240
  arglist.each do |elem|
238
241
  elem_value = elem.value
239
242
  case [raw_result.class, elem_value.class]
240
243
  when [int_class, int_class]
241
244
  if raw_result.modulo(elem_value).zero?
242
- raw_result = raw_result / elem_value
245
+ raw_result /= elem_value
243
246
  else
244
247
  raw_result = Rational(raw_result, elem_value)
245
248
  end
246
249
 
247
250
  when [int_class, Rational]
248
- raw_result = raw_result * reciprocal(elem_value)
251
+ raw_result *= reciprocal(elem_value)
249
252
 
250
253
  when [Rational, Rational]
251
- raw_result = raw_result * reciprocal(elem_value)
254
+ raw_result *= reciprocal(elem_value)
252
255
  else
253
256
  raw_result = raw_result.to_f
254
257
  raw_result /= elem_value
@@ -262,8 +265,8 @@ module Skeem
262
265
  end
263
266
 
264
267
  def create_floor_slash(aRuntime)
265
- primitive = ->(_runtime, operand_1, operand_2) do
266
- (quotient, modulus) = operand_1.value.divmod(operand_2.value)
268
+ primitive = lambda do |_runtime, operand1, operand2|
269
+ (quotient, modulus) = operand1.value.divmod(operand2.value)
267
270
  SkmPair.new(to_datum(quotient), to_datum(modulus)) # improper list!
268
271
  end
269
272
 
@@ -271,10 +274,10 @@ module Skeem
271
274
  end
272
275
 
273
276
  def create_truncate_slash(aRuntime)
274
- primitive = ->(_runtime, operand_1, operand_2) do
275
- modulo_ = operand_1.value / operand_2.value
276
- modulo_ += 1 if modulo_ < 0
277
- remainder_ = operand_1.value.remainder(operand_2.value)
277
+ primitive = lambda do |_runtime, operand1, operand2|
278
+ modulo_ = operand1.value / operand2.value
279
+ modulo_ += 1 if modulo_.negative?
280
+ remainder_ = operand1.value.remainder(operand2.value)
278
281
  SkmPair.new(to_datum(modulo_), to_datum(remainder_)) # improper list!
279
282
  end
280
283
 
@@ -282,7 +285,7 @@ module Skeem
282
285
  end
283
286
 
284
287
  def create_gcd(aRuntime)
285
- primitive = ->(_runtime, arglist) do
288
+ primitive = lambda do |_runtime, arglist|
286
289
  if arglist.empty?
287
290
  integer(0)
288
291
  else
@@ -301,7 +304,7 @@ module Skeem
301
304
  end
302
305
 
303
306
  def create_lcm(aRuntime)
304
- primitive = ->(_runtime, arglist) do
307
+ primitive = lambda do |_runtime, arglist|
305
308
  if arglist.empty?
306
309
  integer(1)
307
310
  else
@@ -315,7 +318,7 @@ module Skeem
315
318
  end
316
319
 
317
320
  def create_numerator(aRuntime)
318
- primitive = ->(_runtime, arg_evaluated) do
321
+ primitive = lambda do |_runtime, arg_evaluated|
319
322
  case arg_evaluated
320
323
  when SkmInteger
321
324
  result = arg_evaluated
@@ -329,7 +332,7 @@ module Skeem
329
332
  end
330
333
 
331
334
  def create_denominator(aRuntime)
332
- primitive = ->(_runtime, arg_evaluated) do
335
+ primitive = lambda do |_runtime, arg_evaluated|
333
336
  case arg_evaluated
334
337
  when SkmInteger
335
338
  result = 1
@@ -343,7 +346,7 @@ module Skeem
343
346
  end
344
347
 
345
348
  def create_floor(aRuntime)
346
- primitive = ->(_runtime, arg_evaluated) do
349
+ primitive = lambda do |_runtime, arg_evaluated|
347
350
  result = arg_evaluated.value.floor
348
351
  integer(result)
349
352
  end
@@ -352,7 +355,7 @@ module Skeem
352
355
  end
353
356
 
354
357
  def create_ceiling(aRuntime)
355
- primitive = ->(_runtime, arg_evaluated) do
358
+ primitive = lambda do |_runtime, arg_evaluated|
356
359
  result = arg_evaluated.value.ceil
357
360
  integer(result)
358
361
  end
@@ -361,7 +364,7 @@ module Skeem
361
364
  end
362
365
 
363
366
  def create_round(aRuntime)
364
- primitive = ->(_runtime, arg_evaluated) do
367
+ primitive = lambda do |_runtime, arg_evaluated|
365
368
  result = arg_evaluated.value.round
366
369
  integer(result)
367
370
  end
@@ -375,8 +378,8 @@ module Skeem
375
378
  end
376
379
 
377
380
  def create_eqv?(aRuntime)
378
- primitive = ->(runtime, operand_1, operand_2) do
379
- core_eqv?(operand_1, operand_2)
381
+ primitive = lambda do |_runtime, operand1, operand2|
382
+ core_eqv?(operand1, operand2)
380
383
  end
381
384
 
382
385
  define_primitive_proc(aRuntime, 'eqv?', binary, primitive)
@@ -388,7 +391,7 @@ module Skeem
388
391
  end
389
392
 
390
393
  def create_eq?(aRuntime)
391
- primitive = ->(_runtime, operand_1, operand_2) do
394
+ primitive = lambda do |_runtime, operand1, operand2|
392
395
  core_eq?(operand1, operand2)
393
396
  end
394
397
 
@@ -396,8 +399,8 @@ module Skeem
396
399
  end
397
400
 
398
401
  def create_equal?(aRuntime)
399
- primitive = ->(_runtime, operand_1, operand_2) do
400
- raw_result = operand_1.skm_equal?(operand_2)
402
+ primitive = lambda do |_runtime, operand1, operand2|
403
+ raw_result = operand1.skm_equal?(operand2)
401
404
  boolean(raw_result)
402
405
  end
403
406
 
@@ -405,7 +408,7 @@ module Skeem
405
408
  end
406
409
 
407
410
  def create_equal(aRuntime)
408
- primitive = ->(_runtime, first_operand, arglist) do
411
+ primitive = lambda do |_runtime, first_operand, arglist|
409
412
  if arglist.empty?
410
413
  boolean(true)
411
414
  else
@@ -419,11 +422,11 @@ module Skeem
419
422
  end
420
423
 
421
424
  def create_lt(aRuntime)
422
- primitive = ->(_runtime, first_operand, arglist) do
425
+ primitive = lambda do |runtime, first_operand, arglist|
423
426
  if arglist.empty?
424
427
  result = false
425
428
  else
426
- result = primitive_comparison(:<, _runtime, first_operand, arglist)
429
+ result = primitive_comparison(:<, runtime, first_operand, arglist)
427
430
  end
428
431
  boolean(result)
429
432
  end
@@ -432,11 +435,11 @@ module Skeem
432
435
  end
433
436
 
434
437
  def create_gt(aRuntime)
435
- primitive = ->(_runtime, first_operand, arglist) do
438
+ primitive = lambda do |runtime, first_operand, arglist|
436
439
  if arglist.empty?
437
440
  result = false
438
441
  else
439
- result = primitive_comparison(:>, _runtime, first_operand, arglist)
442
+ result = primitive_comparison(:>, runtime, first_operand, arglist)
440
443
  end
441
444
  boolean(result)
442
445
  end
@@ -445,11 +448,11 @@ module Skeem
445
448
  end
446
449
 
447
450
  def create_lte(aRuntime)
448
- primitive = ->(_runtime, first_operand, arglist) do
451
+ primitive = lambda do |runtime, first_operand, arglist|
449
452
  if arglist.empty?
450
453
  result = true
451
454
  else
452
- result = primitive_comparison(:<=, _runtime, first_operand, arglist)
455
+ result = primitive_comparison(:<=, runtime, first_operand, arglist)
453
456
  end
454
457
  boolean(result)
455
458
  end
@@ -458,11 +461,11 @@ module Skeem
458
461
  end
459
462
 
460
463
  def create_gte(aRuntime)
461
- primitive = ->(_runtime, first_operand, arglist) do
464
+ primitive = lambda do |runtime, first_operand, arglist|
462
465
  if arglist.empty?
463
466
  result = true
464
467
  else
465
- result = primitive_comparison(:>=, _runtime, first_operand, arglist)
468
+ result = primitive_comparison(:>=, runtime, first_operand, arglist)
466
469
  end
467
470
  boolean(result)
468
471
  end
@@ -481,7 +484,7 @@ module Skeem
481
484
  end
482
485
 
483
486
  def create_max(aRuntime)
484
- primitive = ->(_runtime, first_operand, arglist) do
487
+ primitive = lambda do |_runtime, first_operand, arglist|
485
488
  if arglist.empty?
486
489
  result = first_operand
487
490
  else
@@ -499,7 +502,7 @@ module Skeem
499
502
  end
500
503
 
501
504
  def create_min(aRuntime)
502
- primitive = ->(_runtime, first_operand, arglist) do
505
+ primitive = lambda do |_runtime, first_operand, arglist|
503
506
  if arglist.empty?
504
507
  result = first_operand
505
508
  else
@@ -518,7 +521,7 @@ module Skeem
518
521
 
519
522
  def create_number2string(aRuntime)
520
523
  # TODO: add support for radix argument
521
- primitive = ->(_runtime, arg_evaluated) do
524
+ primitive = lambda do |_runtime, arg_evaluated|
522
525
  check_argtype(arg_evaluated, SkmNumber, 'number', 'number->string')
523
526
  string(arg_evaluated.value)
524
527
  end
@@ -529,7 +532,7 @@ module Skeem
529
532
  def create_and(aRuntime)
530
533
  # arglist should be a Ruby Array
531
534
  # Arguments aren't evaluated yet!...
532
- primitive = ->(runtime, arglist) do
535
+ primitive = lambda do |runtime, arglist|
533
536
  if arglist.empty?
534
537
  boolean(true) # in conformance with 4.2.1
535
538
  else
@@ -537,7 +540,7 @@ module Skeem
537
540
  last_result = nil
538
541
  # $stderr.puts arglist.inspect
539
542
  arglist.each do |raw_arg|
540
- argument = raw_arg.evaluate(aRuntime)
543
+ argument = raw_arg.evaluate(runtime)
541
544
  last_result = argument
542
545
  raw_result &&= !(argument.boolean? && !argument.value)
543
546
  break unless raw_result # stop here, a false was found...
@@ -555,14 +558,14 @@ module Skeem
555
558
  def create_or(aRuntime)
556
559
  # arglist should be a Ruby Array
557
560
  # Arguments aren't evaluated yet!...
558
- primitive = ->(runtime, arglist) do
561
+ primitive = lambda do |runtime, arglist|
559
562
  if arglist.empty?
560
563
  boolean(false) # in conformance with 4.2.1
561
564
  else
562
565
  raw_result = false
563
566
  last_result = nil
564
567
  arglist.each do |raw_arg|
565
- argument = raw_arg.evaluate(aRuntime)
568
+ argument = raw_arg.evaluate(runtime)
566
569
  last_result = argument
567
570
  raw_result ||= (!argument.boolean? || argument.value)
568
571
  break if raw_result # stop here, a true was found...
@@ -602,7 +605,7 @@ module Skeem
602
605
  end
603
606
 
604
607
  def create_boolean_equal(aRuntime)
605
- primitive = ->(_runtime, first_operand, arglist) do
608
+ primitive = lambda do |_runtime, first_operand, arglist|
606
609
  compare_all(first_operand, arglist, :==)
607
610
  end
608
611
 
@@ -610,7 +613,7 @@ module Skeem
610
613
  end
611
614
 
612
615
  def create_char2int(aRuntime)
613
- primitive = ->(runtime, arg_evaluated) do
616
+ primitive = lambda do |_runtime, arg_evaluated|
614
617
  check_argtype(arg_evaluated, SkmChar, 'character', 'char->integer')
615
618
  integer(arg_evaluated.value.ord)
616
619
  end
@@ -619,7 +622,7 @@ module Skeem
619
622
  end
620
623
 
621
624
  def create_int2char(aRuntime)
622
- primitive = ->(runtime, arg_evaluated) do
625
+ primitive = lambda do |_runtime, arg_evaluated|
623
626
  check_argtype(arg_evaluated, SkmInteger, 'integer', 'integer->char')
624
627
  char(arg_evaluated.value.ord)
625
628
  end
@@ -628,7 +631,7 @@ module Skeem
628
631
  end
629
632
 
630
633
  def create_char_equal(aRuntime)
631
- primitive = ->(_runtime, first_operand, arglist) do
634
+ primitive = lambda do |_runtime, first_operand, arglist|
632
635
  compare_all(first_operand, arglist, :==)
633
636
  end
634
637
 
@@ -636,7 +639,7 @@ module Skeem
636
639
  end
637
640
 
638
641
  def create_char_lt(aRuntime)
639
- primitive = ->(_runtime, first_operand, arglist) do
642
+ primitive = lambda do |_runtime, first_operand, arglist|
640
643
  compare_all(first_operand, arglist, :<)
641
644
  end
642
645
 
@@ -644,7 +647,7 @@ module Skeem
644
647
  end
645
648
 
646
649
  def create_char_gt(aRuntime)
647
- primitive = ->(_runtime, first_operand, arglist) do
650
+ primitive = lambda do |_runtime, first_operand, arglist|
648
651
  compare_all(first_operand, arglist, :>)
649
652
  end
650
653
 
@@ -652,7 +655,7 @@ module Skeem
652
655
  end
653
656
 
654
657
  def create_char_lte(aRuntime)
655
- primitive = ->(_runtime, first_operand, arglist) do
658
+ primitive = lambda do |_runtime, first_operand, arglist|
656
659
  compare_all(first_operand, arglist, :<=)
657
660
  end
658
661
 
@@ -660,16 +663,15 @@ module Skeem
660
663
  end
661
664
 
662
665
  def create_char_gte(aRuntime)
663
- primitive = ->(_runtime, first_operand, arglist) do
666
+ primitive = lambda do |_runtime, first_operand, arglist|
664
667
  compare_all(first_operand, arglist, :>=)
665
668
  end
666
669
 
667
670
  define_primitive_proc(aRuntime, 'char>=?', one_or_more, primitive)
668
671
  end
669
672
 
670
-
671
673
  def create_make_string(aRuntime)
672
- primitive = ->(runtime, count_arg, arglist) do
674
+ primitive = lambda do |_runtime, count_arg, arglist|
673
675
  count = count_arg
674
676
  check_argtype(count, SkmInteger, 'integer', 'make-string')
675
677
  if arglist.empty?
@@ -685,11 +687,11 @@ module Skeem
685
687
  end
686
688
 
687
689
  def create_string_string(aRuntime)
688
- primitive = ->(_runtime, arglist) do
690
+ primitive = lambda do |_runtime, arglist|
689
691
  if arglist.empty?
690
692
  value = ''
691
693
  else
692
- value = arglist.reduce('') do |interim, some_char|
694
+ value = arglist.reduce(+'') do |interim, some_char|
693
695
  check_argtype(some_char, SkmChar, 'character', 'string')
694
696
  interim << some_char.value
695
697
  end
@@ -702,7 +704,7 @@ module Skeem
702
704
  end
703
705
 
704
706
  def create_string_equal(aRuntime)
705
- primitive = ->(_runtime, first_operand, arglist) do
707
+ primitive = lambda do |_runtime, first_operand, arglist|
706
708
  all_same?(first_operand, arglist)
707
709
  end
708
710
 
@@ -710,11 +712,11 @@ module Skeem
710
712
  end
711
713
 
712
714
  def create_string_append(aRuntime)
713
- primitive = ->(_runtime, arglist) do
715
+ primitive = lambda do |_runtime, arglist|
714
716
  if arglist.empty?
715
717
  value = ''
716
718
  else
717
- value = arglist.reduce('') { |interim, substr| interim << substr.value }
719
+ value = arglist.reduce(+'') { |interim, substr| interim << substr.value }
718
720
  end
719
721
 
720
722
  string(value)
@@ -724,7 +726,7 @@ module Skeem
724
726
  end
725
727
 
726
728
  def create_string_length(aRuntime)
727
- primitive = ->(runtime, arg_evaluated) do
729
+ primitive = lambda do |_runtime, arg_evaluated|
728
730
  check_argtype(arg_evaluated, SkmString, 'string', 'string-length')
729
731
  integer(arg_evaluated.length)
730
732
  end
@@ -733,7 +735,7 @@ module Skeem
733
735
  end
734
736
 
735
737
  def create_string2symbol(aRuntime)
736
- primitive = ->(runtime, arg_evaluated) do
738
+ primitive = lambda do |_runtime, arg_evaluated|
737
739
  check_argtype(arg_evaluated, SkmString, 'string', 'string->symbol')
738
740
  identifier(arg_evaluated)
739
741
  end
@@ -742,7 +744,7 @@ module Skeem
742
744
  end
743
745
 
744
746
  def create_symbol2string(aRuntime)
745
- primitive = ->(runtime, arg_evaluated) do
747
+ primitive = lambda do |_runtime, arg_evaluated|
746
748
  check_argtype(arg_evaluated, SkmIdentifier, 'symbol', 'symbol->string')
747
749
  string(arg_evaluated)
748
750
  end
@@ -751,7 +753,7 @@ module Skeem
751
753
  end
752
754
 
753
755
  def create_car(aRuntime)
754
- primitive = ->(runtime, arg_evaluated) do
756
+ primitive = lambda do |_runtime, arg_evaluated|
755
757
  check_argtype(arg_evaluated, SkmPair, 'pair', 'car')
756
758
  arg_evaluated.car
757
759
  end
@@ -760,7 +762,7 @@ module Skeem
760
762
  end
761
763
 
762
764
  def create_cdr(aRuntime)
763
- primitive = ->(_runtime, arg_evaluated) do
765
+ primitive = lambda do |_runtime, arg_evaluated|
764
766
  check_argtype(arg_evaluated, SkmPair, 'pair', 'cdr')
765
767
  arg_evaluated.cdr
766
768
  end
@@ -769,15 +771,15 @@ module Skeem
769
771
  end
770
772
 
771
773
  def create_cons(aRuntime)
772
- primitive = ->(_runtime, obj1, obj2) do
774
+ primitive = lambda do |_runtime, obj1, obj2|
773
775
  SkmPair.new(obj1, obj2)
774
776
  end
775
777
 
776
778
  define_primitive_proc(aRuntime, 'cons', binary, primitive)
777
779
  end
778
-
780
+
779
781
  def create_make_list(aRuntime)
780
- primitive = ->(runtime, count_arg, arglist) do
782
+ primitive = lambda do |_runtime, count_arg, arglist|
781
783
  count = count_arg
782
784
  check_argtype(count, SkmInteger, 'integer', 'make-list')
783
785
  if arglist.empty?
@@ -789,11 +791,11 @@ module Skeem
789
791
  SkmPair.create_from_a(arr)
790
792
  end
791
793
 
792
- define_primitive_proc(aRuntime, 'make-list', one_or_two, primitive)
794
+ define_primitive_proc(aRuntime, 'make-list', one_or_two, primitive)
793
795
  end
794
796
 
795
797
  def create_length(aRuntime)
796
- primitive = ->(_runtime, arg_evaluated) do
798
+ primitive = lambda do |_runtime, arg_evaluated|
797
799
  check_argtype(arg_evaluated, [SkmPair, SkmEmptyList], 'list', 'length')
798
800
  integer(arg_evaluated.length)
799
801
  end
@@ -802,7 +804,7 @@ module Skeem
802
804
  end
803
805
 
804
806
  def create_list2vector(aRuntime)
805
- primitive = ->(_runtime, arg_evaluated) do
807
+ primitive = lambda do |_runtime, arg_evaluated|
806
808
  check_argtype(arg_evaluated, [SkmPair, SkmEmptyList], 'list', 'list->vector')
807
809
  vector(arg_evaluated.to_a)
808
810
  end
@@ -818,19 +820,17 @@ module Skeem
818
820
  else
819
821
  but_last = arglist.take(arglist.length - 1)
820
822
  check_arguments(but_last, [SkmPair, SkmEmptyList], 'list', 'append')
821
- result = arglist.shift.klone # First list is taken
823
+ result = arglist.shift.klone # First list is taken
822
824
  arglist.each do |arg|
823
825
  case arg
824
826
  when SkmPair
825
827
  cloned = arg.klone
826
828
  if result.kind_of?(SkmEmptyList)
827
829
  result = cloned
830
+ elsif result.kind_of?(SkmEmptyList)
831
+ result = SkmPair.new(arg, SkmEmptyList.instance)
828
832
  else
829
- if result.kind_of?(SkmEmptyList)
830
- result = SkmPair.new(arg, SkmEmptyList.instance)
831
- else
832
- result.append_list(cloned)
833
- end
833
+ result.append_list(cloned)
834
834
  end
835
835
  when SkmEmptyList
836
836
  # Do nothing
@@ -849,9 +849,9 @@ module Skeem
849
849
 
850
850
  def create_append(aRuntime)
851
851
  # Arguments aren't evaluated yet!...
852
- primitive = ->(runtime, arglist) do
852
+ primitive = lambda do |runtime, arglist|
853
853
  if arglist.size > 1
854
- arguments = evaluate_arguments(arglist, aRuntime)
854
+ arguments = evaluate_arguments(arglist, runtime)
855
855
  else
856
856
  arguments = arglist
857
857
  end
@@ -863,13 +863,14 @@ module Skeem
863
863
  end
864
864
 
865
865
  def create_reverse(aRuntime)
866
- primitive = ->(_runtime, arg_evaluated) do
866
+ primitive = lambda do |_runtime, arg_evaluated|
867
867
  check_argtype(arg_evaluated, [SkmPair, SkmEmptyList], 'list', 'reverse')
868
868
  if arg_evaluated == SkmEmptyList.instance
869
869
  result = arg_evaluated
870
870
  else
871
871
  err_msg = 'reverse procedure requires a proper list as argument'
872
- raise StandardError, err_msg unless arg_evaluated.proper?
872
+ raise StandardError, err_msg unless arg_evaluated.proper?
873
+
873
874
  elems_reversed = arg_evaluated.to_a.reverse
874
875
  result = SkmPair.create_from_a(elems_reversed)
875
876
  end
@@ -881,7 +882,7 @@ module Skeem
881
882
 
882
883
  def create_setcar(aRuntime)
883
884
  # Arguments aren't evaluated yet!...
884
- primitive = ->(runtime, pair_arg, obj_arg) do
885
+ primitive = lambda do |runtime, pair_arg, obj_arg|
885
886
  case pair_arg
886
887
  when SkmPair
887
888
  pair = pair_arg
@@ -906,7 +907,7 @@ module Skeem
906
907
 
907
908
  def create_setcdr(aRuntime)
908
909
  # Arguments aren't evaluated yet!...
909
- primitive = ->(runtime, pair_arg, obj_arg) do
910
+ primitive = lambda do |runtime, pair_arg, obj_arg|
910
911
  case pair_arg
911
912
  when SkmPair
912
913
  pair = pair_arg
@@ -930,21 +931,22 @@ module Skeem
930
931
  end
931
932
 
932
933
  def create_assq(aRuntime)
933
- primitive = ->(runtime, obj_arg, alist_arg) do
934
+ primitive = lambda do |runtime, obj_arg, alist_arg|
934
935
  assoc_list = alist_arg.evaluate(runtime)
935
936
  check_assoc_list(assoc_list, 'assq')
936
937
  obj = obj_arg.evaluate(runtime)
937
938
  result = boolean(false)
938
939
  unless assoc_list.empty?
939
940
  pair = assoc_list
940
- begin
941
+ loop do
941
942
  are_equal = core_eq?(pair.car.car, obj)
942
943
  if are_equal.value
943
944
  result = pair.car
944
945
  break
945
946
  end
946
947
  pair = pair.cdr
947
- end while (pair && (pair.kind_of?(SkmPair)))
948
+ break unless pair&.kind_of?(SkmPair)
949
+ end
948
950
  end
949
951
 
950
952
  result
@@ -953,19 +955,20 @@ module Skeem
953
955
  end
954
956
 
955
957
  def create_assv(aRuntime)
956
- primitive = ->(runtime, obj, assoc_list) do
958
+ primitive = lambda do |_runtime, obj, assoc_list|
957
959
  check_assoc_list(assoc_list, 'assq')
958
960
  result = boolean(false)
959
961
  unless assoc_list.empty?
960
962
  pair = assoc_list
961
- begin
963
+ loop do
962
964
  are_equal = core_eqv?(pair.car.car, obj)
963
965
  if are_equal.value
964
966
  result = pair.car
965
967
  break
966
968
  end
967
969
  pair = pair.cdr
968
- end while (pair && (pair.kind_of?(SkmPair)))
970
+ break unless pair&.kind_of?(SkmPair)
971
+ end
969
972
  end
970
973
 
971
974
  result
@@ -978,15 +981,16 @@ module Skeem
978
981
 
979
982
  unless alist.empty?
980
983
  cell = SkmPair.new(integer(1), alist)
981
- begin
984
+ loop do
982
985
  cell = cell.cdr
983
986
  check_argtype(cell, SkmPair, 'association list', proc_name)
984
- end while cell.cdr.kind_of?(SkmPair)
987
+ break unless cell.cdr.kind_of?(SkmPair)
988
+ end
985
989
  end
986
990
  end
987
991
 
988
992
  def create_list_copy(aRuntime)
989
- primitive = ->(runtime, arg_evaluated) do
993
+ primitive = lambda do |_runtime, arg_evaluated|
990
994
  check_argtype(arg_evaluated, [SkmPair, SkmEmptyList], 'list', 'list-copy')
991
995
  arg_evaluated.klone # Previously: arg.klone
992
996
  end
@@ -995,7 +999,7 @@ module Skeem
995
999
  end
996
1000
 
997
1001
  def create_vector(aRuntime)
998
- primitive = ->(_runtime, elements) do
1002
+ primitive = lambda do |_runtime, elements|
999
1003
  vector(elements)
1000
1004
  end
1001
1005
 
@@ -1003,7 +1007,7 @@ module Skeem
1003
1007
  end
1004
1008
 
1005
1009
  def create_vector_length(aRuntime)
1006
- primitive = ->(_runtime, arg_evaluated) do
1010
+ primitive = lambda do |_runtime, arg_evaluated|
1007
1011
  check_argtype(arg_evaluated, SkmVector, 'vector', 'vector-length')
1008
1012
  integer(arg_evaluated.length)
1009
1013
  end
@@ -1012,7 +1016,7 @@ module Skeem
1012
1016
  end
1013
1017
 
1014
1018
  def create_make_vector(aRuntime)
1015
- primitive = ->(runtime, count_arg, arglist) do
1019
+ primitive = lambda do |runtime, count_arg, arglist|
1016
1020
  count = count_arg.evaluate(runtime)
1017
1021
  check_argtype(count, SkmInteger, 'integer', 'make_vector')
1018
1022
  if arglist.empty?
@@ -1028,8 +1032,8 @@ module Skeem
1028
1032
  end
1029
1033
 
1030
1034
  def create_vector_ref(aRuntime)
1031
- # argument 1: a vector, argument 2: an index(integer)
1032
- primitive = ->(runtime, vector, index) do
1035
+ # argument 1: a vector, argument 2: an index(integer)
1036
+ primitive = lambda do |_runtime, vector, index|
1033
1037
  check_argtype(vector, SkmVector, 'vector', 'vector-ref')
1034
1038
  check_argtype(index, SkmInteger, 'integer', 'vector-ref')
1035
1039
  # TODO: index checking
@@ -1039,10 +1043,10 @@ module Skeem
1039
1043
 
1040
1044
  define_primitive_proc(aRuntime, 'vector-ref', binary, primitive)
1041
1045
  end
1042
-
1046
+
1043
1047
  def create_vector_set(aRuntime)
1044
- # Arguments aren't evaluated yet!...
1045
- primitive = ->(runtime, vector, k, object) do
1048
+ # Arguments aren't evaluated yet!...
1049
+ primitive = lambda do |runtime, vector, k, object|
1046
1050
  index = k.evaluate(runtime)
1047
1051
  check_argtype(vector, SkmVector, 'vector', 'vector-set!')
1048
1052
  check_argtype(index, SkmInteger, 'integer', 'vector-set!')
@@ -1050,12 +1054,12 @@ module Skeem
1050
1054
  vector.members[index.value] = object
1051
1055
  vector
1052
1056
  end
1053
-
1057
+
1054
1058
  define_primitive_proc(aRuntime, 'vector-set!', ternary, primitive)
1055
1059
  end
1056
1060
 
1057
1061
  def create_vector2list(aRuntime)
1058
- primitive = ->(runtime, arg_evaluated) do
1062
+ primitive = lambda do |_runtime, arg_evaluated|
1059
1063
  check_argtype(arg_evaluated, SkmVector, 'vector', 'vector->list')
1060
1064
  SkmPair.create_from_a(arg_evaluated.members)
1061
1065
  end
@@ -1064,7 +1068,7 @@ module Skeem
1064
1068
  end
1065
1069
 
1066
1070
  def create_apply(aRuntime)
1067
- primitive = ->(runtime, proc_arg, arglist) do
1071
+ primitive = lambda do |runtime, proc_arg, arglist|
1068
1072
  if arglist.empty?
1069
1073
  result = SkmEmptyList.instance
1070
1074
  else
@@ -1072,18 +1076,19 @@ module Skeem
1072
1076
  invoke = ProcedureCall.new(nil, proc_arg, single_list.to_a)
1073
1077
  result = invoke.evaluate(runtime)
1074
1078
  end
1079
+ result
1075
1080
  end
1076
1081
 
1077
1082
  define_primitive_proc(aRuntime, 'apply', one_or_more, primitive)
1078
1083
  end
1079
1084
 
1080
1085
  def create_map(aRuntime)
1081
- primitive = ->(runtime, proc_arg, arglist) do
1086
+ primitive = lambda do |runtime, proc_arg, arglist|
1082
1087
  if arglist.empty?
1083
1088
  result = SkmEmptyList.instance
1084
1089
  else
1085
1090
  curr_cells = arglist
1086
- arity = curr_cells.size
1091
+ # arity = curr_cells.size
1087
1092
  initial_result = nil
1088
1093
  curr_result = nil
1089
1094
  loop do
@@ -1099,7 +1104,7 @@ module Skeem
1099
1104
  curr_result = new_result
1100
1105
 
1101
1106
  curr_cells.map!(&:cdr)
1102
- break if curr_cells.find { |cdr_entry| ! cdr_entry.kind_of?(SkmPair) }
1107
+ break if curr_cells.find { |cdr_entry| !cdr_entry.kind_of?(SkmPair) }
1103
1108
  end
1104
1109
 
1105
1110
  result = initial_result
@@ -1110,19 +1115,27 @@ module Skeem
1110
1115
 
1111
1116
  define_primitive_proc(aRuntime, 'map', one_or_more, primitive)
1112
1117
  end
1113
-
1118
+
1114
1119
  def create_display(aRuntime)
1115
- primitive = ->(runtime, arg_evaluated) do
1120
+ primitive = lambda do |_runtime, arg_evaluated|
1116
1121
  # @TODO: make output stream configurable
1117
1122
  print arg_evaluated.value.to_s
1118
1123
  SkmUndefined.instance
1119
1124
  end
1120
-
1121
- define_primitive_proc(aRuntime, 'display', unary, primitive)
1125
+
1126
+ define_primitive_proc(aRuntime, 'display', unary, primitive)
1127
+ end
1128
+
1129
+ def create_error(aRuntime)
1130
+ primitive = lambda do |_runtime, arg_evaluated|
1131
+ raise SkmError, arg_evaluated.value
1132
+ end
1133
+
1134
+ define_primitive_proc(aRuntime, 'error', unary, primitive)
1122
1135
  end
1123
1136
 
1124
1137
  def create_test_assert(aRuntime)
1125
- primitive = ->(runtime, arg_evaluated) do
1138
+ primitive = lambda do |_runtime, arg_evaluated|
1126
1139
  if arg_evaluated.boolean? && arg_evaluated.value == false
1127
1140
  assert_call = aRuntime.caller
1128
1141
  pos = assert_call.call_site
@@ -1141,7 +1154,7 @@ module Skeem
1141
1154
  # DON'T USE IT
1142
1155
  # Non-standard procedure reserved for internal testing/debugging purposes.
1143
1156
  def create_debug(aRuntime)
1144
- primitive = ->(runtime) do
1157
+ primitive = lambda do |_runtime|
1145
1158
  require 'debug'
1146
1159
  end
1147
1160
 
@@ -1151,7 +1164,7 @@ module Skeem
1151
1164
  # DON'T USE IT
1152
1165
  # Non-standard procedure reserved for internal testing/debugging purposes.
1153
1166
  def create_inspect(aRuntime)
1154
- primitive = ->(runtime, arg_evaluated) do
1167
+ primitive = lambda do |_runtime, arg_evaluated|
1155
1168
  $stderr.puts 'INSPECT>' + arg_evaluated.inspect
1156
1169
  Skeem::SkmUndefined.instance
1157
1170
  end
@@ -1160,7 +1173,7 @@ module Skeem
1160
1173
 
1161
1174
  def create_object_predicate(aRuntime, predicate_name, msg_name = nil)
1162
1175
  msg_name = predicate_name if msg_name.nil?
1163
- primitive = ->(runtime, arg_evaluated) do
1176
+ primitive = lambda do |_runtime, arg_evaluated|
1164
1177
  to_datum(arg_evaluated.send(msg_name))
1165
1178
  end
1166
1179
 
@@ -1234,4 +1247,4 @@ module Skeem
1234
1247
  end
1235
1248
  end # module
1236
1249
  end # module
1237
- end # module
1250
+ end # module