skeem 0.2.14 → 0.2.18

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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +451 -195
  3. data/.travis.yml +27 -0
  4. data/CHANGELOG.md +35 -1
  5. data/Gemfile +2 -0
  6. data/README.md +125 -56
  7. data/Rakefile +2 -0
  8. data/appveyor.yml +3 -4
  9. data/bin/cubic.skm +4 -0
  10. data/bin/hello-world.skm +1 -0
  11. data/bin/skeem +72 -0
  12. data/lib/skeem/datum_dsl.rb +40 -30
  13. data/lib/skeem/element_visitor.rb +5 -2
  14. data/lib/skeem/grammar.rb +88 -26
  15. data/lib/skeem/interpreter.rb +9 -7
  16. data/lib/skeem/parser.rb +6 -4
  17. data/lib/skeem/primitive/primitive_builder.rb +148 -122
  18. data/lib/skeem/primitive/primitive_procedure.rb +23 -25
  19. data/lib/skeem/runtime.rb +17 -15
  20. data/lib/skeem/s_expr_builder.rb +49 -117
  21. data/lib/skeem/s_expr_nodes.rb +147 -132
  22. data/lib/skeem/skeem_exception.rb +1 -0
  23. data/lib/skeem/skm_binding.rb +9 -11
  24. data/lib/skeem/skm_compound_datum.rb +9 -6
  25. data/lib/skeem/skm_element.rb +15 -13
  26. data/lib/skeem/skm_empty_list.rb +6 -4
  27. data/lib/skeem/skm_exception.rb +9 -0
  28. data/lib/skeem/skm_expression.rb +3 -1
  29. data/lib/skeem/skm_frame.rb +3 -2
  30. data/lib/skeem/skm_pair.rb +26 -18
  31. data/lib/skeem/skm_procedure_exec.rb +11 -6
  32. data/lib/skeem/skm_simple_datum.rb +23 -20
  33. data/lib/skeem/skm_unary_expression.rb +34 -37
  34. data/lib/skeem/standard/base.skm +4 -0
  35. data/lib/skeem/tokenizer.rb +38 -28
  36. data/lib/skeem/version.rb +3 -1
  37. data/lib/skeem.rb +2 -0
  38. data/skeem.gemspec +9 -6
  39. data/spec/skeem/add4.skm +4 -0
  40. data/spec/skeem/datum_dsl_spec.rb +13 -12
  41. data/spec/skeem/element_visitor_spec.rb +14 -10
  42. data/spec/skeem/interpreter_spec.rb +84 -44
  43. data/spec/skeem/lambda_spec.rb +13 -11
  44. data/spec/skeem/parser_spec.rb +23 -19
  45. data/spec/skeem/primitive/primitive_builder_spec.rb +65 -48
  46. data/spec/skeem/primitive/primitive_procedure_spec.rb +14 -12
  47. data/spec/skeem/runtime_spec.rb +20 -18
  48. data/spec/skeem/s_expr_nodes_spec.rb +8 -6
  49. data/spec/skeem/skm_compound_datum_spec.rb +12 -10
  50. data/spec/skeem/skm_element_spec.rb +7 -5
  51. data/spec/skeem/skm_empty_list_spec.rb +7 -5
  52. data/spec/skeem/skm_frame_spec.rb +5 -4
  53. data/spec/skeem/skm_pair_spec.rb +9 -8
  54. data/spec/skeem/skm_procedure_exec_spec.rb +2 -0
  55. data/spec/skeem/skm_simple_datum_spec.rb +24 -22
  56. data/spec/skeem/skm_unary_expression_spec.rb +11 -9
  57. data/spec/skeem/tokenizer_spec.rb +54 -43
  58. data/spec/skeem_spec.rb +2 -0
  59. data/spec/spec_helper.rb +15 -10
  60. metadata +18 -10
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../../spec_helper' # Use the RSpec framework
2
4
 
3
5
  # Load the class under test
@@ -41,8 +43,8 @@ SKEEM
41
43
  ['(+)', 0], # '+' as nullary operator. Example from section 6.2.6
