skeem 0.2.15 → 0.2.19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +451 -195
  3. data/.travis.yml +27 -0
  4. data/CHANGELOG.md +26 -0
  5. data/Gemfile +2 -0
  6. data/README.md +3 -2
  7. data/Rakefile +2 -0
  8. data/appveyor.yml +3 -4
  9. data/bin/skeem +15 -15
  10. data/lib/skeem/datum_dsl.rb +40 -30
  11. data/lib/skeem/element_visitor.rb +5 -2
  12. data/lib/skeem/grammar.rb +77 -54
  13. data/lib/skeem/interpreter.rb +9 -7
  14. data/lib/skeem/parser.rb +6 -4
  15. data/lib/skeem/primitive/primitive_builder.rb +130 -122
  16. data/lib/skeem/primitive/primitive_procedure.rb +23 -25
  17. data/lib/skeem/runtime.rb +17 -15
  18. data/lib/skeem/s_expr_builder.rb +39 -147
  19. data/lib/skeem/s_expr_nodes.rb +147 -132
  20. data/lib/skeem/skeem_exception.rb +1 -0
  21. data/lib/skeem/skm_binding.rb +9 -11
  22. data/lib/skeem/skm_compound_datum.rb +9 -6
  23. data/lib/skeem/skm_element.rb +15 -13
  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 +26 -18
  29. data/lib/skeem/skm_procedure_exec.rb +11 -6
  30. data/lib/skeem/skm_simple_datum.rb +23 -20
  31. data/lib/skeem/skm_unary_expression.rb +34 -37
  32. data/lib/skeem/tokenizer.rb +40 -30
  33. data/lib/skeem/version.rb +3 -1
  34. data/lib/skeem.rb +2 -0
  35. data/skeem.gemspec +7 -5
  36. data/spec/skeem/add4.skm +4 -0
  37. data/spec/skeem/datum_dsl_spec.rb +13 -12
  38. data/spec/skeem/element_visitor_spec.rb +14 -10
  39. data/spec/skeem/interpreter_spec.rb +76 -46
  40. data/spec/skeem/lambda_spec.rb +13 -11
  41. data/spec/skeem/parser_spec.rb +23 -19
  42. data/spec/skeem/primitive/primitive_builder_spec.rb +55 -46
  43. data/spec/skeem/primitive/primitive_procedure_spec.rb +14 -12
  44. data/spec/skeem/runtime_spec.rb +20 -18
  45. data/spec/skeem/s_expr_nodes_spec.rb +8 -6
  46. data/spec/skeem/skm_compound_datum_spec.rb +12 -10
  47. data/spec/skeem/skm_element_spec.rb +7 -5
  48. data/spec/skeem/skm_empty_list_spec.rb +7 -5
  49. data/spec/skeem/skm_frame_spec.rb +5 -4
  50. data/spec/skeem/skm_pair_spec.rb +9 -8
  51. data/spec/skeem/skm_procedure_exec_spec.rb +2 -0
  52. data/spec/skeem/skm_simple_datum_spec.rb +24 -22
  53. data/spec/skeem/skm_unary_expression_spec.rb +11 -9
  54. data/spec/skeem/tokenizer_spec.rb +54 -43
  55. data/spec/skeem_spec.rb +2 -0
  56. data/spec/spec_helper.rb +15 -10
  57. metadata +13 -9
@@ -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,16 +22,16 @@ 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
27
29
 
28
- def parse(source, mode = nil)
30
+ def parse(source, _mode = nil)
29
31
  @parser ||= Parser.new
30
32
  @ptree = parser.parse(source)
31
- # $stderr.puts @ptree.root.inspect if mode.nil?
32
- # require 'debug' unless mode.nil?
33
+ # $stderr.puts @ptree.root.inspect if _mode.nil?
34
+ # require 'debug' unless _mode.nil?
33
35
  end
34
36
 
35
37
  def run(source, mode = nil)
@@ -43,7 +45,7 @@ module Skeem
43
45
  end
44
46
 
45
47
  def add_standard(_runtime)
46
- std_pathname = File.dirname(__FILE__) + '/standard/base.skm'
48
+ std_pathname = "#{File.dirname(__FILE__)}/standard/base.skm"
47
49
  load_lib(std_pathname)
48
50
  end
49
51
 
@@ -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,26 @@ 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
- # 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
236
-
237
237
  arglist.each do |elem|
238
238
  elem_value = elem.value
239
239
  case [raw_result.class, elem_value.class]
240
- when [int_class, int_class]
240
+ when [Integer, Integer]
241
241
  if raw_result.modulo(elem_value).zero?
242
- raw_result = raw_result / elem_value
242
+ raw_result /= elem_value
243
243
  else
244
244
  raw_result = Rational(raw_result, elem_value)
245
245
  end
246
246
 
247
- when [int_class, Rational]
248
- raw_result = raw_result * reciprocal(elem_value)
247
+ when [Integer, Rational]
248
+ raw_result *= reciprocal(elem_value)
249
249
 
