nendo 0.6.8 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
data/test/syntax_spec.rb DELETED
@@ -1,1059 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # -*- encoding: utf-8 -*-
3
- #
4
- # syntax_spec.rb - "RSpec file for nendo language (syntax part)"
5
- #
6
- # Copyright (c) 2009-2010 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
- describe Nendo, "when read the core syntax keyword " do
40
- before do
41
- @nendo = Nendo::Core.new()
42
- end
43
- it "should" do
44
- @nendo.evalStr( "(define a 1)" ).should == '1'
45
- @nendo.evalStr( "(define a if)" ).should match( /Nendo::LispCoreSyntax/ )
46
- @nendo.evalStr( "(eq? a if)" ).should == '#t'
47
- @nendo.evalStr( "(define a begin)" ).should match( /Nendo::LispCoreSyntax/ )
48
- @nendo.evalStr( "(eq? a begin)" ).should == '#t'
49
- @nendo.evalStr( "(define a lambda)" ).should match( /Nendo::LispCoreSyntax/ )
50
- @nendo.evalStr( "(eq? a lambda)" ).should == '#t'
51
- @nendo.evalStr( "(define a macro)" ).should match( /Nendo::LispCoreSyntax/ )
52
- @nendo.evalStr( "(eq? a macro)" ).should == '#t'
53
- @nendo.evalStr( "(define a &block)" ).should match( /Nendo::LispCoreSyntax/ )
54
- @nendo.evalStr( "(eq? a &block)" ).should == '#t'
55
- @nendo.evalStr( "(define a %let)" ).should match( /Nendo::LispCoreSyntax/ )
56
- @nendo.evalStr( "(eq? a %let)" ).should == '#t'
57
- @nendo.evalStr( "(define a letrec)" ).should match( /Nendo::LispCoreSyntax/ )
58
- @nendo.evalStr( "(eq? a letrec)" ).should == '#t'
59
- @nendo.evalStr( "(define a set!)" ).should match( /Nendo::LispCoreSyntax/ )
60
- @nendo.evalStr( "(eq? a set!)" ).should == '#t'
61
- end
62
- end
63
-
64
-
65
- describe Nendo, "when use lib functions for let-syntax " do
66
- before do
67
- @nendo = Nendo::Core.new()
68
- end
69
- it "should" do
70
- @nendo.evaluator.write_to_string(
71
- @nendo.evaluator.__wrapNestedLet( 1000,
72
- [[ :a, Cell.new( 2 ) ]]
73
- )).should == "(%let ((a 2)) 1000)"
74
- @nendo.evaluator.write_to_string(
75
- @nendo.evaluator.__wrapNestedLet( 1000,
76
- [[ :a, Cell.new( 2 ) ], [ :b, Cell.new( 3 ) ]]
77
- )).should == "(%let ((a 2)) (%let ((b 3)) 1000))"
78
- @nendo.evaluator.write_to_string(
79
- @nendo.evaluator.__wrapNestedLet( Cell.new( :"+", Cell.new( :a, Cell.new( :b ))),
80
- [[ :a, Cell.new( 2 ) ], [ :b, Cell.new( 3 ) ]]
81
- )).should == "(%let ((a 2)) (%let ((b 3)) (+ a b)))"
82
-
83
- @nendo.evalStr( "(strip-syntax-quote 'abc)" ).should == "abc"
84
- @nendo.evalStr( "(strip-syntax-quote '())" ).should == "()"
85
- @nendo.evalStr( "(strip-syntax-quote '(a (b) ((c))))" ).should == "(a (b) ((c)))"
86
- @nendo.evalStr( "(strip-syntax-quote '(syntax-quote abc))" ).should == "(quote abc)"
87
- @nendo.evalStr( "(strip-syntax-quote '(syntax-quote (syntax-quote abc)))" ).should == "(quote (quote abc))"
88
-
89
- @nendo.evalStr( "(strip-let-syntax-keyword 'abc)" ).should == "abc"
90
- @nendo.evalStr( <<EOS
91
- (strip-let-syntax-keyword
92
- '(let-syntax ((nil!
93
- (syntax-rules ()
94
- ((_ x)
95
- (set! x '())))))
96
- (nil! aa)))
97
- EOS
98
- ).should == "(begin (nil! aa))"
99
-
100
- @nendo.evalStr( <<EOS
101
- (strip-let-syntax-keyword
102
- '(let ()
103
- (let-syntax ((a (syntax-rules () ((_ ?x) (+ ?x 8))))
104
- (b (syntax-rules () ((_ ?x) (- ?x 8)))))
105
- (let-syntax ((a (syntax-rules () ((_ ?y) (b 2))))
106
- (b (syntax-rules () ((_ ?y) (a 3)))))
107
- (list (a 7) (b 8))))))
108
- EOS
109
- ).should == "(let () (begin (begin (list (a 7) (b 8)))))"
110
- end
111
- end
112
-
113
-
114
- describe Nendo, "when use identifier checker " do
115
- before do
116
- @nendo = Nendo::Core.new()
117
- @nendo.loadInitFile
118
- end
119
- it "should" do
120
- @nendo.evalStr( "(symbol? 'a)" ).should == '#t'
121
- @nendo.evalStr( "(identifier? 'a)" ).should == '#t'
122
- @nendo.evalStr( "(identifier? 'identifier)" ).should == '#t'
123
- @nendo.evalStr( "(identifier? 'lambda)" ).should == '#t'
124
- @nendo.evalStr( "(identifier? 10)" ).should == '#f'
125
- @nendo.evalStr( "(identifier? \"str\")" ).should == '#f'
126
- @nendo.evalStr( "(identifier=? '() 'lambda '() 'lambda)" ).should == '#t'
127
- @nendo.evalStr( "(identifier=? '() 'define '() 'lambda)" ).should == '#f'
128
- @nendo.evalStr( "(identifier=? '() 'if '() '/nendo/macroenv/if)" ).should == '#f'
129
- end
130
- end
131
-
132
-
133
- describe Nendo, "when call make-syntactic-closure " do
134
- before do
135
- @nendo = Nendo::Core.new()
136
- @nendo.loadInitFile
137
- end
138
- it "should" do
139
- @nendo.evalStr( "(make-syntactic-closure (global-variables) '() 'print )" ).should == 'print'
140
- @nendo.evalStr( "(make-syntactic-closure (global-variables) '() 'if )" ).should == 'if'
141
- @nendo.evalStr( "(make-syntactic-closure (global-variables) '() 'lambda )" ).should == 'lambda'
142
- @nendo.evalStr( "(make-syntactic-closure (global-variables) '() 'aaaa )" ).should match( /SyntacticClosure.aaaa:_aaaa_/ )
143
- @nendo.evalStr( "(make-syntactic-closure (global-variables) '() 'tmp )" ).should match( /SyntacticClosure.tmp:_tmp_/ )
144
- @nendo.evalStr( "(define name (make-syntactic-closure (global-variables) '() 'tmp ))" ).should match( /SyntacticClosure.tmp:_tmp_/ )
145
- @nendo.evalStr( "name" ).should match( /SyntacticClosure.tmp:_tmp_/ )
146
- @nendo.evalStr( "(make-syntactic-closure (global-variables) '() 'new_global_var)" ).should match( /SyntacticClosure.new_global_var:_new_global_var_/ )
147
- @nendo.evalStr( "(define new_global_var 10)" ).should == '10'
148
- @nendo.evalStr( "(make-syntactic-closure (global-variables) '() 'new_global_var)" ).should == 'new_global_var'
149
-
150
- @nendo.evalStr( "(strip-syntactic-closures name)" ).should match( /_tmp_/ )
151
- @nendo.evalStr( "(strip-syntactic-closures (list name name))" ).should match( /[(]_tmp_/ )
152
- end
153
- end
154
-
155
-
156
- describe Nendo, "when use core syntax " do
157
- before do
158
- @nendo = Nendo::Core.new()
159
- @nendo.loadInitFile
160
- end
161
- it "should" do
162
- @nendo.evalStr( "(if #t 1 2)" ).should == '1'
163
- @nendo.evalStr( "(if #f 1 2)" ).should == '2'
164
- @nendo.evalStr( "(/nendo/core/if #t 1 2)" ).should == '1'
165
- @nendo.evalStr( "(/nendo/core/if #f 1 2)" ).should == '2'
166
- @nendo.evalStr( "(begin 1 2 3)" ).should == '3'
167
- @nendo.evalStr( "(/nendo/core/begin 1 2 3)" ).should == '3'
168
- @nendo.evalStr( "(car (memq '/nendo/core/begin (global-variables)))" ).should == '/nendo/core/begin'
169
- end
170
- end
171
-
172
-
173
- describe Nendo, "when use er-macro-transformer " do
174
- before do
175
- @nendo = Nendo::Core.new()
176
- @nendo.loadInitFile
177
- end
178
- it "should" do
179
-
180
- @nendo.evalStr( <<EOS
181
- (define-syntax test-of-identifier1?
182
- (er-macro-transformer
183
- (lambda (expr rename compare)
184
- (cons (rename 'list)
185
- (list (identifier? 'rename)
186
- (identifier? 'sym))))))
187
- test-of-identifier1?
188
- EOS
189
- ).should match( /Nendo::LispSyntax/ )
190
-
191
- @nendo.evalStr( "(test-of-identifier1? 1)" ).should == '(#t #t)'
192
-
193
- @nendo.evalStr( <<EOS
194
- (define-syntax test-of-identifier2?
195
- (er-macro-transformer
196
- (lambda (expr rename compare)
197
- (identifier? (cadr expr)))))
198
-
199
- (let ((a 1)
200
- (b 2)
201
- (c 3))
202
- (let ((b a))
203
- (list
204
- a
205
- b
206
- c
207
- (test-of-identifier2? a)
208
- (test-of-identifier2? b)
209
- (test-of-identifier2? c)
210
- (test-of-identifier2? d)
211
- (test-of-identifier2? 'e))))
212
- EOS
213
- ).should == '(1 1 3 #t #t #t #t #f)'
214
-
215
- @nendo.evalStr( <<EOS
216
- (define-syntax test-of-rename
217
- (er-macro-transformer
218
- (lambda (expr rename compare)
219
- (list (rename 'quote)
220
- (rename 'sym)))))
221
- test-of-rename
222
- EOS
223
- ).should match( /Nendo::LispSyntax/ )
224
- @nendo.evalStr( "(test-of-rename 2)" ).should == 'sym'
225
-
226
- @nendo.evalStr( <<EOS
227
- (define-syntax test-of-identifier=?
228
- (er-macro-transformer
229
- (lambda (expr rename compare)
230
- (let ((_compare (rename 'compare)))
231
- (compare
232
- (cadr expr)
233
- (caddr expr))))))
234
- (let ((a 1)
235
- (b 2)
236
- (c 3))
237
- (let ((b a))
238
- (list
239
- a
240
- b
241
- c
242
- (test-of-identifier=? a a)
243
- (test-of-identifier=? b b)
244
- (test-of-identifier=? c c)
245
- (test-of-identifier=? a b)
246
- (test-of-identifier=? a c))))
247
- EOS
248
- ).should == '(1 1 3 #t #t #t #f #f)'
249
-
250
- @nendo.evalStr( <<EOS
251
- (define-syntax my-or
252
- (er-macro-transformer
253
- (lambda (expr rename compare)
254
- (cond ((null? (cdr expr)) #f)
255
- ((null? (cddr expr)) (cadr expr))
256
- (else
257
- (list (rename 'let) (list (list (rename 'tmp) (cadr expr)))
258
- (list (rename 'if) (rename 'tmp)
259
- (rename 'tmp)
260
- (cons (rename 'my-or) (cddr expr)))))))))
261
- my-or
262
- EOS
263
- ).should match( /Nendo::LispSyntax/ )
264
- @nendo.evalStr( "(my-or 1 2)" ).should == '1'
265
- @nendo.evalStr( "(my-or #f 100 200)" ).should == '100'
266
- @nendo.evalStr( "(my-or #f #f #f #f 500)" ).should == '500'
267
- @nendo.evalStr( "(my-or #f #f #f #f #f)" ).should == '#f'
268
-
269
- @nendo.evalStr( <<EOS
270
- (define-syntax my-and
271
- (er-macro-transformer
272
- (lambda (expr rename compare)
273
- (cond ((null? (cdr expr)))
274
- ((null? (cddr expr)) (cadr expr))
275
- (else (list (rename 'if) (cadr expr)
276
- (cons (rename 'my-and) (cddr expr))
277
- #f))))))
278
- my-and
279
- EOS
280
- ).should match( /Nendo::LispSyntax/ )
281
- @nendo.evalStr( "(my-and 1 2)" ).should == '2'
282
- @nendo.evalStr( "(my-and 1 2 3 4)" ).should == '4'
283
- @nendo.evalStr( "(my-and #t #t #t #t 500)" ).should == '500'
284
- @nendo.evalStr( "(my-and 1 2 3 4 #f)" ).should == '#f'
285
- @nendo.evalStr( "(my-and 1 2 #f 4 5)" ).should == '#f'
286
- end
287
- end
288
-
289
-
290
- describe Nendo, "when use syntax-rules " do
291
- before do
292
- @nendo = Nendo::Core.new()
293
- @nendo.setDisplayErrors( false )
294
- @nendo.loadInitFile
295
- end
296
- it "should" do
297
- @nendo.evalStr( <<EOS
298
- (define-syntax nil!
299
- (syntax-rules ()
300
- ((_ x)
301
- (set! x '()))))
302
- nil!
303
- EOS
304
- ).should match( /Nendo::LispSyntax/ )
305
- @nendo.evalStr( "(define a 1) a" ).should == '1'
306
- @nendo.evalStr( "(nil! a) a" ).should == '()'
307
- @nendo.evalStr( "(set! a 2) a" ).should == '2'
308
- @nendo.evalStr( "(nil! a) a" ).should == '()'
309
- @nendo.evalStr( <<EOS
310
- (define-syntax test-syntax
311
- (syntax-rules ()
312
- ((_ a)
313
- (list a))
314
- ((_ a b)
315
- (list a (list b)))
316
- ((_ a b c ...)
317
- (list a (list b (list c ...))))))
318
- test-syntax
319
- EOS
320
- ).should match( /Nendo::LispSyntax/ )
321
- @nendo.evalStr( "(test-syntax 1)" ).should == '(1)'
322
- @nendo.evalStr( "(test-syntax 1 2)" ).should == '(1 (2))'
323
- @nendo.evalStr( "(test-syntax 1 2 3)" ).should == '(1 (2 (3)))'
324
- @nendo.evalStr( "(test-syntax 1 2 3 4)" ).should == '(1 (2 (3 4)))'
325
- @nendo.evalStr( "(test-syntax 1 2 3 4 5)" ).should == '(1 (2 (3 4 5)))'
326
- @nendo.evalStr( "(test-syntax 1 2 3 4 5 6)" ).should == '(1 (2 (3 4 5 6)))'
327
- @nendo.evalStr( "(test-syntax 'a)" ).should == '(a)'
328
- @nendo.evalStr( "(test-syntax 'a \"B\")" ).should == '(a ("B"))'
329
- @nendo.evalStr( "(test-syntax 'a \"B\" 'C)" ).should == '(a ("B" (C)))'
330
- @nendo.evalStr( "(test-syntax 'a \"B\" 'C \"d\")" ).should == '(a ("B" (C "d")))'
331
- lambda { @nendo.evalStr( <<EOS
332
- (define-syntax dummy-syntax
333
- (syntax-rules))
334
- EOS
335
- ) }.should raise_error( RuntimeError, /syntax-rules.+\(1\)/ )
336
- lambda { @nendo.evalStr( <<EOS
337
- (define-syntax dummy-syntax
338
- (syntax-rules eee))
339
- EOS
340
- ) }.should raise_error( RuntimeError, /syntax-rules.+\(2\)/ )
341
-
342
- lambda { @nendo.evalStr( <<EOS
343
- (define-syntax dummy-syntax
344
- (syntax-rules
345
- ((_ arg1)
346
- arg1)))
347
- EOS
348
- ) }.should raise_error( RuntimeError, /syntax-rules.+\(3\)/ )
349
-
350
- @nendo.evalStr( <<EOS
351
- (define this-is-var 1)
352
- (define-syntax dummy-syntax
353
- (syntax-rules ()
354
- ((_ arg1)
355
- this-is-var)))
356
- (macroexpand
357
- '(dummy-syntax 100))
358
- EOS
359
- ).should == "this-is-var"
360
-
361
- @nendo.evalStr( <<EOS
362
- (define-syntax dummy-syntax
363
- (syntax-rules ()
364
- ((_ arg1)
365
- 'this-is-symbol)))
366
- (macroexpand
367
- '(dummy-syntax 100))
368
- EOS
369
- ).should match( /quote #<SyntacticClosure.this-is-symbol:_this/ )
370
-
371
- @nendo.evalStr( <<EOS
372
- (define-syntax dummy-syntax
373
- (syntax-rules ()
374
- ((_ arg1)
375
- 'this-is-symbol)))
376
- (dummy-syntax 100)
377
- EOS
378
- ).should == "this-is-symbol"
379
-
380
- end
381
- end
382
-
383
- describe Nendo, "When use let-syntax" do
384
- before do
385
- @nendo = Nendo::Core.new()
386
- @nendo.setDisplayErrors( false )
387
- @nendo.loadInitFile
388
- end
389
- it "should" do
390
-
391
- @nendo.evalStr( <<EOS
392
- (macroexpand
393
- '(let-syntax ((nil!
394
- (syntax-rules ()
395
- ((_ x)
396
- (set! x '())))))
397
- (nil! aa)))
398
- EOS
399
- ).should == "(begin (set! aa (quote ())))"
400
-
401
- @nendo.evalStr( <<EOS
402
- (macroexpand
403
- '(let-syntax ((dummy-syntax
404
- (syntax-rules ()
405
- ((_ x)
406
- 'this-is-symbol))))
407
- (dummy-syntax 100)))
408
- EOS
409
- ).should match( /begin [(]quote #<SyntacticClosure.this-is-symbol:/ )
410
-
411
- @nendo.evalStr( <<EOS
412
- (macroexpand
413
- '(let-syntax ((dummy-syntax
414
- (syntax-rules ()
415
- ((_ x)
416
- (begin "this is debug line"
417
- #?.)))))
418
- (dummy-syntax 100)))
419
- EOS
420
- ).should == "(begin (begin \"this is debug line\" \"(string):6\"))"
421
-
422
- @nendo.evalStr( <<EOS
423
- (define aa 100)
424
- (let-syntax ((nil!
425
- (syntax-rules ()
426
- ((_ x)
427
- (set! x '())))))
428
- (nil! aa))
429
- aa
430
- EOS
431
- ).should == "()"
432
-
433
- @nendo.evalStr( <<EOS
434
- (let ()
435
- (let-syntax ()
436
- (define internal-def 'ok)
437
- internal-def))
438
- EOS
439
- ).should == "ok"
440
-
441
- @nendo.evalStr( <<EOS
442
- '"internal-def2"
443
- (let ()
444
- (let-syntax ()
445
- (define internal-def 'ok)
446
- internal-def))
447
- EOS
448
- ).should == "ok"
449
-
450
- @nendo.evalStr( <<EOS
451
- (let-syntax
452
- ((foo (syntax-rules ()
453
- ((foo args ... penultimate ultimate)
454
- (list ultimate penultimate args ...)))))
455
- (foo 1 2 3 4 5))
456
- EOS
457
- ).should == "(5 4 1 2 3)"
458
-
459
- lambda { @nendo.evalStr( <<EOS
460
- (let-syntax ((a (+ 1 2)))
461
- (a))
462
- EOS
463
- ) }.should raise_error( SyntaxError, /syntax-rules/ )
464
-
465
- lambda { @nendo.evalStr( <<EOS
466
- (let-syntax ((a 100))
467
- (a))
468
- EOS
469
- ) }.should raise_error( SyntaxError, /syntax-rules/ )
470
-
471
- lambda { @nendo.evalStr( <<EOS
472
- (let-syntax ((a (syntax-rules-dummy () 1))
473
- (b (syntax-rules () 2)))
474
- (list (a) (b)))
475
- EOS
476
- ) }.should raise_error( SyntaxError, /syntax-rules/ )
477
-
478
- @nendo.evalStr( <<EOS
479
- (let-syntax ()
480
- (list 1 2))
481
- EOS
482
- ).should == "(1 2)"
483
-
484
- @nendo.evalStr( <<EOS
485
- (let ()
486
- (let-syntax ((a (syntax-rules () ((_ ?x) (+ ?x 8))))
487
- (b (syntax-rules () ((_ ?x) (- ?x 8)))))
488
- (list (a 7) (b 8))))
489
- EOS
490
- ).should == "(15 0)"
491
-
492
- @nendo.evalStr( <<EOS
493
- (let ()
494
- (let-syntax ((a (syntax-rules () ((_ ?x) (+ ?x 8))))
495
- (b (syntax-rules () ((_ ?x) (- ?x 8)))))
496
- (let-syntax ((aa (syntax-rules () ((_ ?x) (b 2))))
497
- (bb (syntax-rules () ((_ ?x) (a 3)))))
498
- (list (aa 7) (bb 8)))))
499
- EOS
500
- ).should == "(-6 11)"
501
-
502
- @nendo.evalStr( <<EOS
503
- (let ()
504
- (let-syntax ((a (syntax-rules () ((_ ?x) (+ ?x 8))))
505
- (b (syntax-rules () ((_ ?x) (- ?x 8)))))
506
- (let-syntax ((a (syntax-rules () ((_ ?y) (b 2))))
507
- (b (syntax-rules () ((_ ?y) (a 3)))))
508
- (list (a 7) (b 8)))))
509
- EOS
510
- ).should == "(-6 11)"
511
- end
512
- end
513
-
514
-
515
- describe Nendo, "When use let-syntax in lexical scope " do
516
- before do
517
- @nendo = Nendo::Core.new()
518
- @nendo.loadInitFile
519
- end
520
- it "should" do
521
-
522
- @nendo.evalStr( <<EOS
523
- (let ((... 2))
524
- (let-syntax ((s (syntax-rules ()
525
- ((_ x ...) 'bad)
526
- ((_ . r) 'ok))))
527
- (s a b c)))
528
- EOS
529
- ).should == "ok"
530
-
531
- @nendo.evalStr( <<EOS
532
- (let ((x 'outer))
533
- (let-syntax ((m (syntax-rules () ((m) x))))
534
- (let ((x 'inner))
535
- (m)))) ;; '
536
- EOS
537
- ).should == "outer"
538
-
539
- @nendo.evalStr( <<EOS
540
- (let ((x 'outer1))
541
- (let ((y 'outer2))
542
- (let ((z 'outer3))
543
- (let-syntax ((m (syntax-rules () ((m) (list x y z)))))
544
- (let ((x 'inner1))
545
- (let ((y 'inner2))
546
- (let ((z 'inner3))
547
- (m))))))))
548
- EOS
549
- ).should == "(outer1 outer2 outer3)"
550
-
551
- @nendo.evalStr( <<EOS
552
- (let ((x 'outer))
553
- (let-syntax ((with-x
554
- (syntax-rules ()
555
- ((_ y expr)
556
- (let-syntax ((y (syntax-rules () ((_) x))))
557
- expr)))))
558
- (let ((x 'inner))
559
- (with-x z (z)))))
560
- EOS
561
- ).should == "outer"
562
-
563
- # pending( "nested let fails on limitation of Nendo's let-syntax." )
564
- #
565
- # @nendo.evalStr( <<EOS
566
- #(define z 'top-level-1)
567
- #(let ((x 'outer1))
568
- # (let ((y x))
569
- # (let ((z y))
570
- # (let-syntax ((m (syntax-rules () ((m) z))))
571
- # (let ((x 'inner1))
572
- # (let ((y x))
573
- # (let ((z y))
574
- # (m))))))))
575
- #EOS
576
- # ).should == "outer1"
577
-
578
- end
579
- end
580
-
581
- describe Nendo, "When use complex let-syntax" do
582
- before do
583
- @nendo = Nendo::Core.new()
584
- @nendo.loadInitFile
585
- end
586
- it "should" do
587
-
588
- @nendo.evalStr( <<EOS
589
- (define-syntax %cut
590
- (syntax-rules (<> <...>)
591
- ((%cut e? params args)
592
- (lambda params args))
593
- ((%cut e? (params ...) (args ...) <> . rest)
594
- (%cut e? (params ... tmp) (args ... tmp) . rest))
595
- ((%cut e? (params ...) (args ...) <...>)
596
- (%cut e? (params ... . tmp) (apply args ... tmp)))
597
- ((%cut e? (params ...) (args ...) <...> . rest)
598
- (error "cut: non-terminal <...>"))
599
- ((%cut #t (params ...) (args ...) x . rest)
600
- (let ((tmp x)) (%cut #t (params ...) (args ... tmp) . rest)))
601
- ((%cut #f (params ...) (args ...) x . rest)
602
- (%cut #t (params ...) (args ... x) . rest))))
603
- EOS
604
- ).should match( /Nendo::LispSyntax/ )
605
-
606
- @nendo.evalStr( <<EOS
607
- (define-syntax cut
608
- (syntax-rules () ((cut args ...) (%cut #f () () args ...))))
609
- EOS
610
- ).should match( /Nendo::LispSyntax/ )
611
-
612
- @nendo.evalStr( <<EOS
613
- (define rassq (cut rassoc <> <> eq?))
614
- EOS
615
- ).should match( /Proc/ )
616
-
617
- @nendo.evalStr( <<EOS
618
- ((cut list 1 <> 3 <>) 2 4)
619
- EOS
620
- ).should == "(1 2 3 4)"
621
-
622
- @nendo.evalStr( <<EOS
623
- (define-syntax match-check-ellipse
624
- (syntax-rules ()
625
- ((match-check-ellipse (a . b) success-k failure-k) failure-k)
626
- ((match-check-ellipse #(a ...) success-k failure-k) failure-k)
627
- ;; matching an atom
628
- ((match-check-ellipse id success-k failure-k)
629
- (let-syntax ((ellipse? (syntax-rules ()
630
- ((ellipse? (foo id) sk fk) sk)
631
- ((ellipse? other sk fk) fk))))
632
- (ellipse? (a b c) success-k failure-k)))))
633
- EOS
634
- ).should match( /Nendo::LispSyntax/ )
635
-
636
- @nendo.evalStr( <<EOS
637
- (match-check-ellipse (aa bb) (+ #?. " ellipse") (+ #?. " non-ellipse"))
638
- EOS
639
- ).should == '"(string):1 non-ellipse"'
640
-
641
- @nendo.evalStr( <<EOS
642
- (match-check-ellipse xxx (+ #?. " ellipse") (+ #?. " non-ellipse"))
643
- EOS
644
- ).should == '"(string):1 non-ellipse"'
645
-
646
- @nendo.evalStr( <<EOS
647
- (match-check-ellipse ... (+ #?. " ellipse") (+ #?. " non-ellipse"))
648
- EOS
649
- ).should == '"(string):1 ellipse"'
650
-
651
- @nendo.evalStr( <<EOS
652
- (define-syntax dummy-syntax
653
- (syntax-rules ()
654
- ((_ arg)
655
- (match-check-ellipse arg (result-str "ellipse") (result-str "non-ellipse")))))
656
- (define-syntax result-str
657
- (syntax-rules ()
658
- ((_ arg-str)
659
- (+ #?. " " arg-str))))
660
- (dummy-syntax xxx)
661
- EOS
662
- ).should == '"(string):8 non-ellipse"'
663
-
664
- @nendo.evalStr( <<EOS
665
- (match-check-ellipse ... (match-check-ellipse xxx 'tt 'tf) (match-check-ellipse xxx 'ft 'ff))
666
- EOS
667
- ).should == 'tf'
668
-
669
- @nendo.evalStr( <<EOS
670
- (match-check-ellipse yyy (match-check-ellipse xxx 'tt 'tf) (match-check-ellipse xxx 'ft 'ff))
671
- EOS
672
- ).should == 'ff'
673
-
674
- @nendo.evalStr( <<EOS
675
- (define-syntax match-check-identifier
676
- (syntax-rules ()
677
- ;; fast-case failures, lists and vectors are not identifiers
678
- ((_ (x . y) success-k failure-k) failure-k)
679
- ((_ #(x ...) success-k failure-k) failure-k)
680
- ;; x is an atom
681
- ((_ x success-k failure-k)
682
- (let-syntax
683
- ((sym?
684
- (syntax-rules ()
685
- ((sym? x sk fk) sk)
686
- ;; otherwise x is a non-symbol datum
687
- ((sym? y sk fk) (begin #?. fk)))))
688
- (sym? abracadabra success-k failure-k)))))
689
- EOS
690
- ).should match( /Nendo::LispSyntax/ )
691
-
692
- @nendo.evalStr( <<EOS
693
- (match-check-identifier (aa bb) "id" "non-id")
694
- EOS
695
- ).should == '"non-id"'
696
-
697
- @nendo.evalStr( <<EOS
698
- (match-check-identifier xx "id" "non-id")
699
- EOS
700
- ).should == '"id"'
701
-
702
- @nendo.evalStr( <<EOS
703
- (let ([yy (match-check-identifier xx "id" "non-id")])
704
- yy)
705
- EOS
706
- ).should == '"id"'
707
-
708
- end
709
- end
710
-
711
-
712
- describe Nendo, "When expand guard special form" do
713
- before do
714
- @nendo = Nendo::Core.new()
715
- @nendo.loadInitFile
716
- end
717
- it "should" do
718
- @nendo.evalStr( <<EOS
719
- (macroexpand-1
720
- (quote
721
- (%guard-var (exc
722
- (else (print "ELSE"))))))
723
- EOS
724
- ).should == "exc"
725
-
726
- @nendo.evalStr( <<EOS
727
- (macroexpand-1
728
- (quote
729
- (%guard-var (exc
730
- ((exc.is_a? RuntimeError)
731
- (print "<<RuntimeError>>"))
732
- (else (print "ELSE"))))))
733
- EOS
734
- ).should == "exc"
735
-
736
- @nendo.evalStr( <<EOS
737
- (macroexpand-1
738
- (quote
739
- (%guard-var (exc
740
- ((exc.is_a? RuntimeError)
741
- (print "<<RuntimeError>>"))
742
- (else
743
- => (lambda (e)
744
- (printf "Type is [%s]\n" e.class)))))))
745
- EOS
746
- ).should == "exc"
747
-
748
- @nendo.evalStr( <<EOS
749
- (macroexpand-1
750
- (quote
751
- (%guard-clause (exc
752
- (else (print "ELSE"))))))
753
- EOS
754
- ).should match( /^[(]cond.+else.+print.+ELSE.+[(]#t [(]raise.+exc[)][)][)]$/ )
755
-
756
-
757
- @nendo.evalStr( <<EOS
758
- (macroexpand-1
759
- (quote
760
- (%guard-clause (exc
761
- ((exc.is_a? RuntimeError)
762
- (print "<<RuntimeError>>"))
763
- (else (print "ELSE"))))))
764
- EOS
765
- ).should match( /^[(]cond.+exc.is_a.+RuntimeError.+<<RuntimeError>>.+else.+print.+ELSE.+[(]#t [(]raise.+exc[)][)][)]$/ )
766
-
767
- @nendo.evalStr( <<EOS
768
- (macroexpand-1
769
- (quote
770
- (%guard-clause (exc
771
- ((exc.is_a? RuntimeError)
772
- (print "<<RuntimeError>>"))))))
773
- EOS
774
- ).should match( /^[(]cond.+exc.is_a.+RuntimeError.+<<RuntimeError>>.+[(]#t [(]raise.+exc[)][)][)]$/ )
775
-
776
- @nendo.evalStr( <<EOS
777
- (macroexpand-1
778
- (quote
779
- (%guard-clause (exc))))
780
- EOS
781
- ).should match( /^[(]cond.+[(]#t [(]raise.+exc[)][)][)]$/ )
782
-
783
- @nendo.evalStr( <<EOS
784
- (macroexpand-1
785
- (quote
786
- (%guard-clause (exc
787
- ((exc.is_a? RuntimeError)
788
- (print "<<RuntimeError>>"))
789
- (else
790
- => (lambda (e)
791
- (sprintf "Type is [%s]" e.class)))))))
792
- EOS
793
- ).should match( /^[(]cond.+exc.is_a.+RuntimeError.+print.+RuntimeError.+else.+feedto.+[(]#t [(]raise exc[)][)][)]$/ )
794
-
795
-
796
- end
797
- end
798
-
799
-
800
- describe Nendo, "When use guard special form" do
801
- before do
802
- @nendo = Nendo::Core.new()
803
- @nendo.setDisplayErrors( false )
804
- @nendo.loadInitFile
805
- end
806
- it "should" do
807
- @nendo.evalStr( <<EOS
808
- (guard
809
- (exc (else (sprintf "Type is [%s]" (exc.class))))
810
- (error "This is RuntimeError"))
811
- EOS
812
- ).should == '"Type is [RuntimeError]"'
813
-
814
- @nendo.evalStr( <<EOS
815
- (guard
816
- (exc (else (sprintf "Type is [%s]" exc.class)))
817
- (+ (Array.new) 1))
818
- EOS
819
- ).should == '"Type is [TypeError]"'
820
-
821
- @nendo.evalStr( <<EOS
822
- (guard
823
- (exc (else (sprintf "Type is [%s]" exc.class)))
824
- (+ (Array.new) 1)
825
- (error "This is RuntimeError"))
826
- EOS
827
- ).should == '"Type is [TypeError]"'
828
-
829
- @nendo.evalStr( <<EOS
830
- (guard
831
- (exc (else (sprintf "Type is [%s]" exc.class)))
832
- (error "This is RuntimeError")
833
- (+ (Array.new) 1))
834
- EOS
835
- ).should == '"Type is [RuntimeError]"'
836
-
837
- @nendo.evalStr( <<EOS
838
- (guard
839
- (exc ((exc.is_a? RuntimeError)
840
- "Type is [RuntimeError]")
841
- ((exc.is_a? TypeError)
842
- "Type is [TypeError]")
843
- (else
844
- "Type is Others"))
845
- (error "This is RuntimeError")
846
- (+ (Array.new) 1))
847
- EOS
848
- ).should == '"Type is [RuntimeError]"'
849
-
850
- @nendo.evalStr( <<EOS
851
- (guard
852
- (exc ((exc.is_a? RuntimeError)
853
- "Type is [RuntimeError]")
854
- ((exc.is_a? TypeError)
855
- "Type is [TypeError]"))
856
- (+ (Array.new) 1)
857
- (error "This is RuntimeError"))
858
- EOS
859
- ).should == '"Type is [TypeError]"'
860
-
861
- @nendo.evalStr( <<EOS
862
- (guard
863
- (exc ((exc.is_a? TypeError)
864
- "Type is [TypeError]"))
865
- (+ (Array.new) 1)
866
- (error "This is RuntimeError"))
867
- EOS
868
- ).should == '"Type is [TypeError]"'
869
-
870
- @nendo.evalStr( <<EOS
871
- (guard
872
- (exc ((exc.is_a? RuntimeError)
873
- "Type is [RuntimeError]"))
874
- (error "This is RuntimeError")
875
- (+ (Array.new) 1))
876
- EOS
877
- ).should == '"Type is [RuntimeError]"'
878
-
879
- lambda { @nendo.evalStr( <<EOS
880
- (guard
881
- (exc)
882
- (error "This is RuntimeError"))
883
- EOS
884
- ) }.should raise_error( RuntimeError )
885
-
886
- lambda { @nendo.evalStr( <<EOS
887
- (begin
888
- (guard
889
- (exc ((exc.is_a? RuntimeError)
890
- "Type is [RuntimeError]"))
891
- (+ (Array.new) 1))
892
- \"-END-\")
893
- EOS
894
- ) }.should raise_error( TypeError )
895
-
896
- end
897
- end
898
-
899
-
900
-
901
- describe Nendo, "When use guard and raise" do
902
- before do
903
- @nendo = Nendo::Core.new()
904
- @nendo.setDisplayErrors( false )
905
- @nendo.loadInitFile
906
- end
907
- it "should" do
908
- @nendo.evalStr( <<EOS
909
- (guard
910
- (exc ((exc.is_a? TypeError)
911
- "[TypeError]")
912
- (else
913
- "[OtherError]"))
914
- (guard
915
- (exc (else (+ "a" 1.1)))
916
- (error "This is RuntimeError")))
917
- EOS
918
- ).should == '"[TypeError]"'
919
-
920
- @nendo.evalStr( <<EOS
921
- (let1 lst '()
922
- (guard
923
- (exc (else (push! lst 2)))
924
- (guard
925
- (exc (else (push! lst 1)))
926
- (error "Error occur")))
927
- lst)
928
- EOS
929
- ).should == '(1)'
930
-
931
- @nendo.evalStr( <<EOS
932
- (let1 lst '()
933
- (guard
934
- (exc (else (push! lst 2)))
935
- (guard
936
- (exc (else (push! lst 1)
937
- (error "Error occur(2)")))
938
- (error "Error occur(1)")))
939
- lst)
940
- EOS
941
- ).should == '(2 1)'
942
-
943
-
944
- lambda { @nendo.evalStr( <<EOS
945
- (let1 lst '()
946
- (guard
947
- (exc (else (push! lst 3)
948
- (errorf "Error occur:%s" (write-to-string lst))))
949
- (guard
950
- (exc (else (push! lst 2)
951
- (error "Error occur(3)")))
952
- (guard
953
- (exc (else (push! lst 1)
954
- (error "Error occur(2)")))
955
- (error "Error occur(1)"))))
956
- #t)
957
- EOS
958
- ) }.should raise_error( RuntimeError, /Error occur:[(]3 2 1[)]/ )
959
-
960
-
961
- @nendo.evalStr( <<EOS
962
- (define a
963
- (guard
964
- (exc (else (exc.message))) ;; line 1
965
- (raise RuntimeError)))
966
- (define b
967
- (guard
968
- (exc (else (exc.message))) ;; line 5
969
- (raise NoMethodError)))
970
- (define c
971
- (guard
972
- (exc (else (exc.message))) ;; line 9
973
- (raise ArgumentError)))
974
- (list a b c)
975
- EOS
976
- ).should == '("(string):1 raised RuntimeError" "(string):5 raised NoMethodError" "(string):9 raised ArgumentError")'
977
-
978
-
979
- end
980
- end
981
-
982
-
983
- describe Nendo, "When use unwind-protect" do
984
- before do
985
- @nendo = Nendo::Core.new()
986
- @nendo.setDisplayErrors( false )
987
- @nendo.loadInitFile
988
- end
989
-
990
- it "should" do
991
- @nendo.evalStr( "(macroexpand '(unwind-protect 1 2)) ;; '" ).should match( /[(]%guard #<SyntacticClosure.exc:_exc__gensym/ )
992
-
993
- lambda { @nendo.evalStr( <<EOS
994
- (let1 cnt 0
995
- (begin
996
- (set! cnt (+ cnt 1))
997
- (set! cnt (+ cnt "string"))
998
- ))
999
- EOS
1000
- ) }.should raise_error( TypeError )
1001
-
1002
- @nendo.evalStr( <<EOS
1003
- (let1 cnt 0
1004
- (unwind-protect
1005
- 1
1006
- 2))
1007
- EOS
1008
- ).should == '1'
1009
-
1010
- @nendo.evalStr( <<EOS
1011
- (let1 cnt 0
1012
- (unwind-protect
1013
- (begin 1 2)
1014
- 3))
1015
- EOS
1016
- ).should == '2'
1017
-
1018
- @nendo.evalStr( <<EOS
1019
- (let* ([cnt 0]
1020
- [result (unwind-protect
1021
- (begin
1022
- (set! cnt (+ cnt 1))
1023
- (set! cnt (+ cnt 2))
1024
- (+ 1.1 "str")
1025
- (set! cnt (+ cnt 3)))
1026
- (set! cnt (+ cnt 100)))])
1027
- (list result cnt))
1028
- EOS
1029
- ).should == '(#f 103)'
1030
-
1031
- @nendo.evalStr( <<EOS
1032
- (let* ([cnt 0]
1033
- [result (unwind-protect
1034
- (begin
1035
- (set! cnt (+ cnt 10))
1036
- (set! cnt (+ cnt 01))
1037
- (error "[RuntimeError]")
1038
- (set! cnt (+ cnt 02)))
1039
- (set! cnt (+ cnt 100)))])
1040
- (list result cnt))
1041
- EOS
1042
- ).should == '(#f 111)'
1043
-
1044
- @nendo.evalStr( <<EOS
1045
- (let* ([cnt 0]
1046
- [result (unwind-protect
1047
- (begin
1048
- (set! cnt (+ cnt 10))
1049
- (set! cnt (+ cnt 01))
1050
- (guard (exc (else (set! cnt (+ cnt 100))))
1051
- (error "[RuntimeError]"))
1052
- (set! cnt (+ cnt 02)))
1053
- (set! cnt (+ cnt 1000)))])
1054
- (list result cnt))
1055
- EOS
1056
- ).should == '(113 1113)'
1057
-
1058
- end
1059
- end