42
44
  ['(+ -3)', -3], # '+' as unary operator
43
45
  ['(+ 3 4)', 7], # '+' as binary operator. Example from section 4.1.3
44
- ['(+ 1/2 2/3)', Rational(7,6)],
45
- ['(+ 1/2 3)', Rational(7,2)],
46
+ ['(+ 1/2 2/3)', Rational(7, 6)],
47
+ ['(+ 1/2 3)', Rational(7, 2)],
46
48
  ['(+ 2 2.34)', 4.34]
47
49
  ]
48
50
  compare_to_predicted(checks)
@@ -219,7 +221,7 @@ SKEEM
219
221
  ["(equal? (make-vector 5 'a) (make-vector 5 'a))", true],
220
222
  ['(equal? car car)', true],
221
223
  ['(equal? car cdr)', false],
222
- ['(equal? (lambda (x) x) (lambda (y) y))', false],
224
+ ['(equal? (lambda (x) x) (lambda (y) y))', false]
223
225
  ]
224
226
  compare_to_predicted(checks) do |result, expectation|
225
227
  if result.length > 1
@@ -355,7 +357,7 @@ SKEEM
355
357
  ['(integer? "3")', false],
356
358
  ['(integer? #t)', false]
357
359
  ]
358
- compare_to_predicted(checks)
360
+ compare_to_predicted(checks)
359
361
  end
360
362
 
361
363
  it 'should implement the number->string procedure' do
@@ -396,7 +398,7 @@ SKEEM
396
398
  ['(or)', false],
397
399
  ['(or #f)', false],
398
400
  ['(or #f #t)', true],
399
- ['(or #f #f #f)', false],
401
+ ['(or #f #f #f)', false]
400
402
 
401
403
  ]
402
404
  compare_to_predicted(checks)
@@ -485,11 +487,11 @@ SKEEM
485
487
  compare_to_predicted(checks)
486
488
  end
487
489
 
488
- it 'should implement the string-length procedure' do
490
+ it 'should implement the string-length procedure' do
489
491
  checks = [
490
492
  ['(string-length "abc")', 3],
491
493
  ['(string-length "")', 0],
492
- ['(string-length "hi there")', 8],
494
+ ['(string-length "hi there")', 8]
493
495
  ]
494
496
  compare_to_predicted(checks)
495
497
  end
@@ -544,7 +546,7 @@ SKEEM
544
546
  compare_to_predicted(checks)
545
547
  end
546
548
 
