shen-ruby 0.10.0 → 0.11.0

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 (128) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -0
  3. data/.travis.yml +9 -3
  4. data/Gemfile +1 -4
  5. data/HISTORY.md +16 -0
  6. data/MIT_LICENSE.txt +1 -1
  7. data/README.md +25 -26
  8. data/Rakefile +3 -11
  9. data/bin/shen_test_suite.rb +15 -3
  10. data/bin/srrepl +6 -8
  11. data/lib/shen_ruby.rb +6 -1
  12. data/lib/shen_ruby/converters.rb +23 -0
  13. data/lib/shen_ruby/version.rb +1 -1
  14. data/shen-ruby.gemspec +4 -1
  15. data/shen/lib/shen_ruby/shen.rb +49 -33
  16. data/shen/release/benchmarks/N_queens.shen +45 -45
  17. data/shen/release/benchmarks/README.shen +14 -14
  18. data/shen/release/benchmarks/benchmarks.shen +52 -52
  19. data/shen/release/benchmarks/einstein.shen +32 -32
  20. data/shen/release/benchmarks/interpreter.shen +219 -219
  21. data/shen/release/benchmarks/jnk.shen +193 -193
  22. data/shen/release/benchmarks/powerset.shen +10 -10
  23. data/shen/release/benchmarks/prime.shen +10 -10
  24. data/shen/release/benchmarks/short.shen +129 -129
  25. data/shen/release/k_lambda/core.kl +181 -181
  26. data/shen/release/k_lambda/declarations.kl +131 -131
  27. data/shen/release/k_lambda/load.kl +84 -84
  28. data/shen/release/k_lambda/macros.kl +112 -112
  29. data/shen/release/k_lambda/prolog.kl +252 -252
  30. data/shen/release/k_lambda/reader.kl +222 -222
  31. data/shen/release/k_lambda/sequent.kl +166 -166
  32. data/shen/release/k_lambda/sys.kl +271 -271
  33. data/shen/release/k_lambda/t-star.kl +139 -139
  34. data/shen/release/k_lambda/toplevel.kl +135 -135
  35. data/shen/release/k_lambda/track.kl +103 -103
  36. data/shen/release/k_lambda/types.kl +324 -324
  37. data/shen/release/k_lambda/writer.kl +105 -105
  38. data/shen/release/k_lambda/yacc.kl +113 -113
  39. data/shen/release/test_programs/Chap13/problems.txt +26 -26
  40. data/shen/release/test_programs/README.shen +52 -52
  41. data/shen/release/test_programs/TinyLispFunctions.txt +15 -15
  42. data/shen/release/test_programs/TinyTypes.shen +55 -55
  43. data/shen/release/test_programs/binary.shen +24 -24
  44. data/shen/release/test_programs/bubble_version_1.shen +28 -28
  45. data/shen/release/test_programs/bubble_version_2.shen +22 -22
  46. data/shen/release/test_programs/calculator.shen +21 -21
  47. data/shen/release/test_programs/cartprod.shen +23 -23
  48. data/shen/release/test_programs/change.shen +25 -25
  49. data/shen/release/test_programs/classes-defaults.shen +94 -94
  50. data/shen/release/test_programs/classes-inheritance.shen +100 -100
  51. data/shen/release/test_programs/classes-typed.shen +74 -74
  52. data/shen/release/test_programs/classes-untyped.shen +46 -46
  53. data/shen/release/test_programs/depth_.shen +14 -14
  54. data/shen/release/test_programs/einstein.shen +34 -34
  55. data/shen/release/test_programs/fruit_machine.shen +46 -46
  56. data/shen/release/test_programs/interpreter.shen +217 -217
  57. data/shen/release/test_programs/metaprog.shen +85 -85
  58. data/shen/release/test_programs/minim.shen +192 -192
  59. data/shen/release/test_programs/mutual.shen +11 -11
  60. data/shen/release/test_programs/n_queens.shen +45 -45
  61. data/shen/release/test_programs/newton_version_1.shen +33 -33
  62. data/shen/release/test_programs/newton_version_2.shen +24 -24
  63. data/shen/release/test_programs/parse.prl +14 -14
  64. data/shen/release/test_programs/parser.shen +51 -51
  65. data/shen/release/test_programs/powerset.shen +10 -10
  66. data/shen/release/test_programs/prime.shen +10 -10
  67. data/shen/release/test_programs/prolog.shen +78 -78
  68. data/shen/release/test_programs/proof_assistant.shen +80 -80
  69. data/shen/release/test_programs/proplog_version_1.shen +25 -25
  70. data/shen/release/test_programs/proplog_version_2.shen +27 -27
  71. data/shen/release/test_programs/qmachine.shen +66 -66
  72. data/shen/release/test_programs/red-black.shen +54 -54
  73. data/shen/release/test_programs/search.shen +55 -55
  74. data/shen/release/test_programs/semantic_net.shen +44 -44
  75. data/shen/release/test_programs/spreadsheet.shen +34 -34
  76. data/shen/release/test_programs/stack.shen +27 -27
  77. data/shen/release/test_programs/streams.shen +20 -20
  78. data/shen/release/test_programs/strings.shen +57 -57
  79. data/shen/release/test_programs/structures-typed.shen +71 -71
  80. data/shen/release/test_programs/structures-untyped.shen +41 -41
  81. data/shen/release/test_programs/tests.shen +232 -232
  82. data/shen/release/test_programs/types.shen +11 -11
  83. data/shen/release/test_programs/whist.shen +239 -239
  84. data/shen/release/test_programs/yacc.shen +132 -132
  85. data/spec/shen_ruby/converters_spec.rb +48 -0
  86. data/spec/spec_helper.rb +1 -2
  87. metadata +55 -60
  88. data/k_lambda_spec/atom_spec.rb +0 -85
  89. data/k_lambda_spec/primitives/arithmetic_spec.rb +0 -175
  90. data/k_lambda_spec/primitives/assignments_spec.rb +0 -44
  91. data/k_lambda_spec/primitives/boolean_operations_spec.rb +0 -136
  92. data/k_lambda_spec/primitives/generic_functions_spec.rb +0 -120
  93. data/k_lambda_spec/primitives/lists_spec.rb +0 -40
  94. data/k_lambda_spec/primitives/strings_spec.rb +0 -77
  95. data/k_lambda_spec/primitives/symbols_spec.rb +0 -24
  96. data/k_lambda_spec/primitives/vectors_spec.rb +0 -92
  97. data/k_lambda_spec/spec_helper.rb +0 -29
  98. data/k_lambda_spec/support/shared_examples.rb +0 -124
  99. data/k_lambda_spec/tail_recursion_spec.rb +0 -30
  100. data/lib/kl.rb +0 -7
  101. data/lib/kl/absvector.rb +0 -12
  102. data/lib/kl/compiler.rb +0 -360
  103. data/lib/kl/cons.rb +0 -51
  104. data/lib/kl/empty_list.rb +0 -12
  105. data/lib/kl/environment.rb +0 -163
  106. data/lib/kl/error.rb +0 -4
  107. data/lib/kl/internal_error.rb +0 -7
  108. data/lib/kl/lexer.rb +0 -186
  109. data/lib/kl/primitives/arithmetic.rb +0 -60
  110. data/lib/kl/primitives/assignments.rb +0 -15
  111. data/lib/kl/primitives/booleans.rb +0 -21
  112. data/lib/kl/primitives/error_handling.rb +0 -13
  113. data/lib/kl/primitives/extensions.rb +0 -12
  114. data/lib/kl/primitives/generic_functions.rb +0 -29
  115. data/lib/kl/primitives/lists.rb +0 -23
  116. data/lib/kl/primitives/streams.rb +0 -28
  117. data/lib/kl/primitives/strings.rb +0 -63
  118. data/lib/kl/primitives/symbols.rb +0 -18
  119. data/lib/kl/primitives/time.rb +0 -17
  120. data/lib/kl/primitives/vectors.rb +0 -36
  121. data/lib/kl/reader.rb +0 -46
  122. data/spec/kl/cons_spec.rb +0 -12
  123. data/spec/kl/environment_spec.rb +0 -282
  124. data/spec/kl/interop_spec.rb +0 -68
  125. data/spec/kl/lexer_spec.rb +0 -149
  126. data/spec/kl/primitives/generic_functions_spec.rb +0 -29
  127. data/spec/kl/primitives/symbols_spec.rb +0 -21
  128. data/spec/kl/reader_spec.rb +0 -42
