nendo 0.6.8 → 0.7.0

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