250
250
  when [Rational, Rational]
251
- raw_result = raw_result * reciprocal(elem_value)
251
+ raw_result *= reciprocal(elem_value)
252
252
  else
253
253
  raw_result = raw_result.to_f
254
254
  raw_result /= elem_value
@@ -262,8 +262,8 @@ module Skeem
262
262
  end
263
263
 
264
264
  def create_floor_slash(aRuntime)
265
- primitive = ->(_runtime, operand_1, operand_2) do
266
- (quotient, modulus) = operand_1.value.divmod(operand_2.value)
265
+ primitive = lambda do |_runtime, operand1, operand2|
266
+ (quotient, modulus) = operand1.value.divmod(operand2.value)
267
267
  SkmPair.new(to_datum(quotient), to_datum(modulus)) # improper list!
268
268
  end
269
269
 
@@ -271,10 +271,10 @@ module Skeem
271
271
  end
272
272
 
273
273
  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)
274
+ primitive = lambda do |_runtime, operand1, operand2|
275
+ modulo_ = operand1.value / operand2.value
276
+ modulo_ += 1 if modulo_.negative?
277
+ remainder_ = operand1.value.remainder(operand2.value)
278
278
  SkmPair.new(to_datum(modulo_), to_datum(remainder_)) # improper list!
279
279
  end
280
280
 
@@ -282,7 +282,7 @@ module Skeem
282
282
  end
283
283
 
284
284
  def create_gcd(aRuntime)
285
- primitive = ->(_runtime, arglist) do
285
+ primitive = lambda do |_runtime, arglist|
286
286
  if arglist.empty?
287
287
  integer(0)
288
288
  else
@@ -301,7 +301,7 @@ module Skeem
301
301
  end
302
302
 
303
303
  def create_lcm(aRuntime)
304
- primitive = ->(_runtime, arglist) do
304
+ primitive = lambda do |_runtime, arglist|
305
305
  if arglist.empty?
306
306
  integer(1)
307
307
  else
@@ -315,7 +315,7 @@ module Skeem
315
315
  end
316
316
 
317
317
  def create_numerator(aRuntime)
318
- primitive = ->(_runtime, arg_evaluated) do
318
+ primitive = lambda do |_runtime, arg_evaluated|
319
319
  case arg_evaluated
320
320
  when SkmInteger
321
321
  result = arg_evaluated
@@ -329,7 +329,7 @@ module Skeem
329
329
  end
330
330
 
331
331
  def create_denominator(aRuntime)
332
- primitive = ->(_runtime, arg_evaluated) do
332
+ primitive = lambda do |_runtime, arg_evaluated|
333
333
  case arg_evaluated
334
334
  when SkmInteger
335
335
  result = 1
@@ -343,7 +343,7 @@ module Skeem
343
343
  end
344
344
 
345
345
  def create_floor(aRuntime)
346
- primitive = ->(_runtime, arg_evaluated) do
346
+ primitive = lambda do |_runtime, arg_evaluated|
347
347
  result = arg_evaluated.value.floor
348
348
  integer(result)
349
349
  end
@@ -352,7 +352,7 @@ module Skeem
352
352
  end
353
353
 
354
354
  def create_ceiling(aRuntime)
355
- primitive = ->(_runtime, arg_evaluated) do
355
+ primitive = lambda do |_runtime, arg_evaluated|
356
356
  result = arg_evaluated.value.ceil
357
357
  integer(result)
358
358
  end
@@ -361,7 +361,7 @@ module Skeem
361
361
  end
362
362
 
363
363
  def create_round(aRuntime)
364
- primitive = ->(_runtime, arg_evaluated) do
364
+ primitive = lambda do |_runtime, arg_evaluated|
365
365
  result = arg_evaluated.value.round
366
366
  integer(result)
367
367
  end
@@ -375,8 +375,8 @@ module Skeem
375
375
  end
376
376
 
377
377
  def create_eqv?(aRuntime)
378
- primitive = ->(runtime, operand_1, operand_2) do
379
- core_eqv?(operand_1, operand_2)
378
+ primitive = lambda do |_runtime, operand1, operand2|
379
+ core_eqv?(operand1, operand2)
380
380
  end
381
381
 
382
382
  define_primitive_proc(aRuntime, 'eqv?', binary, primitive)
@@ -388,7 +388,7 @@ module Skeem
388
388
  end
389
389
 
390
390
  def create_eq?(aRuntime)
391
- primitive = ->(_runtime, operand_1, operand_2) do
391
+ primitive = lambda do |_runtime, operand1, operand2|
392
392
  core_eq?(operand1, operand2)
393
393
  end
394
394
 
@@ -396,8 +396,8 @@ module Skeem
396
396
  end
397
397
 
398
398
  def create_equal?(aRuntime)
399
- primitive = ->(_runtime, operand_1, operand_2) do
400
- raw_result = operand_1.skm_equal?(operand_2)
399
+ primitive = lambda do |_runtime, operand1, operand2|
400
+ raw_result = operand1.skm_equal?(operand2)
401
401
  boolean(raw_result)