@@ -1,85 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'Atoms:' do
4
- describe 'a string' do
5
- it 'is self-evaluating' do
6
- kl_eval('"string"').should == 'string'
7
- end
8
- end
9
-
10
- describe 'a symbol' do
11
- it 'is self-evaluating' do
12
- kl_eval('symbol').should == :symbol
13
- end
14
-
15
- it 'may include any of the legal characters for symbol' do
16
- # See http://www.shenlanguage.org/documentation/shendoc.htm#The%20Syntax%20of%20Symbols
17
- all_legal_chars = 'abcdefghijklmnopqrstuvwxyz' +
18
- 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
19
- '0123456789' +
20
- '=-*/+_?$!@~.><&%\'#`;:{}'
21
- kl_eval(all_legal_chars).should == all_legal_chars.to_sym
22
- end
23
-
24
- it 'may begin with any legal character other than a digit' do
25
- legal_non_digits = 'abcdefghijklmnopqrstuvwxyz' +
26
- 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
27
- '=-*/+_?$!@~.><&%\'#`;:{}'
28
- legal_non_digits.each_char do |char|
29
- kl_eval(char).should == char.to_sym
30
- end
31
- end
32
-
33
- it 'may not begin with a digit' do
34
- digits = '01234567890'
35
- digits.each_char do |char|
36
- kl_eval(char).should_not be_kind_of Symbol
37
- end
38
- end
39
- end
40
-
41
- describe 'numbers' do
42
- it 'parses integers as integers' do
43
- result = kl_eval('123')
44
- result.should == 123
45
- result.should be_kind_of Fixnum
46
- end
47
-
48
- it 'parses floating point numbers as reals' do
49
- result = kl_eval('12.3')
50
- result.should == 12.3
51
- result.should be_kind_of Float
52
- end
53
-
54
- describe 'with leading sign characters' do
55
- it 'recognizes negative numbers' do
56
- kl_eval('-123').should == -123
57
- end
58
-
59
- it 'treats any odd number of minuses as negative' do
60
- kl_eval('---123').should == -123
61
- end
62
-
63
- it 'treats any even number of minuses as positive' do
64
- kl_eval('----123').should == 123
65
- end
66
-
67
- it 'ignores leading plusses' do
68
- kl_eval('+123').should == 123
69
- kl_eval('--+-123').should == -123
70
- end
71
- end
72
- end
73
-
74
- describe 'true' do
75
- it 'evaluates to boolean true rather than a symbol' do
76
- kl_eval('true').should == true
77
- end
78
- end
79
-
80
- describe 'false' do
81
- it 'evaluates to boolean false rather than a symbol' do
82
- kl_eval('false').should == false
83
- end
84
- end
85
- end
@@ -1,175 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'Primitives for Arithmetic' do
4
- describe '+' do
5
- it 'adds its arguments' do
6
- kl_eval('(+ 1 2)').should == 3
7
- end
8
-
9
- it 'returns an integer when both arguments are integers' do
10
- kl_eval('(+ 1 2)').should be_kind_of Fixnum
11
- end
12
-
13
- it ('returns a real when either argument is a real') do
14
- kl_eval('(+ 1.0 2)').should be_kind_of Float
15
- kl_eval('(+ 1 2.0)').should be_kind_of Float
16
- end
17
-
18
- include_examples 'argument types', %w(+ 1 2),
19
- 1 => [:integer, :real],
20
- 2 => [:integer, :real]
21
- include_examples 'applicative order evaluation', %w(+ 1 2)
22
- include_examples 'partially-applicable function', %w(+ 1 2)
23
- end
24
-
25
- describe '-' do
26
- it 'subtracts its second argument from its first' do
27
- kl_eval('(- 3 2)').should == 1
28
- end
29
-
30
- it 'returns an integer when both arguments are integers' do
31
- kl_eval('(- 3 2)').should be_kind_of Fixnum
32
- end
33
-
34
- it ('returns a real when either argument is a real') do
35
- kl_eval('(- 3.0 2)').should be_kind_of Float
36
- kl_eval('(- 3 2.0)').should be_kind_of Float
37
- end
38
-
39
- include_examples 'argument types', %w(- 3 2),
40
- 1 => [:integer, :real],
41
- 2 => [:integer, :real]
42
- include_examples 'applicative order evaluation', %w(- 3 2)
43
- include_examples 'partially-applicable function', %w(- 3 2)
44
- end
45
-
46
- describe '*' do
47
- it 'multiplies its arguments' do
48
- kl_eval('(* 2 3)').should == 6
49
- end
50
-
51
- it 'returns an integer when both arguments are integers' do
52
- kl_eval('(* 2 3)').should be_kind_of Fixnum
53
- end
54
-
55
- it ('returns a real when either argument is a real') do
56
- kl_eval('(* 2.0 3)').should be_kind_of Float
57
- kl_eval('(* 2 3.0)').should be_kind_of Float
58
- end
59
-
60
- include_examples 'argument types', %w(* 2 3),
61
- 1 => [:integer, :real],
62
- 2 => [:integer, :real]
63
- include_examples 'applicative order evaluation', %w(* 2 3)
64
- include_examples 'partially-applicable function', %w(* 2 3)
65
- end
66
-
67
- describe '/' do
68
- it 'divides its first argument by its second argument' do
69
- kl_eval('(/ 6 3)').should == 2
70
- end
71
-
72
- it 'returns an integer when an integer evenly divides another integer' do
73
- kl_eval('(/ 6 3)').should be_kind_of Fixnum
74
- end
75
-
76
- it 'returns a real when an integer does not evenly divide another integer' do
77
- kl_eval('(/ 4 3)').should be_kind_of Float
78
- end
79
-
80
- it ('returns a real when either argument is a real') do
81
- kl_eval('(/ 6.0 3)').should be_kind_of Float
82
- kl_eval('(/ 6 3.0)').should be_kind_of Float
83
- end
84
-
85
- include_examples 'argument types', %w(/ 6 3),
86
- 1 => [:integer, :real],
87
- 2 => [:integer, :real]
88
- include_examples 'applicative order evaluation', %w(/ 6 3)
89
- include_examples 'partially-applicable function', %w(/ 6 3)
90
- end
91
-
92
- describe '>' do
93
- it 'returns false if its first argument is less than its second argument' do
94
- kl_eval('(> 1 2)').should == false
95
- end
96
-
97
- it 'returns false if its first argument is equal to its second argument' do
98
- kl_eval('(> 2 2)').should == false
99
- end
100
-
101
- it 'returns true if its first argument is greater than its second argument' do
102
- kl_eval('(> 3 2)').should == true
103
- end
104
-
105
- include_examples 'argument types', %w(> 1 2),
106
- 1 => [:integer, :real],
107
- 2 => [:integer, :real]
108
- include_examples 'applicative order evaluation', %w(> 1 2)
109
- include_examples 'partially-applicable function', %w(> 1 2)
110
- end
111
-
112
- describe '<' do
113
- it 'returns true if its first argument is less than its second argument' do
114
- kl_eval('(< 1 2)').should == true
115
- end
116
-
117
- it 'returns false if its first argument is equal to its second argument' do
118
- kl_eval('(< 2 2)').should == false
119
- end
120
-
121
- it 'returns false if its first argument is greater than its second argument' do
122
- kl_eval('(< 3 2)').should == false
123
- end
124
-
125
- include_examples 'argument types', %w(< 1 2),
126
- 1 => [:integer, :real],
127
- 2 => [:integer, :real]
128
- include_examples 'applicative order evaluation', %w(> 1 2)
129
- include_examples 'partially-applicable function', %w(> 1 2)
130
- end
131
-
132
- describe '>=' do
133
- it 'returns false if its first argument is less than its second argument' do
134
- kl_eval('(>= 1 2)').should == false
135
- end
136
-
137
- it 'returns true if its first argument is equal to its second argument' do
138
- kl_eval('(>= 2 2)').should == true
139
- end
140
-
141
- it 'returns true if its first argument is greater than its second argument' do
142
- kl_eval('(>= 3 2)').should == true
143
- end
144
-
145
- include_examples 'argument types', %w(>= 1 2),
146
- 1 => [:integer, :real],
147
- 2 => [:integer, :real]
148
- include_examples 'applicative order evaluation', %w(> 1 2)
149
- include_examples 'partially-applicable function', %w(> 1 2)
150
- end
151
-
152
- describe '<=' do
153
- it 'returns true if its first argument is less than its second argument' do
154
- kl_eval('(<= 1 2)').should == true
155
- end
156
-
157
- it 'returns true if its first argument is equal to its second argument' do
158
- kl_eval('(<= 2 2)').should == true
159
- end
160
-
161
- it 'returns false if its first argument is greater than its second argument' do
162
- kl_eval('(<= 3 2)').should == false
163
- end
164
-
165
- include_examples 'argument types', %w(<= 1 2),
166
- 1 => [:integer, :real],
167
- 2 => [:integer, :real]
168
- include_examples 'applicative order evaluation', %w(> 1 2)
169
- include_examples 'partially-applicable function', %w(> 1 2)
170
- end
171
-
172
- describe 'number?' do
173
- include_examples 'type predicate', 'number?', [:integer, :real]
174
- end
175
- end
@@ -1,44 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'Primitives for assignment' do
4
- describe '(set Name Value)' do
5
- it 'associates Value with Name' do
6
- kl_eval('(set foo bar)')
7
- kl_eval('(value foo)').should == :bar
8
- end
9
-
10
- it 'returns Value' do
11
- kl_eval('(set foo bar)').should == :bar
12
- end
13
-
14
- it 'overwrites the previous value when called again with same Name' do
15
- kl_eval('(set foo bar)')
16
- kl_eval('(set foo baz)').should == :baz
17
- end
18
-
19
- include_examples 'argument types', %w(set foo bar), 1 => [:symbol]
20
- include_examples 'partially-applicable function', %w(set foo bar)
21
- include_examples 'applicative order evaluation', %w(set foo bar)
22
- end
23
-
24
- describe '(value Name)' do
25
- before(:each) do
26
- # a-symbol is the example symbol used by the argument type specs.
27
- # Set it so that they do not throw and unset variable error.
28
- kl_eval('(set a-symbol bar)')
29
- end
30
-
31
- it 'returns the value associated with Name' do
32
- kl_eval('(value a-symbol)').should == :bar
33
- end
34
-
35
- it 'raises an error if Name has not previously been set' do
36
- expect {
37
- kl_eval('(value baz)')
38
- }.to raise_error(Kl::Error, 'variable baz has no value')
39
- end
40
-
41
- include_examples 'argument types', %w(value a-symbol), 1 => [:symbol]
42
- include_examples 'partially-applicable function', %w(value a-symbol)
43
- end
44
- end
@@ -1,136 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'Primitives for Boolean Operations' do
4
- describe 'if special form' do
5
- include_examples "partially-applicable function", %w(if true a b)
6
-
7
- it 'evaluates its first argument' do
8
- define_kl_do
9
- kl_eval('(set flag clear)')
10
- kl_eval('(if (kl-do (set flag set) true) a b)')
11
- kl_eval('(value flag)').should == :set
12
- end
13
-
14
- describe 'when its first argument evaluates to true' do
15
- it 'returns the normal form of its second argument' do
16
- kl_eval('(if true (+ 1 2) 10)').should == 3
17
- end
18
-
19
- it 'does not evaluate its third argument' do
20
- define_kl_do
21
- kl_eval('(set flag clear)')
22
- kl_eval('(if true 1 (kl-do (set flag set) 2))')
23
- kl_eval('(value flag)').should == :clear
24
- end
25
- end
26
-
27
- describe 'when its first argument evaluates to false' do
28
- it 'returns the normal form of its third argument' do
29
- kl_eval('(if false 1 (+ 1 2))').should == 3
30
- end
31
-
32
- it 'does not evaluate its second argument' do
33
- define_kl_do
34
- kl_eval('(set flag clear)')
35
- kl_eval('(if false (kl-do (set flag set) 1) 2)')
36
- kl_eval('(value flag)').should == :clear
37
- end
38
- end
39
- end
40
-
41
- describe 'and special form' do
42
- it 'evaluates its first argument' do
43
- define_kl_do
44
- kl_eval('(set flag clear)')
45
- kl_eval('(and (kl-do (set flag set) true) false)')
46
- kl_eval('(value flag)').should == :set
47
- end
48
-
49
- describe 'when its first argument evaluates to true' do
50
- it 'returns true if its second argument evaluates to true' do
51
- kl_eval('(defun return-true () true)')
52
- kl_eval('(and true (return-true))').should == true
53
- end
54
-
55
- it 'returns false if its second argument evaluates to false' do
56
- kl_eval('(defun return-false () false)')
57
- kl_eval('(and true (return-false))').should == false
58
- end
59
- end
60
-
61
- describe 'when its first argument evaluates to false' do
62
- it 'returns false' do
63
- kl_eval('(and false true)').should == false
64
- end
65
-
66
- it 'does not evaluate it second argument' do
67
- kl_eval('(set flag clear)')
68
- kl_eval('(and false (kl-do (set flag set) true))').should == false
69
- kl_eval('(value flag)').should == :clear
70
- end
71
- end
72
-
73
- describe 'partial application' do
74
- include_examples "partially-applicable function", %w(and true false)
75
-
76
- it 'results in it no longer short-circuiting argument evaluation' do
77
- define_kl_do
78
- kl_eval('(set flag clear)')
79
- kl_eval('((and false) (kl-do (set flag set) false)))').should == false
80
- kl_eval('(value flag)').should == :set
81
- end
82
- end
83
-
84
- it 'may be passed as an argument to a higher-order function' do
85
- kl_eval('((lambda F (F true false)) and)').should == false
86
- end
87
- end
88
-
89
- describe 'or special form' do
90
- it 'evaluates its first argument' do
91
- define_kl_do
92
- kl_eval('(set flag clear)')
93
- kl_eval('(or (kl-do (set flag set) false) false)')
94
- kl_eval('(value flag)').should == :set
95
- end
96
-
97
- describe 'when its first argument evaluates to false' do
98
- it 'returns true if its second argument evaluates to true' do
99
- kl_eval('(defun return-true () true)')
100
- kl_eval('(or false (return-true))').should == true
101
- end
102
-
103
- it 'returns false if its second argument evaluates to false' do
104
- kl_eval('(defun return-false () false)')
105
- kl_eval('(or false (return-false))').should == false
106
- end
107
- end
108
-
109
- describe 'when its first argument evaluates to true' do
110
- it 'returns true' do
111
- kl_eval('(or true false)').should == true
112
- end
113
-
114
- it 'does not evaluate it second argument' do
115
- kl_eval('(set flag clear)')
116
- kl_eval('(or true (kl-do (set flag set) false))').should == true
117
- kl_eval('(value flag)').should == :clear
118
- end
119
- end
120
-
121
- describe 'partial application' do
122
- include_examples "partially-applicable function", %w(or false true)
123
-
124
- it 'results in it no longer short-circuiting argument evaluation' do
125
- define_kl_do
126
- kl_eval('(set flag clear)')
127
- kl_eval('((or true) (kl-do (set flag set) false)))').should == true
128
- kl_eval('(value flag)').should == :set
129
- end
130
- end
131
-
132
- it 'may be passed as an argument to a higher-order function' do
133
- kl_eval('((lambda F (F true true)) or)').should == true
134
- end
135
- end
136
- end
@@ -1,120 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'Primitives for Generic Functions' do
4
- describe '(defun Name ArgList Expr)' do
5
- it 'does not evaulate Expr' do
6
- kl_eval('(set flag clear)')
7
- kl_eval('(defun foo () (set flag set))')
8
- kl_eval('(value flag)').should == :clear
9
- end
10
-
11
- it 'returns Name' do
12
- kl_eval('(defun foo () true)').should == :foo
13
- end
14
-
15
- it 'binds Name to a function having ArgList as its formals and Expr as its body' do
16
- kl_eval('(defun my-add (A B) (+ A B))')
17
- kl_eval('(my-add 1 2)').should == 3
18
- end
19
-
20
- it 'allows ArgList to be the empty list' do
21
- kl_eval('(defun foo () success)').should == :foo
22
- kl_eval('(foo)').should == :success
23
- end
24
-
25
- it 'allows previously defined non-primitive functions to be redefined' do
26
- kl_eval('(defun my-add (A B) (+ A B))')
27
- kl_eval('(defun my-add (A B) surprise!)')
28
- kl_eval('(my-add 1 2)').should == :surprise!
29
- end
30
-
31
- it 'raises an error when attempting to redefine a primitive' do
32
- expect {
33
- kl_eval('(defun + (A B) :surprise!)')
34
- }.to raise_error(Kl::Error, '+ is primitive and may not be redefined')
35
- end
36
-
37
- include_examples 'argument types', %w[defun foo () success],
38
- 1 => [:symbol]
39
-
40
- it 'raises an error if ArgList is not a list' do
41
- expect {
42
- kl_eval('(defun foo bar baz)')
43
- }.to raise_error(Kl::Error, 'bar is not a list')
44
- end
45
-
46
- it 'raises an error if ArgList contains non-symbols' do
47
- expect {
48
- kl_eval('(defun foo (1) baz)')
49
- }.to raise_error(Kl::Error, '1 is not a symbol')
50
- end
51
- include_examples "non-partially-applicable function",
52
- %w[defun foo () success]
53
- end
54
-
55
- describe '(lambda X Expr)' do
56
- it 'does not evaulate Expr' do
57
- kl_eval('(set flag clear)')
58
- kl_eval('(lambda X 37)')
59
- kl_eval('(value flag)').should == :clear
60
- end
61
-
62
- it 'returns a function' do
63
- kl_eval('(lambda X 37)').should be_kind_of Proc
64
- end
65
-
66
- describe 'the returned function, when applied' do
67
- it 'evaluates Expr with X bound to its argument' do
68
- kl_eval('((lambda X (+ 1 X)) 2)').should == 3
69
- end
70
- end
71
-
72
- include_examples 'argument types', %w(lambda X 37),
73
- 1 => [:symbol]
74
- include_examples "non-partially-applicable function", %w(lambda X 37)
75
- end
76
-
77
- describe '(freeze Expr)' do
78
- it 'does not evaluate Expr' do
79
- kl_eval('(set flag clear)')
80
- kl_eval('(freeze (set flag set))')
81
- kl_eval('(value flag)').should == :clear
82
- end
83
-
84
- it 'returns a continuation' do
85
- kl_eval('(freeze a)').should be_kind_of Proc
86
- end
87
-
88
- describe 'the returned continuation, upon thawing' do
89
- before(:each) do
90
- kl_eval('(defun my-thaw (X) (X))')
91
- end
92
-
93
- it 'evaluates and returns the value of Expr' do
94
- kl_eval('(my-thaw (freeze (+ 1 2)))').should == 3
95
- end
96
-
97
- it 're-evaluates Expr with each thawing' do
98
- define_kl_do
99
- kl_eval('(set count 0)')
100
- kl_eval('(let C (freeze (set count (+ (value count) 1)))
101
- (kl-do (my-thaw C) (my-thaw C)))')
102
- kl_eval('(value count)').should == 2
103
- end
104
- end
105
-
106
- describe 'partial application' do
107
- # Can't compare two functions so we implement this manually
108
- it 'supports partial application of 0 arguments' do
109
- kl_eval('(defun my-thaw (X) (X))')
110
- kl_eval('(my-thaw ((freeze) 37))').should == 37
111
- end
112
-
113
- it 'results in it no longer delaying execution of Expr' do
114
- kl_eval('(set flag clear)')
115
- kl_eval('((freeze) (set flag set))').should
116
- kl_eval('(value flag)').should == :set
117
- end
118
- end
119
- end
120
- end