shen-ruby 0.10.0 → 0.11.0

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