402
402
  end
403
403
 
@@ -405,7 +405,7 @@ module Skeem
405
405
  end
406
406
 
407
407
  def create_equal(aRuntime)
408
- primitive = ->(_runtime, first_operand, arglist) do
408
+ primitive = lambda do |_runtime, first_operand, arglist|
409
409
  if arglist.empty?
410
410
  boolean(true)
411
411
  else
@@ -419,11 +419,11 @@ module Skeem
419
419
  end
420
420
 
421
421
  def create_lt(aRuntime)
422
- primitive = ->(_runtime, first_operand, arglist) do
422
+ primitive = lambda do |runtime, first_operand, arglist|
423
423
  if arglist.empty?
424
424
  result = false
425
425
  else
426
- result = primitive_comparison(:<, _runtime, first_operand, arglist)
426
+ result = primitive_comparison(:<, runtime, first_operand, arglist)
427
427
  end
428
428
  boolean(result)
429
429
  end
@@ -432,11 +432,11 @@ module Skeem
432
432
  end
433
433
 
434
434
  def create_gt(aRuntime)
435
- primitive = ->(_runtime, first_operand, arglist) do
435
+ primitive = lambda do |runtime, first_operand, arglist|
436
436
  if arglist.empty?
437
437
  result = false
438
438
  else
439
- result = primitive_comparison(:>, _runtime, first_operand, arglist)
439
+ result = primitive_comparison(:>, runtime, first_operand, arglist)
440
440
  end
441
441
  boolean(result)
442
442
  end
@@ -445,11 +445,11 @@ module Skeem
445
445
  end
446
446
 
447
447
  def create_lte(aRuntime)
448
- primitive = ->(_runtime, first_operand, arglist) do
448
+ primitive = lambda do |runtime, first_operand, arglist|
449
449
  if arglist.empty?
450
450
  result = true
451
451
  else
452
- result = primitive_comparison(:<=, _runtime, first_operand, arglist)
452
+ result = primitive_comparison(:<=, runtime, first_operand, arglist)
453
453
  end
454
454
  boolean(result)
455
455
  end
@@ -458,11 +458,11 @@ module Skeem
458
458
  end
459
459
 
460
460
  def create_gte(aRuntime)
461
- primitive = ->(_runtime, first_operand, arglist) do
461
+ primitive = lambda do |runtime, first_operand, arglist|
462
462
  if arglist.empty?
463
463
  result = true
464
464
  else
465
- result = primitive_comparison(:>=, _runtime, first_operand, arglist)
465
+ result = primitive_comparison(:>=, runtime, first_operand, arglist)
466
466
  end
467
467
  boolean(result)
468
468
  end
@@ -481,7 +481,7 @@ module Skeem
481
481
  end
482
482
 
483
483
  def create_max(aRuntime)
484
- primitive = ->(_runtime, first_operand, arglist) do
484
+ primitive = lambda do |_runtime, first_operand, arglist|
485
485
  if arglist.empty?
486
486
  result = first_operand
487
487
  else
@@ -499,7 +499,7 @@ module Skeem
499
499
  end
500
500
 
501
501
  def create_min(aRuntime)
502
- primitive = ->(_runtime, first_operand, arglist) do
502
+ primitive = lambda do |_runtime, first_operand, arglist|
503
503
  if arglist.empty?
504
504
  result = first_operand
505
505
  else
@@ -518,7 +518,7 @@ module Skeem
518
518
 
519
519
  def create_number2string(aRuntime)
520
520
  # TODO: add support for radix argument
521
- primitive = ->(_runtime, arg_evaluated) do
521
+ primitive = lambda do |_runtime, arg_evaluated|
522
522
  check_argtype(arg_evaluated, SkmNumber, 'number', 'number->string')
523
523
  string(arg_evaluated.value)
524
524
  end
@@ -529,7 +529,7 @@ module Skeem
529
529
  def create_and(aRuntime)
530
530
  # arglist should be a Ruby Array
531
531
  # Arguments aren't evaluated yet!...
532
- primitive = ->(runtime, arglist) do
532
+ primitive = lambda do |runtime, arglist|
533
533
  if arglist.empty?
534
534
  boolean(true) # in conformance with 4.2.1
535
535
  else
@@ -537,7 +537,7 @@ module Skeem
537
537
  last_result = nil
538
538
  # $stderr.puts arglist.inspect
539
539
  arglist.each do |raw_arg|
540
- argument = raw_arg.evaluate(aRuntime)
540
+ argument = raw_arg.evaluate(runtime)
541
541
  last_result = argument
542
542
  raw_result &&= !(argument.boolean? && !argument.value)
543
543
  break unless raw_result # stop here, a false was found...
@@ -555,14 +555,14 @@ module Skeem
555
555
  def create_or(aRuntime)
556
556
  # arglist should be a Ruby Array
557
557
  # Arguments aren't evaluated yet!...
