nendo 0.4.1 → 0.5.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/example/scratch.nnd +107 -49
- data/lib/init.nnd +429 -78
- data/lib/init.nndc +16939 -9197
- data/lib/nendo.rb +163 -53
- data/lib/rfc/json.nnd +1 -1
- data/lib/rfc/json.nndc +21 -6
- data/lib/srfi-1.nnd +9 -5
- data/lib/srfi-1.nndc +684 -626
- data/lib/srfi-2.nnd +42 -0
- data/lib/srfi-2.nndc +1350 -0
- data/lib/srfi-26.nnd +50 -0
- data/lib/srfi-26.nndc +4124 -0
- data/lib/text/html-lite.nndc +7 -1
- data/lib/util/list.nnd +184 -0
- data/lib/util/list.nndc +5453 -0
- data/test/{util-test.nnd → nendo-util-test.nnd} +4 -4
- data/test/nendo_spec.rb +136 -81
- data/test/srfi-1-test.nnd +8 -4
- data/test/srfi-2-test.nnd +63 -0
- data/test/srfi-26-test.nnd +89 -0
- data/test/syntax_spec.rb +200 -0
- data/test/util-list-test.nnd +178 -0
- metadata +16 -5
data/lib/init.nnd
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
;;;
|
3
3
|
;;; init.nnd - Nendo's init file.
|
4
4
|
;;;
|
5
|
-
;;; Copyright (c) 2009-
|
5
|
+
;;; Copyright (c) 2009-2011 Kiyoka Nishiyama <kiyoka@sumibi.org>
|
6
6
|
;;;
|
7
7
|
;;; Redistribution and use in source and binary forms, with or without
|
8
8
|
;;; modification, are permitted provided that the following conditions
|
@@ -162,7 +162,12 @@
|
|
162
162
|
(define (ninth lst) (nth 8 lst))
|
163
163
|
(define (tenth lst) (nth 9 lst))
|
164
164
|
|
165
|
-
(define (x->string object)
|
165
|
+
(define (x->string object) (to-s object))
|
166
|
+
(define (number->string num) (x->string num))
|
167
|
+
(define string-append
|
168
|
+
(lambda str-lst
|
169
|
+
(string-join str-lst "")))
|
170
|
+
|
166
171
|
|
167
172
|
;; ----------------------------------------
|
168
173
|
;; basic forms
|
@@ -442,7 +447,8 @@
|
|
442
447
|
;; generic-member
|
443
448
|
(define (generic-member cmp obj lst)
|
444
449
|
(cond
|
445
|
-
((null? lst)
|
450
|
+
((null? lst) #f)
|
451
|
+
((not (pair? lst)) #f)
|
446
452
|
((cmp obj (car lst)) lst)
|
447
453
|
(else (generic-member cmp obj (cdr lst)))))
|
448
454
|
|
@@ -565,14 +571,6 @@
|
|
565
571
|
`(,_sym ,@_src))))))))
|
566
572
|
|
567
573
|
|
568
|
-
(define lambda
|
569
|
-
(macro src
|
570
|
-
(%internal-define-to-letrec 'lambda src)))
|
571
|
-
|
572
|
-
(define macro
|
573
|
-
(macro src
|
574
|
-
(%internal-define-to-letrec 'macro src)))
|
575
|
-
|
576
574
|
(define (%for-each proc . lists)
|
577
575
|
(define (%for-each-arg1 proc lst)
|
578
576
|
(if (null? lst)
|
@@ -629,12 +627,87 @@
|
|
629
627
|
#f
|
630
628
|
(car result))))
|
631
629
|
|
630
|
+
(define (any pred lst)
|
631
|
+
(let1 result (%filter-map pred lst)
|
632
|
+
(if (null? result)
|
633
|
+
#f
|
634
|
+
(car result))))
|
635
|
+
|
632
636
|
(define map %map)
|
633
637
|
(define for-each %for-each)
|
634
638
|
(define filter %filter)
|
635
639
|
(define filter-map %filter-map)
|
636
640
|
|
637
641
|
|
642
|
+
;; ----------------------------------------
|
643
|
+
;; lambda & macro
|
644
|
+
;; ----------------------------------------
|
645
|
+
(define (%%optional-argument-check target arg-and-body)
|
646
|
+
(let1 arg-list (if (list? arg-and-body)
|
647
|
+
(car arg-and-body)
|
648
|
+
'())
|
649
|
+
(when (list? arg-list)
|
650
|
+
(when (any (lambda (x) (keyword? x)) arg-list)
|
651
|
+
(errorf "Error: %s can't handle keyword argument." target)))))
|
652
|
+
|
653
|
+
(define lambda
|
654
|
+
(macro src
|
655
|
+
(%%optional-argument-check 'lambda src)
|
656
|
+
(%internal-define-to-letrec 'lambda src)))
|
657
|
+
|
658
|
+
(define macro
|
659
|
+
(macro src
|
660
|
+
(%%optional-argument-check 'macro src)
|
661
|
+
(%internal-define-to-letrec 'macro src)))
|
662
|
+
|
663
|
+
;; ----------------------------------------
|
664
|
+
;; :optional argument feature for define (The original is Gauche 0.9.1's feature)
|
665
|
+
;; like "(define (func a b : optional (c #f)) ... )"
|
666
|
+
;; ----------------------------------------
|
667
|
+
(define (%transform-optional-arguments arg body-list)
|
668
|
+
(if-let1 rest-of-opts (memq :optional arg)
|
669
|
+
(let([opts '()]
|
670
|
+
[rest-of-opts (cdr rest-of-opts)]
|
671
|
+
[_rest (gensym)])
|
672
|
+
;; arguemnt form check
|
673
|
+
(for-each
|
674
|
+
(lambda (x)
|
675
|
+
(let1 syntax-is-ok (if (pair? x)
|
676
|
+
(= 2 (length x))
|
677
|
+
#f)
|
678
|
+
(unless syntax-is-ok
|
679
|
+
(error "Error: :optional format is illegal ... " arg))))
|
680
|
+
rest-of-opts)
|
681
|
+
(let loop ((arg arg))
|
682
|
+
(if (eq? :optional (car arg))
|
683
|
+
arg
|
684
|
+
(begin
|
685
|
+
(set! opts (cons (car arg) opts))
|
686
|
+
(loop (cdr arg)))))
|
687
|
+
(let1 new-arg (apply list* (append (reverse opts) (list _rest)))
|
688
|
+
(list 'lambda
|
689
|
+
new-arg
|
690
|
+
`(let
|
691
|
+
,rest-of-opts
|
692
|
+
,@(map
|
693
|
+
(lambda (k n)
|
694
|
+
`(when (< ,n (length ,_rest))
|
695
|
+
(set! ,(car k) (nth ,n ,_rest))))
|
696
|
+
rest-of-opts
|
697
|
+
(range (length rest-of-opts)))
|
698
|
+
,@body-list))))
|
699
|
+
`(lambda ,arg ,@body-list)))
|
700
|
+
|
701
|
+
(define %expand-define-form-lambda
|
702
|
+
(lambda (arg body-list)
|
703
|
+
;; (define (func arg...) body)
|
704
|
+
(if (pair? (cdr arg))
|
705
|
+
(if (pair? (car (cdr arg)))
|
706
|
+
(error "Error: define syntax error.")))
|
707
|
+
(cons 'define
|
708
|
+
(list (car arg)
|
709
|
+
(%transform-optional-arguments (cdr arg) body-list)))))
|
710
|
+
|
638
711
|
|
639
712
|
|
640
713
|
;; ----------------------------------------
|
@@ -751,6 +824,11 @@
|
|
751
824
|
(cadr rest)
|
752
825
|
(cddr rest)))))))))
|
753
826
|
|
827
|
+
(define (keyword->symbol kw)
|
828
|
+
(string->symbol
|
829
|
+
(keyword->string kw)))
|
830
|
+
|
831
|
+
|
754
832
|
;; ----------------------------------------
|
755
833
|
;; for Ruby interop
|
756
834
|
;; ----------------------------------------
|
@@ -801,7 +879,7 @@
|
|
801
879
|
;; ----------------------------------------
|
802
880
|
;; hash-table library functions
|
803
881
|
;; ----------------------------------------
|
804
|
-
(define (make-hash-table)
|
882
|
+
(define (make-hash-table . eq)
|
805
883
|
(Hash.new))
|
806
884
|
|
807
885
|
(define (hash-table? h)
|
@@ -810,7 +888,10 @@
|
|
810
888
|
(define (hash-table-num-entries h)
|
811
889
|
(h.length))
|
812
890
|
|
813
|
-
(define (hash-table . kv-list)
|
891
|
+
(define (hash-table type . kv-list)
|
892
|
+
(unless (or (eq? type eq?)
|
893
|
+
(eq? type eqv?))
|
894
|
+
(error "Error: hash-table got eq? or eqv? as type"))
|
814
895
|
(let1 h (make-hash-table)
|
815
896
|
(for-each
|
816
897
|
(lambda (entry)
|
@@ -844,20 +925,6 @@
|
|
844
925
|
keys)))
|
845
926
|
(define hash-table-for-each hash-table-map)
|
846
927
|
|
847
|
-
(define (hash-table->alist h)
|
848
|
-
(if (not (h.is_a? Hash))
|
849
|
-
(error "Error: hash-table->alist expects Hash instance.")
|
850
|
-
(let1 keys (hash-table-keys h)
|
851
|
-
(map
|
852
|
-
(lambda (key)
|
853
|
-
(cons key (hash-table-get h key)))
|
854
|
-
keys))))
|
855
|
-
|
856
|
-
(define (alist->hash-table alist)
|
857
|
-
(if (not (%list? alist))
|
858
|
-
(error "Error: alist->hash-table expects alist.")
|
859
|
-
(apply hash-table alist)))
|
860
|
-
|
861
928
|
|
862
929
|
;; ----------------------------------------
|
863
930
|
;; Vector Library
|
@@ -916,15 +983,24 @@
|
|
916
983
|
;; Utility function for testing and debugging
|
917
984
|
;; ----------------------------------------
|
918
985
|
;; Gauche's #?= like debug print function
|
919
|
-
(define debug-print-length 63)
|
986
|
+
(define *debug-print-length* 63)
|
987
|
+
(define (debug-print-length . len)
|
988
|
+
(let1 len (get-optional len 'none)
|
989
|
+
(if (eq? len 'none)
|
990
|
+
*debug-print-length*
|
991
|
+
(set! *debug-print-length* len))))
|
920
992
|
(define (debug-print-output-func str) ;; default output func
|
921
993
|
(STDERR.print str))
|
922
994
|
(define (debug-limit-length x)
|
923
995
|
(+
|
924
|
-
(
|
925
|
-
|
926
|
-
|
927
|
-
|
996
|
+
(cond
|
997
|
+
((not *debug-print-length*)
|
998
|
+
x)
|
999
|
+
((< *debug-print-length* x.length)
|
1000
|
+
(let1 n *debug-print-length*.to_s
|
1001
|
+
(sprintf (+ "%" n "." n "s ...") x)))
|
1002
|
+
(else
|
1003
|
+
x))
|
928
1004
|
"\n"))
|
929
1005
|
|
930
1006
|
(define debug-print
|
@@ -1232,8 +1308,14 @@
|
|
1232
1308
|
;; ----------------------------------------
|
1233
1309
|
(define (setup-tailcall-mark sexp)
|
1234
1310
|
(define (reserved? sym)
|
1235
|
-
(
|
1236
|
-
|
1311
|
+
(let* ([reserved-orig '(quote syntax-quote macro %syntax begin lambda if let letrec define define-syntax)]
|
1312
|
+
[reserved (append reserved-orig
|
1313
|
+
(map
|
1314
|
+
(lambda (orig)
|
1315
|
+
(string->symbol (+ "/nendo/core/" (symbol->string orig))))
|
1316
|
+
reserved-orig))])
|
1317
|
+
(memq sym reserved)))
|
1318
|
+
|
1237
1319
|
(define (setup-let-args args)
|
1238
1320
|
(map
|
1239
1321
|
(lambda (arg)
|
@@ -1285,50 +1367,64 @@
|
|
1285
1367
|
((null? sexp)
|
1286
1368
|
'())
|
1287
1369
|
((list? sexp)
|
1288
|
-
(
|
1289
|
-
(
|
1290
|
-
|
1291
|
-
|
1292
|
-
|
1293
|
-
|
1294
|
-
|
1295
|
-
|
1296
|
-
|
1297
|
-
|
1298
|
-
|
1299
|
-
|
1300
|
-
|
1301
|
-
|
1302
|
-
(
|
1303
|
-
|
1304
|
-
|
1305
|
-
|
1306
|
-
((
|
1307
|
-
|
1308
|
-
,
|
1309
|
-
|
1310
|
-
|
1311
|
-
|
1312
|
-
|
1313
|
-
|
1314
|
-
|
1315
|
-
|
1316
|
-
|
1317
|
-
|
1318
|
-
|
1319
|
-
|
1320
|
-
|
1321
|
-
`(
|
1322
|
-
|
1323
|
-
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
1327
|
-
|
1328
|
-
|
1329
|
-
|
1330
|
-
|
1331
|
-
|
1370
|
+
(let1 _car (car sexp)
|
1371
|
+
(case _car
|
1372
|
+
((quote /nendo/core/quote)
|
1373
|
+
sexp)
|
1374
|
+
((syntax-quote /nendo/core/syntax-quote)
|
1375
|
+
sexp)
|
1376
|
+
((macro /nendo/core/macro)
|
1377
|
+
sexp)
|
1378
|
+
((%syntax /nendo/core/%syntax)
|
1379
|
+
sexp)
|
1380
|
+
((begin /nendo/core/begin)
|
1381
|
+
`(,_car
|
1382
|
+
,@(setup-proc-body (cdr sexp))))
|
1383
|
+
((lambda /nendo/core/lambda)
|
1384
|
+
`(,_car
|
1385
|
+
,(second sexp)
|
1386
|
+
,@(setup-proc-body (cddr sexp))))
|
1387
|
+
((if /nendo/core/if)
|
1388
|
+
(case (length sexp)
|
1389
|
+
((3)
|
1390
|
+
`(,_car
|
1391
|
+
,(second sexp)
|
1392
|
+
,(setup-proc (third sexp))))
|
1393
|
+
((4)
|
1394
|
+
`(,_car
|
1395
|
+
,(second sexp)
|
1396
|
+
,(setup-proc (third sexp))
|
1397
|
+
,(setup-proc (fourth sexp))))))
|
1398
|
+
((let /nendo/core/let)
|
1399
|
+
`(,_car
|
1400
|
+
,(setup-let-args (second sexp))
|
1401
|
+
,@(setup-proc-body (cddr sexp))))
|
1402
|
+
((letrec /nendo/core/letrec)
|
1403
|
+
`(,_car
|
1404
|
+
,(setup-let-args (second sexp))
|
1405
|
+
,@(setup-proc-body (cddr sexp))))
|
1406
|
+
((define /nendo/core/define define-syntax /nendo/core/define-syntax)
|
1407
|
+
(let1 val (third sexp)
|
1408
|
+
`(,_car
|
1409
|
+
,(second sexp)
|
1410
|
+
,(if (and (list? val)
|
1411
|
+
(not (null? val))
|
1412
|
+
(reserved? (car val)))
|
1413
|
+
(setup-tailcall-mark val)
|
1414
|
+
val))))
|
1415
|
+
((set! /nendo/core/set!)
|
1416
|
+
(let1 val (third sexp)
|
1417
|
+
`(,_car
|
1418
|
+
,(second sexp)
|
1419
|
+
,(if (and (list? val)
|
1420
|
+
(not (null? val))
|
1421
|
+
(reserved? (car val)))
|
1422
|
+
(setup-tailcall-mark val)
|
1423
|
+
val))))
|
1424
|
+
(else
|
1425
|
+
(if (symbol? (car sexp))
|
1426
|
+
`(%tailcall ,sexp)
|
1427
|
+
sexp)))))
|
1332
1428
|
(else
|
1333
1429
|
sexp)))
|
1334
1430
|
|
@@ -1339,4 +1435,259 @@
|
|
1339
1435
|
setup-tailcall-mark
|
1340
1436
|
))
|
1341
1437
|
|
1438
|
+
|
1439
|
+
|
1440
|
+
;; explicit renameing macro transformer
|
1441
|
+
;; ported from chibi-scheme-0.3 by Kiyoka Nishiyama
|
1442
|
+
;;
|
1443
|
+
;; URL: http://community.schemewiki.org/?syntactic-closures
|
1444
|
+
;;
|
1445
|
+
(define (strip-syntactic-closures expr)
|
1446
|
+
expr)
|
1447
|
+
|
1448
|
+
|
1449
|
+
(define (identifier? x)
|
1450
|
+
(symbol? x))
|
1451
|
+
|
1452
|
+
(define (identifier=? use-env-x x use-env-y y)
|
1453
|
+
(eq? x y))
|
1454
|
+
|
1455
|
+
|
1456
|
+
;; readable code for nendo. (original code is chibi-scheme-0.3)
|
1457
|
+
(define er-macro-transformer
|
1458
|
+
(lambda (f)
|
1459
|
+
(%syntax (expr use-env mac-env)
|
1460
|
+
(define (expander-main rename compare)
|
1461
|
+
(f expr rename compare))
|
1462
|
+
(define (_rename renames)
|
1463
|
+
(lambda (identifier)
|
1464
|
+
(let ([cell (assq identifier renames)])
|
1465
|
+
(if cell
|
1466
|
+
(cdr cell)
|
1467
|
+
((lambda (name)
|
1468
|
+
(set! renames (cons (cons identifier name) renames))
|
1469
|
+
name)
|
1470
|
+
(make-syntactic-closure mac-env '() identifier))))))
|
1471
|
+
(define (_compare x y)
|
1472
|
+
(sprintf "compare( %s %s )" x y)
|
1473
|
+
(identifier=? use-env x use-env y))
|
1474
|
+
|
1475
|
+
(expander-main
|
1476
|
+
(_rename '())
|
1477
|
+
_compare))))
|
1478
|
+
|
1479
|
+
|
1480
|
+
;; explicit renameing macro transformer
|
1481
|
+
;; ported from chibi-scheme-0.3 by Kiyoka Nishiyama
|
1482
|
+
(define ... '...)
|
1483
|
+
(define-syntax syntax-rules
|
1484
|
+
(er-macro-transformer
|
1485
|
+
(lambda (expr rename compare)
|
1486
|
+
(let ((ellipse-specified? (identifier? (cadr expr)))
|
1487
|
+
(count 0)
|
1488
|
+
(_er-macro-transformer (rename 'er-macro-transformer))
|
1489
|
+
(_lambda (rename 'lambda)) (_let (rename 'let))
|
1490
|
+
(_begin (rename 'begin)) (_if (rename 'if))
|
1491
|
+
(_and (rename 'and)) (_or (rename 'or))
|
1492
|
+
(_eq? (rename 'eq?)) (_equal? (rename 'equal?))
|
1493
|
+
(_car (rename 'car)) (_cdr (rename 'cdr))
|
1494
|
+
(_cons (rename 'cons)) (_pair? (rename 'pair?))
|
1495
|
+
(_null? (rename 'null?)) (_expr (rename 'expr))
|
1496
|
+
(_rename (rename 'rename)) (_compare (rename 'compare))
|
1497
|
+
(_quote (rename 'syntax-quote)) (_apply (rename 'apply))
|
1498
|
+
(_append (rename 'append)) (_map (rename 'map))
|
1499
|
+
(_vector? (rename 'vector?)) (_list? (rename 'list?))
|
1500
|
+
(_lp (rename 'lp)) (_reverse (rename 'reverse))
|
1501
|
+
(_len (rename'len)) (_length (rename 'length))
|
1502
|
+
(_- (rename '-)) (_>= (rename '>=)) (_error (rename 'error))
|
1503
|
+
(_ls (rename 'ls)) (_res (rename 'res)) (_i (rename 'i))
|
1504
|
+
(_vector->list (rename 'vector->list))
|
1505
|
+
(_list->vector (rename 'list->vector)))
|
1506
|
+
(define ellipse (rename (if ellipse-specified? (cadr expr) '...)))
|
1507
|
+
(define lits (if ellipse-specified? (caddr expr) (cadr expr)))
|
1508
|
+
(define forms (if ellipse-specified? (cdddr expr) (cddr expr)))
|
1509
|
+
(define (next-v)
|
1510
|
+
(set! count (+ count 1))
|
1511
|
+
(rename (string->symbol (string-append "v__" (number->string count)))))
|
1512
|
+
(define (expand-pattern pat tmpl)
|
1513
|
+
(let lp ((p (cdr pat))
|
1514
|
+
(x (list _cdr _expr))
|
1515
|
+
(dim 0)
|
1516
|
+
(vars '())
|
1517
|
+
(k (lambda (vars)
|
1518
|
+
(or (expand-template tmpl vars)
|
1519
|
+
(list _begin #f)))))
|
1520
|
+
(let ((v (next-v)))
|
1521
|
+
(list
|
1522
|
+
_let (list (list v x))
|
1523
|
+
(cond
|
1524
|
+
((identifier? p)
|
1525
|
+
(if (find (lambda (l) (compare p l)) lits)
|
1526
|
+
(list _and (list _compare v (list _quote p)) (k vars))
|
1527
|
+
(list _let (list (list p v)) (k (cons (cons p dim) vars)))))
|
1528
|
+
((ellipse? p)
|
1529
|
+
(cond
|
1530
|
+
((not (null? (cddr p)))
|
1531
|
+
(cond
|
1532
|
+
((not (list? (cddr p)))
|
1533
|
+
(error "dotted ellipse" p))
|
1534
|
+
((find (lambda (x) (and (identifier? x) (compare x ellipse)))
|
1535
|
+
(cddr p))
|
1536
|
+
(error "multiple ellipses" p))
|
1537
|
+
(else
|
1538
|
+
(let ((len (length (cdr (cdr p)))))
|
1539
|
+
`(,_let ((,_len (,_length ,v)))
|
1540
|
+
(,_and (,_>= ,_len ,len)
|
1541
|
+
(,_let ,_lp ((,_ls ,v)
|
1542
|
+
(,_i (,_- ,_len ,len))
|
1543
|
+
(,_res (,_quote ())))
|
1544
|
+
(,_if (,_>= 0 ,_i)
|
1545
|
+
,(lp `(,@(cdr (cdr p)) ,(car p) ,(car (cdr p)))
|
1546
|
+
`(,_append ,_ls (,_reverse ,_res))
|
1547
|
+
dim
|
1548
|
+
vars
|
1549
|
+
k)
|
1550
|
+
(,_lp (,_cdr ,_ls)
|
1551
|
+
(,_- ,_i 1)
|
1552
|
+
(,_cons (,_car ,_ls) ,_res))))))))))
|
1553
|
+
((identifier? (car p))
|
1554
|
+
(list _and (list _list? v)
|
1555
|
+
(list _let (list (list (car p) v))
|
1556
|
+
(k (cons (cons (car p) (+ 1 dim)) vars)))))
|
1557
|
+
(else
|
1558
|
+
(let* ((w (next-v))
|
1559
|
+
(new-vars (all-vars (car p) (+ dim 1)))
|
1560
|
+
(ls-vars (map (lambda (x)
|
1561
|
+
(rename
|
1562
|
+
(string->symbol
|
1563
|
+
(string-append
|
1564
|
+
(symbol->string
|
1565
|
+
(identifier->symbol (car x)))
|
1566
|
+
"-ls"))))
|
1567
|
+
new-vars))
|
1568
|
+
(once
|
1569
|
+
(lp (car p) (list _car w) (+ dim 1) '()
|
1570
|
+
(lambda (_)
|
1571
|
+
(cons
|
1572
|
+
_lp
|
1573
|
+
(cons
|
1574
|
+
(list _cdr w)
|
1575
|
+
(map (lambda (x l)
|
1576
|
+
(list _cons (car x) l))
|
1577
|
+
new-vars
|
1578
|
+
ls-vars)))))))
|
1579
|
+
(list
|
1580
|
+
_let
|
1581
|
+
_lp (cons (list w v)
|
1582
|
+
(map (lambda (x) (list x '())) ls-vars))
|
1583
|
+
(list _if (list _null? w)
|
1584
|
+
(list _let (map (lambda (x l)
|
1585
|
+
(list (car x) (list _reverse l)))
|
1586
|
+
new-vars
|
1587
|
+
ls-vars)
|
1588
|
+
(k (append new-vars vars)))
|
1589
|
+
(list _and (list _pair? w) once)))))))
|
1590
|
+
((pair? p)
|
1591
|
+
(list _and (list _pair? v)
|
1592
|
+
(lp (car p)
|
1593
|
+
(list _car v)
|
1594
|
+
dim
|
1595
|
+
vars
|
1596
|
+
(lambda (vars)
|
1597
|
+
(lp (cdr p) (list _cdr v) dim vars k)))))
|
1598
|
+
((vector? p)
|
1599
|
+
(list _and
|
1600
|
+
(list _vector? v)
|
1601
|
+
(lp (vector->list p) (list _vector->list v) dim vars k)))
|
1602
|
+
((null? p) (list _and (list _null? v) (k vars)))
|
1603
|
+
(else (list _and (list _equal? v p) (k vars))))))))
|
1604
|
+
(define (ellipse-escape? x) (and (pair? x) (compare ellipse (car x))))
|
1605
|
+
(define (ellipse? x)
|
1606
|
+
(and (pair? x) (pair? (cdr x)) (compare ellipse (cadr x))))
|
1607
|
+
(define (ellipse-depth x)
|
1608
|
+
(if (ellipse? x)
|
1609
|
+
(+ 1 (ellipse-depth (cdr x)))
|
1610
|
+
0))
|
1611
|
+
(define (ellipse-tail x)
|
1612
|
+
(if (ellipse? x)
|
1613
|
+
(ellipse-tail (cdr x))
|
1614
|
+
(cdr x)))
|
1615
|
+
(define (all-vars x dim)
|
1616
|
+
(let lp ((x x) (dim dim) (vars '()))
|
1617
|
+
(cond ((identifier? x)
|
1618
|
+
(if (find (lambda (lit) (compare x lit)) lits)
|
1619
|
+
vars
|
1620
|
+
(cons (cons x dim) vars)))
|
1621
|
+
((ellipse? x) (lp (car x) (+ dim 1) vars))
|
1622
|
+
((pair? x) (lp (car x) dim (lp (cdr x) dim vars)))
|
1623
|
+
((vector? x) (lp (vector->list x) dim vars))
|
1624
|
+
(else vars))))
|
1625
|
+
(define (free-vars x vars dim)
|
1626
|
+
(let lp ((x x) (free '()))
|
1627
|
+
(cond
|
1628
|
+
((identifier? x)
|
1629
|
+
(if (and (not (memq x free))
|
1630
|
+
(cond ((assq x vars) => (lambda (cell) (>= (cdr cell) dim)))
|
1631
|
+
(else #f)))
|
1632
|
+
(cons x free)
|
1633
|
+
free))
|
1634
|
+
((pair? x) (lp (car x) (lp (cdr x) free)))
|
1635
|
+
((vector? x) (lp (vector->list x) free))
|
1636
|
+
(else free))))
|
1637
|
+
(define (expand-template tmpl vars)
|
1638
|
+
(let lp ((t tmpl) (dim 0))
|
1639
|
+
(cond
|
1640
|
+
((identifier? t)
|
1641
|
+
(cond
|
1642
|
+
((find (lambda (v) (compare t (car v))) vars)
|
1643
|
+
=> (lambda (cell)
|
1644
|
+
(if (<= (cdr cell) dim)
|
1645
|
+
t
|
1646
|
+
(error "too few ...'s"))))
|
1647
|
+
(else
|
1648
|
+
(list _rename (list _quote t)))))
|
1649
|
+
((pair? t)
|
1650
|
+
(cond
|
1651
|
+
((ellipse-escape? t)
|
1652
|
+
(if (pair? (cdr t))
|
1653
|
+
(if (pair? (cddr t)) (cddr t) (cadr t))
|
1654
|
+
(cdr t)))
|
1655
|
+
((ellipse? t)
|
1656
|
+
(let* ((depth (ellipse-depth t))
|
1657
|
+
(ell-dim (+ dim depth))
|
1658
|
+
(ell-vars (free-vars (car t) vars ell-dim)))
|
1659
|
+
(if (null? ell-vars)
|
1660
|
+
(error "too many ...'s")
|
1661
|
+
(let* ((once (lp (car t) ell-dim))
|
1662
|
+
(nest (if (and (null? (cdr ell-vars))
|
1663
|
+
(identifier? once)
|
1664
|
+
(eq? once (car vars)))
|
1665
|
+
once ;; shortcut
|
1666
|
+
(cons _map
|
1667
|
+
(cons (list _lambda ell-vars once)
|
1668
|
+
ell-vars))))
|
1669
|
+
(many (do ((d depth (- d 1))
|
1670
|
+
(many nest
|
1671
|
+
(list _apply _append many)))
|
1672
|
+
((= d 1) many))))
|
1673
|
+
(if (null? (ellipse-tail t))
|
1674
|
+
many ;; shortcut
|
1675
|
+
(list _append many (lp (ellipse-tail t) dim)))))))
|
1676
|
+
(else (list _cons (lp (car t) dim) (lp (cdr t) dim)))))
|
1677
|
+
((vector? t) (list _list->vector (lp (vector->list t) dim)))
|
1678
|
+
((null? t) (list _quote '()))
|
1679
|
+
(else t))))
|
1680
|
+
(list
|
1681
|
+
_er-macro-transformer
|
1682
|
+
(list _lambda (list _expr _rename _compare)
|
1683
|
+
(cons
|
1684
|
+
_or
|
1685
|
+
(append
|
1686
|
+
(map
|
1687
|
+
(lambda (clause) (expand-pattern (car clause) (cadr clause)))
|
1688
|
+
forms)
|
1689
|
+
(list (list _error "no expansion for"
|
1690
|
+
(list (rename 'strip-syntactic-closures) _expr)))))))))))
|
1691
|
+
|
1692
|
+
|
1342
1693
|
;;[EOS]
|