ignore keywords in non-keyword positions (issue #753)

This commit is contained in:
Alex Shinn 2021-06-28 16:19:43 +09:00
parent 05c546e38d
commit 0fbd89dd00
5 changed files with 24 additions and 17 deletions

View file

@ -156,13 +156,14 @@ currently unspecified.
In R7RS (and R6RS) semantics it is impossible to use two macros from
different modules which both use the same auxiliary keywords (like
\scheme{else} in \scheme{cond} forms) without renaming one of the
keywords. By default Chibi considers all top-level bindings
effectively unbound when matching auxiliary keywords, so this case
will "just work". This decision was made because the chance of
different modules using the same keywords seems more likely than user
code unintentionally matching a top-level keyword with a different
binding, however if you want to use R7RS semantics you can compile
with \ccode{SEXP_USE_STRICT_TOPLEVEL_BINDINGS=1}.
keywords. To minimize conflicts Chibi offers a special module named
\scheme{(auto)} which can export any identifier requested with
\scheme{only}, e.g. \scheme{(import (only (auto) foo))} will import
an auxiliary syntax \scheme{foo} binding. Separate modules can use
this to get the same binding without needing to know about each other
in advance. This is a Chibi-specific extension so is non-portable, but
you can always define a static \scheme{(auto)} module exporting a list
of all known bindings for other implementations.
\scheme{load} is extended to accept an optional environment argument, like
\scheme{eval}. You can also \scheme{load} shared libraries in addition to
@ -1584,7 +1585,7 @@ command tells you which you currently have installed. The following
are currently supported:
\itemlist[
\item{chibi - native support as of version 0.7.3}
\item{chibi - version >= 0.7.3}
\item{chicken - version >= 4.9.0 with the \scheme{r7rs} egg}
\item{cyclone - version >= 0.5.3}
\item{foment - version >= 0.4}

View file

@ -78,7 +78,7 @@
;; returns 1 modulo n.
(let ((b (modular-expt a odd n)))
(let lp ((i 0) (b b))
(cond ((or (= b 1) (= b neg1))) ; in (= b 1) case we could factor
(cond ((or (= b 1) (= b neg1))) ; in (= b 1) case we could factor
((>= i twos) #f)
(else (lp (+ i 1) (remainder (* b b) n)))))))

View file

@ -10,5 +10,6 @@
provable-prime? probable-prime?
random-prime random-prime-distinct-from
coprime? random-coprime modular-inverse modular-expt
miller-rabin-composite?)
miller-rabin-composite?
modular-root-of-one?)
(include "prime.scm"))

View file

@ -53,6 +53,8 @@
(test '(0 1 (2 3 4))
(let-optionals '(0 1 2 3 4) ((a 10) (b 11) . c)
(list a b c)))
(test 5 (keyword-ref '(a: b: b: 5) 'b: #f))
(test 5 (keyword-ref* '(a: b: b: 5) 'b: #f))
(cond-expand
(gauche) ; gauche detects this at compile-time, can't catch
(else (test-error '(0 11 12)

View file

@ -95,6 +95,13 @@
((define-opt (name . vars) . body)
(define name (opt-lambda vars . body)))))
(define (mem-key key ls)
(and (pair? ls)
(pair? (cdr ls))
(if (eq? key (car ls))
ls
(mem-key key (cddr ls)))))
;;> \procedure{(keyword-ref ls key [default])}
;;>
;;> Search for the identifier \var{key} in the list \var{ls}, treating
@ -103,12 +110,8 @@
;;> \var{default}, or \scheme{#f}.
(define (keyword-ref ls key . o)
(let lp ((ls ls))
(if (and (pair? ls) (pair? (cdr ls)))
(if (eq? key (car ls))
(cadr ls)
(lp (cddr ls)))
(and (pair? o) (car o)))))
(cond ((mem-key key ls) => (lambda (cell) (cadr cell)))
(else (and (pair? o) (car o)))))
;;> \macro{(keyword-ref* ls key default)}
;;>
@ -118,7 +121,7 @@
(define-syntax keyword-ref*
(syntax-rules ()
((keyword-ref* ls key default)
(cond ((memq key ls) => cadr) (else default)))))
(cond ((mem-key key ls) => cadr) (else default)))))
(define (symbol->keyword sym)
(string->symbol (string-append (symbol->string sym) ":")))