558
- primitive = ->(runtime, arglist) do
558
+ primitive = lambda do |runtime, arglist|
559
559
  if arglist.empty?
560
560
  boolean(false) # in conformance with 4.2.1
561
561
  else
562
562
  raw_result = false
563
563
  last_result = nil
564
564
  arglist.each do |raw_arg|
565
- argument = raw_arg.evaluate(aRuntime)
565
+ argument = raw_arg.evaluate(runtime)
566
566
  last_result = argument
567
567
  raw_result ||= (!argument.boolean? || argument.value)
568
568
  break if raw_result # stop here, a true was found...
@@ -602,7 +602,7 @@ module Skeem
602
602
  end
603
603
 
604
604
  def create_boolean_equal(aRuntime)
605
- primitive = ->(_runtime, first_operand, arglist) do
605
+ primitive = lambda do |_runtime, first_operand, arglist|
606
606
  compare_all(first_operand, arglist, :==)
607
607
  end
608
608
 
@@ -610,7 +610,7 @@ module Skeem
610
610
  end
611
611
 
612
612
  def create_char2int(aRuntime)
613
- primitive = ->(runtime, arg_evaluated) do
613
+ primitive = lambda do |_runtime, arg_evaluated|
614
614
  check_argtype(arg_evaluated, SkmChar, 'character', 'char->integer')
615
615
  integer(arg_evaluated.value.ord)
616
616
  end
@@ -619,7 +619,7 @@ module Skeem
619
619
  end
620
620
 
621
621
  def create_int2char(aRuntime)
622
- primitive = ->(runtime, arg_evaluated) do
622
+ primitive = lambda do |_runtime, arg_evaluated|
623
623
  check_argtype(arg_evaluated, SkmInteger, 'integer', 'integer->char')
624
624
  char(arg_evaluated.value.ord)
625
625
  end
@@ -628,7 +628,7 @@ module Skeem
628
628
  end
629
629
 
630
630
  def create_char_equal(aRuntime)
631
- primitive = ->(_runtime, first_operand, arglist) do
631
+ primitive = lambda do |_runtime, first_operand, arglist|
632
632
  compare_all(first_operand, arglist, :==)
633
633
  end
634
634
 
@@ -636,7 +636,7 @@ module Skeem
636
636
  end
637
637
 
638
638
  def create_char_lt(aRuntime)
639
- primitive = ->(_runtime, first_operand, arglist) do
639
+ primitive = lambda do |_runtime, first_operand, arglist|
640
640
  compare_all(first_operand, arglist, :<)
641
641
  end
642
642
 
@@ -644,7 +644,7 @@ module Skeem
644
644
  end
645
645
 
646
646
  def create_char_gt(aRuntime)
647
- primitive = ->(_runtime, first_operand, arglist) do
647
+ primitive = lambda do |_runtime, first_operand, arglist|
648
648
  compare_all(first_operand, arglist, :>)
649
649
  end
650
650
 
@@ -652,7 +652,7 @@ module Skeem
652
652
  end
653
653
 
654
654
  def create_char_lte(aRuntime)
655
- primitive = ->(_runtime, first_operand, arglist) do
655
+ primitive = lambda do |_runtime, first_operand, arglist|
656
656
  compare_all(first_operand, arglist, :<=)
657
657
  end
658
658
 
@@ -660,16 +660,15 @@ module Skeem
660
660
  end
661
661
 
662
662
  def create_char_gte(aRuntime)
663
- primitive = ->(_runtime, first_operand, arglist) do
663
+ primitive = lambda do |_runtime, first_operand, arglist|
664
664
  compare_all(first_operand, arglist, :>=)
665
665
  end
666
666
 
667
667
  define_primitive_proc(aRuntime, 'char>=?', one_or_more, primitive)
668
668
  end
669
669
 
670
-
671
670
  def create_make_string(aRuntime)
672
- primitive = ->(runtime, count_arg, arglist) do
671
+ primitive = lambda do |_runtime, count_arg, arglist|
673
672
  count = count_arg
674
673
  check_argtype(count, SkmInteger, 'integer', 'make-string')
675
674
  if arglist.empty?
@@ -685,11 +684,11 @@ module Skeem
685
684
  end
686
685
 
687
686
  def create_string_string(aRuntime)
688
- primitive = ->(_runtime, arglist) do
687
+ primitive = lambda do |_runtime, arglist|
689
688
  if arglist.empty?
690
689
  value = ''
691
690
  else
692
- value = arglist.reduce('') do |interim, some_char|
691
+ value = arglist.reduce(+'') do |interim, some_char|
693
692
  check_argtype(some_char, SkmChar, 'character', 'string')
694
693
  interim << some_char.value
695
694
  end
@@ -702,7 +701,7 @@ module Skeem
702
701
  end
703
702
 
704
703
  def create_string_equal(aRuntime)
705
- primitive = ->(_runtime, first_operand, arglist) do
704
+ primitive = lambda do |_runtime, first_operand, arglist|
706
705
  all_same?(first_operand, arglist)
