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 '../../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,21 +618,21 @@ 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
 
623
625
  example = "(cdr '())" # => error
624
626
  expect { subject.run(example) }.to raise_error(StandardError)
625
627
  end
626
-
628
+
627
629
  it 'should implement the length procedure' do
628
630
  example = '(make-list 2 3)'
629
631
  result = subject.run(example)
630
632
  expect(result).to be_list
631
633
  expect(result.length).to eq(2)
632
634
  expect(result.to_a).to eq([3, 3])
633
- end
635
+ end
634
636
 
635
637
  it 'should implement the length procedure' do
636
638
  checks = [
@@ -638,23 +640,23 @@ SKEEM
638
640
  ["(length '(1))", 1],
639
641
  ["(length '(1 2))", 2],
640
642
  ["(length '(1 2 3))", 3],
641
- ["(length '(a (b) (c d e)))", 3]
643
+ ["(length '(a (b) (c d e)))", 3]
642
644
  ]
643
645
  compare_to_predicted(checks)
644
646
  end
645
647
 
646
648
  it 'should implement the append procedure' do
647
649
  checks = [
648
- ["(append '(a b c) '())", array2list_ids(['a', 'b', 'c'])],
649
- ["(append '() '(a b c))", array2list_ids(['a', 'b', 'c'])],
650
- ["(append '(x) '(y))", array2list_ids(['x', 'y'])],
651
- ["(append '(a) '(b c d))", array2list_ids(['a', 'b', 'c', 'd'])],
652
- ["(append '(a b) '(c d))", array2list_ids(['a', 'b', 'c', 'd'])],
653
- ["(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])],
654
656
  ["(append '(a (b)) '((c)))", [SkmIdentifier.create('a'),
655
657
  SkmPair.create_from_a(array2list_ids(['b'])),
656
658
  SkmPair.create_from_a(array2list_ids(['c']))]],
657
- [ "(append '() 'a)", SkmIdentifier.create('a')]
659
+ ["(append '() 'a)", SkmIdentifier.create('a')]
658
660
  ]
659
661
  compare_to_predicted(checks) do |result, expectation|
660
662
  if result.kind_of?(SkmPair)
@@ -667,18 +669,18 @@ SKEEM
667
669
 
668
670
  it 'should implement the procedure for an improper list' do
669
671
  result = subject.run("(append '(a b) '(c . d))")
670
- expect(result.car).to eq( SkmIdentifier.create('a'))
671
- expect(result.cdr.car).to eq( SkmIdentifier.create('b'))
672
- expect(result.cdr.cdr.car).to eq( SkmIdentifier.create('c'))
673
- 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'))
674
676
  end
675
677
 
676
678
 
677
679
  it 'should implement the reverse procedure' do
678
680
  checks = [
679
681
  ["(reverse '())", SkmEmptyList.instance],
680
- ["(reverse '(a b c))", array2list_ids(['c', 'b', 'a'])],
681
- ["(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)]
682
684
  ]
683
685
  compare_to_predicted(checks) do |result, expectation|
684
686
  if result.kind_of?(SkmPair)
@@ -692,7 +694,7 @@ SKEEM
692
694
  it 'should implement the list->vector procedure' do
693
695
  checks = [
694
696
  ["(list->vector '())", []],
695
- ["(list->vector '(a b c))", ['a', 'b', 'c']]
697
+ ["(list->vector '(a b c))", %w[a b c]]
696
698
  ]
697
699
  compare_to_predicted(checks) do |result, expectation|
698
700
  expect(result.to_a).to eq(expectation)
@@ -700,7 +702,7 @@ SKEEM
700
702
  end
701
703
 
702
704
  it 'should implement the set-car! procedure' do
703
- source =<<-SKEEM
705
+ source = <<-SKEEM
704
706
  (define x '(a b c))
705
707
  (set-car! x 1)
706
708
  x
@@ -710,7 +712,7 @@ SKEEM
710
712
  end
711
713
 
712
714
  it 'should implement the set-cdr! procedure' do
713
- source =<<-SKEEM
715
+ source = <<-SKEEM
714
716
  (define x '(a b c))
715
717
  (set-cdr! x 1)
716
718
  x
@@ -744,13 +746,13 @@ SKEEM
744
746
  it 'should implement the list-copy procedure' do
745
747
  checks = [
746
748
  ["(list-copy '())", []],
747
- ["(list-copy '(a b c))", ['a', 'b', 'c']]
749
+ ["(list-copy '(a b c))", %w[a b c]]
748
750
  ]
749
751
  compare_to_predicted(checks) do |result, expectation|
750
752
  expect(result.to_a).to eq(expectation)
751
753
  end
752
754
 
753
- source =<<-SKEEM
755
+ source = <<-SKEEM
754
756
  (define a '(1 8 2 8)) ; a may be immutable
755
757
  (define b (list-copy a))
756
758
  (set-car! b 3) ; b is mutable
@@ -894,7 +896,7 @@ SKEEM
894
896
  checks = [
895
897
  ['(vector-length (make-vector 0))', 0],
896
898
  ["(vector-length (make-vector 0 'a))", 0],
897
- ["(equal? (make-vector 5 'a) '#(a a a a a))", true],
899
+ ["(equal? (make-vector 5 'a) '#(a a a a a))", true]
898
900
  ]
899
901
  compare_to_predicted(checks)
900
902
  end
@@ -907,21 +909,21 @@ SKEEM
907
909
  end
908
910
 
909
911
  it 'should implement the vector-set! procedure' do
910
- source =<<-SKEEM
912
+ source = <<-SKEEM
911
913
  (let
912
914
  ((vec (vector 0 '(2 2 2 2) "Anna")))
913
915
  (vector-set! vec 1 '("Sue" "Sue"))
914
916
  vec)
915
917
  SKEEM
916
- #(0 ("Sue" "Sue") "Anna")
918
+ # (0 ("Sue" "Sue") "Anna")
917
919
  result = subject.run(source)
918
920
  expect(result).to be_kind_of(SkmVector)
919
921
  expectation = [SkmInteger.create(0),
920
- SkmPair.new(SkmString.create("Sue"), SkmPair.new(SkmString.create("Sue"), SkmEmptyList.instance)),
921
- SkmString.create("Anna") ]
922
+ SkmPair.new(SkmString.create('Sue'), SkmPair.new(SkmString.create('Sue'), SkmEmptyList.instance)),
923
+ SkmString.create('Anna')]
922
924
  expect(result).to eq(expectation)
923
925
 
924
- source =<<-SKEEM
926
+ source = <<-SKEEM
925
927
  (let (
926
928
  (v (vector 'a 'b 'c 'd 'e)))
927
929
  (vector-set! v 2 'x)
@@ -929,13 +931,13 @@ SKEEM
929
931
  SKEEM
930
932
  result = subject.run(source)
931
933
  expect(result).to be_kind_of(SkmVector)
932
- expect(result).to eq(array2list_ids(['a', 'b', 'x', 'd', 'e']))
934
+ expect(result).to eq(array2list_ids(%w[a b x d e]))
933
935
  end
934
936
 
935
937
  it 'should implement the vector->list procedure' do
936
938
  checks = [
937
- ["(vector->list #())", []],
938
- ["(vector->list '#(a b c))", ['a', 'b', 'c']]
939
+ ['(vector->list #())', []],
940
+ ["(vector->list '#(a b c))", %w[a b c]]
939
941
  ]
940
942
  compare_to_predicted(checks) do |result, expectation|
941
943
  expect(result.to_a).to eq(expectation)
@@ -946,9 +948,9 @@ SKEEM
946
948
  context 'Control procedures:' do
947
949
  it 'should implement the procedure? predicate' do
948
950
  checks = [
949
- ["(procedure? car)", true],
951
+ ['(procedure? car)', true],
950
952
  ["(procedure? 'car)", false],
951
- ["(procedure? (lambda (x) (* x x)))", true],
953
+ ['(procedure? (lambda (x) (* x x)))', true]
952
954
  # ["(procedure? '(lambda (x) (* x x)))", false] # Parse fail: non-standard syntax
953
955
  ]
954
956
  compare_to_predicted(checks)
@@ -963,7 +965,7 @@ SKEEM
963
965
 
964
966
  it 'should implement the map procedure' do
965
967
  checks = [
966
- ["(map car '((a b) (d e) (g h)))", ['a', 'd', 'g']],
968
+ ["(map car '((a b) (d e) (g h)))", %w[a d g]],
967
969
  ["(map + '(1 2 3) '(4 5 6 7))", [5, 7, 9]]
968
970
  ]
969
971
  compare_to_predicted(checks) do |result, expectation|
@@ -975,7 +977,7 @@ SKEEM
975
977
  context 'IO procedures:' do
976
978
  it 'should implement the display procedure' do
977
979
  default_stdout = $stdout
978
- $stdout = StringIO.new()
980
+ $stdout = StringIO.new
979
981
  subject.run('(display "Hello")')
980
982
  expect($stdout.string).to eq('Hello')
981
983
  $stdout = default_stdout
@@ -983,6 +985,13 @@ SKEEM
983
985
  end # context
984
986
 
985
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
+
986
995
  it 'should return true when an assertion succeeds' do
987
996
  source = <<-SKEEM
988
997
  (define x 2)
@@ -1001,9 +1010,9 @@ SKEEM
1001
1010
  err = StandardError
1002
1011
  msg1 = 'Error: assertion failed on line 3, column 4'
1003
1012
  msg2 = 'with <Skeem::SkmBoolean: false>'
1004
- expect { subject.run(source) }.to raise_error(err, msg1 + ', '+ msg2)
1013
+ expect { subject.run(source) }.to raise_error(err, "#{msg1}, #{msg2}")
1005
1014
  end
1006
1015
  end # context
1007
1016
  end # describe
1008
1017
  end # module
1009
- 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