nendo 0.6.6 → 0.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+