skeem 0.2.15 → 0.2.19

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 (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