(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)
(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
<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
(<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)
(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?))
(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))))
((<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
FETCH_LENGTH (len);
PUSH (scm_string_to_number (scm_from_locale_stringn ((char *)ip, len),
- SCM_UNSPECIFIED /* radix = 10 */));
+ SCM_UNDEFINED /* radix = 10 */));
/* Was: scm_istring2number (ip, len, 10)); */
ip += len;
NEXT;
NEXT;
}
+VM_DEFINE_LOADER (late_bind, "late-bind")
+{
+ SCM sym;
+ size_t len;
+
+ FETCH_LENGTH (len);
+ sym = scm_from_locale_symboln ((char *)ip, len);
+ ip += len;
+
+ PUSH (sym);
+ NEXT;
+}
+
/*
Local Variables:
c-file-style: "gnu"
NEXT;
}
+VM_DEFINE_INSTRUCTION (late_variable_ref, "late-variable-ref", 1, 0, 1)
+{
+ register unsigned objnum = FETCH ();
+ SCM x;
+ CHECK_OBJECT (objnum);
+ x = OBJECT_REF (objnum);
+
+ if (!SCM_VARIABLEP (x))
+ {
+ x = scm_lookup (x); /* might longjmp */
+ OBJECT_SET (objnum, x);
+ if (!VARIABLE_BOUNDP (x))
+ {
+ err_args = SCM_LIST1 (x);
+ goto vm_error_unbound;
+ }
+ }
+
+ PUSH (VARIABLE_REF (x));
+ NEXT;
+}
+
/* set */
VM_DEFINE_INSTRUCTION (local_set, "local-set", 1, 1, 0)
NEXT;
}
+VM_DEFINE_INSTRUCTION (late_variable_set, "late-variable-set", 1, 1, 0)
+{
+ register unsigned objnum = FETCH ();
+ SCM x;
+ CHECK_OBJECT (objnum);
+ x = OBJECT_REF (objnum);
+
+ if (!SCM_VARIABLEP (x))
+ {
+ x = scm_lookup (x); /* might longjmp */
+ OBJECT_SET (objnum, x);
+ if (!VARIABLE_BOUNDP (x))
+ {
+ err_args = SCM_LIST1 (x);
+ goto vm_error_unbound;
+ }
+ }
+
+ VARIABLE_SET (x, *sp);
+ DROP ();
+ NEXT;
+}
+
\f
/*
* branch and jump
t-proc-with-setter.scm \
t-values.scm \
t-records.scm \
- t-match.scm
+ t-match.scm \
+ t-mutual-toplevel-defines.scm
EXTRA_DIST = run-vm-tests.scm $(vm_test_files)
(format #t "running `~a'... " file)
(if (catch #t
(lambda ()
- (equal? (compile/run-test-from-file file)
- (eval (fetch-sexp-from-file file)
- (interaction-environment))))
+ (equal? (pk (compile/run-test-from-file file))
+ (pk (eval (fetch-sexp-from-file file)
+ (interaction-environment)))))
(lambda (key . args)
(format #t "[~a/~a] " key args)
#f))
--- /dev/null
+(define (even? x)
+ (or (zero? x)
+ (not (odd? (1- x)))))
+
+(define (odd? x)
+ (not (even? (1- x))))
+
+(even? 20)