nendo 0.5.0 → 0.5.1
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/emacs/nendo-mode.el +2 -0
- data/lib/init.nnd +51 -35
- data/lib/init.nndc +3371 -2920
- data/lib/nendo.rb +463 -194
- data/lib/srfi-2.nndc +48 -165
- data/lib/srfi-26.nndc +142 -511
- data/lib/text/html-lite.nndc +23 -1
- data/lib/util/combinations.nnd +290 -0
- data/lib/util/combinations.nndc +7218 -0
- data/lib/util/list.nndc +138 -387
- data/lib/util/match.nnd +672 -0
- data/lib/util/match.nndc +81024 -0
- data/test/match-test.nnd +186 -0
- data/test/nendo-util-test.nnd +5 -7
- data/test/nendo_spec.rb +697 -235
- data/test/syntax_spec.rb +561 -52
- data/test/util-combinations-test.nnd +383 -0
- metadata +9 -4
- data/example/scratch.nnd +0 -119
data/test/syntax_spec.rb
CHANGED
@@ -2,24 +2,24 @@
|
|
2
2
|
# -*- encoding: utf-8 -*-
|
3
3
|
#
|
4
4
|
# syntax_spec.rb - "RSpec file for nendo language (syntax part)"
|
5
|
-
#
|
5
|
+
#
|
6
6
|
# Copyright (c) 2009-2010 Kiyoka Nishiyama <kiyoka@sumibi.org>
|
7
|
-
#
|
7
|
+
#
|
8
8
|
# Redistribution and use in source and binary forms, with or without
|
9
9
|
# modification, are permitted provided that the following conditions
|
10
10
|
# are met:
|
11
|
-
#
|
11
|
+
#
|
12
12
|
# 1. Redistributions of source code must retain the above copyright
|
13
13
|
# notice, this list of conditions and the following disclaimer.
|
14
|
-
#
|
14
|
+
#
|
15
15
|
# 2. Redistributions in binary form must reproduce the above copyright
|
16
16
|
# notice, this list of conditions and the following disclaimer in the
|
17
17
|
# documentation and/or other materials provided with the distribution.
|
18
|
-
#
|
18
|
+
#
|
19
19
|
# 3. Neither the name of the authors nor the names of its contributors
|
20
20
|
# may be used to endorse or promote products derived from this
|
21
21
|
# software without specific prior written permission.
|
22
|
-
#
|
22
|
+
#
|
23
23
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
24
24
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
25
25
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
@@ -31,7 +31,7 @@
|
|
31
31
|
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
32
32
|
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
33
33
|
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
34
|
-
#
|
34
|
+
#
|
35
35
|
require 'nendo'
|
36
36
|
include Nendo
|
37
37
|
|
@@ -52,8 +52,8 @@ describe Nendo, "when read the core syntax keyword " do
|
|
52
52
|
@nendo.evalStr( "(eq? a macro)" ).should == '#t'
|
53
53
|
@nendo.evalStr( "(define a &block)" ).should match( /Nendo::LispCoreSyntax/ )
|
54
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'
|
55
|
+
@nendo.evalStr( "(define a %let)" ).should match( /Nendo::LispCoreSyntax/ )
|
56
|
+
@nendo.evalStr( "(eq? a %let)" ).should == '#t'
|
57
57
|
@nendo.evalStr( "(define a letrec)" ).should match( /Nendo::LispCoreSyntax/ )
|
58
58
|
@nendo.evalStr( "(eq? a letrec)" ).should == '#t'
|
59
59
|
@nendo.evalStr( "(define a set!)" ).should match( /Nendo::LispCoreSyntax/ )
|
@@ -62,6 +62,55 @@ describe Nendo, "when read the core syntax keyword " do
|
|
62
62
|
end
|
63
63
|
|
64
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
|
+
|
65
114
|
describe Nendo, "when use identifier checker " do
|
66
115
|
before do
|
67
116
|
@nendo = Nendo::Core.new()
|
@@ -90,13 +139,16 @@ describe Nendo, "when call make-syntactic-closure " do
|
|
90
139
|
@nendo.evalStr( "(make-syntactic-closure (global-variables) '() 'print )" ).should == 'print'
|
91
140
|
@nendo.evalStr( "(make-syntactic-closure (global-variables) '() 'if )" ).should == 'if'
|
92
141
|
@nendo.evalStr( "(make-syntactic-closure (global-variables) '() 'lambda )" ).should == 'lambda'
|
93
|
-
@nendo.evalStr( "(make-syntactic-closure (global-variables) '() 'aaaa )" ).should match( /
|
94
|
-
@nendo.evalStr( "(make-syntactic-closure (global-variables) '() 'tmp )" ).should match( /
|
95
|
-
@nendo.evalStr( "(define name (make-syntactic-closure (global-variables) '() 'tmp ))" ).should match( /
|
96
|
-
@nendo.evalStr( "name" ).should match( /
|
97
|
-
@nendo.evalStr( "(make-syntactic-closure (global-variables) '() 'new_global_var)" ).should match( /
|
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_/ )
|
98
147
|
@nendo.evalStr( "(define new_global_var 10)" ).should == '10'
|
99
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_/ )
|
100
152
|
end
|
101
153
|
end
|
102
154
|
|
@@ -124,33 +176,108 @@ describe Nendo, "when use er-macro-transformer " do
|
|
124
176
|
@nendo.loadInitFile
|
125
177
|
end
|
126
178
|
it "should" do
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
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/ )
|
139
264
|
@nendo.evalStr( "(my-or 1 2)" ).should == '1'
|
140
265
|
@nendo.evalStr( "(my-or #f 100 200)" ).should == '100'
|
141
266
|
@nendo.evalStr( "(my-or #f #f #f #f 500)" ).should == '500'
|
142
267
|
@nendo.evalStr( "(my-or #f #f #f #f #f)" ).should == '#f'
|
143
268
|
|
144
|
-
@nendo.evalStr(
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
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/ )
|
154
281
|
@nendo.evalStr( "(my-and 1 2)" ).should == '2'
|
155
282
|
@nendo.evalStr( "(my-and 1 2 3 4)" ).should == '4'
|
156
283
|
@nendo.evalStr( "(my-and #t #t #t #t 500)" ).should == '500'
|
@@ -166,26 +293,30 @@ describe Nendo, "when use syntax-rules " do
|
|
166
293
|
@nendo.loadInitFile
|
167
294
|
end
|
168
295
|
it "should" do
|
169
|
-
@nendo.evalStr(
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
296
|
+
@nendo.evalStr( <<EOS
|
297
|
+
(define-syntax nil!
|
298
|
+
(syntax-rules ()
|
299
|
+
((_ x)
|
300
|
+
(set! x '()))))
|
301
|
+
nil!
|
302
|
+
EOS
|
303
|
+
).should match( /Nendo::LispSyntax/ )
|
175
304
|
@nendo.evalStr( "(define a 1) a" ).should == '1'
|
176
305
|
@nendo.evalStr( "(nil! a) a" ).should == '()'
|
177
306
|
@nendo.evalStr( "(set! a 2) a" ).should == '2'
|
178
307
|
@nendo.evalStr( "(nil! a) a" ).should == '()'
|
179
|
-
@nendo.evalStr(
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
308
|
+
@nendo.evalStr( <<EOS
|
309
|
+
(define-syntax test-syntax
|
310
|
+
(syntax-rules ()
|
311
|
+
((_ a)
|
312
|
+
(list a))
|
313
|
+
((_ a b)
|
314
|
+
(list a (list b)))
|
315
|
+
((_ a b c ...)
|
316
|
+
(list a (list b (list c ...))))))
|
317
|
+
test-syntax
|
318
|
+
EOS
|
319
|
+
).should match( /Nendo::LispSyntax/ )
|
189
320
|
@nendo.evalStr( "(test-syntax 1)" ).should == '(1)'
|
190
321
|
@nendo.evalStr( "(test-syntax 1 2)" ).should == '(1 (2))'
|
191
322
|
@nendo.evalStr( "(test-syntax 1 2 3)" ).should == '(1 (2 (3)))'
|
@@ -196,5 +327,383 @@ describe Nendo, "when use syntax-rules " do
|
|
196
327
|
@nendo.evalStr( "(test-syntax 'a \"B\")" ).should == '(a ("B"))'
|
197
328
|
@nendo.evalStr( "(test-syntax 'a \"B\" 'C)" ).should == '(a ("B" (C)))'
|
198
329
|
@nendo.evalStr( "(test-syntax 'a \"B\" 'C \"d\")" ).should == '(a ("B" (C "d")))'
|
330
|
+
lambda { @nendo.evalStr( <<EOS
|
331
|
+
(define-syntax dummy-syntax
|
332
|
+
(syntax-rules))
|
333
|
+
EOS
|
334
|
+
) }.should raise_error( RuntimeError, /syntax-rules.+\(1\)/ )
|
335
|
+
lambda { @nendo.evalStr( <<EOS
|
336
|
+
(define-syntax dummy-syntax
|
337
|
+
(syntax-rules eee))
|
338
|
+
EOS
|
339
|
+
) }.should raise_error( RuntimeError, /syntax-rules.+\(2\)/ )
|
340
|
+
|
341
|
+
lambda { @nendo.evalStr( <<EOS
|
342
|
+
(define-syntax dummy-syntax
|
343
|
+
(syntax-rules
|
344
|
+
((_ arg1)
|
345
|
+
arg1)))
|
346
|
+
EOS
|
347
|
+
) }.should raise_error( RuntimeError, /syntax-rules.+\(3\)/ )
|
348
|
+
|
349
|
+
@nendo.evalStr( <<EOS
|
350
|
+
(define this-is-var 1)
|
351
|
+
(define-syntax dummy-syntax
|
352
|
+
(syntax-rules ()
|
353
|
+
((_ arg1)
|
354
|
+
this-is-var)))
|
355
|
+
(macroexpand
|
356
|
+
'(dummy-syntax 100))
|
357
|
+
EOS
|
358
|
+
).should == "this-is-var"
|
359
|
+
|
360
|
+
@nendo.evalStr( <<EOS
|
361
|
+
(define-syntax dummy-syntax
|
362
|
+
(syntax-rules ()
|
363
|
+
((_ arg1)
|
364
|
+
'this-is-symbol)))
|
365
|
+
(macroexpand
|
366
|
+
'(dummy-syntax 100))
|
367
|
+
EOS
|
368
|
+
).should match( /quote #<SyntacticClosure.this-is-symbol:_this/ )
|
369
|
+
|
370
|
+
@nendo.evalStr( <<EOS
|
371
|
+
(define-syntax dummy-syntax
|
372
|
+
(syntax-rules ()
|
373
|
+
((_ arg1)
|
374
|
+
'this-is-symbol)))
|
375
|
+
(dummy-syntax 100)
|
376
|
+
EOS
|
377
|
+
).should == "this-is-symbol"
|
378
|
+
|
199
379
|
end
|
200
380
|
end
|
381
|
+
|
382
|
+
describe Nendo, "When use let-syntax" do
|
383
|
+
before do
|
384
|
+
@nendo = Nendo::Core.new()
|
385
|
+
@nendo.loadInitFile
|
386
|
+
end
|
387
|
+
it "should" do
|
388
|
+
|
389
|
+
@nendo.evalStr( <<EOS
|
390
|
+
(macroexpand
|
391
|
+
'(let-syntax ((nil!
|
392
|
+
(syntax-rules ()
|
393
|
+
((_ x)
|
394
|
+
(set! x '())))))
|
395
|
+
(nil! aa)))
|
396
|
+
EOS
|
397
|
+
).should == "(begin (set! aa (quote ())))"
|
398
|
+
|
399
|
+
@nendo.evalStr( <<EOS
|
400
|
+
(macroexpand
|
401
|
+
'(let-syntax ((dummy-syntax
|
402
|
+
(syntax-rules ()
|
403
|
+
((_ x)
|
404
|
+
'this-is-symbol))))
|
405
|
+
(dummy-syntax 100)))
|
406
|
+
EOS
|
407
|
+
).should match( /begin [(]quote #<SyntacticClosure.this-is-symbol:/ )
|
408
|
+
|
409
|
+
@nendo.evalStr( <<EOS
|
410
|
+
(macroexpand
|
411
|
+
'(let-syntax ((dummy-syntax
|
412
|
+
(syntax-rules ()
|
413
|
+
((_ x)
|
414
|
+
(begin "this is debug line"
|
415
|
+
#?.)))))
|
416
|
+
(dummy-syntax 100)))
|
417
|
+
EOS
|
418
|
+
).should == "(begin (begin \"this is debug line\" \"(string):6\"))"
|
419
|
+
|
420
|
+
@nendo.evalStr( <<EOS
|
421
|
+
(define aa 100)
|
422
|
+
(let-syntax ((nil!
|
423
|
+
(syntax-rules ()
|
424
|
+
((_ x)
|
425
|
+
(set! x '())))))
|
426
|
+
(nil! aa))
|
427
|
+
aa
|
428
|
+
EOS
|
429
|
+
).should == "()"
|
430
|
+
|
431
|
+
@nendo.evalStr( <<EOS
|
432
|
+
(let ()
|
433
|
+
(let-syntax ()
|
434
|
+
(define internal-def 'ok)
|
435
|
+
internal-def))
|
436
|
+
EOS
|
437
|
+
).should == "ok"
|
438
|
+
|
439
|
+
@nendo.evalStr( <<EOS
|
440
|
+
'"internal-def2"
|
441
|
+
(let ()
|
442
|
+
(let-syntax ()
|
443
|
+
(define internal-def 'ok)
|
444
|
+
internal-def))
|
445
|
+
EOS
|
446
|
+
).should == "ok"
|
447
|
+
|
448
|
+
@nendo.evalStr( <<EOS
|
449
|
+
(let-syntax
|
450
|
+
((foo (syntax-rules ()
|
451
|
+
((foo args ... penultimate ultimate)
|
452
|
+
(list ultimate penultimate args ...)))))
|
453
|
+
(foo 1 2 3 4 5))
|
454
|
+
EOS
|
455
|
+
).should == "(5 4 1 2 3)"
|
456
|
+
|
457
|
+
lambda { @nendo.evalStr( <<EOS
|
458
|
+
(let-syntax ((a (+ 1 2)))
|
459
|
+
(a))
|
460
|
+
EOS
|
461
|
+
) }.should raise_error( SyntaxError, /syntax-rules/ )
|
462
|
+
|
463
|
+
lambda { @nendo.evalStr( <<EOS
|
464
|
+
(let-syntax ((a 100))
|
465
|
+
(a))
|
466
|
+
EOS
|
467
|
+
) }.should raise_error( SyntaxError, /syntax-rules/ )
|
468
|
+
|
469
|
+
lambda { @nendo.evalStr( <<EOS
|
470
|
+
(let-syntax ((a (syntax-rules-dummy () 1))
|
471
|
+
(b (syntax-rules () 2)))
|
472
|
+
(list (a) (b)))
|
473
|
+
EOS
|
474
|
+
) }.should raise_error( SyntaxError, /syntax-rules/ )
|
475
|
+
|
476
|
+
@nendo.evalStr( <<EOS
|
477
|
+
(let-syntax ()
|
478
|
+
(list 1 2))
|
479
|
+
EOS
|
480
|
+
).should == "(1 2)"
|
481
|
+
|
482
|
+
@nendo.evalStr( <<EOS
|
483
|
+
(let ()
|
484
|
+
(let-syntax ((a (syntax-rules () ((_ ?x) (+ ?x 8))))
|
485
|
+
(b (syntax-rules () ((_ ?x) (- ?x 8)))))
|
486
|
+
(list (a 7) (b 8))))
|
487
|
+
EOS
|
488
|
+
).should == "(15 0)"
|
489
|
+
|
490
|
+
@nendo.evalStr( <<EOS
|
491
|
+
(let ()
|
492
|
+
(let-syntax ((a (syntax-rules () ((_ ?x) (+ ?x 8))))
|
493
|
+
(b (syntax-rules () ((_ ?x) (- ?x 8)))))
|
494
|
+
(let-syntax ((aa (syntax-rules () ((_ ?x) (b 2))))
|
495
|
+
(bb (syntax-rules () ((_ ?x) (a 3)))))
|
496
|
+
(list (aa 7) (bb 8)))))
|
497
|
+
EOS
|
498
|
+
).should == "(-6 11)"
|
499
|
+
|
500
|
+
@nendo.evalStr( <<EOS
|
501
|
+
(let ()
|
502
|
+
(let-syntax ((a (syntax-rules () ((_ ?x) (+ ?x 8))))
|
503
|
+
(b (syntax-rules () ((_ ?x) (- ?x 8)))))
|
504
|
+
(let-syntax ((a (syntax-rules () ((_ ?y) (b 2))))
|
505
|
+
(b (syntax-rules () ((_ ?y) (a 3)))))
|
506
|
+
(list (a 7) (b 8)))))
|
507
|
+
EOS
|
508
|
+
).should == "(-6 11)"
|
509
|
+
end
|
510
|
+
end
|
511
|
+
|
512
|
+
|
513
|
+
describe Nendo, "When use let-syntax in lexical scope " do
|
514
|
+
before do
|
515
|
+
@nendo = Nendo::Core.new()
|
516
|
+
@nendo.loadInitFile
|
517
|
+
end
|
518
|
+
it "should" do
|
519
|
+
|
520
|
+
@nendo.evalStr( <<EOS
|
521
|
+
(let ((... 2))
|
522
|
+
(let-syntax ((s (syntax-rules ()
|
523
|
+
((_ x ...) 'bad)
|
524
|
+
((_ . r) 'ok))))
|
525
|
+
(s a b c)))
|
526
|
+
EOS
|
527
|
+
).should == "ok"
|
528
|
+
|
529
|
+
@nendo.evalStr( <<EOS
|
530
|
+
(let ((x 'outer))
|
531
|
+
(let-syntax ((m (syntax-rules () ((m) x))))
|
532
|
+
(let ((x 'inner))
|
533
|
+
(m))))
|
534
|
+
EOS
|
535
|
+
).should == "outer"
|
536
|
+
|
537
|
+
@nendo.evalStr( <<EOS
|
538
|
+
(let ((x 'outer1))
|
539
|
+
(let ((y 'outer2))
|
540
|
+
(let ((z 'outer3))
|
541
|
+
(let-syntax ((m (syntax-rules () ((m) (list x y z)))))
|
542
|
+
(let ((x 'inner1))
|
543
|
+
(let ((y 'inner2))
|
544
|
+
(let ((z 'inner3))
|
545
|
+
(m))))))))
|
546
|
+
EOS
|
547
|
+
).should == "(outer1 outer2 outer3)"
|
548
|
+
|
549
|
+
@nendo.evalStr( <<EOS
|
550
|
+
(let ((x 'outer))
|
551
|
+
(let-syntax ((with-x
|
552
|
+
(syntax-rules ()
|
553
|
+
((_ y expr)
|
554
|
+
(let-syntax ((y (syntax-rules () ((_) x))))
|
555
|
+
expr)))))
|
556
|
+
(let ((x 'inner))
|
557
|
+
(with-x z (z)))))
|
558
|
+
EOS
|
559
|
+
).should == "outer"
|
560
|
+
|
561
|
+
pending( "nested let fails on limitation of Nendo's let-syntax." )
|
562
|
+
|
563
|
+
@nendo.evalStr( <<EOS
|
564
|
+
(define z 'top-level-1)
|
565
|
+
(let ((x 'outer1))
|
566
|
+
(let ((y x))
|
567
|
+
(let ((z y))
|
568
|
+
(let-syntax ((m (syntax-rules () ((m) z))))
|
569
|
+
(let ((x 'inner1))
|
570
|
+
(let ((y x))
|
571
|
+
(let ((z y))
|
572
|
+
(m))))))))
|
573
|
+
EOS
|
574
|
+
).should == "outer1"
|
575
|
+
|
576
|
+
end
|
577
|
+
end
|
578
|
+
|
579
|
+
describe Nendo, "When use complex let-syntax" do
|
580
|
+
before do
|
581
|
+
@nendo = Nendo::Core.new()
|
582
|
+
@nendo.loadInitFile
|
583
|
+
end
|
584
|
+
it "should" do
|
585
|
+
|
586
|
+
@nendo.evalStr( <<EOS
|
587
|
+
(define-syntax %cut
|
588
|
+
(syntax-rules (<> <...>)
|
589
|
+
((%cut e? params args)
|
590
|
+
(lambda params args))
|
591
|
+
((%cut e? (params ...) (args ...) <> . rest)
|
592
|
+
(%cut e? (params ... tmp) (args ... tmp) . rest))
|
593
|
+
((%cut e? (params ...) (args ...) <...>)
|
594
|
+
(%cut e? (params ... . tmp) (apply args ... tmp)))
|
595
|
+
((%cut e? (params ...) (args ...) <...> . rest)
|
596
|
+
(error "cut: non-terminal <...>"))
|
597
|
+
((%cut #t (params ...) (args ...) x . rest)
|
598
|
+
(let ((tmp x)) (%cut #t (params ...) (args ... tmp) . rest)))
|
599
|
+
((%cut #f (params ...) (args ...) x . rest)
|
600
|
+
(%cut #t (params ...) (args ... x) . rest))))
|
601
|
+
EOS
|
602
|
+
).should match( /Nendo::LispSyntax/ )
|
603
|
+
|
604
|
+
@nendo.evalStr( <<EOS
|
605
|
+
(define-syntax cut
|
606
|
+
(syntax-rules () ((cut args ...) (%cut #f () () args ...))))
|
607
|
+
EOS
|
608
|
+
).should match( /Nendo::LispSyntax/ )
|
609
|
+
|
610
|
+
@nendo.evalStr( <<EOS
|
611
|
+
(define rassq (cut rassoc <> <> eq?))
|
612
|
+
EOS
|
613
|
+
).should match( /Proc/ )
|
614
|
+
|
615
|
+
@nendo.evalStr( <<EOS
|
616
|
+
((cut list 1 <> 3 <>) 2 4)
|
617
|
+
EOS
|
618
|
+
).should == "(1 2 3 4)"
|
619
|
+
|
620
|
+
@nendo.evalStr( <<EOS
|
621
|
+
(define-syntax match-check-ellipse
|
622
|
+
(syntax-rules ()
|
623
|
+
((match-check-ellipse (a . b) success-k failure-k) failure-k)
|
624
|
+
((match-check-ellipse #(a ...) success-k failure-k) failure-k)
|
625
|
+
;; matching an atom
|
626
|
+
((match-check-ellipse id success-k failure-k)
|
627
|
+
(let-syntax ((ellipse? (syntax-rules ()
|
628
|
+
((ellipse? (foo id) sk fk) sk)
|
629
|
+
((ellipse? other sk fk) fk))))
|
630
|
+
(ellipse? (a b c) success-k failure-k)))))
|
631
|
+
EOS
|
632
|
+
).should match( /Nendo::LispSyntax/ )
|
633
|
+
|
634
|
+
@nendo.evalStr( <<EOS
|
635
|
+
(match-check-ellipse (aa bb) (+ #?. " ellipse") (+ #?. " non-ellipse"))
|
636
|
+
EOS
|
637
|
+
).should == '"(string):1 non-ellipse"'
|
638
|
+
|
639
|
+
@nendo.evalStr( <<EOS
|
640
|
+
(match-check-ellipse xxx (+ #?. " ellipse") (+ #?. " non-ellipse"))
|
641
|
+
EOS
|
642
|
+
).should == '"(string):1 non-ellipse"'
|
643
|
+
|
644
|
+
@nendo.evalStr( <<EOS
|
645
|
+
(match-check-ellipse ... (+ #?. " ellipse") (+ #?. " non-ellipse"))
|
646
|
+
EOS
|
647
|
+
).should == '"(string):1 ellipse"'
|
648
|
+
|
649
|
+
@nendo.evalStr( <<EOS
|
650
|
+
(define-syntax dummy-syntax
|
651
|
+
(syntax-rules ()
|
652
|
+
((_ arg)
|
653
|
+
(match-check-ellipse arg (result-str "ellipse") (result-str "non-ellipse")))))
|
654
|
+
(define-syntax result-str
|
655
|
+
(syntax-rules ()
|
656
|
+
((_ arg-str)
|
657
|
+
(+ #?. " " arg-str))))
|
658
|
+
(dummy-syntax xxx)
|
659
|
+
EOS
|
660
|
+
).should == '"(string):8 non-ellipse"'
|
661
|
+
|
662
|
+
@nendo.evalStr( <<EOS
|
663
|
+
(match-check-ellipse ... (match-check-ellipse xxx 'tt 'tf) (match-check-ellipse xxx 'ft 'ff))
|
664
|
+
EOS
|
665
|
+
).should == 'tf'
|
666
|
+
|
667
|
+
@nendo.evalStr( <<EOS
|
668
|
+
(match-check-ellipse yyy (match-check-ellipse xxx 'tt 'tf) (match-check-ellipse xxx 'ft 'ff))
|
669
|
+
EOS
|
670
|
+
).should == 'ff'
|
671
|
+
|
672
|
+
@nendo.evalStr( <<EOS
|
673
|
+
(define-syntax match-check-identifier
|
674
|
+
(syntax-rules ()
|
675
|
+
;; fast-case failures, lists and vectors are not identifiers
|
676
|
+
((_ (x . y) success-k failure-k) failure-k)
|
677
|
+
((_ #(x ...) success-k failure-k) failure-k)
|
678
|
+
;; x is an atom
|
679
|
+
((_ x success-k failure-k)
|
680
|
+
(let-syntax
|
681
|
+
((sym?
|
682
|
+
(syntax-rules ()
|
683
|
+
((sym? x sk fk) sk)
|
684
|
+
;; otherwise x is a non-symbol datum
|
685
|
+
((sym? y sk fk) (begin #?. fk)))))
|
686
|
+
(sym? abracadabra success-k failure-k)))))
|
687
|
+
EOS
|
688
|
+
).should match( /Nendo::LispSyntax/ )
|
689
|
+
|
690
|
+
@nendo.evalStr( <<EOS
|
691
|
+
(match-check-identifier (aa bb) "id" "non-id")
|
692
|
+
EOS
|
693
|
+
).should == '"non-id"'
|
694
|
+
|
695
|
+
@nendo.evalStr( <<EOS
|
696
|
+
(match-check-identifier xx "id" "non-id")
|
697
|
+
EOS
|
698
|
+
).should == '"id"'
|
699
|
+
|
700
|
+
@nendo.evalStr( <<EOS
|
701
|
+
(let ([yy (match-check-identifier xx "id" "non-id")])
|
702
|
+
yy)
|
703
|
+
EOS
|
704
|
+
).should == '"id"'
|
705
|
+
|
706
|
+
end
|
707
|
+
end
|
708
|
+
|
709
|
+
|