nendo 0.6.6 → 0.6.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2128 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- encoding: utf-8 -*-
3
+ #
4
+ # nendo_spec.rb - "RSpec file for nendo language"
5
+ #
6
+ # Copyright (c) 2009-2011 Kiyoka Nishiyama <kiyoka@sumibi.org>
7
+ #
8
+ # Redistribution and use in source and binary forms, with or without
9
+ # modification, are permitted provided that the following conditions
10
+ # are met:
11
+ #
12
+ # 1. Redistributions of source code must retain the above copyright
13
+ # notice, this list of conditions and the following disclaimer.
14
+ #
15
+ # 2. Redistributions in binary form must reproduce the above copyright
16
+ # notice, this list of conditions and the following disclaimer in the
17
+ # documentation and/or other materials provided with the distribution.
18
+ #
19
+ # 3. Neither the name of the authors nor the names of its contributors
20
+ # may be used to endorse or promote products derived from this
21
+ # software without specific prior written permission.
22
+ #
23
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29
+ # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30
+ # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
+ #
35
+ require 'nendo'
36
+ include Nendo
37
+
38
+
39
+
40
+ describe Nendo, "when use quote and syntax-quote " do
41
+ before do
42
+ @nendo = Nendo::Core.new()
43
+ end
44
+ it "should" do
45
+ @nendo.evalStr( " '() " ).should == "()"
46
+ @nendo.evalStr( " '1 " ).should == "1"
47
+ @nendo.evalStr( " '\"str\" " ).should == '"str"'
48
+ @nendo.evalStr( " '(1 . 2) " ).should == "(1 . 2)"
49
+ @nendo.evalStr( " (quote ())" ).should == "()"
50
+ @nendo.evalStr( " (quote 1)" ).should == "1"
51
+ @nendo.evalStr( " (quote \"str\") " ).should == '"str"'
52
+ @nendo.evalStr( " (quote (1 . 2)) " ).should == "(1 . 2)"
53
+ @nendo.evalStr( " (syntax-quote ())" ).should == "()"
54
+ @nendo.evalStr( " (syntax-quote 1)" ).should == "1"
55
+ @nendo.evalStr( ' (syntax-quote "str") ' ).should == '"str"'
56
+ @nendo.evalStr( " (syntax-quote (1 . 2)) " ).should == "(1 . 2)"
57
+ @nendo.evalStr( " (quote quote) " ).should == "quote"
58
+ @nendo.evalStr( " 'quote " ).should == "quote"
59
+ @nendo.evalStr( " ''1 " ).should == "(quote 1)"
60
+ @nendo.evalStr( " (quote syntax-quote) " ).should == "quote"
61
+ @nendo.evalStr( " (syntax-quote '1) " ).should == "(quote 1)"
62
+ @nendo.evalStr( " (syntax-quote (quote 1)) " ).should == "(quote 1)"
63
+ @nendo.evalStr( " (quote (syntax-quote 1)) " ).should == "(quote 1)"
64
+ end
65
+ end
66
+
67
+ describe Nendo, "when read various list expressions" do
68
+ before do
69
+ @nendo = Nendo::Core.new()
70
+ end
71
+ it "should" do
72
+ @nendo.evalStr( " '() " ).should == "()"
73
+ @nendo.evalStr( " '[] " ).should == "()"
74
+ @nendo.evalStr( " '(1 . 1) " ).should == "(1 . 1)"
75
+ @nendo.evalStr( " '[1 . 1) " ).should == "(1 . 1)"
76
+ @nendo.evalStr( " '(1 . 1] " ).should == "(1 . 1)"
77
+ @nendo.evalStr( " '(1 1 . 1) " ).should == "(1 1 . 1)"
78
+ @nendo.evalStr( " '(1 2 . 3) " ).should == "(1 2 . 3)"
79
+ @nendo.evalStr( " '(1 2 3) " ).should == "(1 2 3)"
80
+ @nendo.evalStr( " '(1.1 2.2 3.3) " ).should == "(1.1 2.2 3.3)"
81
+ @nendo.evalStr( " '(a bb ccc dddd) " ).should == "(a bb ccc dddd)"
82
+ @nendo.evalStr( " '(a (b) ((c)) (((d)))) " ).should == "(a (b) ((c)) (((d))))"
83
+ @nendo.evalStr( " '[a (b) ((c)) (((d)))] " ).should == "(a (b) ((c)) (((d))))"
84
+ @nendo.evalStr( " '(a [b] ([c]) (([d]))) " ).should == "(a (b) ((c)) (((d))))"
85
+ @nendo.evalStr( " '[a [b] [[c]] [[[d]]]] " ).should == "(a (b) ((c)) (((d))))"
86
+ @nendo.evalStr( " '('a)" ).should == "((quote a))"
87
+ @nendo.evalStr( " '(''a)" ).should == "((quote (quote a)))"
88
+ @nendo.evalStr( " '('a 'b 'c)" ).should == "((quote a) (quote b) (quote c))"
89
+ @nendo.evalStr( ' \'("str") ' ).should == '("str")'
90
+ @nendo.evalStr( ' \'("str" . 1) ' ).should == '("str" . 1)'
91
+ @nendo.evalStr( ' \'(1 . "str") ' ).should == '(1 . "str")'
92
+ @nendo.evalStr( ' \'(1 2 . "str") ' ).should == '(1 2 . "str")'
93
+ @nendo.evalStr( " '((a)(b)(c)) " ).should == "((a) (b) (c))"
94
+ @nendo.evalStr( " 'a " ).should == "a"
95
+ @nendo.evalStr( " 'symbol " ).should == "symbol"
96
+ @nendo.evalStr( " 'SYMBOL " ).should == "SYMBOL"
97
+ @nendo.evalStr( " 'SyMbOl " ).should == "SyMbOl"
98
+ @nendo.evalStr( " ''a " ).should == "(quote a)"
99
+ @nendo.evalStr( " '1 " ).should == "1"
100
+ @nendo.evalStr( " ''1 " ).should == "(quote 1)"
101
+ @nendo.evalStr( " '''1 " ).should == "(quote (quote 1))"
102
+ @nendo.evalStr( " '1.1 " ).should == "1.1"
103
+ @nendo.evalStr( " ''1.1 " ).should == "(quote 1.1)"
104
+ @nendo.evalStr( " '''1.1 " ).should == "(quote (quote 1.1))"
105
+ @nendo.evalStr( " '() " ).should == "()"
106
+ @nendo.evalStr( " '(()) " ).should == "(())"
107
+ @nendo.evalStr( " '((())) " ).should == "((()))"
108
+ @nendo.evalStr( " '(((()))) " ).should == "(((())))"
109
+ @nendo.evalStr( " '(() . ()) " ).should == "(())"
110
+ @nendo.evalStr( " '(a . ()) " ).should == "(a)"
111
+ @nendo.evalStr( " '(a . #t) " ).should == "(a . #t)"
112
+ @nendo.evalStr( " '(a . #f) " ).should == "(a . #f)"
113
+ @nendo.evalStr( " '(a . nil) " ).should == "(a . nil)"
114
+ @nendo.evalStr( " '(a b c d e . ()) " ).should == "(a b c d e)"
115
+ @nendo.evalStr( " '(#t #t #f #f nil nil '() '()) " ).should == "(#t #t #f #f nil nil (quote ()) (quote ()))"
116
+ end
117
+ end
118
+
119
+
120
+
121
+
122
+ class TestClassForBlockArgument
123
+ def arg1
124
+ yield 100
125
+ end
126
+ def arg2
127
+ yield 100,200
128
+ end
129
+ def arg5
130
+ yield 10,20,30,40,50
131
+ end
132
+
133
+ def arg1_plus_1( arg1 )
134
+ yield arg1, 200
135
+ end
136
+
137
+ end
138
+
139
+ describe Nendo, "when use &block(Ruby's block) " do
140
+ before do
141
+ @nendo = Nendo::Core.new()
142
+ end
143
+
144
+ it "should" do
145
+ @nendo.evalStr( " (define testclass (TestClassForBlockArgument.new)) testclass.class" ).should == "TestClassForBlockArgument"
146
+ @nendo.evalStr( " (testclass.arg1 (&block (a) (list a))) " ).should == "(100)"
147
+ @nendo.evalStr( " (testclass.arg2 (&block (a b) (cons a b))) " ).should == "(100 . 200)"
148
+ @nendo.evalStr( " (testclass.arg5 (&block (a b c d e) (list a b c d e))) " ).should == "(10 20 30 40 50)"
149
+ @nendo.evalStr( " (testclass.arg5 (&block (a b c d e) (to-arr (list a b c d e)))) " ).should == "#(10 20 30 40 50)"
150
+ end
151
+ end
152
+
153
+ describe Nendo, "when call variable length functions" do
154
+ before do
155
+ @nendo = Nendo::Core.new( )
156
+ @nendo.loadInitFile
157
+ end
158
+ it "should" do
159
+ # fixed length
160
+ @nendo.evalStr( <<EOS
161
+ (define (arg0) 0)
162
+ (define (arg1 a) a)
163
+ (define (arg2 a b) b)
164
+ (define (arg3 a b c) c)
165
+ (define (arg4 a b c d) d)
166
+ (list
167
+ (arg0)
168
+ (arg1 1)
169
+ (arg2 1 2)
170
+ (arg3 1 2 3)
171
+ (arg4 1 2 3 4))
172
+ EOS
173
+ ).should == "(0 1 2 3 4)"
174
+
175
+ @nendo.evalStr( <<EOS
176
+ (define (func-var-arg . arg) arg)
177
+ (list
178
+ (func-var-arg)
179
+ (func-var-arg 1)
180
+ (func-var-arg 1 2)
181
+ (func-var-arg 1 2 3)
182
+ (func-var-arg 1 2 3 4))
183
+ EOS
184
+ ).should == "(() (1) (1 2) (1 2 3) (1 2 3 4))"
185
+
186
+ @nendo.evalStr( <<EOS
187
+ (define (func-var-arg first . rest) rest)
188
+ (list
189
+ (func-var-arg 0)
190
+ (func-var-arg 0 1)
191
+ (func-var-arg 0 1 2)
192
+ (func-var-arg 0 1 2 3)
193
+ (func-var-arg 0 1 2 3 4))
194
+ EOS
195
+ ).should == "(() (1) (1 2) (1 2 3) (1 2 3 4))"
196
+
197
+ @nendo.evalStr( <<EOS
198
+ (define (func-var-arg first second . rest) (cons second rest))
199
+ (list
200
+ (func-var-arg "f" "s")
201
+ (func-var-arg "f" "s" 1)
202
+ (func-var-arg "f" "s" 1 2)
203
+ (func-var-arg "f" "s" 1 2 3)
204
+ (func-var-arg "f" "s" 1 2 3 4))
205
+ EOS
206
+ ).should == '(("s") ("s" 1) ("s" 1 2) ("s" 1 2 3) ("s" 1 2 3 4))'
207
+
208
+ # Ruby method with block
209
+ @nendo.evalStr( <<EOS
210
+ (define testclass (TestClassForBlockArgument.new)) testclass.class
211
+ (list
212
+ (testclass.arg1 (&block (a) (list a)))
213
+ (testclass.arg2 (&block (a b) (cons a b)))
214
+ (testclass.arg1_plus_1 "a" (&block (a b) (list a b)))
215
+ )
216
+ EOS
217
+ ).should == '((100) (100 . 200) ("a" 200))'
218
+
219
+
220
+ # Ruby method with block
221
+ @nendo.evalStr( <<EOS
222
+ (define (read-first-line fobj) (fobj.readline.chomp))
223
+ (let1 filename "./VERSION.yml"
224
+ (list
225
+ (with-open filename read-first-line "r")
226
+ (with-open filename read-first-line)))
227
+ EOS
228
+ ).should == '("---" "---")'
229
+ end
230
+ end
231
+
232
+
233
+ describe Nendo, "when read various vector expressions" do
234
+ before do
235
+ @nendo = Nendo::Core.new()
236
+ @nendo.setDisplayErrors( false )
237
+ end
238
+ it "should" do
239
+ @nendo.evalStr( " '() " ).should == "()"
240
+ @nendo.evalStr( " '[] " ).should == "()"
241
+ @nendo.evalStr( " '#( 1 ) " ).should == "#(1)"
242
+ lambda { @nendo.evalStr( " '#(( 1 ) " ) }.should raise_error( RuntimeError )
243
+ @nendo.evalStr( " '#( 1 2 ) " ).should == "#(1 2)"
244
+ @nendo.evalStr( " '#( 1 () ) " ).should == "#(1 ())"
245
+ @nendo.evalStr( " '#( () 2 ) " ).should == "#(() 2)"
246
+ lambda { @nendo.evalStr( " '#( 1 . 2 ) " ) }.should raise_error( RuntimeError )
247
+ lambda { @nendo.evalStr( " #(+ 1 2) " ) }.should raise_error( RuntimeError )
248
+ @nendo.evalStr( " '#( 1 #( 11 )) " ).should == "#(1 #(11))"
249
+ @nendo.evalStr( " '#( 1 #( 11 12 )) " ).should == "#(1 #(11 12))"
250
+ @nendo.evalStr( " '#( 1 #( 11 #( 111 ))) " ).should == "#(1 #(11 #(111)))"
251
+ @nendo.evalStr( " '#( 1 #( 11 #( 111 112))) " ).should == "#(1 #(11 #(111 112)))"
252
+ @nendo.evalStr( " '#(1 2 3) " ).should == "#(1 2 3)"
253
+ @nendo.evalStr( " '#(1.1 2.2 3.3) " ).should == "#(1.1 2.2 3.3)"
254
+ @nendo.evalStr( " '#(a bb ccc dddd) " ).should == "#(a bb ccc dddd)"
255
+ @nendo.evalStr( " '#(a (b) ((c)) (((d)))) " ).should == "#(a (b) ((c)) (((d))))"
256
+ end
257
+ end
258
+
259
+ describe Nendo, "when call evalStr() with built-in functions" do
260
+ before do
261
+ @nendo = Nendo::Core.new()
262
+ @nendo.setDisplayErrors( false )
263
+ end
264
+ it "should" do
265
+ @nendo.evalStr( " (car '(1 2 3 4)) " ).should == "1"
266
+ @nendo.evalStr( " (cdr '(1 2 3 4)) " ).should == "(2 3 4)"
267
+ @nendo.evalStr( " (null? '()) " ).should == "#t"
268
+ @nendo.evalStr( " (null? '(1)) " ).should == "#f"
269
+ @nendo.evalStr( " (null? false) " ).should == "#f"
270
+ @nendo.evalStr( " (null? nil) " ).should == "#f"
271
+ @nendo.evalStr( " (null? true) " ).should == "#f"
272
+ @nendo.evalStr( " (cons 1 2) " ).should == "(1 . 2)"
273
+ @nendo.evalStr( " (cons 1 '(2 3)) " ).should == "(1 2 3)"
274
+ @nendo.evalStr( " (cons '(1 2) '(3 4)) " ).should == "((1 2) 3 4)"
275
+ @nendo.evalStr( " (cons '(1 2) '((3 4))) " ).should == "((1 2) (3 4))"
276
+ @nendo.evalStr( " (cons '() '()) " ).should == "(())"
277
+ @nendo.evalStr( " (cons 1 '()) " ).should == "(1)"
278
+ @nendo.evalStr( " (cons '() (cdr '(100))) " ).should == "(())"
279
+ @nendo.evalStr( " (cons '() (car '(()))) " ).should == "(())"
280
+ @nendo.evalStr( " (cons (car '(())) '()) " ).should == "(())"
281
+ @nendo.evalStr( " (cons (car '(())) (car '(()))) " ).should == "(())"
282
+ @nendo.evalStr( " (cons '() (cdr '(100))) " ).should == "(())"
283
+ @nendo.evalStr( " (cons (cdr '(100)) '()) " ).should == "(())"
284
+ @nendo.evalStr( " (cons (cdr '(100)) (cdr '(100))) " ).should == "(())"
285
+ lambda { @nendo.evalStr( " (cons 1 2 3) " ) }.should raise_error(ArgumentError)
286
+ lambda { @nendo.evalStr( " (cons 1) " ) }.should raise_error(ArgumentError)
287
+ lambda { @nendo.evalStr( " (cons) " ) }.should raise_error(ArgumentError)
288
+ @nendo.evalStr( " (list 1 2 3) " ).should == "(1 2 3)"
289
+ @nendo.evalStr( " (list '(1) '(2) '(3)) " ).should == "((1) (2) (3))"
290
+ @nendo.evalStr( " (list 'a 'b 'c) " ).should == "(a b c)"
291
+ @nendo.evalStr( " (list '(a) '((b c))) " ).should == "((a) ((b c)))"
292
+ @nendo.evalStr( " (list) " ).should == "()"
293
+ @nendo.evalStr( " (list 1) " ).should == "(1)"
294
+ @nendo.evalStr( " (reverse '(1)) " ).should == "(1)"
295
+ @nendo.evalStr( " (reverse '(1 2 3)) " ).should == "(3 2 1)"
296
+ @nendo.evalStr( " (reverse '(1 2 ())) " ).should == "(() 2 1)"
297
+ @nendo.evalStr( " (reverse (list 1 2 (cdr '(100)))) " ).should == "(() 2 1)"
298
+ @nendo.evalStr( " (define !a 10) !a" ).should == "10"
299
+ @nendo.evalStr( " (define $a 11) $a" ).should == "11"
300
+ @nendo.evalStr( " (define %a 12) %a" ).should == "12"
301
+ @nendo.evalStr( " (define &a 13) &a" ).should == "13"
302
+ @nendo.evalStr( " (define *a 14) *a" ).should == "14"
303
+ @nendo.evalStr( " (define +a 15) +a" ).should == "15"
304
+ @nendo.evalStr( " (define -a 16) -a" ).should == "16"
305
+ @nendo.evalStr( " (define /a 17) /a" ).should == "17"
306
+ @nendo.evalStr( " (define <a 18) <a" ).should == "18"
307
+ @nendo.evalStr( " (define =a 19) =a" ).should == "19"
308
+ @nendo.evalStr( " (define ?a 20) ?a" ).should == "20"
309
+ @nendo.evalStr( " (define @a 21) @a" ).should == "21"
310
+ @nendo.evalStr( " (define ^a 22) ^a" ).should == "22"
311
+ @nendo.evalStr( " (define ~a 23) ~a" ).should == "23"
312
+ @nendo.evalStr( " (define a! 30) a!" ).should == "30"
313
+ @nendo.evalStr( " (define a$ 31) a$" ).should == "31"
314
+ @nendo.evalStr( " (define a% 32) a%" ).should == "32"
315
+ @nendo.evalStr( " (define a& 33) a&" ).should == "33"
316
+ @nendo.evalStr( " (define a* 34) a*" ).should == "34"
317
+ @nendo.evalStr( " (define a+ 35) a+" ).should == "35"
318
+ @nendo.evalStr( " (define a- 36) a-" ).should == "36"
319
+ @nendo.evalStr( " (define a/ 37) a/" ).should == "37"
320
+ @nendo.evalStr( " (define a< 38) a<" ).should == "38"
321
+ @nendo.evalStr( " (define a= 39) a=" ).should == "39"
322
+ @nendo.evalStr( " (define a? 40) a?" ).should == "40"
323
+ @nendo.evalStr( " (define a@ 41) a@" ).should == "41"
324
+ @nendo.evalStr( " (define a^ 42) a^" ).should == "42"
325
+ @nendo.evalStr( " (define a~ 43) a~" ).should == "43"
326
+ @nendo.evalStr( " (define aFunc (lambda (x) x)) true" ).should == "#t"
327
+ @nendo.evalStr( " (define aMacro (macro (x) x)) true" ).should == "#t"
328
+ @nendo.evalStr( " (define a! 123) a!" ).should == "123"
329
+ @nendo.evalStr( " (define b? 321) b?" ).should == "321"
330
+ @nendo.evalStr( " (define a-b 1234) a-b" ).should == "1234"
331
+ @nendo.evalStr( " (define start-end!? 4321) start-end!?" ).should == "4321"
332
+ @nendo.evalStr( " (procedure? car) " ).should == "#t"
333
+ @nendo.evalStr( " (procedure? aFunc) " ).should == "#t"
334
+ @nendo.evalStr( " (procedure? aMacro) " ).should == "#f"
335
+ @nendo.evalStr( " (procedure? 1) " ).should == "#f"
336
+ @nendo.evalStr( " (procedure? 1.1) " ).should == "#f"
337
+ @nendo.evalStr( " (procedure? \"str\") " ).should == "#f"
338
+ @nendo.evalStr( " (procedure? 'a) " ).should == "#f"
339
+ @nendo.evalStr( " (procedure? '(1)) " ).should == "#f"
340
+ @nendo.evalStr( " (procedure? '()) " ).should == "#f"
341
+ @nendo.evalStr( " (symbol? car) " ).should == "#f"
342
+ @nendo.evalStr( " (symbol? aFunc) " ).should == "#f"
343
+ @nendo.evalStr( " (symbol? aMacro) " ).should == "#f"
344
+ @nendo.evalStr( " (symbol? 1) " ).should == "#f"
345
+ @nendo.evalStr( " (symbol? 1.1) " ).should == "#f"
346
+ @nendo.evalStr( " (symbol? \"str\") " ).should == "#f"
347
+ @nendo.evalStr( " (symbol? 'a) " ).should == "#t"
348
+ @nendo.evalStr( " (symbol? '(1)) " ).should == "#f"
349
+ @nendo.evalStr( " (symbol? '()) " ).should == "#f"
350
+ @nendo.evalStr( " (pair? car) " ).should == "#f"
351
+ @nendo.evalStr( " (pair? aFunc) " ).should == "#f"
352
+ @nendo.evalStr( " (pair? aMacro) " ).should == "#f"
353
+ @nendo.evalStr( " (pair? 1) " ).should == "#f"
354
+ @nendo.evalStr( " (pair? 1.1) " ).should == "#f"
355
+ @nendo.evalStr( " (pair? \"str\") " ).should == "#f"
356
+ @nendo.evalStr( " (pair? 'a) " ).should == "#f"
357
+ @nendo.evalStr( " (pair? '(1)) " ).should == "#t"
358
+ @nendo.evalStr( " (pair? '()) " ).should == "#f"
359
+ @nendo.evalStr( " (number? car) " ).should == "#f"
360
+ @nendo.evalStr( " (number? aFunc) " ).should == "#f"
361
+ @nendo.evalStr( " (number? aMacro) " ).should == "#f"
362
+ @nendo.evalStr( " (number? 1) " ).should == "#t"
363
+ @nendo.evalStr( " (number? 1.1) " ).should == "#t"
364
+ @nendo.evalStr( " (number? \"str\") " ).should == "#f"
365
+ @nendo.evalStr( " (number? 'a) " ).should == "#f"
366
+ @nendo.evalStr( " (number? '(1)) " ).should == "#f"
367
+ @nendo.evalStr( " (number? '()) " ).should == "#f"
368
+ @nendo.evalStr( " (integer? car) " ).should == "#f"
369
+ @nendo.evalStr( " (integer? aFunc) " ).should == "#f"
370
+ @nendo.evalStr( " (integer? aMacro) " ).should == "#f"
371
+ @nendo.evalStr( " (integer? 1) " ).should == "#t"
372
+ @nendo.evalStr( " (integer? 1.1) " ).should == "#f"
373
+ @nendo.evalStr( " (integer? \"str\") " ).should == "#f"
374
+ @nendo.evalStr( " (integer? 'a) " ).should == "#f"
375
+ @nendo.evalStr( " (integer? '(1)) " ).should == "#f"
376
+ @nendo.evalStr( " (integer? '()) " ).should == "#f"
377
+ @nendo.evalStr( " (string? car) " ).should == "#f"
378
+ @nendo.evalStr( " (string? aFunc) " ).should == "#f"
379
+ @nendo.evalStr( " (string? aMacro) " ).should == "#f"
380
+ @nendo.evalStr( " (string? 1) " ).should == "#f"
381
+ @nendo.evalStr( " (string? 1.1) " ).should == "#f"
382
+ @nendo.evalStr( " (string? \"str\") " ).should == "#t"
383
+ @nendo.evalStr( " (string? 'a) " ).should == "#f"
384
+ @nendo.evalStr( " (string? '(1)) " ).should == "#f"
385
+ @nendo.evalStr( " (string? '()) " ).should == "#f"
386
+ @nendo.evalStr( " (macro? car) " ).should == "#f"
387
+ @nendo.evalStr( " (macro? aFunc) " ).should == "#f"
388
+ @nendo.evalStr( " (macro? aMacro) " ).should == "#t"
389
+ @nendo.evalStr( " (macro? 1) " ).should == "#f"
390
+ @nendo.evalStr( " (macro? 1.1) " ).should == "#f"
391
+ @nendo.evalStr( " (macro? \"str\") " ).should == "#f"
392
+ @nendo.evalStr( " (macro? 'a) " ).should == "#f"
393
+ @nendo.evalStr( " (macro? '(1)) " ).should == "#f"
394
+ @nendo.evalStr( " (macro? '()) " ).should == "#f"
395
+ @nendo.evalStr( " (length '()) " ).should == "0"
396
+ @nendo.evalStr( " (length '(1)) " ).should == "1"
397
+ @nendo.evalStr( " (length '((1))) " ).should == "1"
398
+ @nendo.evalStr( " (length '(1 2)) " ).should == "2"
399
+ lambda { @nendo.evalStr( " (length \"str\") " ) }.should raise_error(TypeError)
400
+ lambda { @nendo.evalStr( " (length 1) " ) }.should raise_error(TypeError)
401
+ @nendo.evalStr( " (symbol->string 'sym) " ).should == '"sym"'
402
+ @nendo.evalStr( " (string->symbol \"sym\") " ).should == 'sym'
403
+ @nendo.evalStr( ' (string-join \'("Aa" "Bb" "Cc") ) ' ).should == '"AaBbCc"'
404
+ @nendo.evalStr( ' (string-join \'("Aa" "Bb" "Cc") ":") ' ).should == '"Aa:Bb:Cc"'
405
+ @nendo.evalStr( ' (string-join \'("Aa" "Bb" "Cc") "//") ' ).should == '"Aa//Bb//Cc"'
406
+ lambda { @nendo.evalStr( ' (string-join \'("Aa" "Bb" "Cc") 100) ' ) }.should raise_error(TypeError)
407
+ lambda { @nendo.evalStr( ' (string-join \'("Aa" "Bb" "Cc") :xx) ' ) }.should raise_error(TypeError)
408
+ @nendo.evalStr( ' (read-from-string "1") ' ).should == '1'
409
+ @nendo.evalStr( ' (read-from-string "(+ 1 2)") ' ).should == '(+ 1 2)'
410
+ @nendo.evalStr( ' (read-from-string "(\"Aa\" \"Bb\" \"Cc\")") ' ).should == '("Aa" "Bb" "Cc")'
411
+ lambda { @nendo.evalStr( ' (read-from-string 100) ' ) }.should raise_error(TypeError)
412
+ @nendo.evalStr( ' (write-to-string 1) ' ).should == '"1"'
413
+ @nendo.evalStr( ' (write-to-string \'(+ 1 2)) ' ).should == '"(+ 1 2)"'
414
+ @nendo.evalStr( ' (write-to-string \'("Aa" "Bb" "Cc")) ' ).should == '"(\"Aa\" \"Bb\" \"Cc\")"'
415
+ end
416
+ end
417
+
418
+ describe Nendo, "when call evalStr() with variable modifications" do
419
+ before do
420
+ @nendo = Nendo::Core.new()
421
+ end
422
+ it "should" do
423
+ @nendo.evalStr( " (define x 1) x " ).should == "1"
424
+ @nendo.evalStr( " (define x 2) x " ).should == "2"
425
+ @nendo.evalStr( " (define x 100) x " ).should == "100"
426
+ @nendo.evalStr( " (define x true) x " ).should == "#t"
427
+ @nendo.evalStr( " (define x false) x " ).should == "#f"
428
+ @nendo.evalStr( " (define x nil) x " ).should == "nil"
429
+ @nendo.evalStr( " (define x '()) x " ).should == "()"
430
+ @nendo.evalStr( " (define x '(1)) x " ).should == "(1)"
431
+ @nendo.evalStr( " (define x (+ 1 2 3)) x " ).should == "6"
432
+ @nendo.evalStr( " (define x (sprintf \"$%02X\" 17)) x x x " ).should == '"$11"'
433
+ @nendo.evalStr( " 1 2 3 " ).should == "3"
434
+ @nendo.evalStr( " (define x 3.14) (set! x (* x 2)) x " ).should == "6.28"
435
+ @nendo.evalStr( " 1 \n 2 \n 3 \n " ).should == "3"
436
+ @nendo.evalStr( " (define a '(1 . 2)) (set-car! a 100) a " ).should == "(100 . 2)"
437
+ @nendo.evalStr( " (define a '(1 . 2)) (set-car! a '()) a " ).should == "(() . 2)"
438
+ @nendo.evalStr( " (define a '(1 . 2)) (set-car! a #t) a " ).should == "(#t . 2)"
439
+ @nendo.evalStr( " (define a '(1 . 2)) (set-car! a #f) a " ).should == "(#f . 2)"
440
+ @nendo.evalStr( " (define a '(1 . 2)) (set-car! a nil) a " ).should == "(nil . 2)"
441
+ @nendo.evalStr( " (define a '(1 . 2)) (set-cdr! a 200) a " ).should == "(1 . 200)"
442
+ @nendo.evalStr( " (define a '(1 . 2)) (set-cdr! a '(2)) a " ).should == "(1 2)"
443
+ @nendo.evalStr( " (define a '(1 . 2)) (set-cdr! a '()) a " ).should == "(1)"
444
+ @nendo.evalStr( " (define a '(1 . 2)) (set-cdr! a #t) a " ).should == "(1 . #t)"
445
+ @nendo.evalStr( " (define a '(1 . 2)) (set-cdr! a #f) a " ).should == "(1 . #f)"
446
+ @nendo.evalStr( " (define a '(1 . 2)) (set-cdr! a nil) a " ).should == "(1 . nil)"
447
+ @nendo.evalStr( " (define a '((1 . 2) 3)) (set-car! (car a) 100) a " ).should == "((100 . 2) 3)"
448
+ @nendo.evalStr( " (define a '((1 . 2) 3)) (set-cdr! (car a) 200) a " ).should == "((1 . 200) 3)"
449
+ @nendo.evalStr( " (define a '((1 . 2) . 3)) (set-cdr! a 300) a " ).should == "((1 . 2) . 300)"
450
+ end
451
+ end
452
+
453
+ describe Nendo, "when call evalStr() with undefined variable" do
454
+ before do
455
+ @nendo = Nendo::Core.new()
456
+ @nendo.setDisplayErrors( false )
457
+ end
458
+ it "should" do
459
+ lambda { @nendo.evalStr( " true " ) }.should_not raise_error
460
+ lambda { @nendo.evalStr( " false " ) }.should_not raise_error
461
+ lambda { @nendo.evalStr( " nil " ) }.should_not raise_error
462
+ lambda { @nendo.evalStr( " line1 " ) }.should raise_error( NameError )
463
+ lambda { @nendo.evalStr( " true \n line2 " ) }.should raise_error( NameError )
464
+ lambda { @nendo.evalStr( " true \n true \n line3 " ) }.should raise_error( NameError )
465
+ lambda { @nendo.evalStr( " (+ 1 x) " ) }.should raise_error( NameError )
466
+ lambda { @nendo.evalStr( " true \n (+ 1 y) " ) }.should raise_error( NameError )
467
+ end
468
+ end
469
+
470
+ describe Nendo, "when call evalStr() with built-in special forms" do
471
+ before do
472
+ @nendo = Nendo::Core.new()
473
+ @nendo.setDisplayErrors( false )
474
+ end
475
+ it "should" do
476
+ @nendo.evalStr( " (begin 1) " ).should == "1"
477
+ @nendo.evalStr( " (begin 1 2) " ).should == "2"
478
+ @nendo.evalStr( " (begin 1 2 3) " ).should == "3"
479
+ @nendo.evalStr( <<EOS
480
+ (set! x 2)
481
+ (set! y (begin
482
+ (set! x (* x 2))
483
+ (set! x (* x 2))
484
+ (set! x (* x 2))
485
+ 100))
486
+ (+ x y)
487
+ EOS
488
+ ).should == "116"
489
+ @nendo.evalStr( " (%let () 100) " ).should == "100"
490
+ @nendo.evalStr( " (%let ((a 11)) a) " ).should == "11"
491
+ @nendo.evalStr( " (%let ((a 11) (b 22)) (+ a b)) " ).should == "33"
492
+ @nendo.evalStr( " (%let ((a 22)) (%let ((b 33)) (+ a b))) " ).should == "55"
493
+ @nendo.evalStr( " (%let ((a 22)(b 33)) (%let ((c 44) (d 55)) (+ a b c d))) " ).should == "154"
494
+ @nendo.evalStr( " (%let ((a (%let ((b 2)) (+ 100 b)))) a) " ).should == "102"
495
+ @nendo.evalStr( " (letrec () 100) " ).should == "100"
496
+ @nendo.evalStr( " (letrec ((a 11)) a) " ).should == "11"
497
+ @nendo.evalStr( " (letrec ((a 11) (b 22)) (+ a b)) " ).should == "33"
498
+ @nendo.evalStr( " (letrec ((a 22)) (%let ((b 33)) (+ a b))) " ).should == "55"
499
+ @nendo.evalStr( " (letrec ((a 22)(b 33)) (%let ((c 44) (d 55)) (+ a b c d))) " ).should == "154"
500
+ @nendo.evalStr( " (letrec ((a (%let ((b 2)) (+ 100 b)))) a) " ).should == "102"
501
+ @nendo.evalStr( <<EOS
502
+ (letrec ((func1 (lambda () 13))
503
+ (func2 (lambda () (* 2 (func1)))))
504
+ (list (func2) (func1)))
505
+ EOS
506
+ ).should == "(26 13)"
507
+ @nendo.evalStr( <<EOS
508
+ (letrec ((func2 (lambda () (* 2 (func1))))
509
+ (func1 (lambda () 7)))
510
+ (list (func2) (func1)))
511
+ EOS
512
+ ).should == "(14 7)"
513
+ @nendo.evalStr( " (if true 't 'f)" ).should == "t"
514
+ @nendo.evalStr( " (if true '(1) '(2))" ).should == "(1)"
515
+ @nendo.evalStr( " (if false 't 'f)" ).should == "f"
516
+ @nendo.evalStr( " (if false '(1) '(2))" ).should == "(2)"
517
+ @nendo.evalStr( " (set! x 0) (if true (set! x 1) (set! x 2)) x" ).should == "1"
518
+ @nendo.evalStr( " (set! x 0) (if false (set! x 1) (set! x 2)) x" ).should == "2"
519
+ @nendo.evalStr( " (set! func (lambda (arg1) arg1)) (list (func 1) (func 2))" ).should == "(1 2)"
520
+ @nendo.evalStr( " ((lambda (arg1) arg1) 3)" ).should == "3"
521
+ @nendo.evalStr( " ((lambda (arg1) arg1) (+ 1 2 3))" ).should == "6"
522
+ @nendo.evalStr( " ((lambda (arg1 . arg2) arg1) 1 '(2))" ).should == "1"
523
+ @nendo.evalStr( " ((lambda (arg1 . arg2) arg2) 1 '(2))" ).should == "((2))"
524
+ @nendo.evalStr( " ((lambda (arg1 . arg2) arg2) 1 '(2 3))" ).should == "((2 3))"
525
+ @nendo.evalStr( " ((lambda (arg1 . arg2) arg1) '() '())" ).should == "()"
526
+ @nendo.evalStr( " ((lambda (arg1 . arg2) arg2) '() '())" ).should == "(())"
527
+ @nendo.evalStr( " ((lambda (arg1 . arg2) arg1) (cdr '(100)) (cdr '(200)))" ).should == "()"
528
+ @nendo.evalStr( " ((lambda (arg1 . arg2) arg2) (cdr '(100)) (cdr '(200)))" ).should == "(())"
529
+ @nendo.evalStr( " ((if #t + *) 3 4)" ).should == "7"
530
+ @nendo.evalStr( " ((if #f + *) 3 4)" ).should == "12"
531
+ @nendo.evalStr( " (apply1 + '(1 2))" ).should == "3"
532
+ @nendo.evalStr( " (apply1 + (range 10 1))" ).should == "55"
533
+ @nendo.evalStr( " (apply1 cons '(1 2))" ).should == "(1 . 2)"
534
+ @nendo.evalStr( " (apply1 list '(1 2 3))" ).should == "(1 2 3)"
535
+ lambda { @nendo.evalStr( " (error \"My Runtime Error\") " ) }.should raise_error( RuntimeError, /My Runtime Error/ )
536
+ lambda { @nendo.evalStr( " (error \"My Runtime Error\" '(a b c)) " ) }.should raise_error( RuntimeError, /My Runtime Error [(]a b c[)]/ )
537
+ @nendo.evalStr( "((lambda (arg1) (+ 1 arg1)) 2)" ).should == "3"
538
+ lambda { @nendo.evalStr( "((lambda (arg1) (+ 1 arg1)))" ) }.should raise_error( ArgumentError, /wrong number of arguments/ )
539
+ end
540
+ end
541
+
542
+ describe Nendo, "when call evalStr() with built-in special forms (renamed symbol)" do
543
+ before do
544
+ @nendo = Nendo::Core.new( )
545
+ @nendo.setDisplayErrors( false )
546
+ @nendo.loadInitFile
547
+ end
548
+ it "should" do
549
+ @nendo.evalStr( " (/nendo/core/begin 1) " ).should == "1"
550
+ @nendo.evalStr( " (/nendo/core/begin 1 2) " ).should == "2"
551
+ @nendo.evalStr( " (/nendo/core/begin 1 2 3) " ).should == "3"
552
+ @nendo.evalStr( <<EOS
553
+ (/nendo/core/set! x 2)
554
+ (/nendo/core/set! y (/nendo/core/begin
555
+ (/nendo/core/set! x (* x 2))
556
+ (/nendo/core/set! x (* x 2))
557
+ (/nendo/core/set! x (* x 2))
558
+ 100))
559
+ (+ x y)
560
+ EOS
561
+ ).should == "116"
562
+ @nendo.evalStr( " (/nendo/core/%let () 100) " ).should == "100"
563
+ @nendo.evalStr( " (/nendo/core/%let ((a 11)) a) " ).should == "11"
564
+ @nendo.evalStr( " (/nendo/core/%let ((a 11) (b 22)) (+ a b)) " ).should == "33"
565
+ @nendo.evalStr( " (/nendo/core/%let ((a 22)) (let ((b 33)) (+ a b))) " ).should == "55"
566
+ @nendo.evalStr( " (/nendo/core/%let ((a 22)(b 33)) (let ((c 44) (d 55)) (+ a b c d))) " ).should == "154"
567
+ @nendo.evalStr( " (/nendo/core/%let ((a (let ((b 2)) (+ 100 b)))) a) " ).should == "102"
568
+ @nendo.evalStr( " (/nendo/core/letrec () 100) " ).should == "100"
569
+ @nendo.evalStr( " (/nendo/core/letrec ((a 11)) a) " ).should == "11"
570
+ @nendo.evalStr( " (/nendo/core/letrec ((a 11) (b 22)) (+ a b)) " ).should == "33"
571
+ @nendo.evalStr( " (/nendo/core/letrec ((a 22)) (let ((b 33)) (+ a b))) " ).should == "55"
572
+ @nendo.evalStr( " (/nendo/core/letrec ((a 22)(b 33)) (let ((c 44) (d 55)) (+ a b c d))) " ).should == "154"
573
+ @nendo.evalStr( " (/nendo/core/letrec ((a (let ((b 2)) (+ 100 b)))) a) " ).should == "102"
574
+ @nendo.evalStr( <<EOS
575
+ (/nendo/core/letrec ((func1 (/nendo/core/lambda () 13))
576
+ (func2 (/nendo/core/lambda () (* 2 (func1)))))
577
+ (list (func2) (func1)))
578
+ EOS
579
+ ).should == "(26 13)"
580
+ @nendo.evalStr( <<EOS
581
+ (/nendo/core/letrec ((func2 (/nendo/core/lambda () (* 2 (func1))))
582
+ (func1 (/nendo/core/lambda () 7)))
583
+ (list (func2) (func1)))
584
+ EOS
585
+ ).should == "(14 7)"
586
+ @nendo.evalStr( " (/nendo/core/if true 't 'f)" ).should == "t"
587
+ @nendo.evalStr( " (/nendo/core/if true '(1) '(2))" ).should == "(1)"
588
+ @nendo.evalStr( " (/nendo/core/if false 't 'f)" ).should == "f"
589
+ @nendo.evalStr( " (/nendo/core/if false '(1) '(2))" ).should == "(2)"
590
+ @nendo.evalStr( " (/nendo/core/set! x 0) (/nendo/core/if true (set! x 1) (set! x 2)) x" ).should == "1"
591
+ @nendo.evalStr( " (/nendo/core/set! x 0) (/nendo/core/if false (set! x 1) (set! x 2)) x" ).should == "2"
592
+ @nendo.evalStr( <<EOS
593
+ (/nendo/core/set! func (/nendo/core/lambda (arg1) arg1))
594
+ (list (func 1) (func 2))
595
+ EOS
596
+ ).should == "(1 2)"
597
+ @nendo.evalStr( " ((/nendo/core/lambda (arg1) arg1) 3)" ).should == "3"
598
+ @nendo.evalStr( " ((/nendo/core/lambda (arg1) arg1) (+ 1 2 3))" ).should == "6"
599
+ @nendo.evalStr( " ((/nendo/core/if #t + *) 3 4)" ).should == "7"
600
+ @nendo.evalStr( " ((/nendo/core/if #f + *) 3 4)" ).should == "12"
601
+ lambda { @nendo.evalStr( " (/nendo/core/error \"My Runtime Error\") " ) }.should raise_error( RuntimeError )
602
+ end
603
+ end
604
+
605
+
606
+ describe Nendo, "when redefined built-in functions(1)." do
607
+ before do
608
+ @nendo = Nendo::Core.new()
609
+ @nendo.setDisplayErrors( false )
610
+ @nendo.loadInitFile
611
+ end
612
+ it "should" do
613
+ @nendo.evalStr( " (define (+ a b) (list a b)) (+ 1 2)" ).should == "(1 2)"
614
+ lambda { @nendo.evalStr( " (define (+ a b) (list a b)) (+ 1 2 3)" ) }.should raise_error( ArgumentError )
615
+ @nendo.evalStr( " (define (eq? a b) \"eq?\") (eq? 1 1)" ).should == '"eq?"'
616
+ end
617
+ end
618
+
619
+ describe Nendo, "when redefined built-in functions(2)." do
620
+ before do
621
+ @nendo = Nendo::Core.new()
622
+ @nendo.loadInitFile
623
+ end
624
+ it "should" do
625
+ @nendo.evalStr( " (define (< a b) \"<\") (< 1 1)" ).should == '"<"'
626
+ end
627
+ end
628
+
629
+ describe Nendo, "when redefined built-in functions(3)." do
630
+ before do
631
+ @nendo = Nendo::Core.new()
632
+ @nendo.loadInitFile
633
+ end
634
+ it "should" do
635
+ @nendo.evalStr( " (define (car lst) \"car\") (car '(1 2))" ).should == '"car"'
636
+ end
637
+ end
638
+
639
+ describe Nendo, "when call evalStr() with global and lexical scope variable" do
640
+ before do
641
+ @nendo = Nendo::Core.new()
642
+ end
643
+ it "should" do
644
+ @nendo.evalStr( " (define var 111) " ).should == "111"
645
+ @nendo.evalStr( " (%let ((var 222)) var) " ).should == "222"
646
+ @nendo.evalStr( " (%let ((var 222)) (set! var 333) var) " ).should == "333"
647
+ @nendo.evalStr( " (%let ((var 222)) (set! var 333)) var " ).should == "111"
648
+ @nendo.evalStr( " (define global1 \"G\") " ).should == '"G"'
649
+ @nendo.evalStr( <<EOS
650
+ (%let ((local1 \"L\")
651
+ (local2 \"L\"))
652
+ (set! global1 (+ global1 \"lobal1\"))
653
+ (set! local1 (+ local1 \"ocal1\"))
654
+ (set! local2 (+ local2 \"ocal2\"))
655
+ (list global1
656
+ local1
657
+ local2
658
+ (%let ((local1 \"A\")
659
+ (local2 \"B\"))
660
+ (set! local1 (+ local1 \"a\"))
661
+ (set! local2 (+ local2 \"b\"))
662
+ (list local1 local2
663
+ (%let ((local1 \"CCC\"))
664
+ (list global1 local1 local2))))))
665
+ EOS
666
+ ).should == '("Global1" "Local1" "Local2" ("Aa" "Bb" ("Global1" "CCC" "Bb")))'
667
+ end
668
+ end
669
+
670
+ describe Nendo, "when call evalStr() with macroexpand-1 function" do
671
+ before do
672
+ @nendo = Nendo::Core.new()
673
+ end
674
+ it "should" do
675
+ @nendo.evalStr( <<EOS
676
+ (set! twice (macro (x) (list 'begin x x)))
677
+ (macroexpand-1 '(twice (+ 1 1)))
678
+ EOS
679
+ ).should == "(begin (+ 1 1) (+ 1 1))"
680
+ @nendo.evalStr( <<EOS
681
+ (set! inc (macro (x) (list 'set! x (list '+ x 1))))
682
+ (macroexpand-1 '(inc a))
683
+ EOS
684
+ ).should == "(set! a (+ a 1))"
685
+ @nendo.evalStr( " (set! a 10) (inc a) " ).should == "11"
686
+ @nendo.evalStr( " (set! a 10) (inc a) (inc a)" ).should == "12"
687
+ @nendo.evalStr( <<EOS
688
+ (macroexpand-1
689
+ '(twice (twice (inc a))))
690
+ EOS
691
+ ).should ==
692
+ "(begin (twice (inc a)) (twice (inc a)))"
693
+ @nendo.evalStr( <<EOS
694
+ (macroexpand-1
695
+ (macroexpand-1
696
+ '(twice (twice (inc a)))))
697
+ EOS
698
+ ).should ==
699
+ "(begin (begin (inc a) (inc a)) (twice (inc a)))"
700
+ @nendo.evalStr( <<EOS
701
+ (macroexpand-1
702
+ (macroexpand-1
703
+ (macroexpand-1
704
+ '(twice (twice (inc a))))))
705
+ EOS
706
+ ).should ==
707
+ "(begin (begin (set! a (+ a 1)) (inc a)) (twice (inc a)))"
708
+ @nendo.evalStr( <<EOS
709
+ (macroexpand-1
710
+ (macroexpand-1
711
+ (macroexpand-1
712
+ (macroexpand-1
713
+ '(twice (twice (inc a)))))))
714
+ EOS
715
+ ).should ==
716
+ "(begin (begin (set! a (+ a 1)) (set! a (+ a 1))) (twice (inc a)))"
717
+ @nendo.evalStr( " (set! a 10) (twice (twice (inc a)))" ).should == "14"
718
+ end
719
+ end
720
+
721
+
722
+ describe Nendo, "when use #xxxx syntax " do
723
+ before do
724
+ @nendo = Nendo::Core.new()
725
+ @nendo.setDisplayErrors( false )
726
+ @nendo.loadInitFile
727
+ end
728
+ it "should" do
729
+ @nendo.evalStr( " #t " ).should == "#t"
730
+ @nendo.evalStr( " #f " ).should == "#f"
731
+ @nendo.evalStr( " '#( 1 ) " ).should == "#(1)"
732
+ @nendo.evalStr( " '#() " ).should == "#()"
733
+ @nendo.evalStr( " #! \n #t" ).should == "#t"
734
+ @nendo.evalStr( " #! \n 100" ).should == "100"
735
+ @nendo.evalStr( " #! 123 \n 100" ).should == "100"
736
+ @nendo.evalStr( " '#?=1" ).should == "(debug-print 1 \"(string)\" 1 (quote 1))"
737
+ @nendo.evalStr( " '#?." ).should == '"(string):1"'
738
+ @nendo.evalStr( " '#?." ).should == '"(string):1"'
739
+ @nendo.evalStr( " (begin #?. (+ 1 1))" ).should == "2"
740
+ @nendo.evalStr( " (rxmatch #/[a-z]/ \"abc\")" ).should == "a"
741
+ @nendo.evalStr( " (quote #?=(rxmatch #/[a-z]/ \"abc\"))" ).should == '(debug-print (rxmatch #/[a-z]/ "abc") "(string)" 1 (quote (rxmatch #/[a-z]/ "abc")))'
742
+ @nendo.evalStr( <<EOS
743
+ (begin
744
+ #?.
745
+ (+ 1 1)
746
+ #?. )
747
+ EOS
748
+ ).should == '"(string):4"'
749
+ @nendo.evalStr( " #b0 " ).should == Integer("0b0").to_s
750
+ @nendo.evalStr( " #b01 " ).should == Integer("0b01").to_s
751
+ @nendo.evalStr( " #b10 " ).should == Integer("0b10").to_s
752
+ @nendo.evalStr( " #b00000001 " ).should == Integer("0b00000001").to_s
753
+ @nendo.evalStr( " #b1010101010101010 " ).should == Integer("0b1010101010101010").to_s
754
+ lambda { @nendo.evalStr( " #b2 " ) }.should raise_error(RuntimeError)
755
+ lambda { @nendo.evalStr( " #b02 " ) }.should raise_error(RuntimeError)
756
+ lambda { @nendo.evalStr( " #bF " ) }.should raise_error(RuntimeError)
757
+ @nendo.evalStr( " #o0 " ).should == Integer("0o0").to_s
758
+ @nendo.evalStr( " #o7 " ).should == Integer("0o7").to_s
759
+ @nendo.evalStr( " #o01 " ).should == Integer("0o01").to_s
760
+ @nendo.evalStr( " #o10 " ).should == Integer("0o10").to_s
761
+ @nendo.evalStr( " #o777 " ).should == Integer("0o777").to_s
762
+ @nendo.evalStr( " #o00000007 " ).should == Integer("0o00000007").to_s
763
+ @nendo.evalStr( " #o0123456701234567 " ).should == Integer("0o0123456701234567").to_s
764
+ lambda { @nendo.evalStr( " #o8 " ) }.should raise_error(RuntimeError)
765
+ lambda { @nendo.evalStr( " #o08 " ) }.should raise_error(RuntimeError)
766
+ lambda { @nendo.evalStr( " #oA " ) }.should raise_error(RuntimeError)
767
+ @nendo.evalStr( " #d0 " ).should == Integer("0d0").to_s
768
+ @nendo.evalStr( " #d9 " ).should == Integer("0d9").to_s
769
+ @nendo.evalStr( " #d01 " ).should == Integer("0d01").to_s
770
+ @nendo.evalStr( " #d10 " ).should == Integer("0d10").to_s
771
+ @nendo.evalStr( " #d999 " ).should == Integer("0d999").to_s
772
+ @nendo.evalStr( " #d00000009 " ).should == Integer("0d00000009").to_s
773
+ @nendo.evalStr( " #d0123456701234567 " ).should == Integer("0d0123456701234567").to_s
774
+ lambda { @nendo.evalStr( " #dA " ) }.should raise_error(RuntimeError)
775
+ lambda { @nendo.evalStr( " #dF " ) }.should raise_error(RuntimeError)
776
+ @nendo.evalStr( " #x0 " ).should == Integer("0x0").to_s
777
+ @nendo.evalStr( " #x9 " ).should == Integer("0x9").to_s
778
+ @nendo.evalStr( " #xA " ).should == Integer("0xA").to_s
779
+ @nendo.evalStr( " #xF " ).should == Integer("0xF").to_s
780
+ @nendo.evalStr( " #x01 " ).should == Integer("0x01").to_s
781
+ @nendo.evalStr( " #x10 " ).should == Integer("0x10").to_s
782
+ @nendo.evalStr( " #xFFF " ).should == Integer("0xFFF").to_s
783
+ @nendo.evalStr( " #x0000000F " ).should == Integer("0x0000000F").to_s
784
+ @nendo.evalStr( " #x0123456789ABCDEF0123456789ABCDEF " ).should == Integer("0x0123456789ABCDEF0123456789ABCDEF").to_s
785
+ lambda { @nendo.evalStr( " #xg " ) }.should raise_error(RuntimeError)
786
+ lambda { @nendo.evalStr( " #xh " ) }.should raise_error(RuntimeError)
787
+ lambda { @nendo.evalStr( " #xz " ) }.should raise_error(RuntimeError)
788
+ lambda { @nendo.evalStr( " #xG " ) }.should raise_error(RuntimeError)
789
+ lambda { @nendo.evalStr( " #xH " ) }.should raise_error(RuntimeError)
790
+ lambda { @nendo.evalStr( " #xZ " ) }.should raise_error(RuntimeError)
791
+ lambda { @nendo.evalStr( " #a " ) }.should raise_error(NameError)
792
+ lambda { @nendo.evalStr( " #c " ) }.should raise_error(NameError)
793
+ lambda { @nendo.evalStr( " #e " ) }.should raise_error(NameError)
794
+ lambda { @nendo.evalStr( " #tt " ) }.should raise_error(NameError)
795
+ lambda { @nendo.evalStr( " #ff " ) }.should raise_error(NameError)
796
+ lambda { @nendo.evalStr( " #abc " ) }.should raise_error(NameError)
797
+ lambda { @nendo.evalStr( " #? " ) }.should raise_error(NameError)
798
+ lambda { @nendo.evalStr( " #?a " ) }.should raise_error(NameError)
799
+ lambda { @nendo.evalStr( " #= " ) }.should raise_error(NameError)
800
+ lambda { @nendo.evalStr( " #?? " ) }.should raise_error(NameError)
801
+ end
802
+ end
803
+
804
+ describe Nendo, "when use regexp litteral and library functions " do
805
+ before do
806
+ @nendo = Nendo::Core.new()
807
+ @nendo.setDisplayErrors( false )
808
+ @nendo.loadInitFile
809
+ end
810
+ it "should" do
811
+ @nendo.evalStr( " #/abc/ " ).should == "#/abc/"
812
+ @nendo.evalStr( " #/[a-z]/ " ).should == "#/[a-z]/"
813
+ @nendo.evalStr( " #/[a-zA-Z0-9]+/ " ).should == "#/[a-zA-Z0-9]+/"
814
+ @nendo.evalStr( ' #/\d/ ' ).should == '#/\d/'
815
+ @nendo.evalStr( ' #/[\/]/ ' ).should == '#/[\/]/'
816
+ @nendo.evalStr( ' #/\]/ ' ).should == '#/\]/'
817
+ @nendo.evalStr( ' #/^\]/ ' ).should == '#/^\]/'
818
+ @nendo.evalStr( ' #/\[/ ' ).should == '#/\[/'
819
+ @nendo.evalStr( ' #/^\[/ ' ).should == '#/^\[/'
820
+ @nendo.evalStr( ' #/\.\^\$\/\+\-\(\)\|/ ' ).should == '#/\.\^\$\/\+\-\(\)\|/'
821
+ @nendo.evalStr( " #/abc/i " ).should == "#/abc/i"
822
+ @nendo.evalStr( " #/[a-z]/i " ).should == "#/[a-z]/i"
823
+ lambda { @nendo.evalStr( " #/[a-z]/I " ) }.should raise_error(NameError)
824
+ lambda { @nendo.evalStr( " #/[a-z]/a " ) }.should raise_error(NameError)
825
+
826
+ @nendo.evalStr( ' (string->regexp "abc") ' ).should == '#/abc/'
827
+ @nendo.evalStr( ' (string->regexp "[a-z]") ' ).should == '#/[a-z]/'
828
+ @nendo.evalStr( ' (string->regexp "[a-zA-Z0-9]+" ) ' ).should == '#/[a-zA-Z0-9]+/'
829
+ @nendo.evalStr( ' (string->regexp "\\\\d" ) ' ).should == '#/\d/'
830
+ @nendo.evalStr( " (regexp? #/str/ ) " ).should == "#t"
831
+ @nendo.evalStr( " (regexp? #/str/i ) " ).should == "#t"
832
+ @nendo.evalStr( " (regexp? \"str\" ) " ).should == "#f"
833
+ @nendo.evalStr( " (regexp? 'str) " ).should == "#f"
834
+ @nendo.evalStr( " (regexp? (. \"str\" intern)) " ).should == "#f"
835
+ @nendo.evalStr( " (regexp? 100) " ).should == "#f"
836
+
837
+ @nendo.evalStr( " (regexp->string #/abc/ ) " ).should == '"abc"'
838
+ @nendo.evalStr( " (regexp->string #/[a-z]/ ) " ).should == '"[a-z]"'
839
+ @nendo.evalStr( " (regexp->string #/[a-zA-Z0-9]+/ ) " ).should == '"[a-zA-Z0-9]+"'
840
+ @nendo.evalStr( ' (regexp->string #/\d+/ ) ' ).should == '"\\\\d+"'
841
+
842
+ @nendo.evalStr( ' (define matchdata (rxmatch #/(\d+):(\d+)/ "foo314:2000bar")) ' ).should == '314:2000'
843
+ @nendo.evalStr( ' (rxmatch-start matchdata) ' ).should == '3'
844
+ @nendo.evalStr( ' (rxmatch-start matchdata 0) ' ).should == '3'
845
+ @nendo.evalStr( ' (rxmatch-start matchdata 1) ' ).should == '3'
846
+ @nendo.evalStr( ' (rxmatch-start matchdata 2) ' ).should == '7'
847
+ @nendo.evalStr( ' (rxmatch-end matchdata) ' ).should == '11'
848
+ @nendo.evalStr( ' (rxmatch-end matchdata 0) ' ).should == '11'
849
+ @nendo.evalStr( ' (rxmatch-end matchdata 1) ' ).should == '6'
850
+ @nendo.evalStr( ' (rxmatch-end matchdata 2) ' ).should == '11'
851
+ @nendo.evalStr( ' (rxmatch-substring matchdata) ' ).should == '"314:2000"'
852
+ @nendo.evalStr( ' (rxmatch-substring matchdata 0) ' ).should == '"314:2000"'
853
+ @nendo.evalStr( ' (rxmatch-substring matchdata 1) ' ).should == '"314"'
854
+ @nendo.evalStr( ' (rxmatch-substring matchdata 2) ' ).should == '"2000"'
855
+ @nendo.evalStr( ' (rxmatch-num-matches matchdata) ' ).should == '3'
856
+
857
+ @nendo.evalStr( ' (define matchdata (rxmatch #/(\w+)@([\w.]+)/ "foo@example.com")) ' ).should == 'foo@example.com'
858
+ @nendo.evalStr( ' (rxmatch-substring matchdata) ' ).should == '"foo@example.com"'
859
+ @nendo.evalStr( ' (rxmatch-substring matchdata 0) ' ).should == '"foo@example.com"'
860
+ @nendo.evalStr( ' (rxmatch-substring matchdata 1) ' ).should == '"foo"'
861
+ @nendo.evalStr( ' (rxmatch-substring matchdata 2) ' ).should == '"example.com"'
862
+
863
+ @nendo.evalStr( ' (rxmatch->string #/(\w+)@([\w.]+)/ "foo@example.com")' ).should == '"foo@example.com"'
864
+ @nendo.evalStr( ' (rxmatch->string #/(\w+)@([\w.]+)/ "foo@example.com" 0)' ).should == '"foo@example.com"'
865
+ @nendo.evalStr( ' (rxmatch->string #/(\w+)@([\w.]+)/ "foo@example.com" 1)' ).should == '"foo"'
866
+ @nendo.evalStr( ' (rxmatch->string #/(\w+)@([\w.]+)/ "foo@example.com" 2)' ).should == '"example.com"'
867
+
868
+ @nendo.evalStr( ' (rxmatch->string #/abc/ "000abc00ABC000")' ).should == '"abc"'
869
+ @nendo.evalStr( ' (rxmatch->string #/ABC/ "000abc00ABC000")' ).should == '"ABC"'
870
+ @nendo.evalStr( ' (rxmatch->string #/abc/i "abc")' ).should == '"abc"'
871
+ @nendo.evalStr( ' (rxmatch->string #/abc/i "ABC")' ).should == '"ABC"'
872
+ @nendo.evalStr( ' (rxmatch->string #/ABC/i "abc")' ).should == '"abc"'
873
+ @nendo.evalStr( ' (rxmatch->string #/abc/i "AbC")' ).should == '"AbC"'
874
+
875
+ @nendo.evalStr( ' (rxmatch #/abc/i "xxx")' ).should == '#f'
876
+ @nendo.evalStr( ' (rxmatch #/XXX/ "xxx")' ).should == '#f'
877
+ @nendo.evalStr( ' (rxmatch->string #/abc/i "xxx")' ).should == '#f'
878
+ @nendo.evalStr( ' (rxmatch->string #/XXX/ "xxx")' ).should == '#f'
879
+
880
+ pending( "JRuby can't compute correctly" ) if defined? JRUBY_VERSION
881
+ @nendo.evalStr( <<EOS
882
+ (define matchdata
883
+ (rxmatch #/([あ-ん])([あ-ん])([あ-ん])([あ-ん])([あ-ん])/
884
+ "ABC漢字あいうえお漢字ABC"))
885
+ EOS
886
+ ).should == 'あいうえお'
887
+ @nendo.evalStr( ' (rxmatch-start matchdata) ' ).should == '5'
888
+ @nendo.evalStr( ' (rxmatch-end matchdata) ' ).should == '10'
889
+ @nendo.evalStr( ' (rxmatch-substring matchdata) ' ).should == '"あいうえお"'
890
+ @nendo.evalStr( ' (rxmatch-substring matchdata 1) ' ).should == '"あ"'
891
+ @nendo.evalStr( ' (rxmatch-substring matchdata 2) ' ).should == '"い"'
892
+ @nendo.evalStr( ' (rxmatch-substring matchdata 3) ' ).should == '"う"'
893
+ end
894
+ end
895
+
896
+
897
+ describe Nendo, "when call functions in init.nnd " do
898
+ before do
899
+ @nendo = Nendo::Core.new()
900
+ @nendo.loadInitFile
901
+ @nendo.loadInitFile # to self optimizing. The init.nnd file will be loaded twice, so `map' can be optimized on second loading phase.
902
+ end
903
+ it "should" do
904
+ @nendo.evalStr( " (cadr '(1 2 3 4)) " ).should == "2"
905
+ @nendo.evalStr( " (caddr '(1 2 3 4)) " ).should == "3"
906
+ @nendo.evalStr( " (cadddr '(1 2 3 4)) " ).should == "4"
907
+ @nendo.evalStr( " (caar '((5 6 7 8))) " ).should == "5"
908
+ @nendo.evalStr( " (cdar '((5 6 7 8))) " ).should == "(6 7 8)"
909
+ @nendo.evalStr( " (cadar '((5 6 7 8))) " ).should == "6"
910
+ @nendo.evalStr( " (cddar '((5 6 7 8))) " ).should == "(7 8)"
911
+ @nendo.evalStr( " (iota 1) " ).should == "(0)"
912
+ @nendo.evalStr( " (iota 3) " ).should == "(0 1 2)"
913
+ @nendo.evalStr( " (append '() '()) " ).should == "()"
914
+ @nendo.evalStr( " (append '(1) '()) " ).should == "(1)"
915
+ @nendo.evalStr( " (append '() '(2)) " ).should == "(2)"
916
+ @nendo.evalStr( " (append '(1) '(2)) " ).should == "(1 2)"
917
+ @nendo.evalStr( " (append '(1 2) '(3 4)) " ).should == "(1 2 3 4)"
918
+ @nendo.evalStr( " (append '(1 2) (cdr '(200))) " ).should == "(1 2)"
919
+ @nendo.evalStr( " (append (cdr '(100)) '(10 20)) " ).should == "(10 20)"
920
+ @nendo.evalStr( " (define lst '()) " ).should == "()"
921
+ @nendo.evalStr( " (push! lst 1) " ).should == "(1)"
922
+ @nendo.evalStr( " lst " ).should == "(1)"
923
+ @nendo.evalStr( " (push! lst 2) " ).should == "(2 1)"
924
+ @nendo.evalStr( " lst " ).should == "(2 1)"
925
+ @nendo.evalStr( " (push! lst 3) " ).should == "(3 2 1)"
926
+ @nendo.evalStr( " lst " ).should == "(3 2 1)"
927
+ @nendo.evalStr( ' (push! lst "str") ' ).should == '("str" 3 2 1)'
928
+ @nendo.evalStr( " lst " ).should == '("str" 3 2 1)'
929
+ @nendo.evalStr( " (pair? '()) " ).should == "#f"
930
+ @nendo.evalStr( " (pair? '(1)) " ).should == "#t"
931
+ @nendo.evalStr( " (pair? '(1 2)) " ).should == "#t"
932
+ @nendo.evalStr( " (pair? '(1 2 3)) " ).should == "#t"
933
+ @nendo.evalStr( " (pair? '(1 . 2)) " ).should == "#t"
934
+ @nendo.evalStr( " (pair? '(())) " ).should == "#t"
935
+ @nendo.evalStr( " (pair? 1) " ).should == "#f"
936
+ @nendo.evalStr( " (pair? \"str\") " ).should == "#f"
937
+ @nendo.evalStr( " (list? '()) " ).should == "#t"
938
+ @nendo.evalStr( " (list? '(1)) " ).should == "#t"
939
+ @nendo.evalStr( " (list? '(1 2)) " ).should == "#t"
940
+ @nendo.evalStr( " (list? '(1 2 3)) " ).should == "#t"
941
+ @nendo.evalStr( " (list? '(1 . 2)) " ).should == "#f"
942
+ @nendo.evalStr( " (list? '(1 2 . 3)) " ).should == "#f"
943
+ @nendo.evalStr( " (list? '(())) " ).should == "#t"
944
+ @nendo.evalStr( " (list? 1) " ).should == "#f"
945
+ @nendo.evalStr( " (list? \"str\") " ).should == "#f"
946
+ @nendo.evalStr( " (even? 2) " ).should == "#t"
947
+ @nendo.evalStr( " (even? 1) " ).should == "#f"
948
+ @nendo.evalStr( " (even? 0) " ).should == "#t"
949
+ @nendo.evalStr( " (even? -1) " ).should == "#f"
950
+ @nendo.evalStr( " (even? -2) " ).should == "#t"
951
+ @nendo.evalStr( " (odd? 2) " ).should == "#f"
952
+ @nendo.evalStr( " (odd? 1) " ).should == "#t"
953
+ @nendo.evalStr( " (odd? 0) " ).should == "#f"
954
+ @nendo.evalStr( " (odd? -1) " ).should == "#t"
955
+ @nendo.evalStr( " (odd? -2) " ).should == "#f"
956
+ @nendo.evalStr( " (zero? 0) " ).should == "#t"
957
+ @nendo.evalStr( " (zero? #f) " ).should == "#f"
958
+ @nendo.evalStr( " (zero? #t) " ).should == "#f"
959
+ @nendo.evalStr( " (zero? 1) " ).should == "#f"
960
+ @nendo.evalStr( " (zero? 2) " ).should == "#f"
961
+ @nendo.evalStr( " (zero? -1) " ).should == "#f"
962
+ @nendo.evalStr( " (zero? \"str\") " ).should == "#f"
963
+ @nendo.evalStr( " (zero? zero?) " ).should == "#f"
964
+ @nendo.evalStr( " (positive? 1) " ).should == "#t"
965
+ @nendo.evalStr( " (positive? 0) " ).should == "#f"
966
+ @nendo.evalStr( " (positive? -1) " ).should == "#f"
967
+ @nendo.evalStr( " (negative? 1) " ).should == "#f"
968
+ @nendo.evalStr( " (negative? 0) " ).should == "#f"
969
+ @nendo.evalStr( " (negative? -1) " ).should == "#t"
970
+ @nendo.evalStr( " (abs -1) " ).should == "1"
971
+ @nendo.evalStr( " (abs 1) " ).should == "1"
972
+ @nendo.evalStr( " (abs -1000) " ).should == "1000"
973
+ @nendo.evalStr( " (abs 1000) " ).should == "1000"
974
+ @nendo.evalStr( " (max -2 1 0 1 2 3 4 5) " ).should == "5"
975
+ @nendo.evalStr( " (max 5 4 3 2 1 0 -1 -2) " ).should == "5"
976
+ @nendo.evalStr( " (max 1000000000 10 -10000) " ).should == "1000000000"
977
+ @nendo.evalStr( " (min -2 1 0 1 2 3 4 5) " ).should == "-2"
978
+ @nendo.evalStr( " (min 5 4 3 2 1 0 -1 -2) " ).should == "-2"
979
+ @nendo.evalStr( " (min 1000000000 10 -10000) " ).should == "-10000"
980
+ @nendo.evalStr( " (succ -1) " ).should == "0"
981
+ @nendo.evalStr( " (succ 0) " ).should == "1"
982
+ @nendo.evalStr( " (succ 1) " ).should == "2"
983
+ @nendo.evalStr( " (pred -1) " ).should == "-2"
984
+ @nendo.evalStr( " (pred 0) " ).should == "-1"
985
+ @nendo.evalStr( " (pred 1) " ).should == "0"
986
+ @nendo.evalStr( " (pred 2) " ).should == "1"
987
+ @nendo.evalStr( " (min 1000000000 10 -10000) " ).should == "-10000"
988
+ @nendo.evalStr( " (nth 0 '(100 200 300)) " ).should == "100"
989
+ @nendo.evalStr( " (nth 1 '(100 200 300)) " ).should == "200"
990
+ @nendo.evalStr( " (nth 2 '(100 200 300)) " ).should == "300"
991
+ @nendo.evalStr( " (nth 3 '(100 200 300)) " ).should == "()"
992
+ @nendo.evalStr( " (nth -1 '(100 200 300)) " ).should == "()"
993
+ @nendo.evalStr( " (first '(100 200 300 400 500 600 700 800 900 1000)) " ).should == "100"
994
+ @nendo.evalStr( " (second '(100 200 300 400 500 600 700 800 900 1000)) " ).should == "200"
995
+ @nendo.evalStr( " (third '(100 200 300 400 500 600 700 800 900 1000)) " ).should == "300"
996
+ @nendo.evalStr( " (fourth '(100 200 300 400 500 600 700 800 900 1000)) " ).should == "400"
997
+ @nendo.evalStr( " (fifth '(100 200 300 400 500 600 700 800 900 1000)) " ).should == "500"
998
+ @nendo.evalStr( " (sixth '(100 200 300 400 500 600 700 800 900 1000)) " ).should == "600"
999
+ @nendo.evalStr( " (seventh '(100 200 300 400 500 600 700 800 900 1000)) " ).should == "700"
1000
+ @nendo.evalStr( " (eighth '(100 200 300 400 500 600 700 800 900 1000)) " ).should == "800"
1001
+ @nendo.evalStr( " (ninth '(100 200 300 400 500 600 700 800 900 1000)) " ).should == "900"
1002
+ @nendo.evalStr( " (tenth '(100 200 300 400 500 600 700 800 900 1000)) " ).should == "1000"
1003
+ @nendo.evalStr( " (first '()) " ).should == "()"
1004
+ @nendo.evalStr( " (tenth '()) " ).should == "()"
1005
+ @nendo.evalStr( " (to-s 10) " ).should == '"10"'
1006
+ @nendo.evalStr( " (to_s 10) " ).should == '"10"'
1007
+ @nendo.evalStr( " (x->string 10) " ).should == '"10"'
1008
+ @nendo.evalStr( " (number->string 11) " ).should == '"11"'
1009
+ @nendo.evalStr( " (to-s 2.1) " ).should == '"2.1"'
1010
+ @nendo.evalStr( " (to_s 2.1) " ).should == '"2.1"'
1011
+ @nendo.evalStr( " (x->string 2.1) " ).should == '"2.1"'
1012
+ @nendo.evalStr( " (number->string 2.2) " ).should == '"2.2"'
1013
+ @nendo.evalStr( ' (string-append) ' ).should == '""'
1014
+ @nendo.evalStr( ' (string-append "a") ' ).should == '"a"'
1015
+ @nendo.evalStr( ' (string-append "a" "b") ' ).should == '"ab"'
1016
+ @nendo.evalStr( ' (string-append "a" "B" "c" "D" "e") ' ).should == '"aBcDe"'
1017
+ @nendo.evalStr( ' (string=? "ABC" "ABC") ' ).should == '#t'
1018
+ @nendo.evalStr( ' (string=? "ABC" "ABc") ' ).should == '#f'
1019
+ @nendo.evalStr( ' (string=? "ABC" "abc") ' ).should == '#f'
1020
+ @nendo.evalStr( ' (string=? 100 100) ' ).should == '#t'
1021
+ @nendo.evalStr( ' (string=? (+ "A" "B") "AB") ' ).should == '#t'
1022
+ @nendo.evalStr( " (to_i \"22\") " ).should == '22'
1023
+ @nendo.evalStr( " (to-i \"22\") " ).should == '22'
1024
+ @nendo.evalStr( " (to_i \"10000\") " ).should == '10000'
1025
+ @nendo.evalStr( " (to-i \"10000\") " ).should == '10000'
1026
+ @nendo.evalStr( " (let1 aaa 111 aaa) " ).should == "111"
1027
+ @nendo.evalStr( " (let1 aaa (+ 2 3) aaa) " ).should == "5"
1028
+ @nendo.evalStr( " (let1 aaa 333 (let1 bbb 444 (+ aaa bbb))) " ).should == "777"
1029
+ @nendo.evalStr( " (let1 aaa 333 (let1 bbb 444 (set! bbb 555) (+ aaa bbb))) " ).should == "888"
1030
+ @nendo.evalStr( " (memq 'b '(a b c d)) " ).should == "(b c d)"
1031
+ @nendo.evalStr( " (memq 'c '(a b c d)) " ).should == "(c d)"
1032
+ @nendo.evalStr( " (memq 'd '(a b c d)) " ).should == "(d)"
1033
+ @nendo.evalStr( " (memq 'e '(a b c d)) " ).should == "#f"
1034
+ @nendo.evalStr( " (memq 'e '(a b c d . e)) " ).should == "#f"
1035
+ @nendo.evalStr( ' (memq "b" \'("a" "b" "c" "d")) ' ).should == '("b" "c" "d")'
1036
+ @nendo.evalStr( ' (memv "b" \'("a" "b" "c" "d")) ' ).should == '("b" "c" "d")'
1037
+ @nendo.evalStr( ' (memv "c" \'("a" "b" "c" "d")) ' ).should == '("c" "d")'
1038
+ @nendo.evalStr( ' (memv "d" \'("a" "b" "c" "d")) ' ).should == '("d")'
1039
+ @nendo.evalStr( ' (memv "e" \'("a" "b" "c" "d")) ' ).should == '#f'
1040
+ @nendo.evalStr( ' (memv "e" \'("a" "b" "c" "d" . "e")) ' ).should == '#f'
1041
+ @nendo.evalStr( ' (memv \'("b") \'(("a") ("b") ("c") ("d"))) ' ).should == '#f'
1042
+ @nendo.evalStr( ' (member \'("b") \'(("a") ("b") ("c") ("d"))) ' ).should == '(("b") ("c") ("d"))'
1043
+ @nendo.evalStr( ' (member \'("c") \'(("a") ("b") ("c") ("d"))) ' ).should == '(("c") ("d"))'
1044
+ @nendo.evalStr( ' (member \'("d") \'(("a") ("b") ("c") ("d"))) ' ).should == '(("d"))'
1045
+ @nendo.evalStr( ' (member \'("e") \'(("a") ("b") ("c") ("d"))) ' ).should == '#f'
1046
+ @nendo.evalStr( ' (member \'("e") \'(("a") ("b") ("c") ("d") . ("e"))) ' ).should == '#f'
1047
+ @nendo.evalStr( " (let1 v (map (lambda (x) x) '(1 2 3)) v) " ).should == "(1 2 3)"
1048
+ @nendo.evalStr( " (let ((v (map (lambda (x) x) '(1 2 3)))) v) " ).should == "(1 2 3)"
1049
+ @nendo.evalStr( " (cond (true 1) (false 2)) " ).should == "1"
1050
+ @nendo.evalStr( " (cond (true ) (false )) " ).should == "#t"
1051
+ @nendo.evalStr( " (cond (false 1) (true 2)) " ).should == "2"
1052
+ @nendo.evalStr( " (cond (true 1) (true 2)) " ).should == "1"
1053
+ @nendo.evalStr( " (cond (false 1) (false 2)) " ).should == "()"
1054
+ @nendo.evalStr( " (cond (false 1) (false 2) (else 3)) " ).should == "3"
1055
+ @nendo.evalStr( <<EOS
1056
+ (cond
1057
+ ((- 10 9)
1058
+ =>
1059
+ (lambda (x)
1060
+ (+ \"<\" (to_s x) \">\")))
1061
+ (else
1062
+ 2))
1063
+ EOS
1064
+ ).should == '"<1>"'
1065
+ @nendo.evalStr( <<EOS
1066
+ (cond
1067
+ (true 1)
1068
+ ((- 10 8)
1069
+ =>
1070
+ (lambda (x)
1071
+ (+ \"<\" (to_s x) \">\")))
1072
+ (else
1073
+ 3))
1074
+ EOS
1075
+ ).should == "1"
1076
+ @nendo.evalStr( " (or) " ).should == "#f"
1077
+ @nendo.evalStr( " (or true) " ).should == "#t"
1078
+ @nendo.evalStr( " (or false) " ).should == "#f"
1079
+ @nendo.evalStr( " (or nil) " ).should == "#f"
1080
+ @nendo.evalStr( " (or '(1)) " ).should == "(1)"
1081
+ @nendo.evalStr( " (or '()) " ).should == "()"
1082
+ @nendo.evalStr( " (or true true true) " ).should == "#t"
1083
+ @nendo.evalStr( " (or 1 2 3) " ).should == "1"
1084
+ @nendo.evalStr( " (or false 2) " ).should == "2"
1085
+ @nendo.evalStr( " (or false false 3) " ).should == "3"
1086
+ @nendo.evalStr( " (or false '(2) false) " ).should == "(2)"
1087
+ @nendo.evalStr( " (and) " ).should == "#t"
1088
+ @nendo.evalStr( " (and true) " ).should == "#t"
1089
+ @nendo.evalStr( " (and false) " ).should == "#f"
1090
+ @nendo.evalStr( " (and nil) " ).should == "nil"
1091
+ @nendo.evalStr( " (and '(1)) " ).should == "(1)"
1092
+ @nendo.evalStr( " (and '()) " ).should == "()"
1093
+ @nendo.evalStr( " (and true true true) " ).should == "#t"
1094
+ @nendo.evalStr( " (and 1 2 3) " ).should == "3"
1095
+ @nendo.evalStr( " (and false 2) " ).should == "#f"
1096
+ @nendo.evalStr( " (and false false 3) " ).should == "#f"
1097
+ @nendo.evalStr( " (and true 2) " ).should == "2"
1098
+ @nendo.evalStr( " (and true true 3) " ).should == "3"
1099
+ @nendo.evalStr( " (and true true 3 false) " ).should == "#f"
1100
+ @nendo.evalStr( " (and true '(2) true) " ).should == "#t"
1101
+ @nendo.evalStr( " (and true true '(2)) " ).should == "(2)"
1102
+ @nendo.evalStr( " (and true '(2) false) " ).should == "#f"
1103
+ @nendo.evalStr( <<EOS
1104
+ (define total 0)
1105
+ (and 1
1106
+ 2
1107
+ (set! total (+ total 1))
1108
+ (set! total (+ total 2))
1109
+ 5)
1110
+ total
1111
+ EOS
1112
+ ).should == "3"
1113
+ @nendo.evalStr( <<EOS
1114
+ (define total 1)
1115
+ (and 1
1116
+ 2
1117
+ false
1118
+ (set! total (+ total 2))
1119
+ (set! total (+ total 3))
1120
+ 5)
1121
+ total
1122
+ EOS
1123
+ ).should == "1"
1124
+ @nendo.evalStr( " (apply + 100 '()) " ).should == "100"
1125
+ @nendo.evalStr( " (apply + '(1 2)) " ).should == "3"
1126
+ @nendo.evalStr( " (apply + 1 2 '(3)) " ).should == "6"
1127
+ @nendo.evalStr( " (apply + 1 2 '(3 4)) " ).should == "10"
1128
+ @nendo.evalStr( " (apply + 1 2 3 '(4)) " ).should == "10"
1129
+ @nendo.evalStr( ' (apply + \'("a" "b" "c")) ' ).should == '"abc"'
1130
+ @nendo.evalStr( " (range 5) " ).should == "(0 1 2 3 4)"
1131
+ @nendo.evalStr( " (range 5 1) " ).should == "(1 2 3 4 5)"
1132
+ @nendo.evalStr( " (range 5 2) " ).should == "(2 3 4 5 6)"
1133
+ @nendo.evalStr( " (iota 5 2) " ).should == "(2 3 4 5 6)"
1134
+ @nendo.evalStr( " (apply + (range 11)) " ).should == "55"
1135
+ @nendo.evalStr( " (apply + (map (lambda (x) (+ x 1)) (range 10))) " ).should == "55"
1136
+ @nendo.evalStr( " (apply + (append (range 11) '(100))) " ).should == "155"
1137
+ @nendo.evalStr( " (apply cons '(1 2)) " ).should == "(1 . 2)"
1138
+ @nendo.evalStr( " (apply list '(1 2)) " ).should == "(1 2)"
1139
+ @nendo.evalStr( " (apply list (list 1 '())) " ).should == "(1 ())"
1140
+ @nendo.evalStr( " (apply list (list 1 (cdr '(100)))) " ).should == "(1 ())"
1141
+ @nendo.evalStr( " (map (lambda (x) 1) '()) " ).should == "()"
1142
+ @nendo.evalStr( " (map (lambda (x) 1) (to-list '#())) " ).should == "()"
1143
+ @nendo.evalStr( " (map (lambda (x) (* x 2)) '(1 2 3)) " ).should == "(2 4 6)"
1144
+ @nendo.evalStr( " (map (lambda (x) (+ x 1)) '(1 2 3)) " ).should == "(2 3 4)"
1145
+ @nendo.evalStr( <<EOS
1146
+ (map
1147
+ (lambda (a b) (+ a b))
1148
+ '(1 2 3)
1149
+ '(10 20 30))
1150
+ EOS
1151
+ ).should == "(11 22 33)"
1152
+ @nendo.evalStr( <<EOS
1153
+ (map
1154
+ (lambda (a b)
1155
+ (- b a))
1156
+ '(1 2 3)
1157
+ '(10 20 30))
1158
+ EOS
1159
+ ).should == "(9 18 27)"
1160
+ @nendo.evalStr( <<EOS
1161
+ (map
1162
+ (lambda (a b c)
1163
+ (+ a b c))
1164
+ '(1 2 3)
1165
+ '(10 20 30)
1166
+ '(100 200 300))
1167
+ EOS
1168
+ ).should == "(111 222 333)"
1169
+ @nendo.evalStr( <<EOS
1170
+ (define _result
1171
+ (map
1172
+ (lambda (x)
1173
+ (* x 2))
1174
+ (range 10000 1)))
1175
+ (list
1176
+ (first _result)
1177
+ (second _result)
1178
+ (last-pair _result))
1179
+ EOS
1180
+ ).should == "(2 4 (20000))"
1181
+
1182
+ @nendo.evalStr( <<EOS
1183
+ (list
1184
+ (list* 1)
1185
+ (list* 1 2)
1186
+ (list* 1 2 3)
1187
+ (list* 1 2 3 4))
1188
+ EOS
1189
+ ).should == "(1 (1 . 2) (1 2 . 3) (1 2 3 . 4))"
1190
+
1191
+ @nendo.evalStr( <<EOS
1192
+ (list
1193
+ (list* '())
1194
+ (list* 1 '())
1195
+ (list* 1 2 '())
1196
+ (list* 1 2 3 '()))
1197
+ EOS
1198
+ ).should == "(() (1) (1 2) (1 2 3))"
1199
+
1200
+ @nendo.evalStr( <<EOS
1201
+ (list
1202
+ (list* (cdr '(100)))
1203
+ (list* 1 (cdr '(100)))
1204
+ (list* 1 2 (cdr '(100)))
1205
+ (list* 1 2 3 (cdr '(100))))
1206
+ EOS
1207
+ ).should == "(() (1) (1 2) (1 2 3))"
1208
+
1209
+ @nendo.evalStr( <<EOS
1210
+ (list
1211
+ (list* '())
1212
+ (list* '() '())
1213
+ (list* '() '() '())
1214
+ (list* '() '() '() '()))
1215
+ EOS
1216
+ ).should == "(() (()) (() ()) (() () ()))"
1217
+
1218
+ @nendo.evalStr( <<EOS
1219
+ (define _lst '())
1220
+ (for-each
1221
+ (lambda (x)
1222
+ (set! _lst (cons 1 _lst)))
1223
+ '())
1224
+ _lst
1225
+ EOS
1226
+ ).should == "()"
1227
+ @nendo.evalStr( <<EOS
1228
+ (define _lst '())
1229
+ (for-each
1230
+ (lambda (x)
1231
+ (set! _lst (cons (* x 2) _lst)))
1232
+ '(1 2 3))
1233
+ _lst
1234
+ EOS
1235
+ ).should == "(6 4 2)"
1236
+ @nendo.evalStr( <<EOS
1237
+ (define _lst '())
1238
+ (for-each
1239
+ (lambda (x)
1240
+ (set! _lst (cons (+ x 1) _lst)))
1241
+ '(1 2 3))
1242
+ _lst
1243
+ EOS
1244
+ ).should == "(4 3 2)"
1245
+ @nendo.evalStr( <<EOS
1246
+ (define _lst '())
1247
+ (for-each
1248
+ (lambda (a b)
1249
+ (set! _lst (cons (cons a b) _lst)))
1250
+ '(1 2 3)
1251
+ '(10 20 30))
1252
+ _lst
1253
+ EOS
1254
+ ).should ==
1255
+ "((3 . 30) (2 . 20) (1 . 10))"
1256
+ @nendo.evalStr( <<EOS
1257
+ (define _cnt 0)
1258
+ (for-each
1259
+ (lambda (x)
1260
+ (set! _cnt (+ _cnt 1)))
1261
+ (range 10000))
1262
+ _cnt
1263
+ EOS
1264
+ ).should == "10000"
1265
+ @nendo.evalStr( " (filter (lambda (x) x) '()) " ).should == "()"
1266
+ @nendo.evalStr( " (filter (lambda (x) (= x 100)) '(1 2 3)) " ).should == "()"
1267
+ @nendo.evalStr( " (filter (lambda (x) (= x 2)) '(1 2 3)) " ).should == "(2)"
1268
+ @nendo.evalStr( " (filter (lambda (x) (not (= x 2))) '(1 2 3)) " ).should == "(1 3)"
1269
+ @nendo.evalStr( " (filter (lambda (x) (if (= x 2) (* x 100) false)) '(1 2 3)) " ).should == "(2)"
1270
+ @nendo.evalStr( " (find (lambda (x) (= x 100)) '(1 2 3)) " ).should == "#f"
1271
+ @nendo.evalStr( " (find (lambda (x) (= x 2)) '(1 2 3)) " ).should == "2"
1272
+ @nendo.evalStr( " (find (lambda (x) (not (= x 2))) '(1 2 3)) " ).should == "1"
1273
+ @nendo.evalStr( " (find (lambda (x) (if (= x 2) (* x 100) false)) '(1 2 3)) " ).should == "2"
1274
+ @nendo.evalStr( " (eq? find any)" ).should == "#f"
1275
+ @nendo.evalStr( " (find even? '(1 2 3)) " ).should == "2"
1276
+ @nendo.evalStr( " (filter-map (lambda (x) x) '()) " ).should == "()"
1277
+ @nendo.evalStr( " (filter-map (lambda (x) (= x 100)) '(1 2 3)) " ).should == "()"
1278
+ @nendo.evalStr( " (filter-map (lambda (x) (= x 2)) '(1 2 3)) " ).should == "(#t)"
1279
+ @nendo.evalStr( " (filter-map (lambda (x) (not (= x 2))) '(1 2 3)) " ).should == "(#t #t)"
1280
+ @nendo.evalStr( " (fold (lambda (x y) x y) 0 '()) " ).should == "0"
1281
+ @nendo.evalStr( " (fold (lambda (x y) (+ x y)) 0 '(1 2 3)) " ).should == "6"
1282
+ @nendo.evalStr( " (fold (lambda (x y) (+ x y)) 1 '(2 3 4)) " ).should == "10"
1283
+ @nendo.evalStr( " (fold (lambda (x y) (* x y)) 1 '(2 3 4 5)) " ).should == "120"
1284
+ @nendo.evalStr( " (fold (lambda (x y) (* x y)) 0 '(2 3 4 5)) " ).should == "0"
1285
+ @nendo.evalStr( <<EOS
1286
+ (filter-map
1287
+ (lambda (x)
1288
+ (if (= x 2) (* x 10) false))
1289
+ '(1 2 3))
1290
+ EOS
1291
+ ).should == "(20)"
1292
+ @nendo.evalStr( <<EOS
1293
+ (filter-map
1294
+ (lambda (x)
1295
+ (if (not (= x 2)) (* x 10) false))
1296
+ '(1 2 3))
1297
+ EOS
1298
+ ).should == "(10 30)"
1299
+ @nendo.evalStr( " (any even? '(1 2 3)) " ).should == "#t"
1300
+ @nendo.evalStr( " (any even? '(1 3)) " ).should == "#f"
1301
+ @nendo.evalStr( " (any odd? '(1 3)) " ).should == "#t"
1302
+ @nendo.evalStr( " (any (lambda (x) x) '(1 2 3)) " ).should == "1"
1303
+ @nendo.evalStr( <<EOS
1304
+ (let1 result '()
1305
+ (do
1306
+ ((i 0 (+ i 1)))
1307
+ ((< 10 i) #f)
1308
+ (set! result (cons i result)))
1309
+ (reverse result))
1310
+ EOS
1311
+ ).should == "(0 1 2 3 4 5 6 7 8 9 10)"
1312
+ @nendo.evalStr( <<EOS
1313
+ (let1 result '()
1314
+ (do
1315
+ ((i 0 (+ i 3)))
1316
+ ((< (* 3 10) i) #f)
1317
+ (set! result (cons i result)))
1318
+ (reverse result))
1319
+ EOS
1320
+ ).should == "(0 3 6 9 12 15 18 21 24 27 30)"
1321
+ end
1322
+ end
1323
+
1324
+ describe Nendo, "when use raise function " do
1325
+ before do
1326
+ @nendo = Nendo::Core.new()
1327
+ @nendo.setDisplayErrors( false )
1328
+ @nendo.loadInitFile
1329
+ end
1330
+ it "should" do
1331
+ lambda { @nendo.evalStr( ' (%raise TypeError "typeError" "nendo_spec.rb:1 typeError" ) ' ) }.should raise_error( TypeError )
1332
+ lambda { @nendo.evalStr( ' (%raise ArgumentError "argumentError" "nendo_spec.rb:1 argumentError") ' ) }.should raise_error( ArgumentError )
1333
+ lambda { @nendo.evalStr( ' (raise TypeError "typeError" ) ' ) }.should raise_error( TypeError )
1334
+ lambda { @nendo.evalStr( ' (raise ArgumentError "argumentError" ) ' ) }.should raise_error( ArgumentError )
1335
+ lambda { @nendo.evalStr( ' (raise TypeError ) ' ) }.should raise_error( TypeError )
1336
+ lambda { @nendo.evalStr( ' (raise ArgumentError ) ' ) }.should raise_error( ArgumentError )
1337
+ end
1338
+ end
1339
+
1340
+ describe Nendo, "when use values " do
1341
+ before do
1342
+ @nendo = Nendo::Core.new()
1343
+ @nendo.setDisplayErrors( false )
1344
+ @nendo.loadInitFile
1345
+ end
1346
+ it "should" do
1347
+ @nendo.evalStr( " (values? (make-values '())) " ).should == "#t"
1348
+ lambda { @nendo.evalStr( " (make-values '(1))) " ) }.should raise_error(ArgumentError)
1349
+ @nendo.evalStr( " (values? (make-values '(1 2))) " ).should == "#t"
1350
+ @nendo.evalStr( " (values? (make-values '(1 2 3))) " ).should == "#t"
1351
+ @nendo.evalStr( " (values? (values)) " ).should == "#t"
1352
+ @nendo.evalStr( " (values? (values 1)) " ).should == "#f"
1353
+ @nendo.evalStr( " (values 1) " ).should == "1"
1354
+ @nendo.evalStr( " (values? (values 1 2)) " ).should == "#t"
1355
+ @nendo.evalStr( " (values? (values 1 2 3)) " ).should == "#t"
1356
+ @nendo.evalStr( " (values? (values '(a) \"b\" '(\"C\"))) " ).should == "#t"
1357
+ @nendo.evalStr( " (values-values (values)) " ).should == "()"
1358
+ lambda { @nendo.evalStr( " (values-values (values 1)) " ) }.should raise_error(TypeError)
1359
+ @nendo.evalStr( " (values-values (values 1 2)) " ).should == "(1 2)"
1360
+ @nendo.evalStr( " (values-values (values 1 2 3)) " ).should == "(1 2 3)"
1361
+ @nendo.evalStr( " (values-values (values '(a) \"b\" '(\"C\"))) " ).should == '((a) "b" ("C"))'
1362
+ @nendo.evalStr( <<EOS
1363
+ (call-with-values
1364
+ (lambda () (values 4 5))
1365
+ (lambda (a b) b))
1366
+ EOS
1367
+ ).should == "5"
1368
+ @nendo.evalStr( <<EOS
1369
+ (call-with-values
1370
+ (lambda () (values 1 2))
1371
+ cons)
1372
+ EOS
1373
+ ).should == "(1 . 2)"
1374
+ @nendo.evalStr( <<EOS
1375
+ (call-with-values
1376
+ (lambda () (values 10))
1377
+ list)
1378
+ EOS
1379
+ ).should == "(10)"
1380
+ @nendo.evalStr( <<EOS
1381
+ (call-with-values
1382
+ (lambda () (values))
1383
+ list)
1384
+ EOS
1385
+ ).should == "()"
1386
+ @nendo.evalStr( " (call-with-values * -) " ).should == "-1"
1387
+ @nendo.evalStr( " (receive (a) (values 10) (list a)) " ).should == "(10)"
1388
+ @nendo.evalStr( " (receive (a b) (values 10 20) (list a b)) " ).should == "(10 20)"
1389
+ @nendo.evalStr( " (receive (a b c) (values 10 20 30) (list a b c)) " ).should == "(10 20 30)"
1390
+ @nendo.evalStr( " (receive (a . b) (values 10) (list a b)) " ).should == "(10 ())"
1391
+ @nendo.evalStr( " (receive (a . b) (values 10 20) (list a b)) " ).should == "(10 (20))"
1392
+ @nendo.evalStr( " (receive (a . b) (values 10 20 30) (list a b)) " ).should == "(10 (20 30))"
1393
+ @nendo.evalStr( " (receive all (values) all) " ).should == "()"
1394
+ @nendo.evalStr( " (receive all (values 10) all) " ).should == "(10)"
1395
+ @nendo.evalStr( " (receive all (values 10 20) all) " ).should == "(10 20)"
1396
+ @nendo.evalStr( " (receive all (values 10 20 30) all) " ).should == "(10 20 30)"
1397
+ @nendo.evalStr( " (receive (a b) (values '(1) '(2)) (list a b)) " ).should == "((1) (2))"
1398
+ @nendo.evalStr( " (receive (a b) (values '() '(2)) (list a b)) " ).should == "(() (2))"
1399
+ @nendo.evalStr( " (receive (a b) (values '(1) '()) (list a b)) " ).should == "((1) ())"
1400
+ @nendo.evalStr( " (receive (a b) (values #t #t) (cons a b)) " ).should == "(#t . #t)"
1401
+ @nendo.evalStr( " (receive (a b) (values #t #f) (cons a b)) " ).should == "(#t . #f)"
1402
+ @nendo.evalStr( " (receive (a b) (values nil #t) (cons a b)) " ).should == "(nil . #t)"
1403
+ @nendo.evalStr( " (receive (a b) (values nil #f) (cons a b)) " ).should == "(nil . #f)"
1404
+ @nendo.evalStr( " (receive (a b) (values nil nil) (cons a b)) " ).should == "(nil . nil)"
1405
+ lambda { @nendo.evalStr( " (receive (a) (values) (list a)) " ) }.should raise_error( ArgumentError, /wrong number of arguments/ )
1406
+ lambda { @nendo.evalStr( <<EOS
1407
+ (map
1408
+ (lambda (a) a))
1409
+ EOS
1410
+ ) }.should raise_error( ArgumentError, /wrong number of arguments/ )
1411
+ lambda { @nendo.evalStr( <<EOS
1412
+ (map
1413
+ (lambda () 1)
1414
+ '(1 2 3))
1415
+ EOS
1416
+ ) }.should raise_error( ArgumentError, /wrong number of arguments/ )
1417
+ lambda { @nendo.evalStr( <<EOS
1418
+ (map
1419
+ (lambda (a) a)
1420
+ '(1 2 3)
1421
+ '(10 20 30))
1422
+ EOS
1423
+ ) }.should raise_error( ArgumentError, /wrong number of arguments/ )
1424
+ lambda { @nendo.evalStr( <<EOS
1425
+ (map
1426
+ (lambda (a b) (+ a b))
1427
+ '(1 2 3))
1428
+ EOS
1429
+ ) }.should raise_error( ArgumentError, /wrong number of arguments/ )
1430
+ end
1431
+ end
1432
+
1433
+ describe Nendo, "when toplevel variable was overwritten " do
1434
+ before do
1435
+ @nendo = Nendo::Core.new()
1436
+ @nendo.setDisplayErrors( false )
1437
+ @nendo.loadInitFile
1438
+ end
1439
+ it "should" do
1440
+ @nendo.evalStr( " (define a 1) a" ).should == "1"
1441
+ lambda { @nendo.evalStr( " (define (c-func) (+ a b)) (c-func)" ) }.should raise_error( NameError )
1442
+ @nendo.evalStr( " (define b 2) b" ).should == "2"
1443
+ @nendo.evalStr( " (c-func) " ).should == "3"
1444
+ @nendo.evalStr( " (define b 20) " ).should == "20"
1445
+ @nendo.evalStr( " (c-func) " ).should == "21"
1446
+
1447
+ @nendo.evalStr( " (define (a-func) 10) (a-func)" ).should == "10"
1448
+ lambda { @nendo.evalStr( " (define (c-func) (* (a-func) (b-func))) (c-func)" ) }.should raise_error( NameError )
1449
+ @nendo.evalStr( " (define (b-func) 20) (b-func)" ).should == "20"
1450
+ @nendo.evalStr( " (c-func) " ).should == "200"
1451
+ @nendo.evalStr( " (define (b-func) 200) (b-func)" ).should == "200"
1452
+ @nendo.evalStr( " (c-func) " ).should == "2000"
1453
+ end
1454
+ end
1455
+
1456
+ describe Nendo, "when use quasiquote macro " do
1457
+ before do
1458
+ @nendo = Nendo::Core.new()
1459
+ @nendo.loadInitFile
1460
+ end
1461
+ it "should" do
1462
+ @nendo.evalStr( " '(a b c) " ).should == "(a b c)"
1463
+ @nendo.evalStr( " `(a b c) " ).should == "(a b c)"
1464
+ @nendo.evalStr( " `(1 2 3) " ).should == "(1 2 3)"
1465
+ @nendo.evalStr( " (set! a 3) `(1 2 ,a) " ).should == "(1 2 3)"
1466
+ @nendo.evalStr( " (set! a 3) `(1 2 ,@(list a)) " ).should == "(1 2 3)"
1467
+ @nendo.evalStr( " (set! a 3) `(1 ,@(list 2 a)) " ).should == "(1 2 3)"
1468
+ @nendo.evalStr( " (set! a 11) `,a " ).should == "11"
1469
+ @nendo.evalStr( " (set! a 12) ``,a " ).should == "(quasiquote (unquote a))"
1470
+ @nendo.evalStr( ' (define str "string") str ' ).should == '"string"'
1471
+ @nendo.evalStr( ' `(,str) ' ).should == '("string")'
1472
+ @nendo.evalStr( ' `("STRING") ' ).should == '("STRING")'
1473
+ @nendo.evalStr( ' `(,str "STRING") ' ).should == '("string" "STRING")'
1474
+ @nendo.evalStr( ' `("STRING" ,str) ' ).should == '("STRING" "string")'
1475
+ @nendo.evalStr( ' (car `("STRING" ,str)) ' ).should == '"STRING"'
1476
+ @nendo.evalStr( ' (second `("STRING" ,str)) ' ).should == '"string"'
1477
+ @nendo.evalStr( ' (caar `(("STRING" ,str))) ' ).should == '"STRING"'
1478
+ @nendo.evalStr( ' (string-join `("A" "B" "C" "D")) ' ).should == '"ABCD"'
1479
+ @nendo.evalStr( " `(list ,(+ 1 2) 4) " ).should == "(list 3 4)"
1480
+ @nendo.evalStr( " (let ((name 'a)) `(list ,name ',name)) " ).should == "(list a (quote a))"
1481
+ @nendo.evalStr( " `(a `(b ,(+ 1 2) ,(foo ,(+ 1 3) d) e) f) " ).should == "(a (quasiquote (b (unquote (+ 1 2)) (unquote (foo 4 d)) e)) f)"
1482
+ @nendo.evalStr( " `(( foo ,(- 10 3)) ,@(cdr '(c)) . ,(car '(cons))) " ).should == "((foo 7) . cons)"
1483
+ end
1484
+ end
1485
+
1486
+ describe Nendo, "when use macros made by quasiquote. " do
1487
+ before do
1488
+ @nendo = Nendo::Core.new()
1489
+ @nendo.loadInitFile
1490
+ end
1491
+ it "should" do
1492
+ @nendo.evalStr( " (case (length '(1 )) ((1) \"one\") ((2) \"two\") (else \"else\")) " ).should == '"one"'
1493
+ @nendo.evalStr( " (case (length '(1 2 )) ((1) \"one\") ((2) \"two\") (else \"else\")) " ).should == '"two"'
1494
+ @nendo.evalStr( " (case (length '(1 2 3 )) ((1) \"one\") ((2) \"two\") (else \"else\")) " ).should == '"else"'
1495
+ @nendo.evalStr( " (case (length '(1 2 3 4)) ((1) \"one\") ((2) \"two\") (else \"else\")) " ).should == '"else"'
1496
+ @nendo.evalStr( " (case 100 ((1) \"one\") ((2) \"two\") (else \"else\")) " ).should == '"else"'
1497
+ @nendo.evalStr( " (case (car '(a b 1)) ((a) 'a) ((b) 'b) (else 'else)) " ).should == 'a'
1498
+ @nendo.evalStr( " (case (cadr '(a b 1)) ((a) 'a) ((b) 'b) (else 'else)) " ).should == 'b'
1499
+ @nendo.evalStr( " (case (caddr '(a b 1)) ((a b) 'a) ((1 2) 'number) (else 'else)) " ).should == 'number'
1500
+ @nendo.evalStr( " (case (cadddr '(a b 1 2)) ((a b) 'a) ((1 2) 'number) (else 'else)) " ).should == 'number'
1501
+ @nendo.evalStr( " (let* ((a 1) (b (+ a 2))) (cons a b)) " ).should == "(1 . 3)"
1502
+ @nendo.evalStr( " (let* ((a 10) (b (* a 2))) (cons a b)) " ).should == "(10 . 20)"
1503
+ @nendo.evalStr( " (let* ((a 10) (b (* a 2)) (c (* b 3))) (list a b c)) " ).should == "(10 20 60)"
1504
+ @nendo.evalStr( " (begin0 1 2 3) " ).should == "1"
1505
+ @nendo.evalStr( <<EOS
1506
+ (define a 2)
1507
+ (begin0 (set! a (* a 2))
1508
+ (set! a (* a 2))
1509
+ (set! a (* a 2)))
1510
+ EOS
1511
+ ).should == "4"
1512
+ @nendo.evalStr( " (begin0 100) " ).should == "100"
1513
+ @nendo.evalStr( " (begin0) " ).should == "#f"
1514
+ @nendo.evalStr( <<EOS
1515
+ (receive (a b)
1516
+ (begin0
1517
+ (values 1 2)
1518
+ (values 10 20)
1519
+ (values 100 200))
1520
+ (cons a b))
1521
+ EOS
1522
+ ).should == "(1 . 2)"
1523
+ @nendo.evalStr( " (macroexpand '(when #t (print \"1\") (print \"2\"))) " ).should == '(if #t (begin (print "1") (print "2")))'
1524
+ @nendo.evalStr( " (macroexpand '(unless #t (print \"1\") (print \"2\"))) " ).should == '(if (not #t) (begin (print "1") (print "2")))'
1525
+ @nendo.evalStr( " (macroexpand '(if-let1 a #t (print \"T\") (print \"F\"))) " ).should == '(%let ((a #t)) (if a (print "T") (print "F")))'
1526
+ @nendo.evalStr( " (let1 count 0 (when #t (set! count (+ count 1)) (set! count (+ count 1))) count) " ).should == "2"
1527
+ @nendo.evalStr( " (let1 count 0 (when #f (set! count (+ count 1)) (set! count (+ count 1))) count) " ).should == "0"
1528
+ @nendo.evalStr( " (let1 count 0 (unless #t (set! count (+ count 1)) (set! count (+ count 1))) count) " ).should == "0"
1529
+ @nendo.evalStr( " (let1 count 0 (unless #f (set! count (+ count 1)) (set! count (+ count 1))) count) " ).should == "2"
1530
+ @nendo.evalStr( " (if-let1 m (rxmatch #/([0-9]+)/ \"abc100abc\") (rxmatch-substring m 1)) " ).should == '"100"'
1531
+ @nendo.evalStr( " (macroexpand '#?.) " ).should == '"(string):1"'
1532
+ @nendo.evalStr( " (macroexpand '(begin 1 2 #?. 4 5)) " ).should == '(begin 1 2 "(string):1" 4 5)'
1533
+ end
1534
+ end
1535
+
1536
+ describe Nendo, "when use define and lambda macro " do
1537
+ before do
1538
+ @nendo = Nendo::Core.new()
1539
+ @nendo.loadInitFile
1540
+ end
1541
+ it "should" do
1542
+ @nendo.evalStr( <<EOS
1543
+ (macroexpand
1544
+ '(define (main argv)
1545
+ (newline)
1546
+ 0))
1547
+ EOS
1548
+ ).should == "(define main (lambda (argv) (newline) 0))"
1549
+ @nendo.evalStr( <<EOS
1550
+ (macroexpand
1551
+ '(define (main argv)
1552
+ (define (foo x) x)
1553
+ (+ 10 20)
1554
+ 0
1555
+ (foo 111)))
1556
+ EOS
1557
+ ).should == "(define main (lambda (argv) (letrec ((foo (lambda (x) x))) (+ 10 20) 0 (foo 111))))"
1558
+ @nendo.evalStr( <<EOS
1559
+ (macroexpand
1560
+ '(define (main argv)
1561
+ (define result '())
1562
+ (define (foo x) x)
1563
+ (define val 0)
1564
+ (define (bar x)
1565
+ (+ val 10))))
1566
+ EOS
1567
+ ).should == "(define main (lambda (argv) (letrec ((result (quote ())) (foo (lambda (x) x)) (val 0) (bar (lambda (x) (+ val 10)))))))"
1568
+ @nendo.evalStr( <<EOS
1569
+ (define (main . argv)
1570
+ (define (foo x) x)
1571
+ (+ 10 20)
1572
+ 0
1573
+ (foo 111))
1574
+ (main)
1575
+ EOS
1576
+ ).should == "111"
1577
+ @nendo.evalStr( <<EOS
1578
+ (define (main argv)
1579
+ (define (foo1 x) (+ 1 x))
1580
+ (define (foo2 x) (+ 2 x))
1581
+ (*
1582
+ (foo1 20)
1583
+ (foo2 30)))
1584
+ (main '())
1585
+ EOS
1586
+ ).should == "672"
1587
+ @nendo.evalStr( " (macroexpand '(define (main argv) 0)) " ).should == "(define main (lambda (argv) 0))"
1588
+ end
1589
+ end
1590
+
1591
+ describe Nendo, "when use macro macro " do
1592
+ before do
1593
+ @nendo = Nendo::Core.new()
1594
+ @nendo.loadInitFile
1595
+ end
1596
+ it "should" do
1597
+ @nendo.evalStr( <<EOS
1598
+ (define inc!-macro
1599
+ (macro (x)
1600
+ (+ x 1)))
1601
+ EOS
1602
+ ).should match( /Nendo::LispMacro/ )
1603
+ @nendo.evalStr( " (inc!-macro 10) " ).should == "11"
1604
+ @nendo.evalStr( <<EOS
1605
+ (define dec!-macro
1606
+ (macro (x)
1607
+ (define (dec! v)
1608
+ (- v 1))
1609
+ (dec! x)))
1610
+ EOS
1611
+ ).should match( /Nendo::LispMacro/ )
1612
+ @nendo.evalStr( " (dec!-macro 10) " ).should == "9"
1613
+ @nendo.evalStr( " (. (dec!-macro 10) class) " ).should == 'Fixnum'
1614
+ end
1615
+ end
1616
+
1617
+ describe Nendo, "when use macros expand some syntax. " do
1618
+ before do
1619
+ @nendo = Nendo::Core.new()
1620
+ @nendo.loadInitFile
1621
+ end
1622
+ it "should" do
1623
+ @nendo.evalStr( "" +
1624
+ " (let1 total 0" +
1625
+ " (let loop ((cnt 10))" +
1626
+ " (if (< 0 cnt)" +
1627
+ " (begin" +
1628
+ " (set! total (+ total cnt))" +
1629
+ " (loop (- cnt 1)))))" +
1630
+ " total)" +
1631
+ "" ).should == "55"
1632
+ @nendo.evalStr( "" +
1633
+ "(let label ((a 2)" +
1634
+ " (b 3))" +
1635
+ " (if (<= 9 (+ a b))" +
1636
+ " (* a b)" +
1637
+ " (label 4 5)))" +
1638
+ "" ).should == "20"
1639
+ @nendo.evalStr( "" +
1640
+ "(macroexpand '(let loop ((x 1)) "+
1641
+ " 1"+
1642
+ " 2"+
1643
+ " (loop 100)))" ).should == "(letrec ((loop (lambda (x) 1 2 (loop 100)))) (loop 1))"
1644
+ end
1645
+ end
1646
+
1647
+ describe Nendo, "when occur illegal syntax. " do
1648
+ before do
1649
+ @nendo = Nendo::Core.new()
1650
+ @nendo.loadInitFile
1651
+ end
1652
+ it "should" do
1653
+
1654
+ lambda { @nendo.evalStr( <<EOS
1655
+ (let abc 1 ;; let1 style form is illegal syntax for let form.
1656
+ (print abc))
1657
+ EOS
1658
+ ) }.should raise_error( SyntaxError, /^named let requires/ )
1659
+
1660
+ lambda { @nendo.evalStr( "(let 1)" ) }.should raise_error( SyntaxError, /^let requires/ )
1661
+ lambda { @nendo.evalStr( "(let ())" ) }.should raise_error( SyntaxError, /^let requires/ )
1662
+ @nendo.evalStr( "(let () 1)" ).should == '1'
1663
+ lambda { @nendo.evalStr( "(let loop 1)" ) }.should raise_error( SyntaxError, /^named let requires/ )
1664
+ lambda { @nendo.evalStr( "(let loop ())" ) }.should raise_error( SyntaxError, /^named let requires/ )
1665
+ @nendo.evalStr( "(let loop () 1)" ).should == '1'
1666
+
1667
+ lambda { @nendo.evalStr( "(let1)" ) }.should raise_error( SyntaxError, /^let1 requires/ )
1668
+ lambda { @nendo.evalStr( "(let1 a)" ) }.should raise_error( SyntaxError, /^let1 requires/ )
1669
+ lambda { @nendo.evalStr( "(let1 a 1)" ) }.should raise_error( SyntaxError, /^let1 requires/ )
1670
+ lambda { @nendo.evalStr( "(let1 (a 1) (print a))" ) }.should raise_error( SyntaxError, /^let1 requires/ )
1671
+ lambda { @nendo.evalStr( "(let1 ((a 1)) (print a))" ) }.should raise_error( SyntaxError, /^let1 requires/ )
1672
+ @nendo.evalStr( "(let1 a 123 a)" ).should == '123'
1673
+ @nendo.evalStr( "(let1 b (+ 100 20 3) b)" ).should == '123'
1674
+ end
1675
+ end
1676
+
1677
+
1678
+ describe Nendo, "when use dot-operator (.) macro " do
1679
+ before do
1680
+ @nendo = Nendo::Core.new()
1681
+ @nendo.setDisplayErrors( false )
1682
+ @nendo.loadInitFile
1683
+ end
1684
+ it "should" do
1685
+ @nendo.evalStr( " (macroexpand '(. a b)) " ).should == "(a.b)"
1686
+ @nendo.evalStr( " (macroexpand '(. a b c)) " ).should == "(a.b c)"
1687
+ @nendo.evalStr( " (macroexpand '(. Kernel open)) " ).should == "(Kernel.open)"
1688
+ lambda { @nendo.evalStr( " (macroexpand '(. open)) " ) }.should raise_error( ArgumentError )
1689
+ lambda { @nendo.evalStr( " (macroexpand '(. open \"aaa\")) " ) }.should raise_error( TypeError )
1690
+ @nendo.evalStr( " (macroexpand '(. a size)) " ).should == "(a.size)"
1691
+ @nendo.evalStr( " (macroexpand '(. (. a size) to_s)) " ).gsub( /_[0-9][0-9][0-9][0-9][0-9]/, "_X0000" ).should == "(%let ((__gensym__fb4e25e49e9fb4e46342224606faf2e3eabf1251_X0000 (a.size))) (__gensym__fb4e25e49e9fb4e46342224606faf2e3eabf1251_X0000.to_s))"
1692
+ @nendo.evalStr( " (macroexpand '(. (. (. a size) to_s) to_i)) " ).gsub( /_[0-9][0-9][0-9][0-9][0-9]/, "_X0000" ).should == "(%let ((__gensym__fb4e25e49e9fb4e46342224606faf2e3eabf1251_X0000 (%let ((__gensym__fb4e25e49e9fb4e46342224606faf2e3eabf1251_X0000 (a.size))) (__gensym__fb4e25e49e9fb4e46342224606faf2e3eabf1251_X0000.to_s)))) (__gensym__fb4e25e49e9fb4e46342224606faf2e3eabf1251_X0000.to_i))"
1693
+ lambda { @nendo.evalStr( " (macroexpand '(. (. a size))) " ) }.should raise_error( ArgumentError )
1694
+ @nendo.evalStr( " (set! str \"str\") str.size " ).should == "3"
1695
+ @nendo.evalStr( " (set! str \"str\") (. str size) " ).should == "3"
1696
+ @nendo.evalStr( " (set! str \"str\") (+ 1 (. str size)) " ).should == "4"
1697
+ @nendo.evalStr( " (set! str \"string\") (. (. str size) to_s) " ).should == '"6"'
1698
+ @nendo.evalStr( " (to-s str.size) " ).should == '"6"'
1699
+ @nendo.evalStr( " (to-s 'str.size) " ).should == '"str.size"'
1700
+ @nendo.evalStr( " (require \"date\") " ).should == "#f"
1701
+ @nendo.evalStr( " (. (Date.new 0) strftime \"%F %r\") " ).should == '"0000-01-01 12:00:00 AM"'
1702
+ @nendo.evalStr( " (require \"digest/md5\") " ).should == "#f"
1703
+ @nendo.evalStr( " (Digest::MD5.hexdigest \"abc\") " ).should == '"900150983cd24fb0d6963f7d28e17f72"'
1704
+ @nendo.evalStr( " (Digest::MD5.hexdigest \"source text\") " ).should == '"20f79a1416626eeacc0bd9a8db87faa2"'
1705
+ @nendo.evalStr( " (define a 1) (a.is_a? Fixnum) " ).should == "#t"
1706
+ @nendo.evalStr( " (define a 1) (a.is_a? Float) " ).should == "#f"
1707
+ @nendo.evalStr( " (define a 1) (a.is_a? String) " ).should == "#f"
1708
+ @nendo.evalStr( " (define a 1.1) (a.is_a? Fixnum) " ).should == "#f"
1709
+ @nendo.evalStr( " (define a 1.1) (a.is_a? Float) " ).should == "#t"
1710
+ @nendo.evalStr( " (define a 1.1) (a.is_a? String) " ).should == "#f"
1711
+ @nendo.evalStr( " (define a \"s\") (a.is_a? Fixnum) " ).should == "#f"
1712
+ @nendo.evalStr( " (define a \"s\") (a.is_a? Float) " ).should == "#f"
1713
+ @nendo.evalStr( " (define a \"s\") (a.is_a? String) " ).should == "#t"
1714
+ @nendo.evalStr( ' (equal? (read-from-string "\"100\"") (. 100 to_s)) ' ).should == "#t"
1715
+ end
1716
+ end
1717
+
1718
+ describe Nendo, "when use dot-operator (.) macro and (&block ...) " do
1719
+ before do
1720
+ @nendo = Nendo::Core.new()
1721
+ @nendo.loadInitFile
1722
+ end
1723
+ it "should" do
1724
+ @nendo.evalStr( " (define arr '#(10 50 40 10000 20 30))" ).should == "#(10 50 40 10000 20 30)"
1725
+ @nendo.evalStr( " (arr.sort)" ).should == "#(10 20 30 40 50 10000)"
1726
+ @nendo.evalStr( " (arr.sort (&block (a b) (if (le? a b) 1 -1))) " ).should == "#(10000 50 40 30 20 10)"
1727
+ @nendo.evalStr( " (arr.sort_by (&block (item) item.to_s)) " ).should == "#(10 10000 20 30 40 50)"
1728
+ end
1729
+ end
1730
+
1731
+ describe Nendo, "when use sort libraries " do
1732
+ before do
1733
+ @nendo = Nendo::Core.new()
1734
+ @nendo.loadInitFile
1735
+ end
1736
+ it "should" do
1737
+ @nendo.evalStr( " (define lst '(1 50 60 30000 4000 200)) " ).should == "(1 50 60 30000 4000 200)"
1738
+ @nendo.evalStr( " (sort lst) " ).should == "(1 50 60 200 4000 30000)"
1739
+ @nendo.evalStr( " (sort '()) " ).should == "()"
1740
+ @nendo.evalStr( " (sort lst (lambda (a b) (- b a))) " ).should == "(30000 4000 200 60 50 1)"
1741
+ @nendo.evalStr( " (sort-by lst (lambda (item) item)) " ).should == "(1 50 60 200 4000 30000)"
1742
+ @nendo.evalStr( " (sort-by '() (lambda (item) item)) " ).should == "()"
1743
+ @nendo.evalStr( " (define lst2 '((1 . \"ddd\") (2 . \"cc\") (3 . \"bbbb\") (4 . \"a\"))) " ).should == '((1 . "ddd") (2 . "cc") (3 . "bbbb") (4 . "a"))'
1744
+ @nendo.evalStr( " (sort lst2 (lambda (a b) (- (car a) (car b)))) " ).should == '((1 . "ddd") (2 . "cc") (3 . "bbbb") (4 . "a"))'
1745
+ @nendo.evalStr( " (sort lst2 (lambda (a b) (if (>= (cdr a) (cdr b)) 1 -1))) " ).should == '((4 . "a") (3 . "bbbb") (2 . "cc") (1 . "ddd"))'
1746
+ @nendo.evalStr( " (sort-by lst2 (lambda (item) (car item))) " ).should == '((1 . "ddd") (2 . "cc") (3 . "bbbb") (4 . "a"))'
1747
+ @nendo.evalStr( " (sort-by lst2 (lambda (item) (cdr item))) " ).should == '((4 . "a") (3 . "bbbb") (2 . "cc") (1 . "ddd"))'
1748
+ @nendo.evalStr( " (sort-by lst2 (lambda (item) (. (cdr item) size))) " ).should == '((4 . "a") (2 . "cc") (1 . "ddd") (3 . "bbbb"))'
1749
+ end
1750
+ end
1751
+
1752
+ describe Nendo, "when use with-open libraries " do
1753
+ before do
1754
+ @nendo = Nendo::Core.new()
1755
+ @nendo.setDisplayErrors( false )
1756
+ @nendo.loadInitFile
1757
+ @fn = "/tmp/for-with-open.dat"
1758
+ open( @fn, "w" ) { |f|
1759
+ f.puts( "line1" )
1760
+ f.puts( "line2" )
1761
+ f.puts( "line3" )
1762
+ }
1763
+ end
1764
+ it "should" do
1765
+ @nendo.evalStr( sprintf( " (with-open \"%s\" (lambda (f) (f.readline.chop))) ", @fn )).should == '"line1"'
1766
+ @nendo.evalStr( sprintf( " (with-open \"%s\" (lambda (f) (f.readline.chop))) ", @fn )).should == '"line1"'
1767
+ @nendo.evalStr( sprintf( " (with-open \"%s\" (lambda (f) (f.readline.chop) (f.readline.chop))) ", @fn )).should == '"line2"'
1768
+ @nendo.evalStr( sprintf( " (with-open \"%s\" (lambda (f) (map (lambda (line) (line.chop)) f))) ", @fn )).should == '#("line1" "line2" "line3")'
1769
+ @nendo.evalStr( sprintf( " (with-open \"%s\" (lambda (f) (f.puts \"Wrote from Nendo.\")) \"w\") #t", @fn )).should == "#t"
1770
+ @nendo.evalStr( sprintf( " (with-open \"%s\" (lambda (f) (f.readline.chop))) ", @fn )).should == '"Wrote from Nendo."'
1771
+ lambda { @nendo.evalStr( sprintf( " (with-open \"%s\" (lambda (f) #t) 1 2 ", @fn )) }.should raise_error(RuntimeError)
1772
+ lambda { @nendo.evalStr( sprintf( " (with-open \"%s\" \"string\" 1 2 ", @fn )) }.should raise_error(RuntimeError)
1773
+ end
1774
+
1775
+ after do
1776
+ File.unlink( @fn )
1777
+ end
1778
+ end
1779
+
1780
+ describe Nendo, "when use (use ...) macro " do
1781
+ before do
1782
+ @nendo = Nendo::Core.new()
1783
+ @nendo.setDisplayErrors( false )
1784
+ @nendo.loadInitFile
1785
+ end
1786
+ it "should" do
1787
+ @nendo.evalStr( " (macroexpand '(use abc)) " ).should == '(load "abc")'
1788
+ @nendo.evalStr( " (macroexpand '(use a.b)) " ).should == '(load "a/b")'
1789
+ @nendo.evalStr( " (macroexpand '(use a.b.c)) " ).should == '(load "a/b/c")'
1790
+ @nendo.evalStr( " (macroexpand '(use a.b.c.d.e.f.g)) " ).should == '(load "a/b/c/d/e/f/g")'
1791
+ @nendo.evalStr( " (macroexpand '(use srfi-1)) " ).should == '(load "srfi-1")'
1792
+ @nendo.evalStr( " (macroexpand '(use text.tree)) " ).should == '(load "text/tree")'
1793
+ @nendo.evalStr( " (macroexpand '(use debug.syslog)) " ).should == '(load "debug/syslog")'
1794
+ @nendo.evalStr( " (macroexpand `(use ,(string->symbol (+ \"text\" \".\" \"tree\")))) " ).should == '(load "text/tree")'
1795
+ lambda { @nendo.evalStr( " (macroexpand '(use '(a)) " ) }.should raise_error( RuntimeError )
1796
+ lambda { @nendo.evalStr( " (macroexpand '(use \"srfi-1\") " ) }.should raise_error( RuntimeError )
1797
+ lambda { @nendo.evalStr( " (macroexpand '(use 1)) " ) }.should raise_error( RuntimeError )
1798
+ lambda { @nendo.evalStr( " (macroexpand '(use (+ 10 20))) " ) }.should raise_error( RuntimeError )
1799
+ end
1800
+ end
1801
+
1802
+ describe Nendo, "when use keyword feature " do
1803
+ before do
1804
+ @nendo = Nendo::Core.new()
1805
+ @nendo.setDisplayErrors( false )
1806
+ @nendo.loadInitFile
1807
+ end
1808
+ it "should" do
1809
+ @nendo.evalStr( " (keyword? :a) " ).should == "#t"
1810
+ @nendo.evalStr( ' (keyword? (intern ":a")) ' ).should == "#f"
1811
+ @nendo.evalStr( ' (symbol? (intern ":a")) ' ).should == "#t"
1812
+ @nendo.evalStr( " (keyword? ':a) " ).should == "#t"
1813
+ @nendo.evalStr( " (symbol? ':a) " ).should == "#f"
1814
+ @nendo.evalStr( " (eq? :a :a) " ).should == "#t"
1815
+ @nendo.evalStr( " (eqv? :a :a) " ).should == "#t"
1816
+ @nendo.evalStr( ' (eq? :a (intern ":a")) ' ).should == "#f"
1817
+ @nendo.evalStr( ' (eqv? :a (intern ":a")) ' ).should == "#f"
1818
+ @nendo.evalStr( ' (keyword? (make-keyword "a")) ' ).should == "#t"
1819
+ @nendo.evalStr( " :a " ).should == ":a"
1820
+ @nendo.evalStr( " ::a " ).should == "::a"
1821
+ @nendo.evalStr( " :::key " ).should == ":::key"
1822
+ @nendo.evalStr( ' (make-keyword "a") ' ).should == ":a"
1823
+ @nendo.evalStr( ' (make-keyword ":a") ' ).should == "::a"
1824
+ @nendo.evalStr( " (make-keyword 'a) " ).should == ":a"
1825
+ @nendo.evalStr( " (keyword->string :a) " ).should == '"a"'
1826
+ @nendo.evalStr( " (keyword->string :abcde) " ).should == '"abcde"'
1827
+ lambda { @nendo.evalStr( " (keyword->string 'a) " ) }.should raise_error( TypeError )
1828
+ @nendo.evalStr( " : " ).should == ':'
1829
+ @nendo.evalStr( " (keyword->string :) " ).should == '""'
1830
+ @nendo.evalStr( ' (make-keyword "") ' ).should == ":"
1831
+ @nendo.evalStr( " (get-keyword :y '(:x 1 :y 2 :z 3)) " ).should == "2"
1832
+ @nendo.evalStr( " (get-keyword 'z '(x 1 y 2 z 3)) " ).should == "3"
1833
+ lambda { @nendo.evalStr( " (get-keyword 'z '(x 1 y 2 z)) " ) }.should raise_error( RuntimeError )
1834
+ lambda { @nendo.evalStr( " (get-keyword :t '(:x 1 :y 2 :z 3)) " ) }.should raise_error( RuntimeError )
1835
+ @nendo.evalStr( " (get-keyword :t '() #f) " ).should == "#f"
1836
+ @nendo.evalStr( " (get-keyword :t '(:x) #f) " ).should == "#f"
1837
+ lambda { @nendo.evalStr( " (get-keyword :t '()) " ) }.should raise_error( RuntimeError )
1838
+ lambda { @nendo.evalStr( " (get-keyword :t '(:x)) " ) }.should raise_error( RuntimeError )
1839
+ lambda { @nendo.evalStr( " (get-keyword :t 1) " ) }.should raise_error( RuntimeError )
1840
+ @nendo.evalStr( " (get-keyword :t 1 #f) " ).should == "#f"
1841
+ end
1842
+ end
1843
+
1844
+ describe Nendo, "when use hash-table feature " do
1845
+ before do
1846
+ @nendo = Nendo::Core.new()
1847
+ @nendo.setDisplayErrors( false )
1848
+ @nendo.loadInitFile
1849
+ end
1850
+ it "should" do
1851
+ @nendo.evalStr( " (define h (make-hash-table)) " ).should == "{}"
1852
+ @nendo.evalStr( " (hash-table? 1) " ).should == "#f"
1853
+ @nendo.evalStr( " (hash-table? '(1)) " ).should == "#f"
1854
+ @nendo.evalStr( " (hash-table? (Array.new)) " ).should == "#f"
1855
+ @nendo.evalStr( " (hash-table? (Hash.new)) " ).should == "#t"
1856
+ @nendo.evalStr( " h " ).should == "{}"
1857
+ @nendo.evalStr( " (hash-table-put! h 'k1 'v1) h" ).should == "{:k1=>:v1}"
1858
+ @nendo.evalStr( " (hash-table-put! h 'k2 200) h" ).should == "{:k1=>:v1, :k2=>200}"
1859
+ @nendo.evalStr( " (hash-table-get h 'k1)" ).should == "v1"
1860
+ @nendo.evalStr( " (hash-table-get h 'k2)" ).should == "200"
1861
+ @nendo.evalStr( " (hash-table-exist? h 'k1)" ).should == "#t"
1862
+ @nendo.evalStr( " (hash-table-exist? h 'k2)" ).should == "#t"
1863
+ @nendo.evalStr( " (hash-table-exist? h 'k3)" ).should == "#f"
1864
+ @nendo.evalStr( " (hash-table-exist? h \"k1\")" ).should == "#f"
1865
+ @nendo.evalStr( " (hash-table-num-entries h)" ).should == "2"
1866
+ @nendo.evalStr( " (hash-table-delete! h 'k1)" ).should == "v1"
1867
+ lambda { @nendo.evalStr( " (hash-table-get h 'k1)" ) }.should raise_error( RuntimeError )
1868
+ @nendo.evalStr( " (hash-table-get h 'k1 #f) " ).should == "#f"
1869
+ @nendo.evalStr( " (hash-table-num-entries h)" ).should == "1"
1870
+ @nendo.evalStr( " (hash-table-clear! h)" ).should == "{}"
1871
+ @nendo.evalStr( " (hash-table-num-entries h)" ).should == "0"
1872
+ @nendo.evalStr( <<EOS
1873
+ (set! h (hash-table eq?
1874
+ '("a" "AAA")
1875
+ '("b" "BBB")
1876
+ '("c" "CCC" 100)))
1877
+ (hash-table-keys h)
1878
+ EOS
1879
+ ).should == "(\"a\" \"b\" \"c\")"
1880
+ @nendo.evalStr( <<EOS
1881
+ (set! h (hash-table eq?
1882
+ '("a" "AAA")
1883
+ '("b" "BBB")
1884
+ '("c" "CCC" 100)))
1885
+ (hash-table-values h)
1886
+ EOS
1887
+ ).should == "((\"AAA\") (\"BBB\") (\"CCC\" 100))"
1888
+ @nendo.evalStr( <<EOS
1889
+ (set! h (hash-table eq?
1890
+ '("a" . "AAA")
1891
+ '("b" . "BBB")
1892
+ '("c" . "CCC")))
1893
+ h
1894
+ EOS
1895
+ ).should == "{\"a\"=>\"AAA\", \"b\"=>\"BBB\", \"c\"=>\"CCC\"}"
1896
+ @nendo.evalStr( " (hash-table-keys h)" ).should == '("a" "b" "c")'
1897
+ @nendo.evalStr( " (hash-table-values h)" ).should == '("AAA" "BBB" "CCC")'
1898
+ @nendo.evalStr( " (hash-table-map h (lambda (a b) (+ a b)))" ).should == '("aAAA" "bBBB" "cCCC")'
1899
+ @nendo.evalStr( " (hash-table-for-each h (lambda (a b) (+ a b)))" ).should == '("aAAA" "bBBB" "cCCC")'
1900
+ @nendo.evalStr( " (set! h (make-hash-table)) " ).should == "{}"
1901
+ @nendo.evalStr( <<EOS
1902
+ (set! h (hash-table eq?
1903
+ '(true . 1)
1904
+ '(false . 2)
1905
+ '(nil . 3)))
1906
+ h
1907
+ EOS
1908
+ ).should == "{true=>1, false=>2, nil=>3}"
1909
+ @nendo.evalStr( " (hash-table-keys h) " ).should == "(#t #f nil)"
1910
+ @nendo.evalStr( <<EOS
1911
+ (set! h (hash-table eq?
1912
+ '(1 . true)
1913
+ '(2 . false)
1914
+ '(3 . nil)))
1915
+ h
1916
+ EOS
1917
+ ).should == "{1=>true, 2=>false, 3=>nil}"
1918
+ @nendo.evalStr( " (hash-table-keys h) " ).should == "(1 2 3)"
1919
+ end
1920
+ end
1921
+
1922
+ describe Nendo, "when use vector feature " do
1923
+ before do
1924
+ @nendo = Nendo::Core.new()
1925
+ @nendo.setDisplayErrors( false )
1926
+ @nendo.loadInitFile
1927
+ end
1928
+ it "should" do
1929
+ @nendo.evalStr( " (define v (vector)) v" ).should == "#()"
1930
+ @nendo.evalStr( " (vector? 1) " ).should == "#f"
1931
+ @nendo.evalStr( " (vector? (vector)) " ).should == "#t"
1932
+ @nendo.evalStr( " (vector? (vector 1)) " ).should == "#t"
1933
+ @nendo.evalStr( " (vector? (vector 1 2)) " ).should == "#t"
1934
+ @nendo.evalStr( " (vector? '#(1)) " ).should == "#t"
1935
+ @nendo.evalStr( " (vector? '#(1 2)) " ).should == "#t"
1936
+ @nendo.evalStr( " (vector? (Array.new)) " ).should == "#t"
1937
+ @nendo.evalStr( " (vector? (Hash.new)) " ).should == "#f"
1938
+ @nendo.evalStr( " (vector? 1.1) " ).should == "#f"
1939
+ @nendo.evalStr( " (vector? \"str\") " ).should == "#f"
1940
+ @nendo.evalStr( " (define v (make-vector 4))" ).should == "#(nil nil nil nil)"
1941
+ @nendo.evalStr( " (vector-set! v 0 'v1) v" ).should == "#(v1 nil nil nil)"
1942
+ @nendo.evalStr( " (vector-set! v 1 '100) v" ).should == "#(v1 100 nil nil)"
1943
+ @nendo.evalStr( " (vector-set! v 2 '200) v" ).should == "#(v1 100 200 nil)"
1944
+ @nendo.evalStr( " (vector-set! v 3 '(a b c)) v" ).should == "#(v1 100 200 (a b c))"
1945
+ @nendo.evalStr( " (vector-length v)" ).should == "4"
1946
+ @nendo.evalStr( " (vector-ref v 0) " ).should == "v1"
1947
+ @nendo.evalStr( " (vector-ref v 1) " ).should == "100"
1948
+ @nendo.evalStr( " (vector-ref v 2) " ).should == "200"
1949
+ @nendo.evalStr( " (vector-ref v 3) " ).should == "(a b c)"
1950
+ lambda { @nendo.evalStr( " (vector-ref v -1)" ) }.should raise_error( RuntimeError )
1951
+ lambda { @nendo.evalStr( " (vector-ref v -2)" ) }.should raise_error( RuntimeError )
1952
+ lambda { @nendo.evalStr( " (vector-ref v 5)" ) }.should raise_error( RuntimeError )
1953
+ lambda { @nendo.evalStr( " (vector-ref v 6)" ) }.should raise_error( RuntimeError )
1954
+ @nendo.evalStr( " (vector-ref v -1 1000)" ).should == "1000"
1955
+ @nendo.evalStr( " (vector-ref v -2 2000)" ).should == "2000"
1956
+ @nendo.evalStr( " (vector-ref v 5 3000)" ).should == "3000"
1957
+ @nendo.evalStr( " (vector-ref v 6 4000)" ).should == "4000"
1958
+ @nendo.evalStr( " (vector-ref v 7 #f)" ).should == "#f"
1959
+ @nendo.evalStr( " (define v (make-vector 10)) v" ).should == "#(nil nil nil nil nil nil nil nil nil nil)"
1960
+ @nendo.evalStr( " (vector->list v)" ).should == "(nil nil nil nil nil nil nil nil nil nil)"
1961
+ @nendo.evalStr( " (define lst '(a b c (d)))" ).should == "(a b c (d))"
1962
+ @nendo.evalStr( " (list->vector lst)" ).should == "#(a b c (d))"
1963
+ @nendo.evalStr( " (list->vector (range 10 1))" ).should == "#(1 2 3 4 5 6 7 8 9 10)"
1964
+ end
1965
+ end
1966
+
1967
+ describe Nendo, "tail call optimization " do
1968
+ before do
1969
+ @nendo = Nendo::Core.new( )
1970
+ @nendo.setDisplayErrors( false )
1971
+ @nendo.loadInitFile
1972
+ @nendo.loadInitFile # to self optimizing. The init.nnd file will be loaded twice, so `filter' can be optimized on second loading phase.
1973
+ end
1974
+ it "should" do
1975
+ @nendo.evalStr( " (%setup-%tailcall-mark '(print \"abc\")) " ).should == "(%tailcall (print \"abc\"))"
1976
+ @nendo.evalStr( " (%setup-%tailcall-mark '(begin (print \"abc\") 1 2 3)) " ).should == "(begin (print \"abc\") 1 2 3)"
1977
+ @nendo.evalStr( " (%setup-%tailcall-mark '(begin 1 2 (print \"abc\") 3)) " ).should == "(begin 1 2 (print \"abc\") 3)"
1978
+ @nendo.evalStr( " (%setup-%tailcall-mark '(begin 1 2 3 (print \"abc\"))) " ).should == "(begin 1 2 3 (%tailcall (print \"abc\")))"
1979
+ @nendo.evalStr( " (%setup-%tailcall-mark '(lambda (x) x)) " ).should == "(lambda (x) x)"
1980
+ @nendo.evalStr( " (%setup-%tailcall-mark '(macro (x) x)) " ).should == "(macro (x) x)"
1981
+ @nendo.evalStr( " (%setup-%tailcall-mark '(%syntax (x) x)) " ).should == "(%syntax (x) x)"
1982
+ @nendo.evalStr( " (%setup-%tailcall-mark '(%syntax (a b c) (begin a b c))) " ).should == "(%syntax (a b c) (begin a b c))"
1983
+ @nendo.evalStr( " (%setup-%tailcall-mark '(lambda (x) (%syntax (y) x))) " ).should == "(lambda (x) (%syntax (y) x))"
1984
+ @nendo.evalStr( " (%setup-%tailcall-mark '(lambda (x) (syntax-quote x))) " ).should == "(lambda (x) (quote x))"
1985
+ @nendo.evalStr( " (%setup-%tailcall-mark '(lambda (x) (quote x))) " ).should == "(lambda (x) (quote x))"
1986
+ @nendo.evalStr( <<EOS
1987
+ (%setup-%tailcall-mark
1988
+ '(lambda '(x)
1989
+ 1
1990
+ 2
1991
+ (print \"abc\")))
1992
+ EOS
1993
+ ).should == "(lambda (quote (x)) 1 2 (%tailcall (print \"abc\")))"
1994
+ @nendo.evalStr( <<EOS
1995
+ (%setup-%tailcall-mark
1996
+ '(lambda (x)
1997
+ 1
1998
+ 2
1999
+ (if #t
2000
+ (begin 1 2 (print "abc"))
2001
+ (begin 1 2 (print "ABC")))))
2002
+ EOS
2003
+ ).should == "(lambda (x) 1 2 (if #t (begin 1 2 (%tailcall (print \"abc\"))) (begin 1 2 (%tailcall (print \"ABC\")))))"
2004
+ @nendo.evalStr( <<EOS
2005
+ (%setup-%tailcall-mark (macroexpand
2006
+ '(define (foo) (foo))
2007
+ ))
2008
+ EOS
2009
+ ).should == "(define foo (lambda () (%tailcall (foo))))"
2010
+ @nendo.evalStr( <<EOS
2011
+ (%setup-%tailcall-mark (macroexpand
2012
+ '(values? (make-values '()))
2013
+ ))
2014
+ EOS
2015
+ ).should == "(%tailcall (values? (make-values (quote ()))))"
2016
+ @nendo.evalStr( <<EOS
2017
+ (%setup-%tailcall-mark (macroexpand
2018
+ '(cond
2019
+ (false 1)
2020
+ (false 2))
2021
+ ))
2022
+ EOS
2023
+ ).should == "(if #f (begin 1) (if #f (begin 2) ()))"
2024
+ @nendo.evalStr( <<EOS
2025
+ (%setup-%tailcall-mark (macroexpand
2026
+ '(cond
2027
+ (false 1)
2028
+ (false 2)
2029
+ (else 3))
2030
+ ))
2031
+ EOS
2032
+ ).should == "(if #f (begin 1) (if #f (begin 2) (if #t (begin 3) ())))"
2033
+ @nendo.evalStr( <<EOS
2034
+ (%setup-%tailcall-mark (macroexpand
2035
+ '(and
2036
+ (foo 1)
2037
+ (bar 2))
2038
+ ))
2039
+ EOS
2040
+ ).should == "(if (not (eq? #f (foo 1))) (%tailcall (bar 2)) #f)"
2041
+ @nendo.evalStr( <<EOS
2042
+ (%setup-%tailcall-mark (macroexpand
2043
+ '(or
2044
+ (foo 1)
2045
+ (bar 2))
2046
+ ))
2047
+ EOS
2048
+ ).gsub( /_[0-9][0-9][0-9][0-9][0-9][ ]/, "_X0000 " ).should == "(%let ((__gensym__fb4e25e49e9fb4e46342224606faf2e3eabf1251_X0000 (foo 1))) (if __gensym__fb4e25e49e9fb4e46342224606faf2e3eabf1251_X0000 __gensym__fb4e25e49e9fb4e46342224606faf2e3eabf1251_X0000 (%let ((__gensym__fb4e25e49e9fb4e46342224606faf2e3eabf1251_X0000 (bar 2))) (if __gensym__fb4e25e49e9fb4e46342224606faf2e3eabf1251_X0000 __gensym__fb4e25e49e9fb4e46342224606faf2e3eabf1251_X0000 #f))))"
2049
+ @nendo.evalStr( <<EOS
2050
+ (%setup-%tailcall-mark (macroexpand
2051
+ '(let loop ((x 1))
2052
+ 1
2053
+ 2
2054
+ (loop 100))
2055
+ ))
2056
+ EOS
2057
+ ).should == "(letrec ((loop (lambda (x) 1 2 (%tailcall (loop 100))))) (%tailcall (loop 1)))"
2058
+ @nendo.evalStr( "(%setup-%tailcall-mark (macroexpand "+
2059
+ " '(let1 aaa 111 aaa)"+
2060
+ " ))" ).should == "(%let ((aaa 111)) aaa)"
2061
+ @nendo.evalStr( <<EOS
2062
+ (%setup-%tailcall-mark
2063
+ '(letrec ((func1
2064
+ (lambda (x)
2065
+ 1
2066
+ (func2)))
2067
+ (func2
2068
+ (lambda (x)
2069
+ 2
2070
+ (func1))))
2071
+ (func1 100)))
2072
+ EOS
2073
+ ).should == "(letrec ((func1 (lambda (x) 1 (%tailcall (func2)))) (func2 (lambda (x) 2 (%tailcall (func1))))) (%tailcall (func1 100)))"
2074
+ @nendo.evalStr( "(set-optimize-level 0) " ).should == "0"
2075
+ lambda { @nendo.evalStr( <<EOS
2076
+ (filter
2077
+ (lambda (x) (< x 10))
2078
+ (range 10000))
2079
+ EOS
2080
+ ) }.should raise_error(SystemStackError)
2081
+ @nendo.evalStr( "(set-optimize-level 1) " ).should == "1"
2082
+ @nendo.evalStr( <<EOS
2083
+ (apply +
2084
+ (map
2085
+ (lambda (x) (* x 2))
2086
+ (range 10000)))
2087
+ EOS
2088
+ ).should == "99990000"
2089
+ @nendo.evalStr( <<EOS
2090
+ (filter
2091
+ (lambda (x) (< x 10))
2092
+ (range 1000))
2093
+ EOS
2094
+ ).should == "(0 1 2 3 4 5 6 7 8 9)"
2095
+ @nendo.evalStr( <<EOS
2096
+ (filter-map
2097
+ (lambda (x)
2098
+ (when (< x 10) (- x)))
2099
+ (range 1000))
2100
+ EOS
2101
+ ).should == "(0 -1 -2 -3 -4 -5 -6 -7 -8 -9)"
2102
+ @nendo.evalStr( <<EOS
2103
+ (define str
2104
+ (if #t
2105
+ (car '("a"))
2106
+ (car '("b"))))
2107
+ (sprintf "A%sZ" str)
2108
+ EOS
2109
+ ).should == '"AaZ"'
2110
+ @nendo.evalStr( <<EOS
2111
+ (letrec ((str (if #t
2112
+ (+ "a" "A")
2113
+ '())))
2114
+ str.class)
2115
+ EOS
2116
+ ).should == 'String'
2117
+ @nendo.evalStr( <<EOS
2118
+ (letrec ((str
2119
+ (if #t
2120
+ (+ \"a\" \"A\")
2121
+ '())))
2122
+ (+ str \"...\"))
2123
+ EOS
2124
+ ).should == '"aA..."'
2125
+ end
2126
+ end
2127
+
2128
+