~ chicken-core (master) /chicken-syntax.scm
Trap1;;;; chicken-syntax.scm - non-standard syntax extensions2;3; Copyright (c) 2008-2022, The CHICKEN Team4; Copyright (c) 2000-2007, Felix L. Winkelmann5; All rights reserved.6;7; Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following8; conditions are met:9;10; Redistributions of source code must retain the above copyright notice, this list of conditions and the following11; disclaimer.12; Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following13; disclaimer in the documentation and/or other materials provided with the distribution.14; Neither the name of the author nor the names of its contributors may be used to endorse or promote15; products derived from this software without specific prior written permission.16;17; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS18; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY19; AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR20; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR21; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR22; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY23; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR24; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE25; POSSIBILITY OF SUCH DAMAGE.262728(declare29 (unit chicken-syntax)30 (uses expand internal)31 (disable-interrupts)32 (fixnum) )3334;; IMPORTANT: These macros expand directly into fully qualified names35;; from the scrutinizer and support modules.3637#+(not debugbuild)38(declare39 (no-bound-checks)40 (no-procedure-checks))4142(import (scheme)43 (chicken base)44 (chicken fixnum)45 (chicken syntax)46 (chicken internal)47 (chicken platform))4849(include "common-declarations.scm")50(include "mini-srfi-1.scm")5152;;; Exceptions:53(set! ##sys#chicken.condition-macro-environment54 (let ((me0 (##sys#macro-environment)))5556(##sys#extend-macro-environment57 'handle-exceptions58 `((call-with-current-continuation . scheme#call-with-current-continuation))59 (##sys#er-transformer60 (lambda (form r c)61 (##sys#check-syntax 'handle-exceptions form '(_ variable _ . _))62 (let ((k (r 'k))63 (args (r 'args)))64 `((,(r 'call-with-current-continuation)65 (##core#lambda66 (,k)67 (chicken.condition#with-exception-handler68 (##core#lambda (,(cadr form)) (,k (##core#lambda () ,(caddr form))))69 (##core#lambda70 ()71 (##sys#call-with-values72 (##core#lambda () ,@(cdddr form))73 (##core#lambda74 ,args75 (,k (##core#lambda () (##sys#apply ##sys#values ,args))))))))))))))7677(##sys#extend-macro-environment78 'condition-case79 `((memv . scheme#memv))80 (##sys#er-transformer81 (lambda (form r c)82 (##sys#check-syntax 'condition-case form '(_ _ . _))83 (let ((exvar (r 'exvar))84 (kvar (r 'kvar))85 (%and (r 'and))86 (%memv (r 'memv))87 (%else (r 'else)))88 (define (parse-clause c)89 (let* ((var (and (symbol? (car c)) (car c)))90 (kinds (if var (cadr c) (car c)))91 (body (if var92 `(##core#let ((,var ,exvar)) ,@(cddr c))93 `(##core#let () ,@(cdr c)))))94 (if (null? kinds)95 `(,%else ,body)96 `((,%and ,kvar ,@(map (lambda (k)97 `(,%memv (##core#quote ,k) ,kvar)) kinds))98 ,body))))99 `(,(r 'handle-exceptions) ,exvar100 (##core#let ((,kvar (,%and (##sys#structure? ,exvar101 (##core#quote condition))102 (##sys#slot ,exvar 1))))103 ,(let ((clauses (map parse-clause (cddr form))))104 `(,(r 'cond)105 ,@clauses106 ,@(if (assq %else clauses)107 `() ; Don't generate two else clauses108 `((,%else (chicken.condition#signal ,exvar)))))))109 ,(cadr form))))))110111(macro-subset me0 ##sys#default-macro-environment)))112113114;;; type-related syntax115116(set! ##sys#chicken.type-macro-environment117 (let ((me0 (##sys#macro-environment)))118119(##sys#extend-macro-environment120 ': '()121 (##sys#er-transformer122 (lambda (x r c)123 (##sys#check-syntax ': x '(_ symbol _ . _))124 (if (not (memq #:compiling ##sys#features))125 '(##core#undefined)126 (let* ((type1 (strip-syntax (caddr x)))127 (name1 (cadr x)))128 ;; we need pred/pure info, so not using129 ;; "chicken.compiler.scrutinizer#check-and-validate-type"130 (let-values (((type pred pure)131 (chicken.compiler.scrutinizer#validate-type132 type1133 (strip-syntax name1))))134 (cond ((not type)135 (##sys#syntax-error ': "invalid type syntax" name1 type1))136 (else137 `(##core#declare138 (type (,name1 ,type1 ,@(cdddr x)))139 ,@(if pure `((pure ,name1)) '())140 ,@(if pred `((predicate (,name1 ,pred))) '()))))))))))141142(##sys#extend-macro-environment143 'the '()144 (##sys#er-transformer145 (lambda (x r c)146 (##sys#check-syntax 'the x '(_ _ _))147 (if (not (memq #:compiling ##sys#features))148 (caddr x)149 `(##core#the ,(chicken.compiler.scrutinizer#check-and-validate-type (cadr x) 'the)150 #t151 ,(caddr x))))))152153(##sys#extend-macro-environment154 'assume '()155 (syntax-rules ()156 ((_ ((var type) ...) body ...)157 (let ((var (the type var)) ...) body ...))))158159(##sys#extend-macro-environment160 'define-specialization '()161 (##sys#er-transformer162 (lambda (x r c)163 (cond ((not (memq #:compiling ##sys#features)) '(##core#undefined))164 (else165 (##sys#check-syntax 'define-specialization x '(_ (variable . #(_ 0)) _ . #(_ 0 1)))166 (let* ((head (cadr x))167 (name (car head))168 (args (cdr head))169 (alias (gensym name))170 (rtypes (and (pair? (cdddr x)) (strip-syntax (caddr x))))171 (%define (r 'define))172 (body (if rtypes (cadddr x) (caddr x))))173 (let loop ((args args) (anames '()) (atypes '()))174 (cond ((null? args)175 (let ((anames (reverse anames))176 (atypes (reverse atypes))177 (spec178 `(,alias ,@(let loop2 ((anames anames) (i 1))179 (if (null? anames)180 '()181 (cons (vector i)182 (loop2 (cdr anames) (fx+ i 1))))))))183 `(##core#begin184 (##core#local-specialization185 ,name186 ,alias187 ,(cons atypes188 (if (and rtypes (pair? rtypes))189 (list190 (map (cut chicken.compiler.scrutinizer#check-and-validate-type191 <>192 'define-specialization)193 rtypes)194 spec)195 (list spec))))196 (##core#declare (inline ,alias) (hide ,alias))197 (,%define (,alias ,@anames)198 (##core#let ,(map (lambda (an at)199 (list an `(##core#the ,at #t ,an)))200 anames atypes)201 ,body)))))202 (else203 (let ((arg (car args)))204 (cond ((symbol? arg)205 (loop (cdr args) (cons arg anames) (cons '* atypes)))206 ((and (list? arg) (fx= 2 (length arg)) (symbol? (car arg)))207 (loop208 (cdr args)209 (cons (car arg) anames)210 (cons211 (chicken.compiler.scrutinizer#check-and-validate-type212 (cadr arg)213 'define-specialization)214 atypes)))215 (else (##sys#syntax-error216 'define-specialization217 "invalid argument syntax" arg head)))))))))))))218219(##sys#extend-macro-environment220 'compiler-typecase '()221 (##sys#er-transformer222 (lambda (x r c)223 (##sys#check-syntax 'compiler-typecase x '(_ _ . #((_ . #(_ 1)) 1)))224 (let ((val (memq #:compiling ##sys#features))225 (var (gensym))226 (ln (get-line-number x)))227 `(##core#let ((,var ,(cadr x)))228 (##core#typecase229 ,ln230 ,var ; must be variable (see: CPS transform)231 ,@(map (lambda (clause)232 (let ((hd (strip-syntax (car clause))))233 (list234 (if (eq? hd 'else)235 'else236 (if val237 (chicken.compiler.scrutinizer#check-and-validate-type238 hd239 'compiler-typecase)240 hd))241 `(##core#begin ,@(cdr clause)))))242 (cddr x))))))))243244(##sys#extend-macro-environment245 'define-type '()246 (##sys#er-transformer247 (lambda (x r c)248 (##sys#check-syntax 'define-type x '(_ variable _))249 (cond ((not (memq #:compiling ##sys#features)) '(##core#undefined))250 (else251 (let ((name (strip-syntax (cadr x)))252 (%quote (r 'quote))253 (t0 (strip-syntax (caddr x))))254 `(##core#elaborationtimeonly255 (##sys#put/restore!256 (,%quote ,name)257 (,%quote ##compiler#type-abbreviation)258 (,%quote259 ,(chicken.compiler.scrutinizer#check-and-validate-type260 t0 'define-type name))))))))))261262(macro-subset me0 ##sys#default-macro-environment)))263264;;; Syntax-related syntax (for use in macro transformers)265266(set! ##sys#chicken.syntax-macro-environment267 (let ((me0 (##sys#macro-environment)))268269(##sys#extend-macro-environment270 'syntax271 '()272 (##sys#er-transformer273 (lambda (x r c)274 (##sys#check-syntax 'syntax x '(_ _))275 `(##core#syntax ,(cadr x)))))276277(##sys#extend-macro-environment278 'begin-for-syntax '()279 (##sys#er-transformer280 (lambda (x r c)281 (##sys#check-syntax 'begin-for-syntax x '(_ . #(_ 0)))282 (##sys#register-meta-expression `(##core#begin ,@(cdr x)))283 `(##core#elaborationtimeonly (##core#begin ,@(cdr x))))))284285(##sys#extend-macro-environment286 'define-for-syntax '()287 (##sys#er-transformer288 (lambda (form r c)289 (##sys#check-syntax 'define-for-syntax form '(_ _ . _))290 `(,(r 'begin-for-syntax)291 (,(r 'define) ,@(cdr form))))))292293294;;; Compiler syntax295296(##sys#extend-macro-environment297 'define-compiler-syntax '()298 (syntax-rules ()299 ((_ name)300 (##core#define-compiler-syntax name #f))301 ((_ name transformer)302 (##core#define-compiler-syntax name transformer))))303304(##sys#extend-macro-environment305 'let-compiler-syntax '()306 (syntax-rules ()307 ((_ (binding ...) body ...)308 (##core#let-compiler-syntax (binding ...) body ...))))309310(macro-subset me0 ##sys#default-macro-environment)))311312313;;; Non-standard macros that provide core/"base" functionality:314315(set! ##sys#chicken.base-macro-environment316 (let ((me0 (##sys#macro-environment)))317318(##sys#extend-macro-environment319 'define-constant320 '()321 (##sys#er-transformer322 (lambda (form r c)323 (##sys#check-syntax 'define-constant form '(_ variable _))324 `(##core#define-constant ,@(cdr form)))))325326(##sys#extend-macro-environment327 'define-record '()328 (##sys#er-transformer329 (lambda (x r c)330 (##sys#check-syntax 'define-record x '(_ variable . _))331 (let* ((type-name (cadr x))332 (plain-name (strip-syntax type-name))333 (prefix (symbol->string plain-name))334 (tag (if (##sys#current-module)335 (symbol-append336 (##sys#module-name (##sys#current-module)) '|#| plain-name)337 plain-name))338 (slots (cddr x))339 (%define (r 'define))340 (%setter (r 'chicken.base#setter))341 (%getter-with-setter (r 'chicken.base#getter-with-setter))342 (slotnames343 (map (lambda (slot)344 (cond ((symbol? slot) slot)345 ((and (pair? slot)346 (c (car slot) %setter)347 (pair? (cdr slot))348 (symbol? (cadr slot))349 (null? (cddr slot)))350 (cadr slot))351 (else352 (##sys#syntax-error353 'define-record "invalid slot specification" slot))))354 slots)))355 `(##core#begin356 (,%define ,type-name (##core#quote ,tag))357 (,%define358 ,(string->symbol (string-append "make-" prefix))359 (##core#lambda360 ,slotnames361 (##sys#make-structure (##core#quote ,tag) ,@slotnames)))362 (,%define363 ,(string->symbol (string-append prefix "?"))364 (##core#lambda (x) (##sys#structure? x (##core#quote ,tag))))365 ,@(let mapslots ((slots slots) (i 1))366 (if (eq? slots '())367 slots368 (let* ((a (car slots))369 (has-setter (not (symbol? a)))370 (slotname (symbol->string (if has-setter (cadr a) a)))371 (setr (string->symbol (string-append prefix "-" slotname "-set!")))372 (getr (string->symbol (string-append prefix "-" slotname)))373 (setrcode374 `(##core#lambda375 (x val)376 (##core#check (##sys#check-structure x (##core#quote ,tag)))377 (##sys#block-set! x ,i val) ) ))378 (cons379 `(##core#begin380 ,@(if has-setter381 '()382 `((,%define ,setr ,setrcode)))383 (,%define384 ,getr385 ,(if has-setter386 `(,%getter-with-setter387 (##core#lambda388 (x)389 (##core#check (##sys#check-structure x (##core#quote ,tag)))390 (##sys#block-ref x ,i) )391 ,setrcode)392 `(##core#lambda393 (x)394 (##core#check (##sys#check-structure x (##core#quote ,tag)))395 (##sys#block-ref x ,i) ) ) ) )396 (mapslots (##sys#slot slots 1) (fx+ i 1)) ) ) ) ) ) ) ) ) )397398(##sys#extend-macro-environment399 'receive400 '()401 (##sys#er-transformer402 (lambda (form r c)403 (##sys#check-syntax 'receive form '(_ _ . #(_ 0)))404 (cond ((null? (cddr form))405 `(##sys#call-with-values (##core#lambda () ,@(cdr form)) ##sys#list) )406 (else407 (##sys#check-syntax 'receive form '(_ lambda-list _ . #(_ 1)))408 (let ((vars (cadr form))409 (exp (caddr form))410 (rest (cdddr form)))411 (if (and (pair? vars) (null? (cdr vars)))412 `(##core#let ((,(car vars) ,exp)) ,@rest)413 `(##sys#call-with-values414 (##core#lambda () ,exp)415 (##core#lambda ,vars ,@rest)) ) ) ) ) )))416417(##sys#extend-macro-environment418 'declare '()419 (##sys#er-transformer420 (lambda (form r c)421 `(##core#declare ,@(cdr form)))))422423(##sys#extend-macro-environment424 'delay-force425 '()426 (##sys#er-transformer427 (lambda (form r c)428 (##sys#check-syntax 'delay-force form '(_ _))429 `(##sys#make-promise (##core#lambda () ,(cadr form))))))430431(##sys#extend-macro-environment432 'include '()433 (##sys#er-transformer434 (lambda (form r c)435 (##sys#check-syntax 'include form '(_ . #(string 1)))436 `(##core#begin ,@(map (lambda (x) `(##core#include ,x #f))437 (cdr form))))))438439(##sys#extend-macro-environment440 'include-ci '()441 (##sys#er-transformer442 (lambda (form r c)443 (##sys#check-syntax 'include-ci form '(_ . #(string 1)))444 `(##core#begin ,@(map (lambda (x) `(##core#include-ci ,x #f))445 (cdr form))))))446447(##sys#extend-macro-environment448 'include-relative '()449 (##sys#er-transformer450 (lambda (form r c)451 (##sys#check-syntax 'include-relative form '(_ . #(string 1)))452 `(##core#begin ,@(map (lambda (x)453 `(##core#include ,x ,##sys#current-source-filename))454 (cdr form))))))455456(##sys#extend-macro-environment457 'fluid-let '()458 (##sys#er-transformer459 (lambda (form r c)460 (##sys#check-syntax 'fluid-let form '(_ #((variable _) 0) . _))461 (let* ((clauses (cadr form))462 (body (cddr form))463 (ids (##sys#map car clauses))464 (new-tmps (##sys#map (lambda (x) (r (gensym))) clauses))465 (old-tmps (##sys#map (lambda (x) (r (gensym))) clauses)))466 `(##core#let467 (,@(map ##sys#list new-tmps (##sys#map cadr clauses))468 ,@(map ##sys#list old-tmps469 (let loop ((n (length clauses)))470 (if (eq? n 0)471 '()472 (cons #f (loop (fx- n 1))) ) ) ) )473 (##sys#dynamic-wind474 (##core#lambda ()475 ,@(map (lambda (ot id) `(##core#set! ,ot ,id))476 old-tmps ids)477 ,@(map (lambda (id nt) `(##core#set! ,id ,nt))478 ids new-tmps)479 (##core#undefined) )480 (##core#lambda () ,@body)481 (##core#lambda ()482 ,@(map (lambda (nt id) `(##core#set! ,nt ,id))483 new-tmps ids)484 ,@(map (lambda (id ot) `(##core#set! ,id ,ot))485 ids old-tmps)486 (##core#undefined) ) ) ) ) )))487488(##sys#extend-macro-environment489 'parameterize '()490 (##sys#er-transformer491 (lambda (form r c)492 (define (pname p)493 (if (symbol? p)494 (gensym p)495 (gensym "parameter")))496 (##sys#check-syntax 'parameterize form '#(_ 2))497 (let* ((bindings (cadr form))498 (body (cddr form))499 (convert? (r 'convert?))500 (params (##sys#map car bindings))501 (vals (##sys#map cadr bindings))502 (param-aliases (##sys#map (lambda (z) (r (pname z))) params))503 (saveds (##sys#map (lambda (z) (r (gensym 'saved))) params))504 (temps (##sys#map (lambda (z) (r (gensym 'tmp))) params)) )505 `(##core#let506 ,(map ##sys#list param-aliases params) ; These may be expressions507 (##core#let508 ,(map ##sys#list saveds vals)509 (##core#let510 ;; Inner names are actually set. This hides the exact511 ;; ordering of the let if any call/cc is used in the512 ;; value expressions (see first example in #1336).513 ,(map ##sys#list saveds saveds)514 (##core#let515 ((,convert? (##core#the boolean #t #t))) ; Convert only first time extent is entered!516 (##sys#dynamic-wind517 (##core#lambda ()518 (##core#let519 ;; First, call converters (which may throw exceptions!)520 ,(map (lambda (p s temp)521 `(,temp (##core#if ,convert? (,p ,s #t #f) ,s)))522 param-aliases saveds temps)523 ;; Save current values so we can restore them later524 ,@(map (lambda (p s) `(##core#set! ,s (,p)))525 param-aliases saveds)526 ;; Set parameters to their new values. This can't fail.527 ,@(map (lambda (p t) `(,p ,t #f #t)) param-aliases temps)528 ;; Remember we already converted (only call converters once!)529 (##core#set! ,convert? #f)))530 (##core#lambda () ,@body)531 (##core#lambda ()532 (##core#let533 ;; Remember the current value of each parameter.534 ,(map (lambda (p s temp) `(,temp (,p)))535 param-aliases saveds temps)536 ;; Restore each parameter to its old value.537 ,@(map (lambda (p s) `(,p ,s #f #t)) param-aliases saveds)538 ;; Save current value for later re-invocations.539 ,@(map (lambda (s temp) `(##core#set! ,s ,temp))540 saveds temps))))))))))))541542(##sys#extend-macro-environment543 'require-library544 '()545 (##sys#er-transformer546 (lambda (x r c)547 `(##core#begin548 ,@(map (lambda (x)549 (let-values (((name lib _ _ _ _) (##sys#decompose-import x r c 'import)))550 (if (not lib)551 '(##core#undefined)552 `(##core#require ,lib ,name))))553 (cdr x))))))554555(##sys#extend-macro-environment556 'when '()557 (##sys#er-transformer558 (lambda (form r c)559 (##sys#check-syntax 'when form '#(_ 2))560 `(##core#if ,(cadr form)561 (##core#begin ,@(cddr form))))))562563(##sys#extend-macro-environment564 'unless '()565 (##sys#er-transformer566 (lambda (form r c)567 (##sys#check-syntax 'unless form '#(_ 2))568 `(##core#if ,(cadr form)569 (##core#undefined)570 (##core#begin ,@(cddr form))))))571572(##sys#extend-macro-environment573 'set!-values '()574 (##sys#er-transformer575 (lambda (form r c)576 (##sys#check-syntax 'set!-values form '(_ lambda-list _))577 (##sys#expand-multiple-values-assignment (cadr form) (caddr form)))))578579(set! chicken.syntax#define-values-definition580 (##sys#extend-macro-environment581 'define-values '()582 (##sys#er-transformer583 (lambda (form r c)584 (##sys#check-syntax 'define-values form '(_ lambda-list _))585 `(##core#begin586 ,@(##sys#decompose-lambda-list587 (cadr form)588 (lambda (vars argc rest)589 (for-each (lambda (nm)590 (let ((name (##sys#get nm '##core#macro-alias nm)))591 (##sys#register-export name (##sys#current-module))))592 vars)593 (map (lambda (nm) `(##core#ensure-toplevel-definition ,nm))594 vars)))595 ,(##sys#expand-multiple-values-assignment (cadr form) (caddr form)))))))596597(##sys#extend-macro-environment598 'let-values '()599 (##sys#er-transformer600 (lambda (form r c)601 (##sys#check-syntax 'let-values form '(_ list . _))602 (let ((vbindings (cadr form))603 (body (cddr form)))604 (letrec ((append* (lambda (il l)605 (if (not (pair? il))606 (cons il l)607 (cons (car il)608 (append* (cdr il) l)))))609 (map* (lambda (proc l)610 (cond ((null? l) '())611 ((not (pair? l)) (proc l))612 (else (cons (proc (car l)) (map* proc (cdr l))))))))613 (let* ([llists (map car vbindings)]614 [vars (let loop ((llists llists) (acc '()))615 (if (null? llists)616 acc617 (let* ((llist (car llists))618 (new-acc619 (cond ((list? llist) (append llist acc))620 ((pair? llist) (append* llist acc))621 (else (cons llist acc)))))622 (loop (cdr llists) new-acc))))]623 [aliases (map (lambda (v) (cons v (r (gensym v)))) vars)]624 [lookup (lambda (v) (cdr (assq v aliases)))]625 [llists2 (let loop ((llists llists) (acc '()))626 (if (null? llists)627 (reverse acc)628 (let* ((llist (car llists))629 (new-acc630 (cond ((not (pair? llist)) (cons (lookup llist) acc))631 (else (cons (map* lookup llist) acc)))))632 (loop (cdr llists) new-acc))))])633 (let fold ([llists llists]634 [exps (map (lambda (x) (cadr x)) vbindings)]635 [llists2 llists2] )636 (cond ((null? llists)637 `(##core#let638 ,(map (lambda (v) (##sys#list v (lookup v))) vars)639 ,@body) )640 ((and (pair? (car llists2)) (null? (cdar llists2)))641 `(##core#let642 ((,(caar llists2) ,(car exps)))643 ,(fold (cdr llists) (cdr exps) (cdr llists2)) ) )644 (else645 `(##sys#call-with-values646 (##core#lambda () ,(car exps))647 (##core#lambda648 ,(car llists2)649 ,(fold (cdr llists) (cdr exps) (cdr llists2))) ) ) ) ) ) ) ) ) ) )650651(##sys#extend-macro-environment652 'let*-values '()653 (##sys#er-transformer654 (lambda (form r c)655 (##sys#check-syntax 'let*-values form '(_ list . _))656 (let ((vbindings (cadr form))657 (body (cddr form))658 (%let-values (r 'let-values)) )659 (let fold ([vbindings vbindings])660 (if (null? vbindings)661 `(##core#let () ,@body)662 `(,%let-values (,(car vbindings))663 ,(fold (cdr vbindings))) ) ) ))))664665;;XXX do we need letrec*-values ?666(##sys#extend-macro-environment667 'letrec-values '()668 (##sys#er-transformer669 (lambda (form r c)670 (##sys#check-syntax 'letrec-values form '(_ #((lambda-list . _) 0) . _))671 (let ((vbindings (cadr form))672 (body (cddr form)))673 (let ((vars (map car vbindings))674 (exprs (map cadr vbindings)))675 `(##core#let676 ,(map (lambda (v) (##sys#list v '(##core#undefined)))677 (foldl (lambda (l v) ; flatten multi-value formals678 (##sys#append l (##sys#decompose-lambda-list679 v (lambda (a _ _) a))))680 '()681 vars))682 ,@(map ##sys#expand-multiple-values-assignment vars exprs)683 ,@body))))))684685(##sys#extend-macro-environment686 'letrec*687 '()688 (##sys#er-transformer689 (lambda (x r c)690 (##sys#check-syntax 'letrec* x '(_ #((variable _) 0) . #(_ 1)))691 (check-for-multiple-bindings (cadr x) x "letrec*")692 `(##core#letrec* ,@(cdr x)))))693694(##sys#extend-macro-environment695 'nth-value696 `((list-ref . scheme#list-ref))697 (##sys#er-transformer698 (lambda (form r c)699 (##sys#check-syntax 'nth-value form '(_ _ _))700 (let ((v (r 'tmp)))701 `(##sys#call-with-values702 (##core#lambda () ,(caddr form))703 (##core#lambda ,v (,(r 'list-ref) ,v ,(cadr form))))))))704705(##sys#extend-macro-environment706 'define-inline '()707 (##sys#er-transformer708 (lambda (form r c)709 (letrec ([quotify-proc710 (lambda (xs id)711 (##sys#check-syntax id xs '#(_ 1))712 (let* ([head (car xs)]713 [name (if (pair? head) (car head) head)]714 [val (if (pair? head)715 `(##core#lambda ,(cdr head) ,@(cdr xs))716 (cadr xs) ) ] )717 (when (or (not (pair? val))718 (and (not (eq? '##core#lambda (car val)))719 (not (c (r 'lambda) (car val)))))720 (##sys#syntax-error721 'define-inline "invalid substitution form - must be lambda"722 name val) )723 (list name val) ) ) ] )724 `(##core#define-inline ,@(quotify-proc (cdr form) 'define-inline)))) ) )725726(##sys#extend-macro-environment727 'and-let* '()728 (##sys#er-transformer729 (lambda (form r c)730 (##sys#check-syntax 'and-let* form '(_ #(_ 0) . _))731 (let ((bindings (cadr form))732 (body (cddr form)))733 (let fold ([bs bindings] [last #t])734 (if (null? bs)735 `(##core#begin ,last . ,body)736 (let ([b (car bs)]737 [bs2 (cdr bs)] )738 (cond [(not (pair? b))739 (##sys#check-syntax 'and-let* b 'variable)740 (let ((var (r (gensym))))741 `(##core#let ((,var ,b))742 (##core#if ,var ,(fold bs2 var) #f)))]743 [(null? (cdr b))744 (let ((var (r (gensym))))745 `(##core#let ((,var ,(car b)))746 (##core#if ,var ,(fold bs2 var) #f)))]747 [else748 (##sys#check-syntax 'and-let* b '(variable _))749 (let ((var (car b)))750 `(##core#let ((,var ,(cadr b)))751 (##core#if ,var ,(fold bs2 var) #f)))]))))))))752753754755;;; Optional argument handling:756757;;; Copyright (C) 1996 by Olin Shivers.758;;;759;;; This file defines three macros for parsing optional arguments to procs:760;;; (LET-OPTIONALS arg-list ((var1 default1) ...) . body)761;;; (LET-OPTIONALS* arg-list ((var1 default1) ...) . body)762;;; (:OPTIONAL rest-arg default-exp)763;;;764;;; The LET-OPTIONALS macro is defined using the Clinger/Rees765;;; explicit-renaming low-level macro system. You'll have to do some work to766;;; port it to another macro system.767;;;768;;; The LET-OPTIONALS* and :OPTIONAL macros are defined with simple769;;; high-level macros, and should be portable to any R4RS system.770;;;771;;; These macros are all careful to evaluate their default forms *only* if772;;; their values are needed.773;;;774;;; The only non-R4RS dependencies in the macros are ERROR775;;; and CALL-WITH-VALUES.776;;; -Olin777778;;; (LET-OPTIONALS arg-list ((var1 default1) ...)779;;; body780;;; ...)781;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;782;;; This form is for binding a procedure's optional arguments to either783;;; the passed-in values or a default.784;;;785;;; The expression takes a rest list ARG-LIST and binds the VARi to786;;; the elements of the rest list. When there are no more elements, then787;;; the remaining VARi are bound to their corresponding DEFAULTi values.788;;;789;;; - The default expressions are *not* evaluated unless needed.790;;;791;;; - When evaluated, the default expressions are carried out in the *outer*792;;; environment. That is, the DEFAULTi forms do *not* see any of the VARi793;;; bindings.794;;;795;;; I originally wanted to have the DEFAULTi forms get eval'd in a LET*796;;; style scope -- DEFAULT3 would see VAR1 and VAR2, etc. But this is797;;; impossible to implement without side effects or redundant conditional798;;; tests. If I drop this requirement, I can use the efficient expansion799;;; shown below. If you need LET* scope, use the less-efficient800;;; LET-OPTIONALS* form defined below.801;;;802;;; Example:803;;; (define (read-string! str . maybe-args)804;;; (let-optionals maybe-args ((port (current-input-port))805;;; (start 0)806;;; (end (string-length str)))807;;; ...))808;;;809;;; expands to:810;;;811;;; (let* ((body (lambda (port start end) ...))812;;; (end-def (lambda (%port %start) (body %port %start <end-default>)))813;;; (start-def (lambda (%port) (end-def %port <start-default>)))814;;; (port-def (lambda () (start-def <port-def>))))815;;; (if (null? rest) (port-def)816;;; (let ((%port (car rest))817;;; (rest (cdr rest)))818;;; (if (null? rest) (start-def %port)819;;; (let ((%start (car rest))820;;; (rest (cdr rest)))821;;; (if (null? rest) (end-def %port %start)822;;; (let ((%end (car rest))823;;; (rest (cdr rest)))824;;; (if (null? rest) (body %port %start %end)825;;; (error ...)))))))))826827828;;; (LET-OPTIONALS args ((var1 default1) ...) body1 ...)829830(##sys#extend-macro-environment831 'let-optionals832 `((null? . scheme#null?)833 (car . scheme#car)834 (cdr . scheme#cdr))835 (##sys#er-transformer836 (lambda (form r c)837 (##sys#check-syntax 'let-optionals form '(_ _ . _))838 (let ((arg-list (cadr form))839 (var/defs (caddr form))840 (body (cdddr form)))841842 ;; This guy makes the END-DEF, START-DEF, PORT-DEF definitions above.843 ;; I wish I had a reasonable loop macro.844845 (define (make-default-procs vars body-proc defaulter-names defs rename)846 (let recur ((vars (reverse vars))847 (defaulter-names (reverse defaulter-names))848 (defs (reverse defs))849 (next-guy body-proc))850 (if (null? vars) '()851 (let ((vars (cdr vars)))852 `((,(car defaulter-names)853 (##core#lambda ,(reverse vars)854 (,next-guy ,@(reverse vars) ,(car defs))))855 . ,(recur vars856 (cdr defaulter-names)857 (cdr defs)858 (car defaulter-names)))))))859860861 ;; This guy makes the (IF (NULL? REST) (PORT-DEF) ...) tree above.862863 (define (make-if-tree vars defaulters body-proc rest rename)864 (let recur ((vars vars) (defaulters defaulters) (non-defaults '()))865 (if (null? vars)866 `(,body-proc . ,(reverse non-defaults))867 (let ((v (car vars)))868 `(##core#if (,(r 'null?) ,rest)869 (,(car defaulters) . ,(reverse non-defaults))870 (##core#let ((,v (,(r 'car) ,rest)) ; we use car/cdr, because of rest-list optimization871 (,rest (,(r 'cdr) ,rest)))872 ,(recur (cdr vars)873 (cdr defaulters)874 (cons v non-defaults))))))))875876 (##sys#check-syntax 'let-optionals var/defs '#((variable _) 0))877 (##sys#check-syntax 'let-optionals body '#(_ 1))878 (let* ((vars (map car var/defs))879 (prefix-sym (lambda (prefix sym)880 (string->symbol (string-append prefix (symbol->string sym)))))881882 ;; Private vars, one for each user var.883 ;; We prefix the % to help keep macro-expanded code from being884 ;; too confusing.885 (vars2 (map (lambda (v) (r (prefix-sym "%" v)))886 vars))887888 (defs (map cadr var/defs))889 (body-proc (r 'body))890891 ;; A private var, bound to the value of the ARG-LIST expression.892 (rest-var (r '_%rest))893894 (defaulter-names (map (lambda (var) (r (prefix-sym "def-" var)))895 vars))896897 (defaulters (make-default-procs vars2 body-proc898 defaulter-names defs gensym))899 (if-tree (make-if-tree vars2 defaulter-names body-proc900 rest-var gensym)))901902 `(,(r 'let*) ((,rest-var ,arg-list)903 (,body-proc (##core#lambda ,vars . ,body))904 . ,defaulters)905 ,if-tree) ) ))))906907908;;; (optional rest-arg default-exp)909;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;910;;; This form is for evaluating optional arguments and their defaults911;;; in simple procedures that take a *single* optional argument. It is912;;; a macro so that the default will not be computed unless it is needed.913;;;914;;; REST-ARG is a rest list from a lambda -- e.g., R in915;;; (lambda (a b . r) ...)916;;; - If REST-ARG has 0 elements, evaluate DEFAULT-EXP and return that.917;;; - If REST-ARG has 1 element, return that element.918919(##sys#extend-macro-environment920 'optional921 `((null? . scheme#null?)922 (car . scheme#car)923 (cdr . scheme#cdr) )924 (##sys#er-transformer925 (lambda (form r c)926 (##sys#check-syntax 'optional form '(_ _ . #(_ 0 1)))927 (let ((var (r 'tmp)))928 `(##core#let ((,var ,(cadr form)))929 (##core#if (,(r 'null?) ,var)930 ,(optional (cddr form) #f)931 (,(r 'car) ,var)))))))932933934;;; (LET-OPTIONALS* args ((var1 default1) ... [rest]) body1 ...)935;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;936;;; This is just like LET-OPTIONALS, except that the DEFAULTi forms937;;; are evaluated in a LET*-style environment. That is, DEFAULT3 is evaluated938;;; within the scope of VAR1 and VAR2, and so forth.939;;;940;;; - If the last form in the ((var1 default1) ...) list is not a941;;; (VARi DEFAULTi) pair, but a simple variable REST, then it is942;;; bound to any left-over values. For example, if we have VAR1 through943;;; VAR7, and ARGS has 9 values, then REST will be bound to the list of944;;; the two values of ARGS. If ARGS is too short, causing defaults to945;;; be used, then REST is bound to '().946947(##sys#extend-macro-environment948 'let-optionals*949 `((null? . scheme#null?)950 (car . scheme#car)951 (cdr . scheme#cdr))952 (##sys#er-transformer953 (lambda (form r c)954 (##sys#check-syntax 'let-optionals* form '(_ _ list . _))955 (let ((args (cadr form))956 (var/defs (caddr form))957 (body (cdddr form))958 (%null? (r 'null?))959 (%car (r 'car))960 (%cdr (r 'cdr)))961 (let ((rvar (r 'tmp)))962 `(##core#let963 ((,rvar ,args))964 ,(let loop ((args rvar) (vardefs var/defs))965 (if (null? vardefs)966 `(##core#let () ,@body)967 (let ((head (car vardefs)))968 (if (pair? head)969 (let ((rvar2 (r 'tmp2)))970 `(##core#let ((,(car head) (##core#if (,%null? ,args)971 ,(cadr head)972 (,%car ,args)))973 (,rvar2 (##core#if (,%null? ,args)974 (##core#quote ())975 (,%cdr ,args))) )976 ,(loop rvar2 (cdr vardefs)) ) )977 `(##core#let ((,head ,args)) ,@body) ) ) ) ) ) ) ))))978979;;; SRFI-9:980981(##sys#extend-macro-environment982 'define-record-type983 `()984 (##sys#er-transformer985 (lambda (form r c)986 (##sys#check-syntax987 'define-record-type988 form989 '(_ variable #(variable 1) variable . _))990 (let* ((type-name (cadr form))991 (plain-name (strip-syntax type-name))992 (tag (if (##sys#current-module)993 (symbol-append994 (##sys#module-name (##sys#current-module))995 '|#| plain-name)996 plain-name))997 (conser (caddr form))998 (pred (cadddr form))999 (slots (cddddr form))1000 (%define (r 'define))1001 (%vector (r 'vector))1002 (%let (r 'let))1003 (%tagvar (r 'tag))1004 (%getter-with-setter (r 'chicken.base#getter-with-setter))1005 (vars (cdr conser))1006 (x (r 'x))1007 (y (r 'y))1008 (slotnames (map car slots)))1009 ;; Check for inconsistencies in slot names vs constructor args1010 (for-each (lambda (vname)1011 (unless (memq vname slotnames)1012 (##sys#syntax-error1013 'define-record-type1014 "unknown slot name in constructor definition"1015 vname)))1016 vars)1017 `(##core#begin1018 (,%define ,type-name (,%vector (##core#quote ,tag)))1019 (,%define ,(car conser)1020 (,%let ((,%tagvar ,type-name))1021 (##core#lambda ,(cdr conser)1022 (##sys#make-structure1023 ,%tagvar1024 ,@(map (lambda (sname)1025 (if (memq sname vars)1026 sname1027 '(##core#undefined) ) )1028 slotnames) ) ) ))1029 (,%define ,pred1030 (,%let ((,%tagvar ,type-name))1031 (##core#lambda (,x)1032 (##sys#structure? ,x ,%tagvar))))1033 ,@(let loop ((slots slots) (i 1))1034 (if (null? slots)1035 '()1036 (let* ((slot (car slots))1037 (settable (pair? (cddr slot)))1038 (setr (and settable (caddr slot)))1039 (ssetter (and (pair? setr)1040 (pair? (cdr setr))1041 (c 'setter (car setr))1042 (cadr setr)))1043 (get `(##core#lambda1044 (,x)1045 (##core#check1046 (##sys#check-structure1047 ,x1048 ,%tagvar1049 (##core#quote ,(cadr slot))))1050 (##sys#block-ref ,x ,i) ) )1051 (set (and settable1052 `(##core#lambda1053 (,x ,y)1054 (##core#check1055 (##sys#check-structure1056 ,x1057 ,%tagvar1058 (##core#quote ,ssetter)))1059 (##sys#block-set! ,x ,i ,y)) )))1060 `((,%define1061 ,(cadr slot)1062 (,%let ((,%tagvar ,type-name))1063 ,(if (and ssetter (c ssetter (cadr slot)))1064 `(,%getter-with-setter ,get ,set)1065 get)))1066 ,@(if settable1067 (if ssetter1068 (if (not (c ssetter (cadr slot)))1069 `((,%let ((,%tagvar ,type-name))1070 ((##sys#setter ##sys#setter) ,ssetter ,set)))1071 '())1072 `((,%define ,setr (,%let ((,%tagvar ,type-name)) ,set))))1073 '())1074 ,@(loop (cdr slots) (add1 i)) ) ) ) ) ) ) ) ) )107510761077;;; SRFI-26:10781079(##sys#extend-macro-environment1080 'cut1081 `((apply . scheme#apply))1082 (##sys#er-transformer1083 (lambda (form r c)1084 (let ((%<> (r '<>))1085 (%<...> (r '<...>))1086 (%apply (r 'apply)))1087 (when (null? (cdr form))1088 (##sys#syntax-error 'cut "you need to supply at least a procedure" form))1089 (let loop ([xs (cdr form)] [vars '()] [vals '()] [rest #f])1090 (if (null? xs)1091 (let ([rvars (reverse vars)]1092 [rvals (reverse vals)] )1093 (if rest1094 (let ([rv (r (gensym))])1095 `(##core#lambda1096 (,@rvars . ,rv)1097 (,%apply ,(car rvals) ,@(cdr rvals) ,rv) ) )1098 ;;XXX should we drop the begin?1099 `(##core#lambda ,rvars ((##core#begin ,(car rvals)) ,@(cdr rvals)) ) ) )1100 (cond ((c %<> (car xs))1101 (let ([v (r (gensym))])1102 (loop (cdr xs) (cons v vars) (cons v vals) #f) ) )1103 ((c %<...> (car xs))1104 (if (null? (cdr xs))1105 (loop '() vars vals #t)1106 (##sys#syntax-error1107 'cut1108 "tail patterns after <...> are not supported"1109 form)))1110 (else (loop (cdr xs) vars (cons (car xs) vals) #f)) ) ) ) ) )))11111112(##sys#extend-macro-environment1113 'cute1114 `((apply . scheme#apply))1115 (##sys#er-transformer1116 (lambda (form r c)1117 (let ((%apply (r 'apply))1118 (%<> (r '<>))1119 (%<...> (r '<...>)))1120 (when (null? (cdr form))1121 (##sys#syntax-error 'cute "you need to supply at least a procedure" form))1122 (let loop ([xs (cdr form)] [vars '()] [bs '()] [vals '()] [rest #f])1123 (if (null? xs)1124 (let ([rvars (reverse vars)]1125 [rvals (reverse vals)] )1126 (if rest1127 (let ([rv (r (gensym))])1128 `(##core#let1129 ,bs1130 (##core#lambda (,@rvars . ,rv)1131 (,%apply ,(car rvals) ,@(cdr rvals) ,rv) ) ) )1132 `(##core#let ,bs1133 (##core#lambda ,rvars (,(car rvals) ,@(cdr rvals)) ) ) ) )1134 (cond ((c %<> (car xs))1135 (let ([v (r (gensym))])1136 (loop (cdr xs) (cons v vars) bs (cons v vals) #f) ) )1137 ((c %<...> (car xs))1138 (if (null? (cdr xs))1139 (loop '() vars bs vals #t)1140 (##sys#syntax-error1141 'cute1142 "tail patterns after <...> are not supported"1143 form)))1144 (else1145 (let ([v (r (gensym))])1146 (loop (cdr xs)1147 vars1148 (cons (list v (car xs)) bs)1149 (cons v vals) #f) ) ))))))))115011511152;;; SRFI-3111531154(##sys#extend-macro-environment1155 'rec '()1156 (##sys#er-transformer1157 (lambda (form r c)1158 (##sys#check-syntax 'rec form '(_ _ . _))1159 (let ((head (cadr form)))1160 (if (pair? head)1161 `(##core#letrec* ((,(car head)1162 (##core#lambda ,(cdr head)1163 ,@(cddr form))))1164 ,(car head))1165 `(##core#letrec* ((,head ,@(cddr form))) ,head))))))116611671168;;; SRFI-5511691170(##sys#extend-macro-environment1171 'require-extension1172 '()1173 (##sys#er-transformer1174 (lambda (x r c)1175 `(,(r 'import) ,@(cdr x)))))117611771178;;; Assertions11791180(##sys#extend-macro-environment1181 'assert '()1182 (##sys#er-transformer1183 (let ((string-append string-append))1184 (lambda (form r c)1185 (##sys#check-syntax 'assert form '#(_ 1))1186 (let* ((exp (cadr form))1187 (msg-and-args (cddr form))1188 (msg (optional msg-and-args "assertion failed"))1189 (tmp (r 'tmp)))1190 (when (string? msg)1191 (and-let* ((ln (get-line-number form)))1192 (set! msg (string-append "(" ln ") " msg))))1193 `(##core#let ((,tmp ,exp))1194 (##core#if (##core#check ,tmp)1195 ,tmp1196 (##sys#error1197 ,msg1198 ,@(if (pair? msg-and-args)1199 (cdr msg-and-args)1200 `((##core#quote ,(strip-syntax exp))))))))))))12011202;; R7RS guard & guard-aux copied verbatim from the draft.1203(##sys#extend-macro-environment1204 'guard '()1205 (##sys#er-transformer1206 (lambda (form r c)1207 (let ((%=> (r '=>))1208 (%else (r 'else))1209 (%begin (r 'begin))1210 (%let (r 'let))1211 (%if (r 'if))1212 (%or (r 'or))1213 (%var (r 'var))1214 (%apply (r 'apply))1215 (%values (r 'values))1216 (%condition (r 'condition))1217 (%call-with-values (r 'call-with-values))1218 (%guard-k (r 'guard-k))1219 (%handler-k (r 'handler-k))1220 (%lambda (r 'lambda)))1221 (##sys#check-syntax 'guard form '(_ (variable . #(_ 1)) . #(_ 1)))1222 (let ((var (caadr form))1223 (clauses (cdadr form))1224 (es (cddr form)))1225 (define (guard-aux reraise body more)1226 (cond ((and (pair? body) (c %else (car body))1227 (null? more))1228 `(,%begin ,@(cdr body)))1229 ((and (pair? body) (pair? (cdr body)) (pair? (cddr body))1230 (c %=> (cadr body)))1231 (let ((%temp (r 'temp)))1232 `(,%let ((,%temp ,(car body)))1233 (,%if ,%temp1234 (,(caddr body) ,%temp)1235 ,(if (null? more)1236 reraise1237 (guard-aux reraise (car more) (cdr more)))))))1238 ((and (pair? body) (null? (cdr body)))1239 (if (null? more)1240 `(,%or ,(car body) ,reraise)1241 (let ((%temp (r 'temp)))1242 `(,%let ((,%temp ,(car body)))1243 (,%if ,%temp1244 ,%temp1245 ,(guard-aux reraise (car more) (cdr more)))))))1246 ((and (pair? body) (pair? (cdr body)))1247 `(,%if ,(car body)1248 (,%begin ,@(cdr body))1249 ,(if (null? more)1250 reraise1251 (guard-aux reraise (car more) (cdr more)))))))1252 `((scheme#call-with-current-continuation1253 (,%lambda (,%guard-k)1254 (scheme#with-exception-handler1255 (,%lambda (,%condition)1256 ((scheme#call-with-current-continuation1257 (,%lambda (,%handler-k)1258 (,%guard-k1259 (,%lambda ()1260 (,%let ((,var ,%condition))1261 ,(guard-aux1262 `(,%handler-k1263 (,%lambda ()1264 (scheme#raise-continuable ,%condition)))1265 (car clauses) (cdr clauses)))))))))1266 (,%lambda ()1267 (scheme#call-with-values1268 (,%lambda () ,@es)1269 (,%lambda args1270 (,%guard-k1271 (,%lambda ()1272 (,%apply ,%values args)))))))))))))))12731274(macro-subset me0 ##sys#default-macro-environment)))127512761277;;; "time"12781279(set! ##sys#chicken.time-macro-environment1280 (let ((me0 (##sys#macro-environment)))12811282(##sys#extend-macro-environment1283 'time '()1284 (##sys#er-transformer1285 (lambda (form r c)1286 (let ((rvar (r 't)))1287 `(##core#begin1288 (##sys#start-timer)1289 (##sys#call-with-values1290 (##core#lambda () ,@(cdr form))1291 (##core#lambda1292 ,rvar1293 (##sys#display-times (##sys#stop-timer))1294 (##sys#apply ##sys#values ,rvar))))))))12951296(macro-subset me0 ##sys#default-macro-environment)))12971298;;; case-lambda (SRFI-16):12991300(set! ##sys#scheme.case-lambda-macro-environment1301 (let ((me0 (##sys#macro-environment)))13021303(##sys#extend-macro-environment1304 'case-lambda1305 `((>= . scheme#>=)1306 (car . scheme#car)1307 (cdr . scheme#cdr)1308 (eq? . scheme#eq?)1309 (length . scheme#length))1310 (##sys#er-transformer1311 (lambda (form r c)1312 (##sys#check-syntax 'case-lambda form '(_ . _))1313 (define (genvars n)1314 (let loop ([i 0])1315 (if (fx>= i n)1316 '()1317 (cons (r (gensym)) (loop (fx+ i 1))) ) ) )1318 (let* ((mincount (apply min (map (lambda (c)1319 (##sys#decompose-lambda-list1320 (car c)1321 (lambda (vars argc rest) argc) ) )1322 (cdr form))))1323 (minvars (genvars mincount))1324 (rvar (r 'rvar))1325 (lvar (r 'lvar))1326 (%>= (r '>=))1327 (%eq? (r 'eq?))1328 (%car (r 'car))1329 (%cdr (r 'cdr))1330 (%length (r 'length)))1331 `(##core#lambda1332 ,(append minvars rvar)1333 (##core#let1334 ((,lvar (,%length ,rvar)))1335 ,(foldr1336 (lambda (c body)1337 (##sys#decompose-lambda-list1338 (car c)1339 (lambda (vars argc rest)1340 (##sys#check-syntax 'case-lambda (car c) 'lambda-list)1341 `(##core#if ,(let ((a2 (fx- argc mincount)))1342 (if rest1343 (if (zero? a2)1344 #t1345 `(,%>= ,lvar ,a2) )1346 `(,%eq? ,lvar ,a2) ) )1347 ,(receive (vars1 vars2)1348 (split-at (take vars argc) mincount)1349 (let ((bindings1350 (let build ((vars2 vars2) (vrest rvar))1351 (if (null? vars2)1352 (cond (rest `(##core#let ((,rest ,vrest)) ,@(cdr c)))1353 ((null? (cddr c)) (cadr c))1354 (else `(##core#let () ,@(cdr c))) )1355 (let ((vrest2 (r (gensym))))1356 `(##core#let ((,(car vars2) (,%car ,vrest))1357 (,vrest2 (,%cdr ,vrest)) )1358 ,(if (pair? (cdr vars2))1359 (build (cdr vars2) vrest2)1360 (build '() vrest2) ) ) ) ) ) ) )1361 (if (null? vars1)1362 bindings1363 `(##core#let ,(map list vars1 minvars) ,bindings) ) ) )1364 ,body) ) ) )1365 '(##core#check (##sys#error (##core#immutable (##core#quote "no matching clause in call to 'case-lambda' form"))))1366 (cdr form))))))))13671368(macro-subset me0 ##sys#default-macro-environment)))13691370;; register features13711372(register-feature! 'srfi-2 'srfi-8 'srfi-9 'srfi-11 'srfi-15 'srfi-16 'srfi-26 'srfi-31 'srfi-55)