707
706
  end
708
707
 
@@ -710,11 +709,11 @@ module Skeem
710
709
  end
711
710
 
712
711
  def create_string_append(aRuntime)
713
- primitive = ->(_runtime, arglist) do
712
+ primitive = lambda do |_runtime, arglist|
714
713
  if arglist.empty?
715
714
  value = ''
716
715
  else
717
- value = arglist.reduce('') { |interim, substr| interim << substr.value }
716
+ value = arglist.reduce(+'') { |interim, substr| interim << substr.value }
718
717
  end
719
718
 
720
719
  string(value)
@@ -724,7 +723,7 @@ module Skeem
724
723
  end
725
724
 
726
725
  def create_string_length(aRuntime)
727
- primitive = ->(runtime, arg_evaluated) do
726
+ primitive = lambda do |_runtime, arg_evaluated|
728
727
  check_argtype(arg_evaluated, SkmString, 'string', 'string-length')
729
728
  integer(arg_evaluated.length)
730
729
  end
@@ -733,7 +732,7 @@ module Skeem
733
732
  end
734
733
 
735
734
  def create_string2symbol(aRuntime)
736
- primitive = ->(runtime, arg_evaluated) do
735
+ primitive = lambda do |_runtime, arg_evaluated|
737
736
  check_argtype(arg_evaluated, SkmString, 'string', 'string->symbol')
738
737
  identifier(arg_evaluated)
739
738
  end
@@ -742,7 +741,7 @@ module Skeem
742
741
  end
743
742
 
744
743
  def create_symbol2string(aRuntime)
745
- primitive = ->(runtime, arg_evaluated) do
744
+ primitive = lambda do |_runtime, arg_evaluated|
746
745
  check_argtype(arg_evaluated, SkmIdentifier, 'symbol', 'symbol->string')
747
746
  string(arg_evaluated)
748
747
  end
@@ -751,7 +750,7 @@ module Skeem
751
750
  end
752
751
 
753
752
  def create_car(aRuntime)
754
- primitive = ->(runtime, arg_evaluated) do
753
+ primitive = lambda do |_runtime, arg_evaluated|
755
754
  check_argtype(arg_evaluated, SkmPair, 'pair', 'car')
756
755
  arg_evaluated.car
757
756
  end
@@ -760,7 +759,7 @@ module Skeem
760
759
  end
761
760
 
762
761
  def create_cdr(aRuntime)
763
- primitive = ->(_runtime, arg_evaluated) do
762
+ primitive = lambda do |_runtime, arg_evaluated|
764
763
  check_argtype(arg_evaluated, SkmPair, 'pair', 'cdr')
765
764
  arg_evaluated.cdr
766
765
  end
@@ -769,15 +768,15 @@ module Skeem
769
768
  end
770
769
 
771
770
  def create_cons(aRuntime)
772
- primitive = ->(_runtime, obj1, obj2) do
771
+ primitive = lambda do |_runtime, obj1, obj2|
773
772
  SkmPair.new(obj1, obj2)
774
773
  end
775
774
 
776
775
  define_primitive_proc(aRuntime, 'cons', binary, primitive)
777
776
  end
778
-
777
+
779
778
  def create_make_list(aRuntime)
780
- primitive = ->(runtime, count_arg, arglist) do
779
+ primitive = lambda do |_runtime, count_arg, arglist|
781
780
  count = count_arg
782
781
  check_argtype(count, SkmInteger, 'integer', 'make-list')
783
782
  if arglist.empty?
@@ -789,11 +788,11 @@ module Skeem
789
788
  SkmPair.create_from_a(arr)
790
789
  end
791
790
 
792
- define_primitive_proc(aRuntime, 'make-list', one_or_two, primitive)
791
+ define_primitive_proc(aRuntime, 'make-list', one_or_two, primitive)
793
792
  end
794
793
 
795
794
  def create_length(aRuntime)
796
- primitive = ->(_runtime, arg_evaluated) do
795
+ primitive = lambda do |_runtime, arg_evaluated|
797
796
  check_argtype(arg_evaluated, [SkmPair, SkmEmptyList], 'list', 'length')
798
797
  integer(arg_evaluated.length)
799
798
  end
@@ -802,7 +801,7 @@ module Skeem
802
801
  end
803
802
 
804
803
  def create_list2vector(aRuntime)
805
- primitive = ->(_runtime, arg_evaluated) do
804
+ primitive = lambda do |_runtime, arg_evaluated|
806
805
  check_argtype(arg_evaluated, [SkmPair, SkmEmptyList], 'list', 'list->vector')
807
806
  vector(arg_evaluated.to_a)
808
807
  end
@@ -818,7 +817,7 @@ module Skeem
818
817
  else
819
818
  but_last = arglist.take(arglist.length - 1)
820
819
  check_arguments(but_last, [SkmPair, SkmEmptyList], 'list', 'append')
821
- result = arglist.shift.klone # First list is taken
820
+ result = arglist.shift.klone # First list is taken
822
821
  arglist.each do |arg|
