skeem 0.2.14 → 0.2.18

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