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.
- checksums.yaml +4 -4
- data/.rspec +1 -0
- data/.travis.yml +9 -3
- data/Gemfile +1 -4
- data/HISTORY.md +16 -0
- data/MIT_LICENSE.txt +1 -1
- data/README.md +25 -26
- data/Rakefile +3 -11
- data/bin/shen_test_suite.rb +15 -3
- data/bin/srrepl +6 -8
- data/lib/shen_ruby.rb +6 -1
- data/lib/shen_ruby/converters.rb +23 -0
- data/lib/shen_ruby/version.rb +1 -1
- data/shen-ruby.gemspec +4 -1
- data/shen/lib/shen_ruby/shen.rb +49 -33
- data/shen/release/benchmarks/N_queens.shen +45 -45
- data/shen/release/benchmarks/README.shen +14 -14
- data/shen/release/benchmarks/benchmarks.shen +52 -52
- data/shen/release/benchmarks/einstein.shen +32 -32
- data/shen/release/benchmarks/interpreter.shen +219 -219
- data/shen/release/benchmarks/jnk.shen +193 -193
- data/shen/release/benchmarks/powerset.shen +10 -10
- data/shen/release/benchmarks/prime.shen +10 -10
- data/shen/release/benchmarks/short.shen +129 -129
- data/shen/release/k_lambda/core.kl +181 -181
- data/shen/release/k_lambda/declarations.kl +131 -131
- data/shen/release/k_lambda/load.kl +84 -84
- data/shen/release/k_lambda/macros.kl +112 -112
- data/shen/release/k_lambda/prolog.kl +252 -252
- data/shen/release/k_lambda/reader.kl +222 -222
- data/shen/release/k_lambda/sequent.kl +166 -166
- data/shen/release/k_lambda/sys.kl +271 -271
- data/shen/release/k_lambda/t-star.kl +139 -139
- data/shen/release/k_lambda/toplevel.kl +135 -135
- data/shen/release/k_lambda/track.kl +103 -103
- data/shen/release/k_lambda/types.kl +324 -324
- data/shen/release/k_lambda/writer.kl +105 -105
- data/shen/release/k_lambda/yacc.kl +113 -113
- data/shen/release/test_programs/Chap13/problems.txt +26 -26
- data/shen/release/test_programs/README.shen +52 -52
- data/shen/release/test_programs/TinyLispFunctions.txt +15 -15
- data/shen/release/test_programs/TinyTypes.shen +55 -55
- data/shen/release/test_programs/binary.shen +24 -24
- data/shen/release/test_programs/bubble_version_1.shen +28 -28
- data/shen/release/test_programs/bubble_version_2.shen +22 -22
- data/shen/release/test_programs/calculator.shen +21 -21
- data/shen/release/test_programs/cartprod.shen +23 -23
- data/shen/release/test_programs/change.shen +25 -25
- data/shen/release/test_programs/classes-defaults.shen +94 -94
- data/shen/release/test_programs/classes-inheritance.shen +100 -100
- data/shen/release/test_programs/classes-typed.shen +74 -74
- data/shen/release/test_programs/classes-untyped.shen +46 -46
- data/shen/release/test_programs/depth_.shen +14 -14
- data/shen/release/test_programs/einstein.shen +34 -34
- data/shen/release/test_programs/fruit_machine.shen +46 -46
- data/shen/release/test_programs/interpreter.shen +217 -217
- data/shen/release/test_programs/metaprog.shen +85 -85
- data/shen/release/test_programs/minim.shen +192 -192
- data/shen/release/test_programs/mutual.shen +11 -11
- data/shen/release/test_programs/n_queens.shen +45 -45
- data/shen/release/test_programs/newton_version_1.shen +33 -33
- data/shen/release/test_programs/newton_version_2.shen +24 -24
- data/shen/release/test_programs/parse.prl +14 -14
- data/shen/release/test_programs/parser.shen +51 -51
- data/shen/release/test_programs/powerset.shen +10 -10
- data/shen/release/test_programs/prime.shen +10 -10
- data/shen/release/test_programs/prolog.shen +78 -78
- data/shen/release/test_programs/proof_assistant.shen +80 -80
- data/shen/release/test_programs/proplog_version_1.shen +25 -25
- data/shen/release/test_programs/proplog_version_2.shen +27 -27
- data/shen/release/test_programs/qmachine.shen +66 -66
- data/shen/release/test_programs/red-black.shen +54 -54
- data/shen/release/test_programs/search.shen +55 -55
- data/shen/release/test_programs/semantic_net.shen +44 -44
- data/shen/release/test_programs/spreadsheet.shen +34 -34
- data/shen/release/test_programs/stack.shen +27 -27
- data/shen/release/test_programs/streams.shen +20 -20
- data/shen/release/test_programs/strings.shen +57 -57
- data/shen/release/test_programs/structures-typed.shen +71 -71
- data/shen/release/test_programs/structures-untyped.shen +41 -41
- data/shen/release/test_programs/tests.shen +232 -232
- data/shen/release/test_programs/types.shen +11 -11
- data/shen/release/test_programs/whist.shen +239 -239
- data/shen/release/test_programs/yacc.shen +132 -132
- data/spec/shen_ruby/converters_spec.rb +48 -0
- data/spec/spec_helper.rb +1 -2
- metadata +55 -60
- data/k_lambda_spec/atom_spec.rb +0 -85
- data/k_lambda_spec/primitives/arithmetic_spec.rb +0 -175
- data/k_lambda_spec/primitives/assignments_spec.rb +0 -44
- data/k_lambda_spec/primitives/boolean_operations_spec.rb +0 -136
- data/k_lambda_spec/primitives/generic_functions_spec.rb +0 -120
- data/k_lambda_spec/primitives/lists_spec.rb +0 -40
- data/k_lambda_spec/primitives/strings_spec.rb +0 -77
- data/k_lambda_spec/primitives/symbols_spec.rb +0 -24
- data/k_lambda_spec/primitives/vectors_spec.rb +0 -92
- data/k_lambda_spec/spec_helper.rb +0 -29
- data/k_lambda_spec/support/shared_examples.rb +0 -124
- data/k_lambda_spec/tail_recursion_spec.rb +0 -30
- data/lib/kl.rb +0 -7
- data/lib/kl/absvector.rb +0 -12
- data/lib/kl/compiler.rb +0 -360
- data/lib/kl/cons.rb +0 -51
- data/lib/kl/empty_list.rb +0 -12
- data/lib/kl/environment.rb +0 -163
- data/lib/kl/error.rb +0 -4
- data/lib/kl/internal_error.rb +0 -7
- data/lib/kl/lexer.rb +0 -186
- data/lib/kl/primitives/arithmetic.rb +0 -60
- data/lib/kl/primitives/assignments.rb +0 -15
- data/lib/kl/primitives/booleans.rb +0 -21
- data/lib/kl/primitives/error_handling.rb +0 -13
- data/lib/kl/primitives/extensions.rb +0 -12
- data/lib/kl/primitives/generic_functions.rb +0 -29
- data/lib/kl/primitives/lists.rb +0 -23
- data/lib/kl/primitives/streams.rb +0 -28
- data/lib/kl/primitives/strings.rb +0 -63
- data/lib/kl/primitives/symbols.rb +0 -18
- data/lib/kl/primitives/time.rb +0 -17
- data/lib/kl/primitives/vectors.rb +0 -36
- data/lib/kl/reader.rb +0 -46
- data/spec/kl/cons_spec.rb +0 -12
- data/spec/kl/environment_spec.rb +0 -282
- data/spec/kl/interop_spec.rb +0 -68
- data/spec/kl/lexer_spec.rb +0 -149
- data/spec/kl/primitives/generic_functions_spec.rb +0 -29
- data/spec/kl/primitives/symbols_spec.rb +0 -21
- data/spec/kl/reader_spec.rb +0 -42
data/k_lambda_spec/atom_spec.rb
DELETED
@@ -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
|