skeem 0.2.15 → 0.2.16

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