1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-18 17:50:29 +02:00

Add instructions for doing very late binding

Fixes the mutually-recursive toplevel definitions case. This could be
fixed by rewriting bodies as letrecs, as r6 does, but that's not really
repl-compatible.

* module/system/il/ghil.scm (ghil-lookup): Ok, if we can't locate a
  variable, mark it as unresolved.

* module/system/il/compile.scm (make-glil-var): Compile unresolved
  variables as <glil-late-bound> objects.

* module/system/il/glil.scm: Add <glil-late-bound> definition.

* module/system/vm/assemble.scm (codegen): And, finally, when we see a
  <vlate-bound> object, allocate a slot for it in the object vector,
  setting it to a symbol. Add a new pair of instructions to resolve that
  symbol to a variable at the last minute.

* src/vm_loader.c (load-number): Bugfix: the radix argument should be
  SCM_UNDEFINED in order to default to 10.
  (late-bind): Add an unresolved symbol to the object vector. Could be
  replaced with load-symbol I guess.

* src/vm_system.c (late-variable-ref, late-variable-set): New
  instructions to do late symbol binding.

* testsuite/Makefile.am (vm_test_files):
* testsuite/t-mutual-toplevel-defines.scm: New test, failing for some
  reason involving the core even? and odd? definitions.
This commit is contained in:
Andy Wingo 2008-05-19 17:46:05 +02:00
parent 1b8abe5514
commit 9cc649b880
9 changed files with 99 additions and 11 deletions

View file

@ -103,6 +103,8 @@
(let ((env (ghil-var-env var)))
(make-glil-module op (and env (ghil-mod-module (ghil-env-mod env)))
(ghil-var-name var))))
((unresolved)
(make-glil-late-bound op (ghil-var-name var)))
(else (error "Unknown kind of variable:" var))))
(define (codegen ghil)

View file

@ -224,12 +224,10 @@
(make-ghil-var found-env sym 'module)))
(else
;; a free variable that we have not resolved
(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))))
(warn "unresolved variable during compilation:" sym)
(let ((var (make-ghil-var #f sym 'unresolved)))
(apush! sym var table)
var))))
((<ghil-env> mod parent table variables)
(let ((found (assq-ref table sym)))
(if found

View file

@ -54,6 +54,9 @@
<glil-module> make-glil-module glil-module?
glil-module-op glil-module-module glil-module-index
<glil-late-bound> make-glil-late-bound glil-late-bound?
glil-late-bound-op glil-late-bound-name
<glil-label> make-glil-label glil-label?
glil-label-label
@ -80,6 +83,7 @@
(<glil-local> op index)
(<glil-external> op depth index)
(<glil-module> op module name)
(<glil-late-bound> op name)
;; Controls
(<glil-label> label)
(<glil-branch> inst label)

View file

@ -44,6 +44,7 @@
(define-record (<venv> parent nexts closure?))
(define-record (<vmod> id))
(define-record (<vlink> module name))
(define-record (<vlate-bound> name))
(define-record (<vdefine> module name))
(define-record (<bytespec> vars bytes meta objs closure?))
@ -158,6 +159,20 @@
(push-object! (make-vdefine :module module :name name))
(push-code! '(variable-set)))))
((<glil-late-bound> op name)
(let* ((var (make-vlate-bound :name name))
(i (cond ((object-assoc var object-alist) => cdr)
(else
(let ((i (length object-alist)))
(set! object-alist (acons var i object-alist))
i)))))
(case op
((ref)
(push-code! `(late-variable-ref ,i)))
((set)
(push-code! `(late-variable-set ,i)))
(else (error "unknown late bound" op name)))))
((<glil-label> label)
(set! label-alist (assq-set! label-alist label (current-address))))
@ -263,6 +278,8 @@
((<vdefine> module name)
;; FIXME: dump module
(push-code! `(define ,(symbol->string name))))
((<vlate-bound> name)
(push-code! `(late-bind ,(symbol->string name))))
((<vmod> id)
(push-code! `(load-module ,id)))
(else