mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-21 12:10:26 +02:00
fix else in cond, letrec env corruption, syntax.scm compile, define-module side effects
* module/language/scheme/translate.scm (primitive-syntax-table): Translate the `else' clause of a cond as (begin ...). We used to use trans-body, which processes internal defines, which are not legal syntax here. * module/system/base/syntax.scm (define-record): Unfortunately, we can't unquote in the actual procedure for `%compute-initargs', because that doesn't work with compilation. So reference %compute-initargs by name, and export it. * module/system/il/ghil.scm (apopq!): Gaaaaar. The order of the arguments to assq-remove! was reversed, which was the badness, causing corruption to the env after calling call-with-ghil-bindings. Grrrrrr. (fix-ghil-mod!, ghil-lookup, ghil-define): As amply commented in the code, deal with compile-time side effects to the current module by lazily noticing and patching up the compile-time environment. A hacky solution until such a time as we special-case something for `define-module'.
This commit is contained in:
parent
6167de4f72
commit
cd702346f2
3 changed files with 30 additions and 7 deletions
|
@ -203,7 +203,7 @@
|
||||||
(cond
|
(cond
|
||||||
;; (cond (CLAUSE BODY...) ...)
|
;; (cond (CLAUSE BODY...) ...)
|
||||||
(() (retrans '(begin)))
|
(() (retrans '(begin)))
|
||||||
(((else . ,body)) (trans-body e l body))
|
(((else . ,body)) (retrans `(begin ,@body)))
|
||||||
(((,test) . ,rest) (retrans `(or ,test (cond ,@rest))))
|
(((,test) . ,rest) (retrans `(or ,test (cond ,@rest))))
|
||||||
(((,test => ,proc) . ,rest)
|
(((,test => ,proc) . ,rest)
|
||||||
;; FIXME hygiene!
|
;; FIXME hygiene!
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
(define-module (system base syntax)
|
(define-module (system base syntax)
|
||||||
|
:export (%compute-initargs)
|
||||||
:export-syntax (define-type define-record record-case))
|
:export-syntax (define-type define-record record-case))
|
||||||
(export-syntax |) ;; emacs doesn't like the |
|
(export-syntax |) ;; emacs doesn't like the |
|
||||||
|
|
||||||
|
@ -57,10 +58,10 @@
|
||||||
(if (pair? slot)
|
(if (pair? slot)
|
||||||
`(cons ',(car slot) ,(cadr slot))
|
`(cons ',(car slot) ,(cadr slot))
|
||||||
`',slot))
|
`',slot))
|
||||||
slots))))
|
slots)))
|
||||||
|
(constructor (record-constructor ,name)))
|
||||||
(lambda args
|
(lambda args
|
||||||
(apply ,(record-constructor type)
|
(apply constructor (%compute-initargs args slots)))))
|
||||||
(,%compute-initargs args slots)))))
|
|
||||||
(define ,(symbol-append stem '?) ,(record-predicate type))
|
(define ,(symbol-append stem '?) ,(record-predicate type))
|
||||||
,@(map (lambda (sname)
|
,@(map (lambda (sname)
|
||||||
`(define ,(symbol-append stem '- sname)
|
`(define ,(symbol-append stem '- sname)
|
||||||
|
|
|
@ -171,7 +171,7 @@
|
||||||
(define-macro (apush! k v loc)
|
(define-macro (apush! k v loc)
|
||||||
`(set! ,loc (acons ,k ,v ,loc)))
|
`(set! ,loc (acons ,k ,v ,loc)))
|
||||||
(define-macro (apopq! k loc)
|
(define-macro (apopq! k loc)
|
||||||
`(set! ,loc (assq-remove! ,k ,loc)))
|
`(set! ,loc (assq-remove! ,loc ,k)))
|
||||||
|
|
||||||
(define (ghil-env-add! env var)
|
(define (ghil-env-add! env var)
|
||||||
(apush! (ghil-var-name var) var (ghil-env-table env))
|
(apush! (ghil-var-name var) var (ghil-env-table env))
|
||||||
|
@ -190,19 +190,39 @@
|
||||||
(and iface
|
(and iface
|
||||||
(make-ghil-env (make-ghil-mod iface)))))
|
(make-ghil-env (make-ghil-mod iface)))))
|
||||||
|
|
||||||
|
(define (fix-ghil-mod! mod for-sym)
|
||||||
|
(warn "during lookup of" for-sym ":" (ghil-mod-module mod) "!= current" (current-module))
|
||||||
|
(if (not (null? (ghil-mod-table mod)))
|
||||||
|
(warn "throwing away old variable table" (ghil-mod-table mod)))
|
||||||
|
(set! (ghil-mod-module mod) (current-module))
|
||||||
|
(set! (ghil-mod-table mod) '())
|
||||||
|
(set! (ghil-mod-imports mod) '()))
|
||||||
|
|
||||||
;; looking up a var has side effects?
|
;; looking up a var has side effects?
|
||||||
(define (ghil-lookup env sym)
|
(define (ghil-lookup env sym)
|
||||||
(or (ghil-env-ref env sym)
|
(or (ghil-env-ref env sym)
|
||||||
(let loop ((e (ghil-env-parent env)))
|
(let loop ((e (ghil-env-parent env)))
|
||||||
(record-case e
|
(record-case e
|
||||||
((<ghil-mod> module table imports)
|
((<ghil-mod> module table imports)
|
||||||
(cond ((assq-ref table sym))
|
(cond ((not (eq? module (current-module)))
|
||||||
|
;; FIXME: the primitive-eval in eval-case and/or macro
|
||||||
|
;; expansion can have side effects on the compilation
|
||||||
|
;; environment, for example changing the current
|
||||||
|
;; module. We probably need to add a special case in
|
||||||
|
;; compilation to handle define-module.
|
||||||
|
(fix-ghil-mod! e sym)
|
||||||
|
(loop e))
|
||||||
|
((assq-ref table sym)) ;; when does this hit?
|
||||||
((module-lookup module sym)
|
((module-lookup module sym)
|
||||||
=> (lambda (found-env)
|
=> (lambda (found-env)
|
||||||
(make-ghil-var found-env sym 'module)))
|
(make-ghil-var found-env sym 'module)))
|
||||||
(else
|
(else
|
||||||
;; a free variable that we have not resolved
|
;; a free variable that we have not resolved
|
||||||
(warn "unresolved variable during compilation:" sym)
|
(if (not (module-locally-bound? module sym))
|
||||||
|
;; For the benefit of repl compilation, that
|
||||||
|
;; doesn't compile modules all-at-once, don't warn
|
||||||
|
;; if we find the symbol locally.
|
||||||
|
(warn "unresolved variable during compilation:" sym))
|
||||||
(make-ghil-var #f sym 'module))))
|
(make-ghil-var #f sym 'module))))
|
||||||
((<ghil-env> mod parent table variables)
|
((<ghil-env> mod parent table variables)
|
||||||
(let ((found (assq-ref table sym)))
|
(let ((found (assq-ref table sym)))
|
||||||
|
@ -211,6 +231,8 @@
|
||||||
(loop parent))))))))
|
(loop parent))))))))
|
||||||
|
|
||||||
(define (ghil-define mod sym)
|
(define (ghil-define mod sym)
|
||||||
|
(if (not (eq? (ghil-mod-module mod) (current-module)))
|
||||||
|
(fix-ghil-mod! mod sym))
|
||||||
(or (assq-ref (ghil-mod-table mod) sym)
|
(or (assq-ref (ghil-mod-table mod) sym)
|
||||||
(let ((var (make-ghil-var (make-ghil-env mod) sym 'module)))
|
(let ((var (make-ghil-var (make-ghil-env mod) sym 'module)))
|
||||||
(apush! sym var (ghil-mod-table mod))
|
(apush! sym var (ghil-mod-table mod))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue