1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-02 21:10:27 +02:00

without-void-checks as new extension for fine-control

* module/language/elisp/README: Document it.
* module/language/elisp/compile-tree-il.scm: Handle without-void-checks.
* test-suite/tests/elisp-compiler.test: Test it.
This commit is contained in:
Daniel Kraft 2009-07-30 13:51:45 +02:00
parent e96a9591ce
commit f3df67e203
3 changed files with 37 additions and 5 deletions

View file

@ -42,6 +42,7 @@ Extensions over original elisp:
* guile-ref, guile-primitive * guile-ref, guile-primitive
* flet and flet* * flet and flet*
* lexical-let and lexical-let* * lexical-let and lexical-let*
* without-void-checks
Details to the implemented extensions Details to the implemented extensions
@ -95,3 +96,12 @@ for compatibility:
* If symbols are accessed where they are not known at compile-time (like * If symbols are accessed where they are not known at compile-time (like
symbol-value or set primitives), this always refers to the dynamic binding symbol-value or set primitives), this always refers to the dynamic binding
and never the lexical one. That's very nice to the implementor... and never the lexical one. That's very nice to the implementor...
without-void-checks:
--------------------
Disable void checks in addition to the compiler option for all or some symbols
in the lexical scope of this construct:
(without-void-checks all body...) or
(without-void-checks (sym1 sym2 ...) body...

View file

@ -111,11 +111,13 @@
; See if we should do a void-check for a given variable. That means, check ; See if we should do a void-check for a given variable. That means, check
; that this check is not disabled via the compiler options for this symbol. ; that this check is not disabled via the compiler options for this symbol.
; Disabling of void check is only done for the value-slot module!
(define (want-void-check? sym) (define (want-void-check? sym module)
(let ((disabled (fluid-ref disable-void-check))) (let ((disabled (fluid-ref disable-void-check)))
(and (not (eq? disabled 'all)) (or (not (equal? module value-slot))
(not (memq sym disabled))))) (and (not (eq? disabled 'all))
(not (memq sym disabled))))))
; Handle access to a variable (reference/setting) correctly depending on ; Handle access to a variable (reference/setting) correctly depending on
@ -146,7 +148,7 @@
; Reference a variable and error if the value is void. ; Reference a variable and error if the value is void.
(define (reference-with-check loc sym module) (define (reference-with-check loc sym module)
(if (want-void-check? sym) (if (want-void-check? sym module)
(let ((var (gensym))) (let ((var (gensym)))
(make-let loc '(value) `(,var) `(,(reference-variable loc sym module)) (make-let loc '(value) `(,var) `(,(reference-variable loc sym module))
(make-conditional loc (make-conditional loc
@ -700,6 +702,23 @@
(not (null? body)))) (not (null? body))))
(generate-let* loc function-slot bindings body)) (generate-let* loc function-slot bindings body))
; Temporarily disable void checks for certain symbols within the lexical
; scope of without-void-checks.
((without-void-checks ,syms . ,body)
(guard (and (list? body) (not (null? body))
(or (eq? syms 'all)
(and (list? syms) (and-map symbol? syms)))))
(let ((disabled (fluid-ref disable-void-check))
(make-body (lambda ()
(make-sequence loc (map compile-expr body)))))
(if (eq? disabled 'all)
(make-body)
(let ((new-disabled (if (eq? syms 'all)
'all
(append syms disabled))))
(with-fluid* disable-void-check new-disabled make-body)))))
; guile-ref allows building TreeIL's module references from within ; guile-ref allows building TreeIL's module references from within
; elisp as a way to access data within ; elisp as a way to access data within
; the Guile universe. The module and symbol referenced are static values, ; the Guile universe. The module and symbol referenced are static values,

View file

@ -241,7 +241,10 @@
#:opts '(#:disable-void-check all)) #:opts '(#:disable-void-check all))
(pass-if "disabled void check (symbol list)" (pass-if "disabled void check (symbol list)"
(progn (makunbound 'a) a t) (progn (makunbound 'a) a t)
#:opts '(#:disable-void-check (x y a b)))) #:opts '(#:disable-void-check (x y a b)))
(pass-if "without-void-checks"
(progn (makunbound 'a)
(= (without-void-checks (a) a 5) 5))))
(with-test-prefix/compile "Let and Let*" (with-test-prefix/compile "Let and Let*"