547
- it 'should implement the null? procedure' do
549
+ it 'should implement the null? procedure' do
548
550
  checks = [
549
551
  ['(null? #f)', false],
550
552
  ['(null? 1)', false],
@@ -591,7 +593,7 @@ SKEEM
591
593
  example = "(cons '(a b) 'c)" # => ((a b) . c)
592
594
  result = subject.run(example)
593
595
  expect(result.car).to be_kind_of(SkmPair)
594
- expect(result.car.to_a).to eq(['a', 'b'])
596
+ expect(result.car.to_a).to eq(%w[a b])
595
597
  expect(result.cdr).to be_kind_of(SkmIdentifier)
596
598
  expect(result.cdr).to eq('c')
597
599
  end
@@ -616,7 +618,7 @@ SKEEM
616
618
  result = subject.run(example)
617
619
  expect(result).to be_list
618
620
  expect(result.length).to eq(3)
619
- expect(result.to_a).to eq(['b', 'c', 'd'])
621
+ expect(result.to_a).to eq(%w[b c d])
620
622
 
621
623
  expect_expr("(cdr '(1 . 2))").to eq(2)
622
624
 
@@ -624,29 +626,37 @@ SKEEM
624
626
  expect { subject.run(example) }.to raise_error(StandardError)
625
627
  end
626
628
 
629
+ it 'should implement the length procedure' do
630
+ example = '(make-list 2 3)'
631
+ result = subject.run(example)
632
+ expect(result).to be_list
633
+ expect(result.length).to eq(2)
634
+ expect(result.to_a).to eq([3, 3])
635
+ end
636
+
627
637
  it 'should implement the length procedure' do
628
638
  checks = [
629
639
  ["(length '())", 0],
630
640
  ["(length '(1))", 1],
631
641
  ["(length '(1 2))", 2],
632
642
  ["(length '(1 2 3))", 3],
633
- ["(length '(a (b) (c d e)))", 3]
643
+ ["(length '(a (b) (c d e)))", 3]
634
644
  ]
635
645
  compare_to_predicted(checks)
636
646
  end
637
647
 
638
648
  it 'should implement the append procedure' do
639
649
  checks = [
640
- ["(append '(a b c) '())", array2list_ids(['a', 'b', 'c'])],
641
- ["(append '() '(a b c))", array2list_ids(['a', 'b', 'c'])],
642
- ["(append '(x) '(y))", array2list_ids(['x', 'y'])],
643
- ["(append '(a) '(b c d))", array2list_ids(['a', 'b', 'c', 'd'])],
644
- ["(append '(a b) '(c d))", array2list_ids(['a', 'b', 'c', 'd'])],
645
- ["(append '(a b) '(c) 'd)", array2list_ids(['a', 'b', 'c', 'd'])],
650
+ ["(append '(a b c) '())", array2list_ids(%w[a b c])],
651
+ ["(append '() '(a b c))", array2list_ids(%w[a b c])],
652
+ ["(append '(x) '(y))", array2list_ids(%w[x y])],
653
+ ["(append '(a) '(b c d))", array2list_ids(%w[a b c d])],
654
+ ["(append '(a b) '(c d))", array2list_ids(%w[a b c d])],
655
+ ["(append '(a b) '(c) 'd)", array2list_ids(%w[a b c d])],
646
656
  ["(append '(a (b)) '((c)))", [SkmIdentifier.create('a'),
647
657
  SkmPair.create_from_a(array2list_ids(['b'])),
648
658
  SkmPair.create_from_a(array2list_ids(['c']))]],
649
- [ "(append '() 'a)", SkmIdentifier.create('a')]
659
+ ["(append '() 'a)", SkmIdentifier.create('a')]
650
660
  ]
651
661
  compare_to_predicted(checks) do |result, expectation|
652
662
  if result.kind_of?(SkmPair)
@@ -659,18 +669,18 @@ SKEEM
659
669
 
660
670
  it 'should implement the procedure for an improper list' do
661
671
  result = subject.run("(append '(a b) '(c . d))")
662
- expect(result.car).to eq( SkmIdentifier.create('a'))
663
- expect(result.cdr.car).to eq( SkmIdentifier.create('b'))
664
- expect(result.cdr.cdr.car).to eq( SkmIdentifier.create('c'))
665
- expect(result.cdr.cdr.cdr).to eq( SkmIdentifier.create('d'))
672
+ expect(result.car).to eq(SkmIdentifier.create('a'))
673
+ expect(result.cdr.car).to eq(SkmIdentifier.create('b'))
674
+ expect(result.cdr.cdr.car).to eq(SkmIdentifier.create('c'))
675
+ expect(result.cdr.cdr.cdr).to eq(SkmIdentifier.create('d'))
666
676
  end
667
677
 
668
678
 
669
679
  it 'should implement the reverse procedure' do
670
680
  checks = [
671
681
  ["(reverse '())", SkmEmptyList.instance],
672
- ["(reverse '(a b c))", array2list_ids(['c', 'b', 'a'])],
673
- ["(reverse '((a) b c))", array2list_ids(['c', 'b']) << SkmPair.new(SkmIdentifier.create('a'), nil)]
682
+ ["(reverse '(a b c))", array2list_ids(%w[c b a])],
683
+ ["(reverse '((a) b c))", array2list_ids(%w[c b]) << SkmPair.new(SkmIdentifier.create('a'), nil)]
674
684
  ]
675
685
  compare_to_predicted(checks) do |result, expectation|
676
686
  if result.kind_of?(SkmPair)
@@ -684,7 +694,7 @@ SKEEM
684
694
  it 'should implement the list->vector procedure' do
685
695
  checks = [
686
696
  ["(list->vector '())", []],
687
- ["(list->vector '(a b c))", ['a', 'b', 'c']]
697
+ ["(list->vector '(a b c))", %w[a b c]]
688
698
  ]
689
699
  compare_to_predicted(checks) do |result, expectation|
690
700
  expect(result.to_a).to eq(expectation)
@@ -692,7 +702,7 @@ SKEEM
692
702
  end
693
703
 
694
704
  it 'should implement the set-car! procedure' do
695
- source =<<-SKEEM
705
+ source = <<-SKEEM
696
706
  (define x '(a b c))
697
707
  (set-car! x 1)
698
708
  x
@@ -702,7 +712,7 @@ SKEEM
702
712
  end
703
713
 
704
714
  it 'should implement the set-cdr! procedure' do
705
- source =<<-SKEEM
715
+ source = <<-SKEEM
706
716
  (define x '(a b c))
707
717
  (set-cdr! x 1)
708
718
  x
@@ -736,13 +746,13 @@ SKEEM
736
746
  it 'should implement the list-copy procedure' do
737
747
  checks = [
738
748
  ["(list-copy '())", []],
739
- ["(list-copy '(a b c))", ['a', 'b', 'c']]
749
+ ["(list-copy '(a b c))", %w[a b c]]
740
750
  ]
741
751
  compare_to_predicted(checks) do |result, expectation|
742
752
  expect(result.to_a).to eq(expectation)
743
753
  end
744
754
 
745
- source =<<-SKEEM
755
+ source = <<-SKEEM
746
756
  (define a '(1 8 2 8)) ; a may be immutable
747
757
  (define b (list-copy a))
748
758
  (set-car! b 3) ; b is mutable
@@ -886,7 +896,7 @@ SKEEM
886
896
  checks = [
887
897
  ['(vector-length (make-vector 0))', 0],
888
898
  ["(vector-length (make-vector 0 'a))", 0],
889
- ["(equal? (make-vector 5 'a) '#(a a a a a))", true],
899
+ ["(equal? (make-vector 5 'a) '#(a a a a a))", true]
890
900
  ]
891
901
  compare_to_predicted(checks)
892
902
  end
@@ -899,21 +909,21 @@ SKEEM
899
909
  end
900
910
 
901
911
  it 'should implement the vector-set! procedure' do
902
- source =<<-SKEEM
912
+ source = <<-SKEEM
903
913
  (let
904
914
  ((vec (vector 0 '(2 2 2 2) "Anna")))
905
915
  (vector-set! vec 1 '("Sue" "Sue"))
906
916
  vec)
907
917
  SKEEM
908
- #(0 ("Sue" "Sue") "Anna")
918
+ # (0 ("Sue" "Sue") "Anna")
909
919
  result = subject.run(source)
910
920
  expect(result).to be_kind_of(SkmVector)
911
- expectation = [SkmInteger.create(0),
912
- SkmPair.new(SkmString.create("Sue"), SkmPair.new(SkmString.create("Sue"), SkmEmptyList.instance)),
913
- SkmString.create("Anna") ]
921
+ expectation = [SkmInteger.create(0),
922
+ SkmPair.new(SkmString.create('Sue'), SkmPair.new(SkmString.create('Sue'), SkmEmptyList.instance)),
923
+ SkmString.create('Anna')]
914
924
  expect(result).to eq(expectation)
915
925
 
916
- source =<<-SKEEM
926
+ source = <<-SKEEM
917
927
  (let (
918
928
  (v (vector 'a 'b 'c 'd 'e)))
919
929
  (vector-set! v 2 'x)
@@ -921,13 +931,13 @@ SKEEM
921
931
  SKEEM
922
932
  result = subject.run(source)
923
933
  expect(result).to be_kind_of(SkmVector)
924
- expect(result).to eq(array2list_ids(['a', 'b', 'x', 'd', 'e']))
934
+ expect(result).to eq(array2list_ids(%w[a b x d e]))
925
935
  end
926
936
 
927
937
  it 'should implement the vector->list procedure' do
928
938
  checks = [
929
- ["(vector->list #())", []],
930
- ["(vector->list '#(a b c))", ['a', 'b', 'c']]
939
+ ['(vector->list #())', []],
940
+ ["(vector->list '#(a b c))", %w[a b c]]
931
941
  ]
932
942
  compare_to_predicted(checks) do |result, expectation|
933
943
  expect(result.to_a).to eq(expectation)
@@ -938,9 +948,9 @@ SKEEM
938
948
  context 'Control procedures:' do
939
949
  it 'should implement the procedure? predicate' do
940
950
  checks = [
941
- ["(procedure? car)", true],
951
+ ['(procedure? car)', true],
942
952
  ["(procedure? 'car)", false],
943
- ["(procedure? (lambda (x) (* x x)))", true],
953
+ ['(procedure? (lambda (x) (* x x)))', true]
944
954
  # ["(procedure? '(lambda (x) (* x x)))", false] # Parse fail: non-standard syntax
945
955
  ]
946
956
  compare_to_predicted(checks)
@@ -955,7 +965,7 @@ SKEEM
955
965
 
956
966
  it 'should implement the map procedure' do
957
967
  checks = [
958
- ["(map car '((a b) (d e) (g h)))", ['a', 'd', 'g']],
968
+ ["(map car '((a b) (d e) (g h)))", %w[a d g]],
959
969
  ["(map + '(1 2 3) '(4 5 6 7))", [5, 7, 9]]
960
970
  ]
961
971
  compare_to_predicted(checks) do |result, expectation|
@@ -965,16 +975,23 @@ SKEEM
965
975
  end # context
966
976
 
967
977
  context 'IO procedures:' do
968
- it 'should implement the newline procedure' do
978
+ it 'should implement the display procedure' do
969
979
  default_stdout = $stdout
970
- $stdout = StringIO.new()
971
- subject.run('(newline) (newline) (newline)')
972
- expect($stdout.string).to match(/\n\n\n$/)
980
+ $stdout = StringIO.new
981
+ subject.run('(display "Hello")')
982
+ expect($stdout.string).to eq('Hello')
973
983
  $stdout = default_stdout
974
984
  end
975
985
  end # context
976
986
 
977
987
  context 'Miscellaneous procedures' do
988
+ it 'should raise an exception with given error message' do
989
+ source = '(error "This is an error message")'
990
+ err = SkmError
991
+ msg = 'This is an error message'
992
+ expect { subject.run(source) }.to raise_error(err, msg)
993
+ end
994
+
978
995
  it 'should return true when an assertion succeeds' do
979
996
  source = <<-SKEEM
980
997
  (define x 2)
@@ -993,9 +1010,9 @@ SKEEM
993
1010
  err = StandardError
994
1011
  msg1 = 'Error: assertion failed on line 3, column 4'
995
1012
  msg2 = 'with <Skeem::SkmBoolean: false>'
996
- expect { subject.run(source) }.to raise_error(err, msg1 + ', '+ msg2)
1013
+ expect { subject.run(source) }.to raise_error(err, "#{msg1}, #{msg2}")
997
1014
  end
998
1015
  end # context
999
1016
  end # describe
1000
1017
  end # module
1001
- end # module
1018
+ end # module
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../../spec_helper' # Use the RSpec framework
2
4
 
3
5
  # Load the class under test
@@ -9,8 +11,8 @@ module Skeem
9
11
  let(:nullary) { SkmArity.new(0, 0) }
10
12
  let(:unary) { SkmArity.new(1, 1) }
11
13
  let(:binary) { SkmArity.new(2, 2) }
12
- let(:zero_or_more) {SkmArity.new(0, '*') }
13
- let(:one_or_more) {SkmArity.new(1, '*') }
14
+ let(:zero_or_more) { SkmArity.new(0, '*') }
15
+ let(:one_or_more) { SkmArity.new(1, '*') }
14
16
  let(:newline_code) do
15
17
  ->(_runtime) { "\n" }
16
18
  end
@@ -49,7 +51,7 @@ module Skeem
49
51
  end
50
52
 
51
53
  it 'should complain if third argument is not a lambda' do
52
- kode = Proc.new { puts '' }
54
+ kode = proc { puts '' }
53
55
 
54
56
  err = StandardError
55
57
  err_msg = "Primitive procedure 'newline' must be implemented with a Ruby lambda."
@@ -57,7 +59,7 @@ module Skeem
57
59
  end
58
60
 
59
61
  it 'should complain if third argument is a nullary lambda' do
60
- kode = ->() { puts '' } # Missing slot for Runtime object
62
+ kode = -> { puts '' } # Missing slot for Runtime object
61
63
 
62
64
  err = StandardError
63
65
  err_msg = "Primitive procedure 'newline' lambda takes no parameter."
@@ -68,10 +70,10 @@ module Skeem
68
70
  err = StandardError
69
71
  msg1 = "Discrepancy in primitive procedure 'cube' "
70
72
 
71
- msg2 = "between arity (0) + 1 and parameter count of lambda 2."
73
+ msg2 = 'between arity (0) + 1 and parameter count of lambda 2.'
72
74
  expect { PrimitiveProcedure.new('cube', nullary, cube) }.to raise_error(err, msg1 + msg2)
73
75
 
74
- msg2 = "between arity (2) + 1 and parameter count of lambda 2."
76
+ msg2 = 'between arity (2) + 1 and parameter count of lambda 2.'
75
77
  expect { PrimitiveProcedure.new('cube', binary, cube) }.to raise_error(err, msg1 + msg2)
76
78
 
77
79
  # Nasty; this discrepancy isn't detected
@@ -79,7 +81,7 @@ module Skeem
79
81
 
80
82
  expect { PrimitiveProcedure.new('cube', unary, cube) }.not_to raise_error
81
83
 
82
- msg2 = "between arity (1) + 2 and parameter count of lambda 2."
84
+ msg2 = 'between arity (1) + 2 and parameter count of lambda 2.'
83
85
  expect { PrimitiveProcedure.new('cube', one_or_more, cube) }.to raise_error(err, msg1 + msg2)
84
86
  end
85
87
  end # context
@@ -109,7 +111,7 @@ module Skeem
109
111
  ms2 = ' (required at least 1, got 0)'
110
112
  expect { pproc.call(rtime, []) }.to raise_error(err, ms1 + ms2)
111
113
 
112
- too_much = ['foo', 'bar']
114
+ too_much = %w[foo bar]
113
115
  err = StandardError
114
116
  ms1 = 'Wrong number of arguments for #<Procedure cube>'
115
117
  ms2 = ' (required at least 1, got 2)'
@@ -129,7 +131,7 @@ module Skeem
129
131
  ms2 = ' (required at least 2, got 1)'
130
132
  expect { pproc.call(rtime, too_few) }.to raise_error(err, ms1 + ms2)
131
133
 
132
- too_much = ['foo', 'bar', 'quux']
134
+ too_much = %w[foo bar quux]
133
135
  err = StandardError
134
136
  ms1 = 'Wrong number of arguments for #<Procedure sum>'
135
137
  ms2 = ' (required at least 2, got 3)'
@@ -146,11 +148,11 @@ module Skeem
146
148
  no_arg = []
147
149
  expect(pproc.call(rtime, no_arg)).to eq(0)
148
150
 
149
- many = [SkmString.create('foo'), SkmString.create('bar'),
151
+ many = [SkmString.create('foo'), SkmString.create('bar'),
150
152
  SkmString.create('quux')]
151
- expect( pproc.call(rtime, many)).to eq(3)
153
+ expect(pproc.call(rtime, many)).to eq(3)
152
154
  end
153
155
  end # context
154
156
  end # describe
155
157
  end # module
156
- end # module
158
+ end # module
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../spec_helper' # Use the RSpec framework
2
4
  require_relative '../../lib/skeem/datum_dsl'
3
5
  require_relative '../../lib/skeem/s_expr_nodes'
@@ -8,7 +10,7 @@ require_relative '../../lib/skeem/runtime' # Load the class under test
8
10
  module Skeem
9
11
  describe Runtime do
10
12
  include DatumDSL
11
-
13
+
12
14
  let(:some_env) { SkmFrame.new }
13
15
  subject { Runtime.new(some_env) }
14
16
 
@@ -20,7 +22,7 @@ module Skeem
20
22
  it 'should know the environment' do
21
23
  expect(subject.environment).to eq(some_env)
22
24
  end
23
-
25
+
24
26
  it 'should have an empty call stack' do
25
27
  expect(subject.call_stack).to be_empty
26
28
  end
@@ -42,10 +44,10 @@ module Skeem
42
44
  expect(subject.include?('dummy')).to be_truthy
43
45
  end
44
46
  end # context
45
-
47
+
46
48
  context 'Evaluation:' do
47
49
  include Primitive::PrimitiveBuilder
48
-
50
+
49
51
  # it 'should evaluate a given entry' do
50
52
  # entry = integer(3)
51
53
  # result = double('fake-procedure')
@@ -54,21 +56,21 @@ module Skeem
54
56
  # subject.define('three', entry)
55
57
  # expect(subject.evaluate('three')).to eq(3)
56
58
  # end
57
-
59
+
58
60
  it 'should evaluate a given list' do
59
61
  add_primitives(subject)
60
62
  sum = list([identifier('+'), 3, 4])
61
-
63
+
62
64
  expect(subject.evaluate_form(sum)).to eq(7)
63
65
  end
64
66
  end # context
65
-
67
+
66
68
  context 'Environment nesting:' do
67
69
  it 'should add nested environment' do
68
70
  expect(subject.depth).to eq(1)
69
71
  env_before = subject.environment
70
72
  subject.nest
71
-
73
+
72
74
  expect(subject.environment).not_to eq(env_before)
73
75
  expect(subject.environment.parent).to eq(env_before)
74
76
  expect(subject.depth).to eq(2)
@@ -79,37 +81,37 @@ module Skeem
79
81
  subject.nest
80
82
  parent_before = subject.environment.parent
81
83
  expect(subject.depth).to eq(2)
82
-
84
+
83
85
  subject.unnest
84
86
  expect(subject.environment).to eq(parent_before)
85
87
  expect(subject.depth).to eq(1)
86
88
  end
87
89
  end # context
88
-
90
+
89
91
  context 'Call stack operations:' do
90
92
  let(:sample_call) do
91
93
  pos = double('fake-position')
92
- ProcedureCall.new(pos, identifier('boolean?'), [integer(42)])
94
+ ProcedureCall.new(pos, identifier('boolean?'), [integer(42)])
93
95
  end
94
-
96
+
95
97
  it 'should push a call to the stack call' do
96
98
  expect { subject.push_call(sample_call) }.not_to raise_error
97
- expect(subject.call_stack.size). to eq(1)
99
+ expect(subject.call_stack.size).to eq(1)
98
100
  expect(subject.caller).to eq(sample_call)
99
-
101
+
100
102
  subject.push_call(sample_call.clone)
101
- expect(subject.call_stack.size). to eq(2)
103
+ expect(subject.call_stack.size).to eq(2)
102
104
  end
103
105
 
104
106
  it 'should pop a call from the call stack' do
105
107
  subject.push_call(sample_call)
106
108
  expect { subject.pop_call }.not_to raise_error
107
109
  expect(subject.call_stack).to be_empty
108
-
110
+
109
111
  err = StandardError
110
112
  msg = 'Skeem call stack empty!'
111
113
  expect { subject.pop_call }.to raise_error(err, msg)
112
114
  end
113
- end # context
115
+ end # context
114
116
  end # describe
115
- end # module
117
+ end # module