823
822
  case arg
824
823
  when SkmPair
@@ -826,11 +825,7 @@ module Skeem
826
825
  if result.kind_of?(SkmEmptyList)
827
826
  result = cloned
828
827
  else
829
- if result.kind_of?(SkmEmptyList)
830
- result = SkmPair.new(arg, SkmEmptyList.instance)
831
- else
832
- result.append_list(cloned)
833
- end
828
+ result.append_list(cloned)
834
829
  end
835
830
  when SkmEmptyList
836
831
  # Do nothing
@@ -849,9 +844,9 @@ module Skeem
849
844
 
850
845
  def create_append(aRuntime)
851
846
  # Arguments aren't evaluated yet!...
852
- primitive = ->(runtime, arglist) do
847
+ primitive = lambda do |runtime, arglist|
853
848
  if arglist.size > 1
854
- arguments = evaluate_arguments(arglist, aRuntime)
849
+ arguments = evaluate_arguments(arglist, runtime)
855
850
  else
856
851
  arguments = arglist
857
852
  end
@@ -863,13 +858,14 @@ module Skeem
863
858
  end
864
859
 
865
860
  def create_reverse(aRuntime)
866
- primitive = ->(_runtime, arg_evaluated) do
861
+ primitive = lambda do |_runtime, arg_evaluated|
867
862
  check_argtype(arg_evaluated, [SkmPair, SkmEmptyList], 'list', 'reverse')
868
863
  if arg_evaluated == SkmEmptyList.instance
869
864
  result = arg_evaluated
870
865
  else
871
866
  err_msg = 'reverse procedure requires a proper list as argument'
872
- raise StandardError, err_msg unless arg_evaluated.proper?
867
+ raise StandardError, err_msg unless arg_evaluated.proper?
868
+
873
869
  elems_reversed = arg_evaluated.to_a.reverse
874
870
  result = SkmPair.create_from_a(elems_reversed)
875
871
  end
@@ -881,7 +877,7 @@ module Skeem
881
877
 
882
878
  def create_setcar(aRuntime)
883
879
  # Arguments aren't evaluated yet!...
884
- primitive = ->(runtime, pair_arg, obj_arg) do
880
+ primitive = lambda do |runtime, pair_arg, obj_arg|
885
881
  case pair_arg
886
882
  when SkmPair
887
883
  pair = pair_arg
@@ -906,7 +902,7 @@ module Skeem
906
902
 
907
903
  def create_setcdr(aRuntime)
908
904
  # Arguments aren't evaluated yet!...
909
- primitive = ->(runtime, pair_arg, obj_arg) do
905
+ primitive = lambda do |runtime, pair_arg, obj_arg|
910
906
  case pair_arg
911
907
  when SkmPair
912
908
  pair = pair_arg
@@ -930,21 +926,22 @@ module Skeem
930
926
  end
931
927
 
932
928
  def create_assq(aRuntime)
933
- primitive = ->(runtime, obj_arg, alist_arg) do
929
+ primitive = lambda do |runtime, obj_arg, alist_arg|
934
930
  assoc_list = alist_arg.evaluate(runtime)
935
931
  check_assoc_list(assoc_list, 'assq')
936
932
  obj = obj_arg.evaluate(runtime)
937
933
  result = boolean(false)
938
934
  unless assoc_list.empty?
939
935
  pair = assoc_list
940
- begin
936
+ loop do
941
937
  are_equal = core_eq?(pair.car.car, obj)
942
938
  if are_equal.value
943
939
  result = pair.car
944
940
  break
945
941
  end
946
942
  pair = pair.cdr
947
- end while (pair && (pair.kind_of?(SkmPair)))
943
+ break unless pair.kind_of?(SkmPair)
944
+ end
948
945
  end
949
946
 
950
947
  result
@@ -953,19 +950,20 @@ module Skeem
953
950
  end
954
951
 
955
952
  def create_assv(aRuntime)
956
- primitive = ->(runtime, obj, assoc_list) do
953
+ primitive = lambda do |_runtime, obj, assoc_list|
957
954
  check_assoc_list(assoc_list, 'assq')
958
955
  result = boolean(false)
959
956
  unless assoc_list.empty?
960
957
  pair = assoc_list
961
- begin
958
+ loop do
962
959
  are_equal = core_eqv?(pair.car.car, obj)
963
960
  if are_equal.value
964
961
  result = pair.car
965
962
  break
966
963
  end
967
964
  pair = pair.cdr
968
- end while (pair && (pair.kind_of?(SkmPair)))
965
+ break unless pair.kind_of?(SkmPair)
966
+ end
969
967
  end
970
968
 
971
969
  result
@@ -978,15 +976,16 @@ module Skeem
978
976
 
979
977
  unless alist.empty?
980
978
  cell = SkmPair.new(integer(1), alist)
981
- begin
979
+ loop do
982
980
  cell = cell.cdr
