1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-20 11:40:18 +02:00

define @bind using syntax-case

* module/ice-9/boot-9.scm (@bind): Define a VM-compatible syntax
  definition for this old evaluator primitive.

* test-suite/tests/dynamic-scope.test: Change the expected error
  messages.
This commit is contained in:
Andy Wingo 2009-08-20 12:48:11 +02:00
parent 32aa211159
commit 12136c7148
2 changed files with 39 additions and 9 deletions

View file

@ -308,6 +308,38 @@
(syntax-rules () (syntax-rules ()
((_ exp) (make-promise (lambda () exp))))) ((_ exp) (make-promise (lambda () exp)))))
;;; @bind is used by the old elisp code as a dynamic scoping mechanism.
;;; Please let the Guile developers know if you are using this macro.
;;;
(define-syntax @bind
(lambda (x)
(define (bound-member id ids)
(cond ((null? ids) #f)
((bound-identifier=? id (car ids)) #t)
((bound-member (car ids) (cdr ids)))))
(syntax-case x ()
((_ () b0 b1 ...)
#'(let () b0 b1 ...))
((_ ((id val) ...) b0 b1 ...)
(and-map identifier? #'(id ...))
(if (let lp ((ids #'(id ...)))
(cond ((null? ids) #f)
((bound-member (car ids) (cdr ids)) #t)
(else (lp (cdr ids)))))
(syntax-violation '@bind "duplicate bound identifier" x)
(with-syntax (((old-v ...) (generate-temporaries #'(id ...)))
((v ...) (generate-temporaries #'(id ...))))
#'(let ((old-v id) ...
(v val) ...)
(dynamic-wind
(lambda ()
(set! id v) ...)
(lambda () b0 b1 ...)
(lambda ()
(set! id old-v) ...)))))))))
;;; {Defmacros} ;;; {Defmacros}

View file

@ -1,7 +1,7 @@
;;;; -*- scheme -*- ;;;; -*- scheme -*-
;;;; dynamic-scop.test --- test suite for dynamic scoping constructs ;;;; dynamic-scop.test --- test suite for dynamic scoping constructs
;;;; ;;;;
;;;; Copyright (C) 2001, 2006 Free Software Foundation, Inc. ;;;; Copyright (C) 2001, 2006, 2009 Free Software Foundation, Inc.
;;;; ;;;;
;;;; This library is free software; you can redistribute it and/or ;;;; This library is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU Lesser General Public ;;;; modify it under the terms of the GNU Lesser General Public
@ -21,12 +21,10 @@
:use-module (test-suite lib)) :use-module (test-suite lib))
(define exception:missing-expr (define exception:syntax-error
(cons 'syntax-error "Missing expression")) (cons 'syntax-error "failed to match"))
(define exception:bad-binding
(cons 'syntax-error "Bad binding"))
(define exception:duplicate-binding (define exception:duplicate-binding
(cons 'syntax-error "Duplicate binding")) (cons 'syntax-error "duplicate"))
(define global-a 0) (define global-a 0)
(define (fetch-global-a) global-a) (define (fetch-global-a) global-a)
@ -48,17 +46,17 @@
(interaction-environment))) (interaction-environment)))
(pass-if-exception "@bind missing expression" (pass-if-exception "@bind missing expression"
exception:missing-expr exception:syntax-error
(eval '(@bind ((global-a 1))) (eval '(@bind ((global-a 1)))
(interaction-environment))) (interaction-environment)))
(pass-if-exception "@bind bad bindings" (pass-if-exception "@bind bad bindings"
exception:bad-binding exception:syntax-error
(eval '(@bind (a) #f) (eval '(@bind (a) #f)
(interaction-environment))) (interaction-environment)))
(pass-if-exception "@bind bad bindings" (pass-if-exception "@bind bad bindings"
exception:bad-binding exception:syntax-error
(eval '(@bind ((a)) #f) (eval '(@bind ((a)) #f)
(interaction-environment))) (interaction-environment)))