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

View file

@ -78,7 +78,7 @@
;; returns 1 modulo n. ;; returns 1 modulo n.
(let ((b (modular-expt a odd n))) (let ((b (modular-expt a odd n)))
(let lp ((i 0) (b b)) (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) ((>= i twos) #f)
(else (lp (+ i 1) (remainder (* b b) n))))))) (else (lp (+ i 1) (remainder (* b b) n)))))))

View file

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

View file

@ -53,6 +53,8 @@
(test '(0 1 (2 3 4)) (test '(0 1 (2 3 4))
(let-optionals '(0 1 2 3 4) ((a 10) (b 11) . c) (let-optionals '(0 1 2 3 4) ((a 10) (b 11) . c)
(list a b 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 (cond-expand
(gauche) ; gauche detects this at compile-time, can't catch (gauche) ; gauche detects this at compile-time, can't catch
(else (test-error '(0 11 12) (else (test-error '(0 11 12)

View file

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