983
981
  check_argtype(cell, SkmPair, 'association list', proc_name)
984
- end while cell.cdr.kind_of?(SkmPair)
982
+ break unless cell.cdr.kind_of?(SkmPair)
983
+ end
985
984
  end
986
985
  end
987
986
 
988
987
  def create_list_copy(aRuntime)
989
- primitive = ->(runtime, arg_evaluated) do
988
+ primitive = lambda do |_runtime, arg_evaluated|
990
989
  check_argtype(arg_evaluated, [SkmPair, SkmEmptyList], 'list', 'list-copy')
991
990
  arg_evaluated.klone # Previously: arg.klone
992
991
  end
@@ -995,7 +994,7 @@ module Skeem
995
994
  end
996
995
 
997
996
  def create_vector(aRuntime)
998
- primitive = ->(_runtime, elements) do
997
+ primitive = lambda do |_runtime, elements|
999
998
  vector(elements)
1000
999
  end
1001
1000
 
@@ -1003,7 +1002,7 @@ module Skeem
1003
1002
  end
1004
1003
 
1005
1004
  def create_vector_length(aRuntime)
1006
- primitive = ->(_runtime, arg_evaluated) do
1005
+ primitive = lambda do |_runtime, arg_evaluated|
1007
1006
  check_argtype(arg_evaluated, SkmVector, 'vector', 'vector-length')
1008
1007
  integer(arg_evaluated.length)
1009
1008
  end
@@ -1012,7 +1011,7 @@ module Skeem
1012
1011
  end
1013
1012
 
1014
1013
  def create_make_vector(aRuntime)
1015
- primitive = ->(runtime, count_arg, arglist) do
1014
+ primitive = lambda do |runtime, count_arg, arglist|
1016
1015
  count = count_arg.evaluate(runtime)
1017
1016
  check_argtype(count, SkmInteger, 'integer', 'make_vector')
1018
1017
  if arglist.empty?
@@ -1028,8 +1027,8 @@ module Skeem
1028
1027
  end
1029
1028
 
1030
1029
  def create_vector_ref(aRuntime)
1031
- # argument 1: a vector, argument 2: an index(integer)
1032
- primitive = ->(runtime, vector, index) do
1030
+ # argument 1: a vector, argument 2: an index(integer)
1031
+ primitive = lambda do |_runtime, vector, index|
1033
1032
  check_argtype(vector, SkmVector, 'vector', 'vector-ref')
1034
1033
  check_argtype(index, SkmInteger, 'integer', 'vector-ref')
1035
1034
  # TODO: index checking
@@ -1039,10 +1038,10 @@ module Skeem
1039
1038
 
1040
1039
  define_primitive_proc(aRuntime, 'vector-ref', binary, primitive)
1041
1040
  end
1042
-
1041
+
1043
1042
  def create_vector_set(aRuntime)
1044
- # Arguments aren't evaluated yet!...
1045
- primitive = ->(runtime, vector, k, object) do
1043
+ # Arguments aren't evaluated yet!...
1044
+ primitive = lambda do |runtime, vector, k, object|
1046
1045
  index = k.evaluate(runtime)
1047
1046
  check_argtype(vector, SkmVector, 'vector', 'vector-set!')
1048
1047
  check_argtype(index, SkmInteger, 'integer', 'vector-set!')
@@ -1050,12 +1049,12 @@ module Skeem
1050
1049
  vector.members[index.value] = object
1051
1050
  vector
1052
1051
  end
1053
-
1052
+
1054
1053
  define_primitive_proc(aRuntime, 'vector-set!', ternary, primitive)
1055
1054
  end
1056
1055
 
1057
1056
  def create_vector2list(aRuntime)
1058
- primitive = ->(runtime, arg_evaluated) do
1057
+ primitive = lambda do |_runtime, arg_evaluated|
1059
1058
  check_argtype(arg_evaluated, SkmVector, 'vector', 'vector->list')
1060
1059
  SkmPair.create_from_a(arg_evaluated.members)
1061
1060
  end
@@ -1064,7 +1063,7 @@ module Skeem
1064
1063
  end
1065
1064
 
1066
1065
  def create_apply(aRuntime)
1067
- primitive = ->(runtime, proc_arg, arglist) do
1066
+ primitive = lambda do |runtime, proc_arg, arglist|
1068
1067
  if arglist.empty?
1069
1068
  result = SkmEmptyList.instance
1070
1069
  else
@@ -1072,18 +1071,19 @@ module Skeem
1072
1071
  invoke = ProcedureCall.new(nil, proc_arg, single_list.to_a)
1073
1072
  result = invoke.evaluate(runtime)
1074
1073
  end
1074
+ result
1075
1075
  end
1076
1076
 
1077
1077
  define_primitive_proc(aRuntime, 'apply', one_or_more, primitive)
1078
1078
  end
1079
1079
 
1080
1080
  def create_map(aRuntime)
1081
- primitive = ->(runtime, proc_arg, arglist) do
1081
+ primitive = lambda do |runtime, proc_arg, arglist|
1082
1082
  if arglist.empty?
1083
1083
  result = SkmEmptyList.instance
1084
1084
  else
1085
1085
  curr_cells = arglist
1086
- arity = curr_cells.size
1086
+ # arity = curr_cells.size
1087
1087
  initial_result = nil
1088
1088
  curr_result = nil
1089
1089
  loop do
@@ -1099,7 +1099,7 @@ module Skeem
1099
1099
  curr_result = new_result
1100
1100
 
1101
1101
  curr_cells.map!(&:cdr)
1102
- break if curr_cells.find { |cdr_entry| ! cdr_entry.kind_of?(SkmPair) }
1102
+ break if curr_cells.find { |cdr_entry| !cdr_entry.kind_of?(SkmPair) }
1103
1103
  end
1104
1104
 
1105
1105
  result = initial_result
@@ -1110,26 +1110,34 @@ module Skeem
1110
1110
 
1111
1111
  define_primitive_proc(aRuntime, 'map', one_or_more, primitive)
1112
1112
  end
1113
-
1113
+
1114
1114
  def create_display(aRuntime)
1115
- primitive = ->(runtime, arg_evaluated) do
1115
+ primitive = lambda do |_runtime, arg_evaluated|
1116
1116
  # @TODO: make output stream configurable
1117
1117
  print arg_evaluated.value.to_s
1118
1118
  SkmUndefined.instance
1119
1119
  end
1120
-
1121
- define_primitive_proc(aRuntime, 'display', unary, primitive)
1120
+
1121
+ define_primitive_proc(aRuntime, 'display', unary, primitive)
1122
+ end
1123
+
1124
+ def create_error(aRuntime)
1125
+ primitive = lambda do |_runtime, arg_evaluated|
1126
+ raise SkmError, arg_evaluated.value
1127
+ end
1128
+
1129
+ define_primitive_proc(aRuntime, 'error', unary, primitive)
1122
1130
  end
1123
1131
 
1124
1132
  def create_test_assert(aRuntime)
1125
- primitive = ->(runtime, arg_evaluated) do
1133
+ primitive = lambda do |_runtime, arg_evaluated|
1126
1134
  if arg_evaluated.boolean? && arg_evaluated.value == false
1127
1135
  assert_call = aRuntime.caller
1128
1136
  pos = assert_call.call_site
1129
1137
  # Error: assertion failed: (> 1 2)
1130
1138
  msg1 = "assertion failed on line #{pos.line}, column #{pos.column}"
1131
1139
  msg2 = ", with #{arg_evaluated.inspect}"
1132
- raise StandardError, 'Error: ' + msg1 + msg2
1140
+ raise StandardError, "Error: #{msg1}#{msg2}"
1133
1141
  else
1134
1142
  boolean(true)
1135
1143
  end
@@ -1141,7 +1149,7 @@ module Skeem
1141
1149
  # DON'T USE IT
1142
1150
  # Non-standard procedure reserved for internal testing/debugging purposes.
1143
1151
  def create_debug(aRuntime)
1144
- primitive = ->(runtime) do
1152
+ primitive = lambda do |_runtime|
1145
1153
  require 'debug'
1146
1154
  end
1147
1155
 
@@ -1151,8 +1159,8 @@ module Skeem
1151
1159
  # DON'T USE IT
1152
1160
  # Non-standard procedure reserved for internal testing/debugging purposes.
1153
1161
  def create_inspect(aRuntime)
1154
- primitive = ->(runtime, arg_evaluated) do
1155
- $stderr.puts 'INSPECT>' + arg_evaluated.inspect
1162
+ primitive = lambda do |_runtime, arg_evaluated|
1163
+ $stderr.puts "INSPECT>#{arg_evaluated.inspect}"
1156
1164
  Skeem::SkmUndefined.instance
1157
1165
  end
1158
1166
  define_primitive_proc(aRuntime, '_inspect', unary, primitive)
@@ -1160,7 +1168,7 @@ module Skeem
1160
1168
 
1161
1169
  def create_object_predicate(aRuntime, predicate_name, msg_name = nil)
1162
1170
  msg_name = predicate_name if msg_name.nil?
1163
- primitive = ->(runtime, arg_evaluated) do
1171
+ primitive = lambda do |_runtime, arg_evaluated|
1164
1172
  to_datum(arg_evaluated.send(msg_name))
1165
1173
  end
1166
1174
 
@@ -1220,7 +1228,7 @@ module Skeem
1220
1228
  else
1221
1229
  msg2 = "but got #{argument.class}"
1222
1230
  end
1223
- raise StandardError, msg1 + ' ' + msg2
1231
+ raise StandardError, "#{msg1} #{msg2}"
1224
1232
  end
1225
1233
 
1226
1234
  def remaining_args(arglist, aRuntime)
@@ -1234,4 +1242,4 @@ module Skeem
1234
1242
  end
1235
1243
  end # module
1236
1244
  end # module
1237
- end # module
1245
+ end # module