1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 03:40:34 +02:00

*** empty log message ***

This commit is contained in:
Keisuke Nishida 2001-04-22 02:13:48 +00:00
parent ac02b386c2
commit ac99cb0cb1
47 changed files with 1319 additions and 854 deletions

View file

@ -1,7 +1,7 @@
misc
libtool libtool
config.* config.*
configure configure
Makefile Makefile
Makefile.in Makefile.in
aclocal.m4 aclocal.m4
misc

View file

@ -12,4 +12,15 @@ AC_PROG_LN_S
AM_PROG_LIBTOOL AM_PROG_LIBTOOL
AC_C_LABELS_AS_VALUES AC_C_LABELS_AS_VALUES
AC_OUTPUT(Makefile src/Makefile doc/Makefile module/Makefile) guiledir="\$(datadir)/guile"
AC_SUBST(guiledir)
GUILEC="GUILE_LOAD_PATH=\$(top_srcdir)/module \
LD_LIBRARY_PATH=\$(top_srcdir)/src/.libs \
guile -s \$(top_srcdir)/src/guilec"
AC_SUBST(GUILEC)
AC_OUTPUT(Makefile src/Makefile doc/Makefile module/Makefile
module/system/Makefile module/system/base/Makefile
module/system/vm/Makefile module/system/il/Makefile
module/system/repl/Makefile)

View file

@ -1,3 +1,5 @@
SUBDIRS = system
DISTDIRS = $(srcdir)/system $(srcdir)/language $(srcdir)/guile $(srcdir)/slib DISTDIRS = $(srcdir)/system $(srcdir)/language $(srcdir)/guile $(srcdir)/slib
EXCLUDES = --exclude=CVS --exclude=*.go --exclude=*~ EXCLUDES = --exclude=CVS --exclude=*.go --exclude=*~

View file

@ -0,0 +1,3 @@
Makefile
Makefile.in
*.go

View file

@ -0,0 +1,3 @@
Makefile
Makefile.in
*.go

View file

@ -0,0 +1,3 @@
Makefile
Makefile.in
*.go

View file

@ -0,0 +1,3 @@
Makefile
Makefile.in
*.go

View file

@ -0,0 +1,3 @@
Makefile
Makefile.in
*.go

View file

@ -29,7 +29,7 @@
(define (translate x e) (define (translate x e)
(call-with-ghil-environment (make-ghil-mod e) '() (call-with-ghil-environment (make-ghil-mod e) '()
(lambda (env vars) (lambda (env vars)
(make-<ghil-lambda> env #f vars 0 (trans env #f x))))) (<ghil-lambda> env #f vars #f (trans env #f x)))))
;;; ;;;
@ -46,25 +46,25 @@
(trans-pair e (or (location x) l) (car x) (cdr x)) (trans-pair e (or (location x) l) (car x) (cdr x))
(trans e l y)))) (trans e l y))))
((symbol? x) ((symbol? x)
(let ((y (expand-symbol x))) (let ((y (symbol-expand x)))
(if (eq? x y) (if (symbol? y)
(make-<ghil-ref> e l (ghil-lookup e x)) (<ghil-ref> e l (ghil-lookup e y))
(trans e l y)))) (trans e l y))))
(else (make-<ghil-quote> e l x)))) (else (<ghil-quote> e l x))))
(define (expand-symbol x) (define (symbol-expand x)
(let loop ((s (symbol->string x))) (let loop ((s (symbol->string x)))
(let ((i (string-rindex s #\.))) (let ((i (string-rindex s #\.)))
(if i (if i
`(slot ,(loop (substring s 0 i)) (let ((sym (string->symbol (substring s (1+ i)))))
(quote ,(string->symbol (substring s (1+ i))))) `(slot ,(loop (substring s 0 i)) (quote ,sym)))
(string->symbol s))))) (string->symbol s)))))
(define (trans-pair e l head tail) (define (trans-pair e l head tail)
(define (trans:x x) (trans e l x)) (define (trans:x x) (trans e l x))
(define (trans:pair x) (trans-pair e l (car x) (cdr x))) (define (trans:pair x) (trans-pair e l (car x) (cdr x)))
(define (trans:body body) (trans-body e l body)) (define (trans:body body) (trans-body e l body))
(define (make:void) (make-<ghil-void> e l)) (define (make:void) (<ghil-void> e l))
(define (bad-syntax) (define (bad-syntax)
(syntax-error l (format #f "bad ~A" head) (cons head tail))) (syntax-error l (format #f "bad ~A" head) (cons head tail)))
(case head (case head
@ -77,26 +77,26 @@
;; (quote OBJ) ;; (quote OBJ)
((quote) ((quote)
(match tail (match tail
((obj) (make-<ghil-quote> e l obj)) ((obj) (<ghil-quote> e l obj))
(else (bad-syntax)))) (else (bad-syntax))))
;; (quasiquote OBJ) ;; (quasiquote OBJ)
((quasiquote) ((quasiquote)
(match tail (match tail
((obj) (make-<ghil-quasiquote> e l (trans-quasiquote e l obj))) ((obj) (<ghil-quasiquote> e l (trans-quasiquote e l obj)))
(else (bad-syntax)))) (else (bad-syntax))))
((define define-private) ((define define-private)
(match tail (match tail
;; (define NAME VAL) ;; (define NAME VAL)
(((? symbol? name) val) (((? symbol? name) val)
(make-<ghil-define> e l (ghil-lookup e name) (trans:x val))) (<ghil-define> e l (ghil-lookup e name) (trans:x val)))
;; (define (NAME FORMALS...) BODY...) ;; (define (NAME FORMALS...) BODY...)
((((? symbol? name) . formals) . body) ((((? symbol? name) . formals) . body)
;; -> (define NAME (lambda FORMALS BODY...)) ;; -> (define NAME (lambda FORMALS BODY...))
(let ((val (trans:x `(lambda ,formals ,@body)))) (let ((val (trans:x `(lambda ,formals ,@body))))
(make-<ghil-define> e l (ghil-lookup e name) val))) (<ghil-define> e l (ghil-lookup e name) val)))
(else (bad-syntax)))) (else (bad-syntax))))
@ -104,7 +104,7 @@
(match tail (match tail
;; (set! NAME VAL) ;; (set! NAME VAL)
(((? symbol? name) val) (((? symbol? name) val)
(make-<ghil-set> e l (ghil-lookup e name) (trans:x val))) (<ghil-set> e l (ghil-lookup e name) (trans:x val)))
;; (set! (NAME ARGS...) VAL) ;; (set! (NAME ARGS...) VAL)
((((? symbol? name) . args) val) ((((? symbol? name) . args) val)
@ -117,22 +117,22 @@
((if) ((if)
(match tail (match tail
((test then) ((test then)
(make-<ghil-if> e l (trans:x test) (trans:x then) (make:void))) (<ghil-if> e l (trans:x test) (trans:x then) (make:void)))
((test then else) ((test then else)
(make-<ghil-if> e l (trans:x test) (trans:x then) (trans:x else))) (<ghil-if> e l (trans:x test) (trans:x then) (trans:x else)))
(else (bad-syntax)))) (else (bad-syntax))))
;; (and EXPS...) ;; (and EXPS...)
((and) ((and)
(make-<ghil-and> e l (map trans:x tail))) (<ghil-and> e l (map trans:x tail)))
;; (or EXPS...) ;; (or EXPS...)
((or) ((or)
(make-<ghil-or> e l (map trans:x tail))) (<ghil-or> e l (map trans:x tail)))
;; (begin EXPS...) ;; (begin EXPS...)
((begin) ((begin)
(make-<ghil-begin> e l (map trans:x tail))) (<ghil-begin> e l (map trans:x tail)))
((let) ((let)
(match tail (match tail
@ -144,14 +144,14 @@
;; (let () BODY...) ;; (let () BODY...)
((() body ...) ((() body ...)
;; NOTE: This differs from `begin' ;; NOTE: This differs from `begin'
(make-<ghil-begin> e l (list (trans:body body)))) (<ghil-begin> e l (list (trans:body body))))
;; (let ((SYM VAL) ...) BODY...) ;; (let ((SYM VAL) ...) BODY...)
(((((? symbol? sym) val) ...) body ...) (((((? symbol? sym) val) ...) body ...)
(let ((vals (map trans:x val))) (let ((vals (map trans:x val)))
(call-with-ghil-bindings e sym (call-with-ghil-bindings e sym
(lambda (vars) (lambda (vars)
(make-<ghil-bind> e l vars vals (trans:body body)))))) (<ghil-bind> e l vars vals (trans:body body))))))
(else (bad-syntax)))) (else (bad-syntax))))
@ -171,7 +171,7 @@
(call-with-ghil-bindings e sym (call-with-ghil-bindings e sym
(lambda (vars) (lambda (vars)
(let ((vals (map trans:x val))) (let ((vals (map trans:x val)))
(make-<ghil-bind> e l vars vals (trans:body body)))))) (<ghil-bind> e l vars vals (trans:body body))))))
(else (bad-syntax)))) (else (bad-syntax))))
;; (cond (CLAUSE BODY...) ...) ;; (cond (CLAUSE BODY...) ...)
@ -222,7 +222,7 @@
(receive (syms rest) (parse-formals formals) (receive (syms rest) (parse-formals formals)
(call-with-ghil-environment e syms (call-with-ghil-environment e syms
(lambda (env vars) (lambda (env vars)
(make-<ghil-lambda> env l vars rest (trans-body env l body)))))) (<ghil-lambda> env l vars rest (trans-body env l body))))))
(else (bad-syntax)))) (else (bad-syntax))))
((eval-case) ((eval-case)
@ -240,8 +240,8 @@
(else (else
(if (memq head scheme-primitives) (if (memq head scheme-primitives)
(make-<ghil-inline> e l head (map trans:x tail)) (<ghil-inline> e l head (map trans:x tail))
(make-<ghil-call> e l (trans:x head) (map trans:x tail)))))) (<ghil-call> e l (trans:x head) (map trans:x tail))))))
(define (trans-quasiquote e l x) (define (trans-quasiquote e l x)
(cond ((not (pair? x)) x) (cond ((not (pair? x)) x)
@ -250,8 +250,8 @@
(match (cdr x) (match (cdr x)
((obj) ((obj)
(if (eq? (car x) 'unquote) (if (eq? (car x) 'unquote)
(make-<ghil-unquote> e l (trans e l obj)) (<ghil-unquote> e l (trans e l obj))
(make-<ghil-unquote-splicing> e l (trans e l obj)))) (<ghil-unquote-splicing> e l (trans e l obj))))
(else (syntax-error l (format #f "bad ~A" (car x)) x))))) (else (syntax-error l (format #f "bad ~A" (car x)) x)))))
(else (cons (trans-quasiquote e l (car x)) (else (cons (trans-quasiquote e l (car x))
(trans-quasiquote e l (cdr x)))))) (trans-quasiquote e l (cdr x))))))

3
module/system/.cvsignore Normal file
View file

@ -0,0 +1,3 @@
Makefile
Makefile.in
*.go

View file

@ -0,0 +1 @@
SUBDIRS = vm

View file

@ -1 +1,3 @@
Makefile
Makefile.in
*.go *.go

View file

@ -0,0 +1,12 @@
SOURCES = syntax.scm language.scm compile.scm
OBJECTS = syntax.go language.go compile.go
vmdir = $(guiledir)/system/vm
vm_DATA = $(SOURCES) $(OBJECTS)
DISTCLEANFILES = $(OBJECTS)
MAINTAINERCLEANFILES = Makefile.in
SUFFIXES = .scm .go
.scm.go:
$(GUILEC) $<

View file

@ -20,10 +20,10 @@
;;; Code: ;;; Code:
(define-module (system base compile) (define-module (system base compile)
:use-module (oop goops)
:use-syntax (system base syntax) :use-syntax (system base syntax)
:use-module (system base language) :use-module (system base language)
:use-module (system il compile) :use-module (system il compile)
:use-module (system il glil)
:use-module (system vm core) :use-module (system vm core)
:use-module (system vm assemble) :use-module (system vm assemble)
:use-module (ice-9 regex)) :use-module (ice-9 regex))
@ -32,19 +32,17 @@
;;; Compiler environment ;;; Compiler environment
;;; ;;;
(define-vm-class <cenv> () (define-record (<cenv> vm language module))
vm language module optimize)
(define-public (make-cenv . rest) (define-public (make-cenv . rest)
(apply make <cenv> rest)) (apply <cenv> rest))
(define-public (syntax-error loc msg exp) (define-public (syntax-error loc msg exp)
(throw 'syntax-error loc msg exp)) (throw 'syntax-error loc msg exp))
(define-public (call-with-compile-error-catch thunk) (define-public (call-with-compile-error-catch thunk)
(catch 'syntax-error (try (thunk)
thunk ((syntax-error loc msg exp)
(lambda (key loc msg exp)
(format #t "~A:~A: ~A: ~A" (car loc) (cdr loc) msg exp)))) (format #t "~A:~A: ~A: ~A" (car loc) (cdr loc) msg exp))))
@ -65,7 +63,9 @@
(let* ((source (read-file-in file scheme)) (let* ((source (read-file-in file scheme))
(objcode (apply compile-in source (current-module) (objcode (apply compile-in source (current-module)
scheme opts))) scheme opts)))
(uniform-array-write (objcode->string objcode) port)))) (if (memq :c opts)
(pprint-glil objcode port)
(uniform-array-write (objcode->string objcode) port)))))
(format #t "Wrote ~A\n" comp)))) (format #t "Wrote ~A\n" comp))))
(lambda (key . args) (lambda (key . args)
(format #t "ERROR: During compiling ~A:\n" file) (format #t "ERROR: During compiling ~A:\n" file)

View file

@ -20,7 +20,6 @@
;;; Code: ;;; Code:
(define-module (system base language) (define-module (system base language)
:use-module (oop goops)
:use-syntax (system base syntax) :use-syntax (system base syntax)
:export (define-language lookup-language)) :export (define-language lookup-language))
@ -29,21 +28,15 @@
;;; Language class ;;; Language class
;;; ;;;
(define-vm-class <language> () (define-record (<language> name title version reader printer read-file
name title version environment
reader printer read-file
(expander (lambda (x e) x)) (expander (lambda (x e) x))
(translator (lambda (x e) x)) (translator (lambda (x e) x))
(evaluator #f) (evaluator #f)
) (environment #f)
))
(define-method (write (lang <language>) port)
(display "#<language " port)
(display lang.name port)
(display ">"))
(define-macro (define-language name . spec) (define-macro (define-language name . spec)
`(define ,name (,make ,<language> :name ',name ,@spec))) `(define ,name (,<language> :name ',name ,@spec)))
(define (lookup-language name) (define (lookup-language name)
(let ((m (resolve-module `(language ,name spec)))) (let ((m (resolve-module `(language ,name spec))))

View file

@ -1,34 +1,34 @@
;;; Guile VM specific syntaxes and utilities ;;; Guile VM specific syntaxes and utilities
;; Copyright (C) 2001 Free Software Foundation, Inc. ;; Copyright (C) 2001 Free Software Foundation, Inc
;; This program is free software; you can redistribute it and/or modify ;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by ;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option) ;; the Free Software Foundation; either version 2, or (at your option)
;; any later version. ;; any later version
;; ;;
;; This program is distributed in the hope that it will be useful, ;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details. ;; GNU General Public License for more details
;; ;;
;; You should have received a copy of the GNU General Public License ;; You should have received a copy of the GNU General Public License
;; along with this program; see the file COPYING. If not, write to ;; along with this program; see the file COPYING. If not, write to
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA. ;; Boston, MA 02111-1307, USA
;;; Code: ;;; Code:
(define-module (system base syntax) (define-module (system base syntax)
:use-module (oop goops) :use-module (ice-9 try)
:use-module (ice-9 match) :use-module (ice-9 match)
:use-module (ice-9 receive) :use-module (ice-9 receive)
:use-module (ice-9 and-let-star) :use-module (ice-9 and-let-star)
:export (match syntax-error and-let* receive)) :export (try stack-catch match syntax-error receive and-let*))
;;; ;;;
;;; Keywords by `:KEYWORD' ;;; Keywords by `:KEYWORD
;;; ;;;
(read-set! keywords 'prefix) (read-set! keywords 'prefix)
@ -41,9 +41,9 @@
;; FOO.BAR -> (slot FOO 'BAR) ;; FOO.BAR -> (slot FOO 'BAR)
(define (expand-dot! x) (define (expand-dot! x)
(cond ((and (symbol? x) (not (eq? x '...))) (expand-symbol x)) (cond ((symbol? x) (expand-symbol x))
((pair? x) ((pair? x)
(cond ((memq (car x) '(quote quasiquote)) x) (cond ((eq? (car x) 'quote) x)
(else (set-car! x (expand-dot! (car x))) (else (set-car! x (expand-dot! (car x)))
(set-cdr! x (expand-dot! (cdr x))) (set-cdr! x (expand-dot! (cdr x)))
x))) x)))
@ -57,39 +57,110 @@
(quote ,(string->symbol (substring s (1+ i))))) (quote ,(string->symbol (substring s (1+ i)))))
(string->symbol s))))) (string->symbol s)))))
(define syntax expand-dot!)
(export-syntax syntax) (export-syntax syntax)
(define syntax expand-dot!)
;; slot accessor
(define slot (make-procedure-with-setter slot-ref slot-set!))
(export slot)
;;; ;;;
;;; Simplified define-class ;;; Type
;;; ;;;
;; (define-vm-class <foo> () (x 1) (y 2)) => (export-syntax define-type)
;; (define-macro (define-type name sig) sig)
;; (define-class <foo> ()
;; (a :init-keyword :a :init-form 1)
;; (b :init-keyword :b :init-form 2))
(define-macro (define-vm-class name supers . rest)
`(define-class ,name ,supers
,@(map (lambda (def)
(if (not (pair? def)) (set! def (list def)))
(let ((name (car def)) (rest (cdr def)))
(cons* name :init-keyword (symbol->keyword name)
(if (or (null? rest) (keyword? (car rest)))
rest
(cons :init-form rest)))))
rest)))
(export-syntax define-vm-class)
;;; ;;;
;;; Other utilities ;;; Record
;;;
(export-syntax define-record)
(define-macro (define-record def)
(let ((name (car def)) (slots (cdr def)))
`(begin
(define (,name . args)
(vector ',name (%make-struct
args
(list ,@(map (lambda (slot)
(if (pair? slot)
`(cons ',(car slot) ,(cadr slot))
`',slot))
slots)))))
(define (,(symbol-append name '?) x)
(and (vector? x) (eq? (vector-ref x 0) ',name)))
,@(do ((n 1 (1+ n))
(slots (cdr def) (cdr slots))
(ls '() (cons (let* ((slot (car slots))
(slot (if (pair? slot) (car slot) slot)))
`(define ,(string->symbol
(format #f "~A-~A" name n))
(lambda (x) (slot x ',slot))))
ls)))
((null? slots) (reverse! ls))))))
(define *unbound* "#<unbound>")
(define-public (%make-struct args slots)
(map (lambda (slot)
(let* ((key (if (pair? slot) (car slot) slot))
(def (if (pair? slot) (cdr slot) *unbound*))
(val (get-key args (symbol->keyword key) def)))
(if (eq? val *unbound*)
(error "Slot unbound:" key)
(cons key val))))
slots))
(define (get-key klist key def)
(do ((ls klist (cddr ls)))
((or (null? ls) (eq? (car ls) key))
(if (null? ls) def (cadr ls)))))
(define-public slot
(make-procedure-with-setter
(lambda (struct name)
(let ((data (assq name (vector-ref struct 1))))
(cond ((not data)
(error "Unknown slot:" name))
(else (cdr data)))))
(lambda (struct name val)
(let ((data (assq name (vector-ref struct 1))))
(cond ((not data)
(error "Unknown slot:" name))
(else (set-cdr! data val)))))))
;;;
;;; Variants
;;;
(export-syntax |)
(define-macro (| . rest)
`(begin ,@(map %make-variant-type rest)))
(define (%make-variant-type def)
(let ((name (car def)) (slots (cdr def)))
`(begin
(define ,def (vector ',name ,@slots))
(define (,(symbol-append name '?) x)
(and (vector? x) (eq? (vector-ref x 0) ',name)))
,@(do ((n 1 (1+ n))
(slots slots (cdr slots))
(ls '() (cons `(define ,(string->symbol
(format #f "~A-~A" name n))
,(string->symbol (format #f "%slot-~A" n)))
ls)))
((null? slots) (reverse! ls))))))
(define-public (%slot-1 x) (vector-ref x 1))
(define-public (%slot-2 x) (vector-ref x 2))
(define-public (%slot-3 x) (vector-ref x 3))
(define-public (%slot-4 x) (vector-ref x 4))
(define-public (%slot-5 x) (vector-ref x 5))
(define-public (%slot-6 x) (vector-ref x 6))
(define-public (%slot-7 x) (vector-ref x 7))
(define-public (%slot-8 x) (vector-ref x 8))
(define-public (%slot-9 x) (vector-ref x 9))
;;;
;;; Utilities
;;; ;;;
(define-public (list-fold f d l) (define-public (list-fold f d l)

View file

@ -1 +1,3 @@
Makefile
Makefile.in
*.go *.go

View file

@ -0,0 +1,12 @@
SOURCES = glil.scm ghil.scm macros.scm compile.scm
OBJECTS = glil.go ghil.go macros.go compile.go
vmdir = $(guiledir)/system/il
vm_DATA = $(SOURCES) $(OBJECTS)
DISTCLEANFILES = $(OBJECTS)
MAINTAINERCLEANFILES = Makefile.in
SUFFIXES = .scm .go
.scm.go:
$(GUILEC) $<

View file

@ -20,7 +20,6 @@
;;; Code: ;;; Code:
(define-module (system il compile) (define-module (system il compile)
:use-module (oop goops)
:use-syntax (system base syntax) :use-syntax (system base syntax)
:use-module (system il glil) :use-module (system il glil)
:use-module (system il ghil) :use-module (system il ghil)
@ -40,22 +39,22 @@
(define (optimize x) (define (optimize x)
(match x (match x
(($ <ghil-set> env var val) (($ <ghil-set> env var val)
(make-<ghil-set> env var (optimize val))) (<ghil-set> env var (optimize val)))
(($ <ghil-if> test then else) (($ <ghil-if> test then else)
(make-<ghil-if> (optimize test) (optimize then) (optimize else))) (<ghil-if> (optimize test) (optimize then) (optimize else)))
(($ <ghil-begin> exps) (($ <ghil-begin> exps)
(make-<ghil-begin> (map optimize exps))) (<ghil-begin> (map optimize exps)))
(($ <ghil-bind> env vars vals body) (($ <ghil-bind> env vars vals body)
(make-<ghil-bind> env vars (map optimize vals) (optimize body))) (<ghil-bind> env vars (map optimize vals) (optimize body)))
(($ <ghil-lambda> env vars rest body) (($ <ghil-lambda> env vars rest body)
(make-<ghil-lambda> env vars rest (optimize body))) (<ghil-lambda> env vars rest (optimize body)))
(($ <ghil-inst> inst args) (($ <ghil-inst> inst args)
(make-<ghil-inst> inst (map optimize args))) (<ghil-inst> inst (map optimize args)))
(($ <ghil-call> env proc args) (($ <ghil-call> env proc args)
(match proc (match proc
@ -67,9 +66,9 @@
(set! v.env env) (set! v.env env)
(ghil-env-add! env v)) (ghil-env-add! env v))
lambda-env.variables) lambda-env.variables)
(optimize (make-<ghil-bind> env vars args body))) (optimize (<ghil-bind> env vars args body)))
(else (else
(make-<ghil-call> env (optimize proc) (map optimize args))))) (<ghil-call> env (optimize proc) (map optimize args)))))
(else x))) (else x)))
@ -77,25 +76,25 @@
;;; Stage 3: Code generation ;;; Stage 3: Code generation
;;; ;;;
(define *ia-void* (make-<glil-void>)) (define *ia-void* (<glil-void>))
(define *ia-drop* (make-<glil-call> 'drop 0)) (define *ia-drop* (<glil-call> 'drop 0))
(define *ia-return* (make-<glil-call> 'return 0)) (define *ia-return* (<glil-call> 'return 0))
(define (make-label) (gensym ":L")) (define (make-label) (gensym ":L"))
(define (make-glil-var op env var) (define (make-glil-var op env var)
(case var.kind (case var.kind
((argument) ((argument)
(make-<glil-argument> op var.index)) (<glil-argument> op var.index))
((local) ((local)
(make-<glil-local> op var.index)) (<glil-local> op var.index))
((external) ((external)
(do ((depth 0 (1+ depth)) (do ((depth 0 (1+ depth))
(e env e.parent)) (e env e.parent))
((eq? e var.env) ((eq? e var.env)
(make-<glil-external> op depth var.index)))) (<glil-external> op depth var.index))))
((module) ((module)
(make-<glil-module> op var.env var.name)) (<glil-module> op var.env var.name))
(else (error "Unknown kind of variable:" var)))) (else (error "Unknown kind of variable:" var))))
(define (codegen ghil) (define (codegen ghil)
@ -104,12 +103,13 @@
(set! stack (cons code stack))) (set! stack (cons code stack)))
(define (comp tree tail drop) (define (comp tree tail drop)
(define (push-label! label) (define (push-label! label)
(push-code! (make-<glil-label> label))) (push-code! (<glil-label> label)))
(define (push-branch! inst label) (define (push-branch! inst label)
(push-code! (make-<glil-branch> inst label))) (push-code! (<glil-branch> inst label)))
(define (push-call! inst args) (define (push-call! loc inst args)
(for-each comp-push args) (for-each comp-push args)
(push-code! (make-<glil-call> inst (length args)))) (push-code! (<glil-call> inst (length args)))
(push-code! (<glil-source> loc)))
;; possible tail position ;; possible tail position
(define (comp-tail tree) (comp tree tail drop)) (define (comp-tail tree) (comp tree tail drop))
;; push the result ;; push the result
@ -131,7 +131,7 @@
(return-code! *ia-void*)) (return-code! *ia-void*))
;; return object if necessary ;; return object if necessary
(define (return-object! obj) (define (return-object! obj)
(return-code! (make-<glil-const> obj))) (return-code! (<glil-const> obj)))
;; ;;
;; dispatch ;; dispatch
(match tree (match tree
@ -145,28 +145,32 @@
(let loop ((x exp)) (let loop ((x exp))
(match x (match x
((? list? ls) ((? list? ls)
(push-call! 'mark '()) (push-call! #f 'mark '())
(for-each loop ls) (for-each loop ls)
(push-call! 'list-mark '())) (push-call! #f 'list-mark '()))
((? pair? pp) ((? pair? pp)
(loop (car pp)) (loop (car pp))
(loop (cdr pp)) (loop (cdr pp))
(push-code! (make-<glil-call> 'cons 2))) (push-code! (<glil-call> 'cons 2)))
(($ <ghil-unquote> env loc exp) (($ <ghil-unquote> env loc exp)
(comp-push exp)) (comp-push exp))
(($ <ghil-unquote-splicing> env loc exp) (($ <ghil-unquote-splicing> env loc exp)
(comp-push exp) (comp-push exp)
(push-call! 'list-break '())) (push-call! #f 'list-break '()))
(else (else
(push-code! (make-<glil-const> x))))) (push-code! (<glil-const> x)))))
(maybe-drop) (maybe-drop)
(maybe-return)) (maybe-return))
(($ <ghil-ref> env loc var) (($ <ghil-ref> env loc var)
(return-code! (make-glil-var 'ref env var))) (return-code! (make-glil-var 'ref env var)))
((or ($ <ghil-set> env loc var val) (($ <ghil-set> env loc var val)
($ <ghil-define> env loc var val)) (comp-push val)
(push-code! (make-glil-var 'set env var))
(return-void!))
(($ <ghil-define> env loc var val)
(comp-push val) (comp-push val)
(push-code! (make-glil-var 'set env var)) (push-code! (make-glil-var 'set env var))
(return-void!)) (return-void!))
@ -228,9 +232,9 @@
(maybe-drop) (maybe-drop)
(maybe-return)) (maybe-return))
(comp-push (car exps)) (comp-push (car exps))
(push-call! 'dup '()) (push-call! #f 'dup '())
(push-branch! 'br-if L1) (push-branch! 'br-if L1)
(push-call! 'drop '()))))) (push-call! #f 'drop '())))))
(($ <ghil-begin> env loc exps) (($ <ghil-begin> env loc exps)
;; EXPS... ;; EXPS...
@ -249,7 +253,10 @@
(for-each comp-push vals) (for-each comp-push vals)
(for-each (lambda (var) (push-code! (make-glil-var 'set env var))) (for-each (lambda (var) (push-code! (make-glil-var 'set env var)))
(reverse vars)) (reverse vars))
(comp-tail body)) (let ((vars (map (lambda (v) (list v.name v.kind v.index)) vars)))
(if (not (null? vars)) (push-code! (<glil-bind> vars))))
(comp-tail body)
(push-code! (<glil-unbind>)))
(($ <ghil-lambda> env loc vars rest body) (($ <ghil-lambda> env loc vars rest body)
(return-code! (codegen tree))) (return-code! (codegen tree)))
@ -257,7 +264,7 @@
(($ <ghil-inline> env loc inst args) (($ <ghil-inline> env loc inst args)
;; ARGS... ;; ARGS...
;; (INST NARGS) ;; (INST NARGS)
(push-call! inst args) (push-call! loc inst args)
(maybe-drop) (maybe-drop)
(maybe-return)) (maybe-return))
@ -266,7 +273,7 @@
;; ARGS... ;; ARGS...
;; ([tail-]call NARGS) ;; ([tail-]call NARGS)
(comp-push proc) (comp-push proc)
(push-call! (if tail 'tail-call 'call) args) (push-call! loc (if tail 'tail-call 'call) args)
(maybe-drop)))) (maybe-drop))))
;; ;;
;; main ;; main
@ -279,19 +286,25 @@
(finalize-index! args) (finalize-index! args)
(finalize-index! locs) (finalize-index! locs)
(finalize-index! exts) (finalize-index! exts)
;; meta bindings
(let ((vars (map (lambda (v) (list v.name v.kind v.index)) args)))
(if (not (null? vars)) (push-code! (<glil-bind> vars))))
;; export arguments ;; export arguments
(do ((n 0 (1+ n)) (do ((n 0 (1+ n))
(l args (cdr l))) (l args (cdr l)))
((null? l)) ((null? l))
(let ((v (car l))) (let ((v (car l)))
(if (eq? v.kind 'external) (cond ((eq? v.kind 'external)
(begin (push-code! (make-<glil-argument> 'ref n)) (push-code! (<glil-argument> 'ref n))
(push-code! (make-<glil-external> 'set 0 v.index)))))) (push-code! (<glil-external> 'set 0 v.index))))))
;; compile body ;; compile body
(comp body #t #f) (comp body #t #f)
;; create GLIL ;; create GLIL
(make-<glil-asm> (length args) (if rest 1 0) (length locs) (let ((vars (<glil-vars> :nargs (length args)
(length exts) (reverse! stack))))))) :nrest (if rest 1 0)
:nlocs (length locs)
:nexts (length exts))))
(<glil-asm> vars (reverse! stack))))))))
(define (finalize-index! list) (define (finalize-index! list)
(do ((n 0 (1+ n)) (do ((n 0 (1+ n))

View file

@ -20,42 +20,38 @@
;;; Code: ;;; Code:
(define-module (system il ghil) (define-module (system il ghil)
:use-module (oop goops)
:use-syntax (system base syntax) :use-syntax (system base syntax)
:use-module (ice-9 match) :use-module (ice-9 match)
:use-module (ice-9 regex) :use-module (ice-9 regex)
:export :export
(parse-ghil (
ghil-lookup ghil-primitive? <ghil-void> <ghil-void>? <ghil-void>-1 <ghil-void>-2
make-<ghil-void> <ghil-void>? <ghil-void>-1 <ghil-void>-2 <ghil-quote> <ghil-quote>? <ghil-quote>-1 <ghil-quote>-2 <ghil-quote>-3
make-<ghil-quote> <ghil-quote>? <ghil-quote>-1 <ghil-quote>-2 <ghil-quote>-3 <ghil-quasiquote> <ghil-quasiquote>?
make-<ghil-quasiquote> <ghil-quasiquote>?
<ghil-quasiquote>-1 <ghil-quasiquote>-2 <ghil-quasiquote>-3 <ghil-quasiquote>-1 <ghil-quasiquote>-2 <ghil-quasiquote>-3
make-<ghil-unquote> <ghil-unquote>? <ghil-unquote> <ghil-unquote>?
<ghil-unquote>-1 <ghil-unquote>-2 <ghil-unquote>-3 <ghil-unquote>-1 <ghil-unquote>-2 <ghil-unquote>-3
make-<ghil-unquote-splicing> <ghil-unquote-splicing>? <ghil-unquote-splicing> <ghil-unquote-splicing>?
<ghil-unquote-splicing>-1 <ghil-unquote-splicing>-2 <ghil-unquote-splicing>-1 <ghil-unquote-splicing>-2
<ghil-unquote-splicing>-3 <ghil-unquote-splicing>-3
make-<ghil-ref> <ghil-ref>? <ghil-ref> <ghil-ref>? <ghil-ref>-1 <ghil-ref>-2 <ghil-ref>-3
<ghil-ref>-1 <ghil-ref>-2 <ghil-ref>-3 <ghil-set> <ghil-set>? <ghil-set>-1 <ghil-set>-2 <ghil-set>-3 <ghil-set>-4
make-<ghil-set> <ghil-set>? <ghil-define> <ghil-define>?
<ghil-set>-1 <ghil-set>-2 <ghil-set>-3 <ghil-set>-4
make-<ghil-define> <ghil-define>?
<ghil-define>-1 <ghil-define>-2 <ghil-define>-3 <ghil-define>-4 <ghil-define>-1 <ghil-define>-2 <ghil-define>-3 <ghil-define>-4
make-<ghil-if> <ghil-if>? <ghil-if> <ghil-if>?
<ghil-if>-1 <ghil-if>-2 <ghil-if>-3 <ghil-if>-4 <ghil-if>-5 <ghil-if>-1 <ghil-if>-2 <ghil-if>-3 <ghil-if>-4 <ghil-if>-5
make-<ghil-and> <ghil-and>? <ghil-and>-1 <ghil-and>-2 <ghil-and>-3 <ghil-and> <ghil-and>? <ghil-and>-1 <ghil-and>-2 <ghil-and>-3
make-<ghil-or> <ghil-or>? <ghil-or>-1 <ghil-or>-2 <ghil-or>-3 <ghil-or> <ghil-or>? <ghil-or>-1 <ghil-or>-2 <ghil-or>-3
make-<ghil-begin> <ghil-begin>? <ghil-begin>-1 <ghil-begin>-2 <ghil-begin>-3 <ghil-begin> <ghil-begin>? <ghil-begin>-1 <ghil-begin>-2 <ghil-begin>-3
make-<ghil-bind> <ghil-bind>? <ghil-bind> <ghil-bind>?
<ghil-bind>-1 <ghil-bind>-2 <ghil-bind>-3 <ghil-bind>-4 <ghil-bind>-5 <ghil-bind>-1 <ghil-bind>-2 <ghil-bind>-3 <ghil-bind>-4 <ghil-bind>-5
make-<ghil-lambda> <ghil-lambda>? <ghil-lambda>-1 <ghil-lambda>-2 <ghil-lambda> <ghil-lambda>? <ghil-lambda>-1 <ghil-lambda>-2
<ghil-lambda>-3 <ghil-lambda>-4 <ghil-lambda>-5 <ghil-lambda>-3 <ghil-lambda>-4 <ghil-lambda>-5
make-<ghil-inline> <ghil-inline>? <ghil-inline> <ghil-inline>?
<ghil-inline>-1 <ghil-inline>-2 <ghil-inline>-3 <ghil-inline>-4 <ghil-inline>-1 <ghil-inline>-2 <ghil-inline>-3 <ghil-inline>-4
make-<ghil-call> <ghil-call>? <ghil-call> <ghil-call>?
<ghil-call>-1 <ghil-call>-2 <ghil-call>-3 <ghil-call>-4 <ghil-call>-1 <ghil-call>-2 <ghil-call>-3 <ghil-call>-4
)) ))
@ -64,27 +60,30 @@
;;; Parse tree ;;; Parse tree
;;; ;;;
(define-structure (<ghil-void> env loc)) (define-type <ghil>
(define-structure (<ghil-quote> env loc obj)) (|
(define-structure (<ghil-quasiquote> env loc exp)) ;; Objects
(define-structure (<ghil-unquote> env loc exp)) (<ghil-void> env loc)
(define-structure (<ghil-unquote-splicing> env loc exp)) (<ghil-quote> env loc obj)
(<ghil-quasiquote> env loc exp)
(<ghil-unquote> env loc exp)
(<ghil-unquote-splicing> env loc exp)
;; Variables
(<ghil-ref> env loc var)
(<ghil-set> env loc var val)
(<ghil-define> env loc var val)
;; Controls
(<ghil-if> env loc test then else)
(<ghil-and> env loc exps)
(<ghil-or> env loc exps)
(<ghil-begin> env loc exps)
(<ghil-bind> env loc vars vals body)
(<ghil-lambda> env loc vars rest body)
(<ghil-call> env loc proc args)
(<ghil-inline> env loc inline args)))
(define-structure (<ghil-ref> env loc var)) (define-public ghil-env %slot-1)
(define-structure (<ghil-set> env loc var val)) (define-public ghil-loc %slot-2)
(define-structure (<ghil-define> env loc var val))
(define-structure (<ghil-if> env loc test then else))
(define-structure (<ghil-and> env loc exps))
(define-structure (<ghil-or> env loc exps))
(define-structure (<ghil-begin> env loc exps))
(define-structure (<ghil-bind> env loc vars vals body))
(define-structure (<ghil-lambda> env loc vars rest body))
(define-structure (<ghil-call> env loc proc args))
(define-structure (<ghil-inline> env loc inline args))
(define-public (ghil-env ghil) (vector-ref ghil 1))
(define-public (ghil-loc ghil) (vector-ref ghil 2))
;;; ;;;
@ -96,7 +95,7 @@
(define *macro-module* (resolve-module '(system il macros))) (define *macro-module* (resolve-module '(system il macros)))
(define (ghil-primitive-macro? x) (define-public (ghil-primitive-macro? x)
(and (module-defined? *macro-module* x) (and (module-defined? *macro-module* x)
(procedure? (module-ref *macro-module* x)))) (procedure? (module-ref *macro-module* x))))
@ -112,78 +111,59 @@
;;; Variables ;;; Variables
;;; ;;;
(define-vm-class <ghil-var> () (define-record (<ghil-var> env name kind (type #f) (value #f) (index #f)))
env name kind type value index)
(define-public (make-ghil-var env name kind) (define-public (make-ghil-var env name kind)
(make <ghil-var> :env env :name name :kind kind)) (<ghil-var> :env env :name name :kind kind))
(define-method (write (var <ghil-var>) port)
(display "#<ghil:var " port)
(display var.name port)
(display ">" port))
;;; ;;;
;;; Modules ;;; Modules
;;; ;;;
(define-vm-class <ghil-mod> () (define-record (<ghil-mod> module (table '()) (imports '())))
(module)
(table '())
(imports '()))
(define-public (make-ghil-mod module) (define-public (make-ghil-mod module)
(make <ghil-mod> :module module)) (<ghil-mod> :module module))
(define-method (write (mod <ghil-mod>) port)
(display "#<ghil:mod " port)
(display (module-name mod.module) port)
(display ">" port))
(define-method (ghil-lookup (mod <ghil-mod>) (sym <symbol>))
(or (assq-ref mod.table sym)
;; (let ((var (make-ghil-var (env-identifier mod.module) sym 'module)))
(let ((var (make-ghil-var #f sym 'module)))
(set! mod.table (acons sym var mod.table))
var)))
;;; ;;;
;;; Environments ;;; Environments
;;; ;;;
(define-vm-class <ghil-env> () (define-record (<ghil-env> mod parent (table '()) (variables '())))
(mod)
(parent #f)
(table '())
(variables '()))
(export make-ghil-env) (define-public (make-ghil-env e)
(define-method (make-ghil-env (m <ghil-mod>)) (match e
(make <ghil-env> :mod m :parent m)) (($ <ghil-mod>) (<ghil-env> :mod e :parent e))
(($ <ghil-env> m) (<ghil-env> :mod m :parent e))))
(define-method (make-ghil-env (e <ghil-env>))
(make <ghil-env> :mod e.mod :parent e))
(define (ghil-env-toplevel? e) (define (ghil-env-toplevel? e)
(eq? e.mod e.parent)) (eq? e.mod e.parent))
(define-method (ghil-env-ref (env <ghil-env>) (sym <symbol>)) (define (ghil-env-ref env sym)
(assq-ref env.table sym)) (assq-ref env.table sym))
(export ghil-env-add!) (define-public (ghil-env-add! env var)
(define-method (ghil-env-add! (env <ghil-env>) (var <ghil-var>))
(set! env.table (acons var.name var env.table)) (set! env.table (acons var.name var env.table))
(set! env.variables (cons var env.variables))) (set! env.variables (cons var env.variables)))
(define-method (ghil-env-remove! (env <ghil-env>) (var <ghil-var>)) (define (ghil-env-remove! env var)
(set! env.table (assq-remove! env.table var.name))) (set! env.table (assq-remove! env.table var.name)))
(define-method (ghil-lookup (env <ghil-env>) (sym <symbol>))
;;;
;;; Public interface
;;;
(define-public (ghil-lookup env sym)
(or (ghil-env-ref env sym) (or (ghil-env-ref env sym)
(let loop ((e env.parent)) (let loop ((e env.parent))
(cond ((is-a? e <ghil-mod>) (ghil-lookup e sym)) (cond ((<ghil-mod>? e)
(or (assq-ref e.table sym)
(let ((var (make-ghil-var #f sym 'module)))
(set! e.table (acons sym var e.table))
var)))
((ghil-env-ref e sym) => ((ghil-env-ref e sym) =>
(lambda (var) (set! var.kind 'external) var)) (lambda (var) (set! var.kind 'external) var))
(else (loop e.parent)))))) (else (loop e.parent))))))
@ -210,156 +190,156 @@
;;; Parser ;;; Parser
;;; ;;;
(define (parse-ghil x e) ;;; (define-public (parse-ghil x e)
(parse `(@lambda () ,x) (make-ghil-mod e))) ;;; (parse `(@lambda () ,x) (make-ghil-mod e)))
;;;
(define (parse x e) ;;; (define (parse x e)
(cond ((pair? x) (parse-pair x e)) ;;; (cond ((pair? x) (parse-pair x e))
((symbol? x) ;;; ((symbol? x)
(let ((str (symbol->string x))) ;;; (let ((str (symbol->string x)))
(case (string-ref str 0) ;;; (case (string-ref str 0)
((#\@) (error "Invalid use of IL primitive" x)) ;;; ((#\@) (error "Invalid use of IL primitive" x))
((#\:) (let ((sym (string->symbol (substring str 1)))) ;;; ((#\:) (let ((sym (string->symbol (substring str 1))))
(make-<ghil-quote> (symbol->keyword sym)))) ;;; (<ghil-quote> (symbol->keyword sym))))
(else (make-<ghil-ref> e (ghil-lookup e x)))))) ;;; (else (<ghil-ref> e (ghil-lookup e x))))))
(else (make-<ghil-quote> x)))) ;;; (else (<ghil-quote> x))))
;;;
(define (map-parse x e) ;;; (define (map-parse x e)
(map (lambda (x) (parse x e)) x)) ;;; (map (lambda (x) (parse x e)) x))
;;;
(define (parse-pair x e) ;;; (define (parse-pair x e)
(let ((head (car x)) (tail (cdr x))) ;;; (let ((head (car x)) (tail (cdr x)))
(if (and (symbol? head) (eq? (string-ref (symbol->string head) 0) #\@)) ;;; (if (and (symbol? head) (eq? (string-ref (symbol->string head) 0) #\@))
(if (ghil-primitive-macro? head) ;;; (if (ghil-primitive-macro? head)
(parse (apply (ghil-macro-expander head) tail) e) ;;; (parse (apply (ghil-macro-expander head) tail) e)
(parse-primitive head tail e)) ;;; (parse-primitive head tail e))
(make-<ghil-call> e (parse head e) (map-parse tail e))))) ;;; (<ghil-call> e (parse head e) (map-parse tail e)))))
;;;
(define (parse-primitive prim args e) ;;; (define (parse-primitive prim args e)
(case prim ;;; (case prim
;; (@ IDENTIFIER) ;;; ;; (@ IDENTIFIER)
((@) ;;; ((@)
(match args ;;; (match args
(() ;;; (()
(make-<ghil-ref> e (make-ghil-var '@ '@ 'module))) ;;; (<ghil-ref> e (make-ghil-var '@ '@ 'module)))
((identifier) ;;; ((identifier)
(receive (module name) (identifier-split identifier) ;;; (receive (module name) (identifier-split identifier)
(make-<ghil-ref> e (make-ghil-var module name 'module)))))) ;;; (<ghil-ref> e (make-ghil-var module name 'module))))))
;;;
;; (@@ OP ARGS...) ;;; ;; (@@ OP ARGS...)
((@@) ;;; ((@@)
(match args ;;; (match args
((op . args) ;;; ((op . args)
(make-<ghil-inline> op (map-parse args e))))) ;;; (<ghil-inline> op (map-parse args e)))))
;;;
;; (@void) ;;; ;; (@void)
((@void) ;;; ((@void)
(match args ;;; (match args
(() (make-<ghil-void>)))) ;;; (() (<ghil-void>))))
;;;
;; (@quote OBJ) ;;; ;; (@quote OBJ)
((@quote) ;;; ((@quote)
(match args ;;; (match args
((obj) ;;; ((obj)
(make-<ghil-quote> obj)))) ;;; (<ghil-quote> obj))))
;;;
;; (@define NAME VAL) ;;; ;; (@define NAME VAL)
((@define) ;;; ((@define)
(match args ;;; (match args
((name val) ;;; ((name val)
(let ((v (ghil-lookup e name))) ;;; (let ((v (ghil-lookup e name)))
(make-<ghil-set> e v (parse val e)))))) ;;; (<ghil-set> e v (parse val e))))))
;;;
;; (@set! NAME VAL) ;;; ;; (@set! NAME VAL)
((@set!) ;;; ((@set!)
(match args ;;; (match args
((name val) ;;; ((name val)
(let ((v (ghil-lookup e name))) ;;; (let ((v (ghil-lookup e name)))
(make-<ghil-set> e v (parse val e)))))) ;;; (<ghil-set> e v (parse val e))))))
;;;
;; (@if TEST THEN [ELSE]) ;;; ;; (@if TEST THEN [ELSE])
((@if) ;;; ((@if)
(match args ;;; (match args
((test then) ;;; ((test then)
(make-<ghil-if> (parse test e) (parse then e) (make-<ghil-void>))) ;;; (<ghil-if> (parse test e) (parse then e) (<ghil-void>)))
((test then else) ;;; ((test then else)
(make-<ghil-if> (parse test e) (parse then e) (parse else e))))) ;;; (<ghil-if> (parse test e) (parse then e) (parse else e)))))
;;;
;; (@begin BODY...) ;;; ;; (@begin BODY...)
((@begin) ;;; ((@begin)
(parse-body args e)) ;;; (parse-body args e))
;;;
;; (@let ((SYM INIT)...) BODY...) ;;; ;; (@let ((SYM INIT)...) BODY...)
((@let) ;;; ((@let)
(match args ;;; (match args
((((sym init) ...) body ...) ;;; ((((sym init) ...) body ...)
(let* ((vals (map-parse init e)) ;;; (let* ((vals (map-parse init e))
(vars (map (lambda (s) ;;; (vars (map (lambda (s)
(let ((v (make-ghil-var e s 'local))) ;;; (let ((v (make-ghil-var e s 'local)))
(ghil-env-add! e v) v)) ;;; (ghil-env-add! e v) v))
sym)) ;;; sym))
(body (parse-body body e))) ;;; (body (parse-body body e)))
(for-each (lambda (v) (ghil-env-remove! e v)) vars) ;;; (for-each (lambda (v) (ghil-env-remove! e v)) vars)
(make-<ghil-bind> e vars vals body))))) ;;; (<ghil-bind> e vars vals body)))))
;;;
;; (@letrec ((SYM INIT)...) BODY...) ;;; ;; (@letrec ((SYM INIT)...) BODY...)
((@letrec) ;;; ((@letrec)
(match args ;;; (match args
((((sym init) ...) body ...) ;;; ((((sym init) ...) body ...)
(let* ((vars (map (lambda (s) ;;; (let* ((vars (map (lambda (s)
(let ((v (make-ghil-var e s 'local))) ;;; (let ((v (make-ghil-var e s 'local)))
(ghil-env-add! e v) v)) ;;; (ghil-env-add! e v) v))
sym)) ;;; sym))
(vals (map-parse init e)) ;;; (vals (map-parse init e))
(body (parse-body body e))) ;;; (body (parse-body body e)))
(for-each (lambda (v) (ghil-env-remove! e v)) vars) ;;; (for-each (lambda (v) (ghil-env-remove! e v)) vars)
(make-<ghil-bind> e vars vals body))))) ;;; (<ghil-bind> e vars vals body)))))
;;;
;; (@lambda FORMALS BODY...) ;;; ;; (@lambda FORMALS BODY...)
((@lambda) ;;; ((@lambda)
(match args ;;; (match args
((formals . body) ;;; ((formals . body)
(receive (syms rest) (parse-formals formals) ;;; (receive (syms rest) (parse-formals formals)
(let* ((e (make-ghil-env e)) ;;; (let* ((e (make-ghil-env e))
(vars (map (lambda (s) ;;; (vars (map (lambda (s)
(let ((v (make-ghil-var e s 'argument))) ;;; (let ((v (make-ghil-var e s 'argument)))
(ghil-env-add! e v) v)) ;;; (ghil-env-add! e v) v))
syms))) ;;; syms)))
(make-<ghil-lambda> e vars rest (parse-body body e))))))) ;;; (<ghil-lambda> e vars rest (parse-body body e)))))))
;;;
;; (@eval-case CLAUSE...) ;;; ;; (@eval-case CLAUSE...)
((@eval-case) ;;; ((@eval-case)
(let loop ((clauses args)) ;;; (let loop ((clauses args))
(cond ((null? clauses) (make-<ghil-void>)) ;;; (cond ((null? clauses) (<ghil-void>))
((or (eq? (caar clauses) '@else) ;;; ((or (eq? (caar clauses) '@else)
(and (memq 'load-toplevel (caar clauses)) ;;; (and (memq 'load-toplevel (caar clauses))
(ghil-env-toplevel? e))) ;;; (ghil-env-toplevel? e)))
(parse-body (cdar clauses) e)) ;;; (parse-body (cdar clauses) e))
(else ;;; (else
(loop (cdr clauses)))))) ;;; (loop (cdr clauses))))))
;;;
(else (error "Unknown primitive:" prim)))) ;;; (else (error "Unknown primitive:" prim))))
;;;
(define (parse-body x e) ;;; (define (parse-body x e)
(make-<ghil-begin> (map-parse x e))) ;;; (<ghil-begin> (map-parse x e)))
;;;
(define (parse-formals formals) ;;; (define (parse-formals formals)
(cond ;;; (cond
;; (@lambda x ...) ;;; ;; (@lambda x ...)
((symbol? formals) (values (list formals) #t)) ;;; ((symbol? formals) (values (list formals) #t))
;; (@lambda (x y z) ...) ;;; ;; (@lambda (x y z) ...)
((list? formals) (values formals #f)) ;;; ((list? formals) (values formals #f))
;; (@lambda (x y . z) ...) ;;; ;; (@lambda (x y . z) ...)
((pair? formals) ;;; ((pair? formals)
(let loop ((l formals) (v '())) ;;; (let loop ((l formals) (v '()))
(if (pair? l) ;;; (if (pair? l)
(loop (cdr l) (cons (car l) v)) ;;; (loop (cdr l) (cons (car l) v))
(values (reverse! (cons l v)) #t)))) ;;; (values (reverse! (cons l v)) #t))))
(else (error "Invalid formals:" formals)))) ;;; (else (error "Invalid formals:" formals))))
;;;
(define (identifier-split identifier) ;;; (define (identifier-split identifier)
(let ((m (string-match "::([^:]*)$" (symbol->string identifier)))) ;;; (let ((m (string-match "::([^:]*)$" (symbol->string identifier))))
(if m ;;; (if m
(values (string->symbol (match:prefix m)) ;;; (values (string->symbol (match:prefix m))
(string->symbol (match:substring m 1))) ;;; (string->symbol (match:substring m 1)))
(values #f identifier)))) ;;; (values #f identifier))))

View file

@ -20,54 +20,59 @@
;;; Code: ;;; Code:
(define-module (system il glil) (define-module (system il glil)
:use-syntax (system base syntax)
:use-module (ice-9 match) :use-module (ice-9 match)
:export :export
(pprint-glil (pprint-glil
make-<glil-asm> <glil-asm>? <glil-vars>
<glil-asm> <glil-asm>?
<glil-asm>-1 <glil-asm>-2 <glil-asm>-3 <glil-asm>-4 <glil-asm>-5 <glil-asm>-1 <glil-asm>-2 <glil-asm>-3 <glil-asm>-4 <glil-asm>-5
make-<glil-vars> <glil-vars>? <glil-vars>-1 <glil-vars>-2 <glil-bind> <glil-bind>? <glil-bind>-1
<glil-unbind> <glil-unbind>?
<glil-source> <glil-source>? <glil-source>-1 <glil-source>-2
make-<glil-void> <glil-void>? <glil-void> <glil-void>?
make-<glil-const> <glil-const>? <glil-const>-1 <glil-const> <glil-const>? <glil-const>-1
make-<glil-argument> <glil-argument>? <glil-argument>-1 <glil-argument>-2 <glil-argument> <glil-argument>? <glil-argument>-1 <glil-argument>-2
make-<glil-local> <glil-local>? <glil-local>-1 <glil-local>-2 <glil-local> <glil-local>? <glil-local>-1 <glil-local>-2
make-<glil-external> <glil-external>? <glil-external> <glil-external>?
<glil-external>-1 <glil-external>-2 <glil-external>-3 <glil-external>-1 <glil-external>-2 <glil-external>-3
make-<glil-module> <glil-module>? <glil-module> <glil-module>?
<glil-module>-1 <glil-module>-2 <glil-module>-3 <glil-module>-1 <glil-module>-2 <glil-module>-3
make-<glil-label> <glil-label>? <glil-label>-1 <glil-label> <glil-label>? <glil-label>-1
make-<glil-branch> <glil-branch>? <glil-branch>-1 <glil-branch>-2 <glil-branch> <glil-branch>? <glil-branch>-1 <glil-branch>-2
make-<glil-call> <glil-call>? <glil-call>-1 <glil-call>-2 <glil-call> <glil-call>? <glil-call>-1 <glil-call>-2
)) ))
;; Meta operations (define-record (<glil-vars> nargs nrest nlocs nexts))
(define-structure (<glil-asm> nargs nrest nlocs nexts body))
(define-structure (<glil-vars> type syms))
;; Constants (define-type <glil>
(define-structure (<glil-void>)) (|
(define-structure (<glil-const> obj)) ;; Meta operations
(<glil-asm> vars body)
;; Variables (<glil-bind> vars)
(define-structure (<glil-argument> op index)) (<glil-unbind>)
(define-structure (<glil-local> op index)) (<glil-source> loc)
(define-structure (<glil-external> op depth index)) ;; Objects
(define-structure (<glil-module> op module name)) (<glil-void>)
(<glil-const> obj)
;; Controls ;; Variables
(define-structure (<glil-label> label)) (<glil-argument> op index)
(define-structure (<glil-branch> inst label)) (<glil-local> op index)
(define-structure (<glil-call> inst nargs)) (<glil-external> op depth index)
(<glil-module> op module name)
;; Controls
(<glil-label> label)
(<glil-branch> inst label)
(<glil-call> inst nargs)))
;;; ;;;
;;; Parser ;;; Parser
;;; ;;;
;; FIXME: This is not working now
;;; (define (parse-glil x) ;;; (define (parse-glil x)
;;; (match x ;;; (match x
;;; (('@asm args . body) ;;; (('@asm args . body)
@ -140,9 +145,12 @@
(define (unparse glil) (define (unparse glil)
(match glil (match glil
;; meta ;; meta
(($ <glil-asm> nargs nrest nlocs nexts body) (($ <glil-asm> vars body)
`(@asm (,nargs ,nrest ,nlocs ,nexts) ,@(map unparse body))) `(@asm (,vars.nargs ,vars.nrest ,vars.nlocs ,vars.nexts)
(($ <glil-vars> type syms) `(,type ,@syms)) ,@(map unparse body)))
(($ <glil-bind> vars) `(@bind ,@vars))
(($ <glil-unbind>) `(@unbind))
(($ <glil-source> loc) `(@source ,(car loc) ,(cdr loc)))
;; constants ;; constants
(($ <glil-void>) `(void)) (($ <glil-void>) `(void))
(($ <glil-const> obj) `(const ,obj)) (($ <glil-const> obj) `(const ,obj))
@ -165,16 +173,17 @@
;;; Printer ;;; Printer
;;; ;;;
(define (pprint-glil glil) (define (pprint-glil glil . port)
(let ((port (if (pair? port) (car port) (current-output-port))))
(let print ((code (unparse glil)) (column 0)) (let print ((code (unparse glil)) (column 0))
(display (make-string column #\space)) (display (make-string column #\space) port)
(cond ((and (pair? code) (eq? (car code) '@asm)) (cond ((and (pair? code) (eq? (car code) '@asm))
(format #t "(@asm ~A\n" (cadr code)) (format port "(@asm ~A\n" (cadr code))
(let ((col (+ column 2))) (let ((col (+ column 2)))
(let loop ((l (cddr code))) (let loop ((l (cddr code)))
(print (car l) col) (print (car l) col)
(if (null? (cdr l)) (if (null? (cdr l))
(display ")") (display ")" port)
(begin (newline) (loop (cdr l))))))) (begin (newline port) (loop (cdr l)))))))
(else (write code)))) (else (write code port))))
(newline)) (newline port)))

View file

@ -1 +1,3 @@
Makefile
Makefile.in
*.go *.go

View file

@ -0,0 +1,12 @@
SOURCES = repl.scm common.scm command.scm
OBJECTS = repl.go common.go command.go
vmdir = $(guiledir)/system/repl
vm_DATA = $(SOURCES) $(OBJECTS)
DISTCLEANFILES = $(OBJECTS)
MAINTAINERCLEANFILES = Makefile.in
SUFFIXES = .scm .go
.scm.go:
$(GUILEC) $<

View file

@ -24,10 +24,13 @@
:use-module (system base compile) :use-module (system base compile)
:use-module (system repl common) :use-module (system repl common)
:use-module (system vm core) :use-module (system vm core)
:autoload (system base language) (lookup-language)
:autoload (system il glil) (pprint-glil) :autoload (system il glil) (pprint-glil)
:autoload (system vm disasm) (disassemble-program disassemble-objcode) :autoload (system vm disasm) (disassemble-program disassemble-objcode)
:autoload (system vm trace) (vm-trace vm-trace-on vm-trace-off) :autoload (system vm trace) (vm-trace vm-trace-on vm-trace-off)
:autoload (system vm profile) (vm-profile) :autoload (system vm profile) (vm-profile)
:autoload (system vm debugger) (vm-debugger)
:autoload (system vm backtrace) (vm-backtrace)
:use-module (ice-9 format) :use-module (ice-9 format)
:use-module (ice-9 session) :use-module (ice-9 session)
:use-module (ice-9 documentation)) :use-module (ice-9 documentation))
@ -44,7 +47,7 @@
(compile (compile c) (compile-file cc) (compile (compile c) (compile-file cc)
(disassemble x) (disassemble-file xx)) (disassemble x) (disassemble-file xx))
(profile (time t) (profile pr)) (profile (time t) (profile pr))
(debug (backtrace bt) (debugger db) (trace r) (step st)) (debug (backtrace bt) (debugger db) (trace tr) (step st))
(system (gc) (statistics stat)))) (system (gc) (statistics stat))))
(define (group-name g) (car g)) (define (group-name g) (car g))
@ -332,16 +335,15 @@ Profile execution."
;;; Debug commands ;;; Debug commands
;;; ;;;
(define guile:backtrace backtrace)
(define (backtrace repl) (define (backtrace repl)
"backtrace "backtrace
Show backtrace (if any)." Display backtrace."
(guile:backtrace)) (vm-backtrace repl.env.vm))
(define (debugger repl) (define (debugger repl)
"debugger "debugger
Start debugger." Start debugger."
(debug)) (vm-debugger repl.env.vm))
(define (trace repl form . opts) (define (trace repl form . opts)
"trace FORM "trace FORM

View file

@ -20,19 +20,17 @@
;;; Code: ;;; Code:
(define-module (system repl common) (define-module (system repl common)
:use-module (oop goops)
:use-syntax (system base syntax) :use-syntax (system base syntax)
:use-module (system base compile) :use-module (system base compile)
:use-module (system base language) :use-module (system base language)
:use-module (system vm core) :use-module (system vm core))
:use-module (system vm trace))
;;; ;;;
;;; Repl type ;;; Repl type
;;; ;;;
(define-vm-class <repl> () env options tm-stats gc-stats vm-stats) (define-record (<repl> env options tm-stats gc-stats vm-stats))
(define repl-default-options (define repl-default-options
'((trace . #f))) '((trace . #f)))
@ -41,8 +39,7 @@
(let ((cenv (make-cenv :vm (the-vm) (let ((cenv (make-cenv :vm (the-vm)
:language (lookup-language lang) :language (lookup-language lang)
:module (current-module)))) :module (current-module))))
(make <repl> (<repl> :env cenv
:env cenv
:options repl-default-options :options repl-default-options
:tm-stats (times) :tm-stats (times)
:gc-stats (gc-stats) :gc-stats (gc-stats)

View file

@ -32,7 +32,7 @@
(repl-welcome repl) (repl-welcome repl)
(let prompt-loop () (let prompt-loop ()
(repl-prompt repl) (repl-prompt repl)
(call-with-error-handlers (catch 'vm-error
(lambda () (lambda ()
(if (eq? (next-char #t) #\,) (if (eq? (next-char #t) #\,)
;; meta command ;; meta command
@ -40,7 +40,11 @@
;; evaluation ;; evaluation
(let rep-loop () (let rep-loop ()
(repl-print repl (repl-eval repl (repl-read repl))) (repl-print repl (repl-eval repl (repl-read repl)))
(if (next-char #f) (rep-loop)))))) (if (next-char #f) (rep-loop)))))
(lambda (key fun msg args)
(display "ERROR: ")
(apply format #t msg args)
(newline)))
(prompt-loop)))) (prompt-loop))))
(define (next-char wait) (define (next-char wait)
@ -50,21 +54,3 @@
((char-whitespace? ch) (read-char) (next-char wait)) ((char-whitespace? ch) (read-char) (next-char wait))
(else ch))) (else ch)))
#f)) #f))
;;;
;;; Error handler
;;;
(define (call-with-error-handlers thunk)
(catch 'vm-error
(lambda () (catch 'user-error thunk error-handler))
error-handler))
(define (error-handler key . args)
(case key
((vm-error)
(write (frame->call (cadddr args)))
(newline)))
(display "ERROR: ")
(apply format #t (cadr args) (caddr args))
(newline))

View file

@ -1 +1,3 @@
Makefile
Makefile.in
*.go *.go

View file

@ -0,0 +1,12 @@
SOURCES = assemble.scm conv.scm core.scm disasm.scm profile.scm trace.scm
OBJECTS = assemble.go conv.go core.go disasm.go profile.go trace.go
vmdir = $(guiledir)/system/vm
vm_DATA = $(SOURCES) $(OBJECTS)
DISTCLEANFILES = $(OBJECTS)
MAINTAINERCLEANFILES = Makefile.in
SUFFIXES = .scm .go
.scm.go:
$(GUILEC) $<

View file

@ -20,6 +20,7 @@
;;; Code: ;;; Code:
(define-module (system vm assemble) (define-module (system vm assemble)
:use-syntax (system base syntax)
:use-module (system il glil) :use-module (system il glil)
:use-module (system vm core) :use-module (system vm core)
:use-module (system vm conv) :use-module (system vm conv)
@ -36,11 +37,11 @@
;;; Types ;;; Types
;;; ;;;
(define-structure (<vm-asm> venv glil body)) (define-record (<vm-asm> venv glil body))
(define-structure (venv parent nexts closure?)) (define-record (<venv> parent nexts closure?))
(define-structure (vmod id)) (define-record (<vmod> id))
(define-structure (vlink module name)) (define-record (<vlink> module name))
(define-structure (bytespec nargs nrest nlocs nexts bytes objs closure?)) (define-record (<bytespec> vars bytes meta objs closure?))
;;; ;;;
@ -49,15 +50,15 @@
(define (preprocess x e) (define (preprocess x e)
(match x (match x
(($ <glil-asm> nargs nrest nlocs nexts body) (($ <glil-asm> vars body)
(let* ((venv (make-venv e nexts #f)) (let* ((venv (<venv> :parent e :nexts vars.nexts :closure? #f))
(body (map (lambda (x) (preprocess x venv)) body))) (body (map (lambda (x) (preprocess x venv)) body)))
(make-<vm-asm> venv x body))) (<vm-asm> :venv venv :glil x :body body)))
(($ <glil-external> op depth index) (($ <glil-external> op depth index)
(do ((d depth (1- d)) (do ((d depth (1- d))
(e e (venv-parent e))) (e e e.parent))
((= d 0)) ((= d 0))
(set-venv-closure?! e #t)) (set! e.closure? #t))
x) x)
(else x))) (else x)))
@ -68,8 +69,10 @@
(define (codegen glil toplevel) (define (codegen glil toplevel)
(match glil (match glil
(($ <vm-asm> venv ($ <glil-asm> nargs nrest nlocs nexts _) body) (($ <vm-asm> venv ($ <glil-asm> vars _) body)
(let ((stack '()) (let ((stack '())
(bind-alist '())
(source-alist '())
(label-alist '()) (label-alist '())
(object-alist '())) (object-alist '()))
(define (push-code! code) (define (push-code! code)
@ -84,11 +87,32 @@
(set! object-alist (acons x i object-alist)) (set! object-alist (acons x i object-alist))
i))))) i)))))
(push-code! `(object-ref ,i)))))) (push-code! `(object-ref ,i))))))
(define (current-address)
(define (byte-length x)
(cond ((string? x) (string-length x))
(else 3)))
(apply + (map byte-length stack)))
(define (generate-code x) (define (generate-code x)
(match x (match x
(($ <vm-asm> venv) (($ <vm-asm> venv)
(push-object! (codegen x #f)) (push-object! (codegen x #f))
(if (venv-closure? venv) (push-code! `(make-closure)))) (if venv.closure? (push-code! `(make-closure))))
(($ <glil-bind> binds)
(let ((binds (map (lambda (v)
(case (cadr v)
((argument) (list (car v) #f (caddr v)))
((local) (list (car v) #f
(+ vars.nargs (caddr v))))
((external) (list (car v) #t (caddr v)))))
binds)))
(set! bind-alist (acons (current-address) binds bind-alist))))
(($ <glil-unbind>)
(set! bind-alist (acons (current-address) #f bind-alist)))
(($ <glil-source> loc)
(set! source-alist (acons (current-address) loc source-alist)))
(($ <glil-void>) (($ <glil-void>)
(push-code! '(void))) (push-code! '(void)))
@ -103,30 +127,26 @@
(($ <glil-local> op index) (($ <glil-local> op index)
(if (eq? op 'ref) (if (eq? op 'ref)
(push-code! `(local-ref ,(+ nargs index))) (push-code! `(local-ref ,(+ vars.nargs index)))
(push-code! `(local-set ,(+ nargs index))))) (push-code! `(local-set ,(+ vars.nargs index)))))
(($ <glil-external> op depth index) (($ <glil-external> op depth index)
(do ((e venv (venv-parent e)) (do ((e venv e.parent)
(d depth (1- d)) (d depth (1- d))
(n 0 (+ n (venv-nexts e)))) (n 0 (+ n e.nexts)))
((= d 0) ((= d 0)
(if (eq? op 'ref) (if (eq? op 'ref)
(push-code! `(external-ref ,(+ n index))) (push-code! `(external-ref ,(+ n index)))
(push-code! `(external-set ,(+ n index))))))) (push-code! `(external-set ,(+ n index)))))))
(($ <glil-module> op module name) (($ <glil-module> op module name)
(push-object! (make-vlink #f name)) ;; FIXME: (make-vmod module) (push-object! (<vlink> :module #f :name name))
(if (eq? op 'ref) (if (eq? op 'ref)
(push-code! '(variable-ref)) (push-code! '(variable-ref))
(push-code! '(variable-set)))) (push-code! '(variable-set))))
(($ <glil-label> label) (($ <glil-label> label)
(define (byte-length x) (set! label-alist (assq-set! label-alist label (current-address))))
(cond ((string? x) (string-length x))
(else 3)))
(let ((addr (apply + (map byte-length stack))))
(set! label-alist (assq-set! label-alist label addr))))
(($ <glil-branch> inst label) (($ <glil-branch> inst label)
(set! stack (cons (list inst label) stack))) (set! stack (cons (list inst label) stack)))
@ -146,13 +166,21 @@
(for-each generate-code body) (for-each generate-code body)
(let ((bytes (stack->bytes (reverse! stack) label-alist))) (let ((bytes (stack->bytes (reverse! stack) label-alist)))
(if toplevel (if toplevel
(bytecode->objcode bytes nlocs nexts) (bytecode->objcode bytes vars.nlocs vars.nexts)
(let ((objs (map car (reverse! object-alist)))) (<bytespec> :vars vars :bytes bytes
(make-bytespec nargs nrest nlocs nexts bytes objs :meta (if (and (null? bind-alist)
(venv-closure? venv))))))))) (null? source-alist))
#f
(cons (reverse! bind-alist)
(reverse! source-alist)))
:objs (let ((objs (map car (reverse! object-alist))))
(if (null? objs) #f (list->vector objs)))
:closure? venv.closure?)))))))
(define (object-assoc x alist) (define (object-assoc x alist)
(if (vlink? x) (assoc x alist) (assq x alist))) (match x
(($ <vlink>) (assoc x alist))
(else (assq x alist))))
(define (stack->bytes stack label-alist) (define (stack->bytes stack label-alist)
(let loop ((result '()) (stack stack) (addr 0)) (let loop ((result '()) (stack stack) (addr 0))
@ -181,10 +209,12 @@
(let dump! ((x x)) (let dump! ((x x))
(cond (cond
((object->code x) => push-code!) ((object->code x) => push-code!)
((bytespec? x) (else
(match x (match x
(($ bytespec nargs nrest nlocs nexts bytes objs closure?) (($ <bytespec> vars bytes meta objs closure?)
;; dump parameters ;; dump parameters
(let ((nargs vars.nargs) (nrest vars.nrest)
(nlocs vars.nlocs) (nexts vars.nexts))
(cond (cond
((and (< nargs 4) (< nlocs 8) (< nexts 4)) ((and (< nargs 4) (< nlocs 8) (< nexts 4))
;; 8-bit representation ;; 8-bit representation
@ -200,41 +230,42 @@
(push-code! (object->code nrest)) (push-code! (object->code nrest))
(push-code! (object->code nlocs)) (push-code! (object->code nlocs))
(push-code! (object->code nexts)) (push-code! (object->code nexts))
(push-code! (object->code #f)))) (push-code! (object->code #f)))))
;; dump object table ;; dump object table
(cond ((not (null? objs)) (if objs (dump! objs))
(for-each dump! objs) ;; dump meta data
(push-code! `(vector ,(length objs))))) (if meta (dump! meta))
;; dump bytecode ;; dump bytecode
(push-code! `(load-program ,bytes))))) (push-code! `(load-program ,bytes)))
((vlink? x) (($ <vlink> module name)
;;; (dump! (vlink-module x)) ;; FIXME: no module support now ;; FIXME: dump module
(push-code! `(link ,(symbol->string (vlink-name x))))) (push-code! `(link ,(symbol->string name))))
((vmod? x) (($ <vmod> id)
(push-code! `(load-module ,(vmod-id x)))) (push-code! `(load-module ,id)))
((and (integer? x) (exact? x)) ((and ($ integer) ($ exact))
(let ((str (do ((n x (quotient n 256)) (let ((str (do ((n x (quotient n 256))
(l '() (cons (modulo n 256) l))) (l '() (cons (modulo n 256) l)))
((= n 0) ((= n 0)
(list->string (map integer->char l)))))) (list->string (map integer->char l))))))
(push-code! `(load-integer ,str)))) (push-code! `(load-integer ,str))))
((number? x) (($ number)
(push-code! `(load-number ,(number->string x)))) (push-code! `(load-number ,(number->string x))))
((string? x) (($ string)
(push-code! `(load-string ,x))) (push-code! `(load-string ,x)))
((symbol? x) (($ symbol)
(push-code! `(load-symbol ,(symbol->string x)))) (push-code! `(load-symbol ,(symbol->string x))))
((keyword? x) (($ keyword)
(push-code! `(load-keyword ,(symbol->string (keyword-dash-symbol x))))) (push-code! `(load-keyword
((list? x) ,(symbol->string (keyword-dash-symbol x)))))
(($ list)
(for-each dump! x) (for-each dump! x)
(push-code! `(list ,(length x)))) (push-code! `(list ,(length x))))
((pair? x) (($ pair)
(dump! (car x)) (dump! (car x))
(dump! (cdr x)) (dump! (cdr x))
(push-code! `(cons))) (push-code! `(cons)))
((vector? x) (($ vector)
(for-each dump! (vector->list x)) (for-each dump! (vector->list x))
(push-code! `(vector ,(vector-length x)))) (push-code! `(vector ,(vector-length x))))
(else (else
(error "Cannot dump:" x))))) (error "Cannot dump:" x)))))))

View file

@ -0,0 +1,33 @@
;;; Guile VM backtrace
;; Copyright (C) 2001 Free Software Foundation, Inc.
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program; see the file COPYING. If not, write to
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;; Code:
(define-module (system vm backtrace)
:use-syntax (system base syntax)
:use-module (system vm core)
:use-module (system vm frame)
:use-module (ice-9 format)
:export (vm-backtrace))
(define (vm-backtrace vm)
(let ((stack (vm-last-frame-stack vm)))
(if (null? stack)
(display "No backtrace available\n")
(for-each print-frame (reverse! stack)))))

View file

@ -35,36 +35,21 @@
;;; ;;;
;;; Loader ;;; High-level procedures
;;; ;;;
(define-public (program-bindings prog)
(cond ((program-meta prog) => car)
(else '())))
(define-public (program-sources prog)
(cond ((program-meta prog) => cdr)
(else '())))
(define-public (vms:time stat) (vector-ref stat 0))
(define-public (vms:clock stat) (vector-ref stat 1))
(define-public (vm-load vm objcode) (define-public (vm-load vm objcode)
(vm (objcode->program objcode))) (vm (objcode->program objcode)))
(set! load-compiled (lambda (file) (vm-load (the-vm) (load-objcode file)))) (set! load-compiled (lambda (file) (vm-load (the-vm) (load-objcode file))))
;;;
;;; Frame interface
;;;
(define-public (frame->call frame)
(let* ((prog (frame-program frame))
(nargs (car (program-arity prog))))
(do ((i 0 (1+ i))
(l (vector->list (frame-variables frame)) (cdr l))
(r '() (cons (car l) r)))
((= i nargs) (cons (program-name prog) (reverse! r))))))
(define (program-name x)
(or (object-property x 'name)
(hash-fold (lambda (s v d) (if (eq? x (variable-ref v)) s d)) x
(module-obarray (current-module)))))
;;;
;;; Statistics interface
;;;
(define-public (vms:time stat) (vector-ref stat 0))
(define-public (vms:clock stat) (vector-ref stat 1))

View file

@ -127,8 +127,7 @@
(else #f))))))) (else #f)))))))
(define (list->info list) (define (list->info list)
(let ((str (object->string list))) (object->string list))
(substring str 1 (1- (string-length str)))))
(define (print-info addr info extra) (define (print-info addr info extra)
(if extra (if extra

125
module/system/vm/frame.scm Normal file
View file

@ -0,0 +1,125 @@
;;; Guile VM frame functions
;; Copyright (C) 2001 Free Software Foundation, Inc.
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program; see the file COPYING. If not, write to
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;; Code:
(define-module (system vm frame)
:use-module (system vm core))
(define-public (vm-return-value vm)
(car (vm-fetch-stack vm)))
(define-public (frame-local-ref frame index)
(vector-ref (frame-local-variables frame) index))
(define-public (frame-external-ref frame index)
(list-ref (frame-external-link frame) index))
;;;
;;; Debug frames
;;;
(define-public frame-index (make-object-property))
(define-public frame-address (make-object-property))
(define-public (vm-last-frame-stack vm)
(make-frame-stack (vm-last-frame vm) (vm:ip vm)))
(define-public (vm-current-frame-stack vm)
(make-frame-stack (vm-current-frame vm) (vm:ip vm)))
(define (make-frame-stack frame addr)
(cond ((frame-dynamic-link frame) =>
(lambda (link)
(let ((stack (make-frame-stack link (frame-return-address frame)))
(base (program-base (frame-program frame))))
(set! (frame-index frame) (1+ (length stack)))
(set! (frame-address frame) (- addr base))
(cons frame stack))))
(else '())))
(define-public (frame-bindings frame addr)
(do ((bs (program-bindings (frame-program frame)) (cdr bs))
(ls '() (if (cdar bs) (cons (cdar bs) ls) (cdr ls))))
((or (null? bs) (> (caar bs) addr))
(apply append ls))))
(define-public (frame-environment frame addr)
(map (lambda (binding)
(let ((name (car binding))
(extp (cadr binding))
(index (caddr binding)))
(cons name (if extp
(frame-external-ref frame index)
(frame-local-ref frame index)))))
(frame-bindings frame addr)))
(define (frame-variable-ref frame sym)
(cond ((assq sym (frame-environment frame)) => cdr)
(else (error "Unbound"))))
(define (frame-object-name frame obj)
(display (frame-address frame))
(let loop ((alist (frame-environment frame (frame-address frame))))
(cond ((null? alist) #f)
((eq? obj (cdar alist)) (caar alist))
(else (loop (cdr alist))))))
;;;
;;; Pretty printing
;;;
(define-public (frame-call-list frame)
(let* ((prog (frame-program frame))
(locs (vector->list (frame-local-variables frame)))
(args (list-truncate locs (car (program-arity prog))))
(name (or (frame-object-name (frame-dynamic-link frame) prog)
(object-name prog))))
(cons name args)))
(define-public (print-frame-call frame)
(define (abbrev x)
(cond ((list? x) (if (> (length x) 3)
(list (abbrev (car x)) (abbrev (cadr x)) '...)
(map abbrev x)))
((pair? x) (cons (abbrev (car x)) (abbrev (cdr x))))
((vector? x) (case (vector-length x)
((0) x)
((1) (vector (abbrev (vector-ref x 0))))
(else (vector (abbrev (vector-ref x 0)) '...))))
(else x)))
(write (abbrev (frame-call-list frame))))
(define-public (print-frame frame)
(format #t "#~A " (frame-index frame))
(print-frame-call frame)
(newline))
(define (list-truncate l n)
(do ((i 0 (1+ i))
(l l (cdr l))
(r '() (cons (car l) r)))
((= i n) (reverse! r))))
(define (object-name x)
(or (object-property x 'name)
(hash-fold (lambda (s v d) (if (eq? x (variable-ref v)) s d))
x (module-obarray (current-module)))))

View file

@ -34,7 +34,7 @@
(add-hook! (vm-enter-hook vm) profile-enter) (add-hook! (vm-enter-hook vm) profile-enter)
(add-hook! (vm-exit-hook vm) profile-exit)) (add-hook! (vm-exit-hook vm) profile-exit))
(lambda () (lambda ()
(let ((val (vm (objcode->program objcode)))) (let ((val (vm-load vm objcode)))
(display-result vm) (display-result vm)
val)) val))
(lambda () (lambda ()

View file

@ -22,13 +22,14 @@
(define-module (system vm trace) (define-module (system vm trace)
:use-syntax (system base syntax) :use-syntax (system base syntax)
:use-module (system vm core) :use-module (system vm core)
:use-module (system vm frame)
:use-module (ice-9 format) :use-module (ice-9 format)
:export (vm-trace vm-trace-on vm-trace-off)) :export (vm-trace vm-trace-on vm-trace-off))
(define (vm-trace vm objcode . opts) (define (vm-trace vm objcode . opts)
(dynamic-wind (dynamic-wind
(lambda () (apply vm-trace-on vm opts)) (lambda () (apply vm-trace-on vm opts))
(lambda () (vm (objcode->program objcode))) (lambda () (vm-load vm objcode))
(lambda () (apply vm-trace-off vm opts)))) (lambda () (apply vm-trace-off vm opts))))
(define (vm-trace-on vm . opts) (define (vm-trace-on vm . opts)
@ -44,30 +45,32 @@
(remove-hook! (vm-return-hook vm) trace-return)) (remove-hook! (vm-return-hook vm) trace-return))
(define (trace-next vm) (define (trace-next vm)
(let ((frame (vm-current-frame vm)))
(format #t "0x~8X ~20S" (vm:ip vm) (vm-fetch-code vm)) (format #t "0x~8X ~20S" (vm:ip vm) (vm-fetch-code vm))
(do ((opts (vm-option vm 'trace-options) (cdr opts))) (do ((opts (vm-option vm 'trace-options) (cdr opts)))
((null? opts) (newline)) ((null? opts) (newline))
(case (car opts) (case (car opts)
((:s) (format #t "~20S" (vm-fetch-stack vm))) ((:s) (format #t "~20S" (vm-fetch-stack vm)))
((:v) (format #t "~20S" (frame-variables frame))) ((:v) (let ((stack (vm-current-frame-stack vm)))
((:e) (format #t "~20A" (object->string (frame-external-link frame)))))))) (if (pair? stack)
(format #t "~20S" (frame-environment (car stack))))))
((:l)
(format #t "~20S" (frame-local-variables (vm-current-frame vm))))
((:e)
(format #t "~20A" (frame-external-link (vm-current-frame vm)))))))
(define (trace-apply vm) (define (trace-apply vm)
(if (vm-option vm 'trace-first) ;; (if (vm-option vm 'trace-first)
(set-vm-option! vm 'trace-first #f) ;; skip the initial program ;; (set-vm-option! vm 'trace-first #f)
(let ((frame (vm-current-frame vm))) (let ((stack (vm-current-frame-stack vm)))
(print-prefix (frame-dynamic-link frame)) (print-indent stack)
(write (frame->call frame)) (print-frame-call (car stack))
(newline))))
(define (trace-return vm)
(let ((frame (vm-current-frame vm)))
(print-prefix (frame-dynamic-link frame))
(write (car (vm-fetch-stack vm)))
(newline))) (newline)))
(define (print-prefix frame) (define (trace-return vm)
(and-let* ((link (frame-dynamic-link frame))) (let ((stack (vm-current-frame-stack vm)))
(display "| ") (print-indent stack)
(print-prefix link))) (write (vm-return-value vm))
(newline)))
(define (print-indent stack)
(cond ((pair? stack) (display "| ") (print-indent (cdr stack)))))

View file

@ -6,13 +6,13 @@ guile_vm_LDFLAGS = $(GUILE_LDFLAGS)
lib_LTLIBRARIES = libguilevm.la lib_LTLIBRARIES = libguilevm.la
libguilevm_la_SOURCES = \ libguilevm_la_SOURCES = \
envs.c instructions.c objcodes.c programs.c vm.c \ envs.c frames.c instructions.c objcodes.c programs.c vm.c \
envs.h instructions.h objcodes.h programs.h vm.h \ envs.h frames.h instructions.h objcodes.h programs.h vm.h \
vm_engine.h vm_expand.h vm_engine.h vm_expand.h
libguilevm_la_LDFLAGS = -version-info 0:0:0 -export-dynamic libguilevm_la_LDFLAGS = -version-info 0:0:0 -export-dynamic
EXTRA_DIST = vm_engine.c vm_system.c vm_scheme.c vm_loader.c EXTRA_DIST = vm_engine.c vm_system.c vm_scheme.c vm_loader.c
BUILT_SOURCES = vm_system.i vm_scheme.i vm_loader.i \ BUILT_SOURCES = vm_system.i vm_scheme.i vm_loader.i \
envs.x instructions.x objcodes.x programs.x vm.x envs.x frames.x instructions.x objcodes.x programs.x vm.x
INCLUDES = $(GUILE_CFLAGS) INCLUDES = $(GUILE_CFLAGS)
DISTCLEANFILES = $(BUILT_SOURCES) DISTCLEANFILES = $(BUILT_SOURCES)

184
src/frames.c Normal file
View file

@ -0,0 +1,184 @@
/* Copyright (C) 2001 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307 USA
*
* As a special exception, the Free Software Foundation gives permission
* for additional uses of the text contained in its release of GUILE.
*
* The exception is that, if you link the GUILE library with other files
* to produce an executable, this does not by itself cause the
* resulting executable to be covered by the GNU General Public License.
* Your use of that executable is in no way restricted on account of
* linking the GUILE library code into it.
*
* This exception does not however invalidate any other reasons why
* the executable file might be covered by the GNU General Public License.
*
* This exception applies only to the code released by the
* Free Software Foundation under the name GUILE. If you copy
* code from other Free Software Foundation releases into a copy of
* GUILE, as the General Public License permits, the exception does
* not apply to the code that you add in this way. To avoid misleading
* anyone as to the status of such modified files, you must delete
* this exception notice from them.
*
* If you write modifications of your own for GUILE, it is your choice
* whether to permit this exception to apply to your modifications.
* If you do not wish that, delete this exception notice. */
#include <string.h>
#include "frames.h"
scm_bits_t scm_tc16_heap_frame;
SCM
scm_c_make_heap_frame (SCM *fp)
{
struct scm_heap_frame *p =
scm_must_malloc (sizeof (struct scm_heap_frame), "make_heap_frame");
p->fp = fp;
p->program = SCM_UNDEFINED;
p->variables = SCM_UNDEFINED;
p->dynamic_link = SCM_UNDEFINED;
p->external_link = SCM_UNDEFINED;
SCM_RETURN_NEWSMOB (scm_tc16_heap_frame, p);
}
static SCM
heap_frame_mark (SCM obj)
{
struct scm_heap_frame *p = SCM_HEAP_FRAME_DATA (obj);
scm_gc_mark (p->program);
scm_gc_mark (p->variables);
scm_gc_mark (p->dynamic_link);
return p->external_link;
}
/* Scheme interface */
SCM_DEFINE (scm_frame_p, "frame?", 1, 0, 0,
(SCM obj),
"")
#define FUNC_NAME s_scm_frame_p
{
return SCM_BOOL (SCM_HEAP_FRAME_P (obj));
}
#undef FUNC_NAME
SCM_DEFINE (scm_frame_program, "frame-program", 1, 0, 0,
(SCM frame),
"")
#define FUNC_NAME s_scm_frame_program
{
SCM_VALIDATE_HEAP_FRAME (1, frame);
return SCM_STACK_FRAME_PROGRAM (SCM_HEAP_FRAME_DATA (frame)->fp);
}
#undef FUNC_NAME
SCM_DEFINE (scm_frame_local_variables, "frame-local-variables", 1, 0, 0,
(SCM frame),
"")
#define FUNC_NAME s_scm_frame_local_variables
{
struct scm_heap_frame *p;
SCM_VALIDATE_HEAP_FRAME (1, frame);
p = SCM_HEAP_FRAME_DATA (frame);
if (SCM_UNBNDP (p->variables))
{
SCM prog = scm_frame_program (frame);
struct scm_program *pp = SCM_PROGRAM_DATA (prog);
int i, size = pp->nargs + pp->nlocs;
p->variables = scm_make_vector (SCM_MAKINUM (size), SCM_BOOL_F);
for (i = 0; i < size; i++)
SCM_VELTS (p->variables)[i] = SCM_STACK_FRAME_VARIABLE (p->fp, i);
}
return p->variables;
}
#undef FUNC_NAME
SCM_DEFINE (scm_frame_return_address, "frame-return-address", 1, 0, 0,
(SCM frame),
"")
#define FUNC_NAME s_scm_frame_return_address
{
SCM_VALIDATE_HEAP_FRAME (1, frame);
return scm_long2num ((long) SCM_VM_BYTE_ADDRESS
(SCM_STACK_FRAME_RETURN_ADDRESS
(SCM_HEAP_FRAME_DATA (frame)->fp)));
}
#undef FUNC_NAME
SCM_DEFINE (scm_frame_dynamic_link, "frame-dynamic-link", 1, 0, 0,
(SCM frame),
"")
#define FUNC_NAME s_scm_frame_dynamic_link
{
struct scm_heap_frame *p;
SCM_VALIDATE_HEAP_FRAME (1, frame);
p = SCM_HEAP_FRAME_DATA (frame);
if (SCM_UNBNDP (p->dynamic_link))
{
SCM *fp = SCM_VM_STACK_ADDRESS (SCM_STACK_FRAME_DYNAMIC_LINK (p->fp));
if (fp)
p->dynamic_link = scm_c_make_heap_frame (fp);
else
p->dynamic_link = SCM_BOOL_F;
}
return p->dynamic_link;
}
#undef FUNC_NAME
SCM_DEFINE (scm_frame_external_link, "frame-external-link", 1, 0, 0,
(SCM frame),
"")
#define FUNC_NAME s_scm_frame_external_link
{
struct scm_heap_frame *p;
SCM_VALIDATE_HEAP_FRAME (1, frame);
p = SCM_HEAP_FRAME_DATA (frame);
if (SCM_UNBNDP (p->external_link))
p->external_link = SCM_STACK_FRAME_EXTERNAL_LINK (p->fp);
return p->external_link;
}
#undef FUNC_NAME
void
scm_init_frames (void)
{
scm_tc16_heap_frame = scm_make_smob_type ("heap_frame", 0);
scm_set_smob_mark (scm_tc16_heap_frame, heap_frame_mark);
#ifndef SCM_MAGIC_SNARFER
#include "frames.x"
#endif
}
/*
Local Variables:
c-file-style: "gnu"
End:
*/

126
src/frames.h Normal file
View file

@ -0,0 +1,126 @@
/* Copyright (C) 2001 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307 USA
*
* As a special exception, the Free Software Foundation gives permission
* for additional uses of the text contained in its release of GUILE.
*
* The exception is that, if you link the GUILE library with other files
* to produce an executable, this does not by itself cause the
* resulting executable to be covered by the GNU General Public License.
* Your use of that executable is in no way restricted on account of
* linking the GUILE library code into it.
*
* This exception does not however invalidate any other reasons why
* the executable file might be covered by the GNU General Public License.
*
* This exception applies only to the code released by the
* Free Software Foundation under the name GUILE. If you copy
* code from other Free Software Foundation releases into a copy of
* GUILE, as the General Public License permits, the exception does
* not apply to the code that you add in this way. To avoid misleading
* anyone as to the status of such modified files, you must delete
* this exception notice from them.
*
* If you write modifications of your own for GUILE, it is your choice
* whether to permit this exception to apply to your modifications.
* If you do not wish that, delete this exception notice. */
#ifndef _SCM_FRAMES_H_
#define _SCM_FRAMES_H_
#include <libguile.h>
#include "config.h"
#include "programs.h"
/*
* VM Address
*/
#define SCM_VM_MAKE_STACK_ADDRESS(ptr) SCM_PACK (ptr)
#define SCM_VM_STACK_ADDRESS(addr) ((SCM *) SCM_UNPACK (addr))
#define SCM_VM_MAKE_BYTE_ADDRESS(ptr) SCM_PACK (ptr)
#define SCM_VM_BYTE_ADDRESS(addr) ((scm_byte_t *) SCM_UNPACK (addr))
/*
* VM Stack frames
*/
/* Stack frames are allocated on the VM stack as follows:
| | <- fp + bp->nargs + bp->nlocs + 3
+------------------+ = SCM_STACK_FRAME_UPPER_ADDRESS (fp)
| Return address |
| Dynamic link |
| External link | <- fp + bp->nargs + bp->nlocs
| Local varialbe 1 | = SCM_STACK_FRAME_DATA_ADDRESS (fp)
| Local variable 0 | <- fp + bp->nargs
| Argument 1 |
| Argument 0 | <- fp
| Program | <- fp - 1
+------------------+ = SCM_STACK_FRAME_LOWER_ADDRESS (fp)
| |
*/
#define SCM_STACK_FRAME_DATA_ADDRESS(fp) \
(fp + SCM_PROGRAM_DATA (SCM_STACK_FRAME_PROGRAM (fp))->nargs \
+ SCM_PROGRAM_DATA (SCM_STACK_FRAME_PROGRAM (fp))->nlocs)
#define SCM_STACK_FRAME_UPPER_ADDRESS(fp) \
(SCM_STACK_FRAME_DATA_ADDRESS (fp) + 3)
#define SCM_STACK_FRAME_LOWER_ADDRESS(fp) (fp - 1)
#define SCM_STACK_FRAME_RETURN_ADDRESS(fp) SCM_STACK_FRAME_DATA_ADDRESS (fp)[2]
#define SCM_STACK_FRAME_DYNAMIC_LINK(fp) SCM_STACK_FRAME_DATA_ADDRESS (fp)[1]
#define SCM_STACK_FRAME_EXTERNAL_LINK(fp) SCM_STACK_FRAME_DATA_ADDRESS (fp)[0]
#define SCM_STACK_FRAME_VARIABLE(fp,i) fp[i]
#define SCM_STACK_FRAME_PROGRAM(fp) fp[-1]
/*
* VM Heap frames
*/
struct scm_heap_frame {
SCM *fp;
SCM program;
SCM variables;
SCM dynamic_link;
SCM external_link;
};
extern scm_bits_t scm_tc16_heap_frame;
#define SCM_HEAP_FRAME_P(x) SCM_SMOB_PREDICATE (scm_tc16_heap_frame, x)
#define SCM_HEAP_FRAME_DATA(f) ((struct scm_heap_frame *) SCM_SMOB_DATA (f))
#define SCM_VALIDATE_HEAP_FRAME(p,x) SCM_MAKE_VALIDATE (p, x, HEAP_FRAME_P)
#define SCM_HEAP_FRAME_PROGRAM(f) SCM_HEAP_FRAME_DATA (f)->program
#define SCM_HEAP_FRAME_VARIABLES(f) SCM_HEAP_FRAME_DATA (f)->variables
#define SCM_HEAP_FRAME_DYNAMIC_LINK(f) SCM_HEAP_FRAME_DATA (f)->dynamic_link
#define SCM_HEAP_FRAME_EXTERNAL_LINK(f) SCM_HEAP_FRAME_DATA (f)->external_link
extern SCM scm_c_make_heap_frame (SCM *fp);
extern void scm_init_frames (void);
#endif /* _SCM_FRAMES_H_ */
/*
Local Variables:
c-file-style: "gnu"
End:
*/

View file

@ -194,14 +194,16 @@ SCM_DEFINE (scm_objcode_to_program, "objcode->program", 1, 0, 0,
SCM prog; SCM prog;
size_t size; size_t size;
char *base; char *base;
struct scm_program *p;
SCM_VALIDATE_OBJCODE (1, objcode); SCM_VALIDATE_OBJCODE (1, objcode);
base = SCM_OBJCODE_BASE (objcode); base = SCM_OBJCODE_BASE (objcode);
size = SCM_OBJCODE_SIZE (objcode); size = SCM_OBJCODE_SIZE (objcode);
prog = scm_c_make_program (base + 10, size - 10, objcode); prog = scm_c_make_program (base + 10, size - 10, objcode);
SCM_PROGRAM_NLOCS (prog) = base[8]; p = SCM_PROGRAM_DATA (prog);
SCM_PROGRAM_NEXTS (prog) = base[9]; p->nlocs = base[8];
p->nexts = base[9];
return prog; return prog;
} }
#undef FUNC_NAME #undef FUNC_NAME

View file

@ -59,6 +59,7 @@ scm_c_make_program (void *addr, size_t size, SCM holder)
p->nrest = 0; p->nrest = 0;
p->nlocs = 0; p->nlocs = 0;
p->nexts = 0; p->nexts = 0;
p->meta = SCM_BOOL_F;
p->objs = zero_vector; p->objs = zero_vector;
p->external = SCM_EOL; p->external = SCM_EOL;
p->holder = holder; p->holder = holder;
@ -78,7 +79,7 @@ scm_c_make_closure (SCM program, SCM external)
{ {
SCM prog = scm_c_make_program (0, 0, program); SCM prog = scm_c_make_program (0, 0, program);
*SCM_PROGRAM_DATA (prog) = *SCM_PROGRAM_DATA (program); *SCM_PROGRAM_DATA (prog) = *SCM_PROGRAM_DATA (program);
SCM_PROGRAM_EXTERNAL (prog) = external; SCM_PROGRAM_DATA (prog)->external = external;
return prog; return prog;
} }
@ -86,6 +87,7 @@ static SCM
program_mark (SCM obj) program_mark (SCM obj)
{ {
struct scm_program *p = SCM_PROGRAM_DATA (obj); struct scm_program *p = SCM_PROGRAM_DATA (obj);
scm_gc_mark (p->meta);
scm_gc_mark (p->objs); scm_gc_mark (p->objs);
scm_gc_mark (p->external); scm_gc_mark (p->external);
return p->holder; return p->holder;
@ -105,19 +107,6 @@ program_free (SCM obj)
return size; return size;
} }
static int
program_print (SCM obj, SCM port, scm_print_state *pstate)
{
SCM name = scm_object_property (obj, scm_sym_name);
scm_puts ("#<program ", port);
if (SCM_FALSEP (name))
scm_intprint ((long) SCM_PROGRAM_BASE (obj), 16, port);
else
scm_display (name, port);
scm_putc ('>', port);
return 1;
}
static SCM static SCM
program_apply (SCM program, SCM args) program_apply (SCM program, SCM args)
{ {
@ -138,16 +127,41 @@ SCM_DEFINE (scm_program_p, "program?", 1, 0, 0,
} }
#undef FUNC_NAME #undef FUNC_NAME
SCM_DEFINE (scm_program_base, "program-base", 1, 0, 0,
(SCM program),
"")
#define FUNC_NAME s_scm_program_base
{
SCM_VALIDATE_PROGRAM (1, program);
return scm_long2num ((long) SCM_PROGRAM_DATA (program)->base);
}
#undef FUNC_NAME
SCM_DEFINE (scm_program_arity, "program-arity", 1, 0, 0, SCM_DEFINE (scm_program_arity, "program-arity", 1, 0, 0,
(SCM program), (SCM program),
"") "")
#define FUNC_NAME s_scm_program_arity #define FUNC_NAME s_scm_program_arity
{ {
struct scm_program *p;
SCM_VALIDATE_PROGRAM (1, program); SCM_VALIDATE_PROGRAM (1, program);
return SCM_LIST4 (SCM_MAKINUM (SCM_PROGRAM_NARGS (program)),
SCM_MAKINUM (SCM_PROGRAM_NREST (program)), p = SCM_PROGRAM_DATA (program);
SCM_MAKINUM (SCM_PROGRAM_NLOCS (program)), return SCM_LIST4 (SCM_MAKINUM (p->nargs),
SCM_MAKINUM (SCM_PROGRAM_NEXTS (program))); SCM_MAKINUM (p->nrest),
SCM_MAKINUM (p->nlocs),
SCM_MAKINUM (p->nexts));
}
#undef FUNC_NAME
SCM_DEFINE (scm_program_meta, "program-meta", 1, 0, 0,
(SCM program),
"")
#define FUNC_NAME s_scm_program_meta
{
SCM_VALIDATE_PROGRAM (1, program);
return SCM_PROGRAM_DATA (program)->meta;
} }
#undef FUNC_NAME #undef FUNC_NAME
@ -157,7 +171,7 @@ SCM_DEFINE (scm_program_objects, "program-objects", 1, 0, 0,
#define FUNC_NAME s_scm_program_objects #define FUNC_NAME s_scm_program_objects
{ {
SCM_VALIDATE_PROGRAM (1, program); SCM_VALIDATE_PROGRAM (1, program);
return SCM_PROGRAM_OBJS (program); return SCM_PROGRAM_DATA (program)->objs;
} }
#undef FUNC_NAME #undef FUNC_NAME
@ -167,7 +181,7 @@ SCM_DEFINE (scm_program_external, "program-external", 1, 0, 0,
#define FUNC_NAME s_scm_program_external #define FUNC_NAME s_scm_program_external
{ {
SCM_VALIDATE_PROGRAM (1, program); SCM_VALIDATE_PROGRAM (1, program);
return SCM_PROGRAM_EXTERNAL (program); return SCM_PROGRAM_DATA (program)->external;
} }
#undef FUNC_NAME #undef FUNC_NAME
@ -177,8 +191,8 @@ SCM_DEFINE (scm_program_bytecode, "program-bytecode", 1, 0, 0,
#define FUNC_NAME s_scm_program_bytecode #define FUNC_NAME s_scm_program_bytecode
{ {
SCM_VALIDATE_PROGRAM (1, program); SCM_VALIDATE_PROGRAM (1, program);
return scm_makfromstr (SCM_PROGRAM_BASE (program), return scm_makfromstr (SCM_PROGRAM_DATA (program)->base,
SCM_PROGRAM_SIZE (program), 0); SCM_PROGRAM_DATA (program)->size, 0);
} }
#undef FUNC_NAME #undef FUNC_NAME
@ -191,7 +205,6 @@ scm_init_programs (void)
scm_tc16_program = scm_make_smob_type ("program", 0); scm_tc16_program = scm_make_smob_type ("program", 0);
scm_set_smob_mark (scm_tc16_program, program_mark); scm_set_smob_mark (scm_tc16_program, program_mark);
scm_set_smob_free (scm_tc16_program, program_free); scm_set_smob_free (scm_tc16_program, program_free);
scm_set_smob_print (scm_tc16_program, program_print);
scm_set_smob_apply (scm_tc16_program, program_apply, 0, 0, 1); scm_set_smob_apply (scm_tc16_program, program_apply, 0, 0, 1);
#ifndef SCM_MAGIC_SNARFER #ifndef SCM_MAGIC_SNARFER

View file

@ -58,6 +58,7 @@ struct scm_program {
unsigned char nlocs; /* the number of local variables */ unsigned char nlocs; /* the number of local variables */
unsigned char nexts; /* the number of external variables */ unsigned char nexts; /* the number of external variables */
scm_byte_t *base; /* program base address */ scm_byte_t *base; /* program base address */
SCM meta; /* meta data */
SCM objs; /* constant objects */ SCM objs; /* constant objects */
SCM external; /* external environment */ SCM external; /* external environment */
SCM holder; /* the owner of bytecode */ SCM holder; /* the owner of bytecode */
@ -69,18 +70,6 @@ extern scm_bits_t scm_tc16_program;
#define SCM_PROGRAM_DATA(x) ((struct scm_program *) SCM_SMOB_DATA (x)) #define SCM_PROGRAM_DATA(x) ((struct scm_program *) SCM_SMOB_DATA (x))
#define SCM_VALIDATE_PROGRAM(p,x) SCM_MAKE_VALIDATE (p, x, PROGRAM_P) #define SCM_VALIDATE_PROGRAM(p,x) SCM_MAKE_VALIDATE (p, x, PROGRAM_P)
#define SCM_PROGRAM_SIZE(x) (SCM_PROGRAM_DATA (x)->size)
#define SCM_PROGRAM_NARGS(x) (SCM_PROGRAM_DATA (x)->nargs)
#define SCM_PROGRAM_NREST(x) (SCM_PROGRAM_DATA (x)->nrest)
#define SCM_PROGRAM_NLOCS(x) (SCM_PROGRAM_DATA (x)->nlocs)
#define SCM_PROGRAM_NEXTS(x) (SCM_PROGRAM_DATA (x)->nexts)
#define SCM_PROGRAM_BASE(x) (SCM_PROGRAM_DATA (x)->base)
#define SCM_PROGRAM_META(x) (SCM_PROGRAM_DATA (x)->meta)
#define SCM_PROGRAM_OBJS(x) (SCM_PROGRAM_DATA (x)->objs)
#define SCM_PROGRAM_LINKS(x) (SCM_PROGRAM_DATA (x)->links)
#define SCM_PROGRAM_EXTERNAL(x) (SCM_PROGRAM_DATA (x)->external)
#define SCM_PROGRAM_HOLDER(x) (SCM_PROGRAM_DATA (x)->holder)
extern SCM scm_c_make_program (void *addr, size_t size, SCM holder); extern SCM scm_c_make_program (void *addr, size_t size, SCM holder);
extern SCM scm_c_make_closure (SCM program, SCM external); extern SCM scm_c_make_closure (SCM program, SCM external);

146
src/vm.c
View file

@ -40,10 +40,11 @@
* If you do not wish that, delete this exception notice. */ * If you do not wish that, delete this exception notice. */
#include <string.h> #include <string.h>
#include "instructions.h"
#include "programs.h"
#include "objcodes.h"
#include "envs.h" #include "envs.h"
#include "frames.h"
#include "instructions.h"
#include "objcodes.h"
#include "programs.h"
#include "vm.h" #include "vm.h"
/* I sometimes use this for debugging. */ /* I sometimes use this for debugging. */
@ -53,119 +54,6 @@
scm_newline (scm_def_errp); \ scm_newline (scm_def_errp); \
} }
/*
* VM Heap frame
*/
scm_bits_t scm_tc16_vm_heap_frame;
static SCM
make_vm_heap_frame (SCM *fp)
{
struct scm_vm_heap_frame *p =
scm_must_malloc (sizeof (struct scm_vm_heap_frame), "make_vm_heap_frame");
p->fp = fp;
p->program = SCM_UNDEFINED;
p->variables = SCM_UNDEFINED;
p->dynamic_link = SCM_UNDEFINED;
p->external_link = SCM_UNDEFINED;
SCM_RETURN_NEWSMOB (scm_tc16_vm_heap_frame, p);
}
static SCM
vm_heap_frame_mark (SCM obj)
{
struct scm_vm_heap_frame *p = SCM_VM_HEAP_FRAME_DATA (obj);
scm_gc_mark (p->program);
scm_gc_mark (p->variables);
scm_gc_mark (p->dynamic_link);
return p->external_link;
}
/* Scheme interface */
SCM_DEFINE (scm_frame_p, "frame?", 1, 0, 0,
(SCM obj),
"")
#define FUNC_NAME s_scm_frame_p
{
return SCM_BOOL (SCM_VM_HEAP_FRAME_P (obj));
}
#undef FUNC_NAME
SCM_DEFINE (scm_frame_program, "frame-program", 1, 0, 0,
(SCM frame),
"")
#define FUNC_NAME s_scm_frame_program
{
SCM_VALIDATE_VM_HEAP_FRAME (1, frame);
return SCM_VM_FRAME_PROGRAM (SCM_VM_HEAP_FRAME_DATA (frame)->fp);
}
#undef FUNC_NAME
SCM_DEFINE (scm_frame_variables, "frame-variables", 1, 0, 0,
(SCM frame),
"")
#define FUNC_NAME s_scm_frame_variables
{
struct scm_vm_heap_frame *p;
SCM_VALIDATE_VM_HEAP_FRAME (1, frame);
p = SCM_VM_HEAP_FRAME_DATA (frame);
if (SCM_UNBNDP (p->variables))
{
SCM prog = scm_frame_program (frame);
int i, size = SCM_PROGRAM_NARGS (prog) + SCM_PROGRAM_NLOCS (prog);
p->variables = scm_make_vector (SCM_MAKINUM (size), SCM_BOOL_F);
for (i = 0; i < size; i++)
SCM_VELTS (p->variables)[i] = SCM_VM_FRAME_VARIABLE (p->fp, i);
}
return p->variables;
}
#undef FUNC_NAME
SCM_DEFINE (scm_frame_dynamic_link, "frame-dynamic-link", 1, 0, 0,
(SCM frame),
"")
#define FUNC_NAME s_scm_frame_dynamic_link
{
struct scm_vm_heap_frame *p;
SCM_VALIDATE_VM_HEAP_FRAME (1, frame);
p = SCM_VM_HEAP_FRAME_DATA (frame);
if (SCM_UNBNDP (p->dynamic_link))
{
SCM *fp = SCM_VM_STACK_ADDRESS (SCM_VM_FRAME_DYNAMIC_LINK (p->fp));
if (fp)
p->dynamic_link = make_vm_heap_frame (fp);
else
p->dynamic_link = SCM_BOOL_F;
}
return p->dynamic_link;
}
#undef FUNC_NAME
SCM_DEFINE (scm_frame_external_link, "frame-external-link", 1, 0, 0,
(SCM frame),
"")
#define FUNC_NAME s_scm_frame_external_link
{
struct scm_vm_heap_frame *p;
SCM_VALIDATE_VM_HEAP_FRAME (1, frame);
p = SCM_VM_HEAP_FRAME_DATA (frame);
if (SCM_UNBNDP (p->external_link))
p->external_link = SCM_VM_FRAME_EXTERNAL_LINK (p->fp);
return p->external_link;
}
#undef FUNC_NAME
/* /*
* VM Continuation * VM Continuation
@ -303,6 +191,7 @@ make_vm (void)
vp->time = 0; vp->time = 0;
vp->clock = 0; vp->clock = 0;
vp->options = SCM_EOL; vp->options = SCM_EOL;
vp->last_frame = SCM_BOOL_F;
for (i = 0; i < SCM_VM_NUM_HOOKS; i++) for (i = 0; i < SCM_VM_NUM_HOOKS; i++)
vp->hooks[i] = SCM_BOOL_F; vp->hooks[i] = SCM_BOOL_F;
SCM_RETURN_NEWSMOB (scm_tc16_vm, vp); SCM_RETURN_NEWSMOB (scm_tc16_vm, vp);
@ -321,8 +210,8 @@ vm_mark (SCM obj)
fp = vp->fp; fp = vp->fp;
while (fp) while (fp)
{ {
SCM *upper = SCM_VM_FRAME_UPPER_ADDRESS (fp); SCM *upper = SCM_STACK_FRAME_UPPER_ADDRESS (fp);
SCM *lower = SCM_VM_FRAME_LOWER_ADDRESS (fp); SCM *lower = SCM_STACK_FRAME_LOWER_ADDRESS (fp);
/* Mark intermediate data */ /* Mark intermediate data */
for (; sp >= upper; sp--) for (; sp >= upper; sp--)
if (SCM_NIMP (*sp)) if (SCM_NIMP (*sp))
@ -337,6 +226,7 @@ vm_mark (SCM obj)
/* Mark the options */ /* Mark the options */
for (i = 0; i < SCM_VM_NUM_HOOKS; i++) for (i = 0; i < SCM_VM_NUM_HOOKS; i++)
scm_gc_mark (vp->hooks[i]); scm_gc_mark (vp->hooks[i]);
scm_gc_mark (vp->last_frame);
return vp->options; return vp->options;
} }
@ -553,7 +443,17 @@ SCM_DEFINE (scm_vm_current_frame, "vm-current-frame", 1, 0, 0,
{ {
SCM_VALIDATE_VM (1, vm); SCM_VALIDATE_VM (1, vm);
VM_CHECK_RUNNING (vm); VM_CHECK_RUNNING (vm);
return make_vm_heap_frame (SCM_VM_DATA (vm)->fp); return scm_c_make_heap_frame (SCM_VM_DATA (vm)->fp);
}
#undef FUNC_NAME
SCM_DEFINE (scm_vm_last_frame, "vm-last-frame", 1, 0, 0,
(SCM vm),
"")
#define FUNC_NAME s_scm_vm_last_frame
{
SCM_VALIDATE_VM (1, vm);
return SCM_VM_DATA (vm)->last_frame;
} }
#undef FUNC_NAME #undef FUNC_NAME
@ -593,7 +493,7 @@ SCM_DEFINE (scm_vm_fetch_stack, "vm-fetch-stack", 1, 0, 0,
VM_CHECK_RUNNING (vm); VM_CHECK_RUNNING (vm);
vp = SCM_VM_DATA (vm); vp = SCM_VM_DATA (vm);
for (sp = SCM_VM_FRAME_UPPER_ADDRESS (vp->fp); sp <= vp->sp; sp++) for (sp = SCM_STACK_FRAME_UPPER_ADDRESS (vp->fp); sp <= vp->sp; sp++)
ls = scm_cons (*sp, ls); ls = scm_cons (*sp, ls);
return ls; return ls;
} }
@ -607,12 +507,10 @@ SCM_DEFINE (scm_vm_fetch_stack, "vm-fetch-stack", 1, 0, 0,
void void
scm_init_vm (void) scm_init_vm (void)
{ {
scm_init_frames ();
scm_init_instructions (); scm_init_instructions ();
scm_init_programs ();
scm_init_objcodes (); scm_init_objcodes ();
scm_init_programs ();
scm_tc16_vm_heap_frame = scm_make_smob_type ("vm_frame", 0);
scm_set_smob_mark (scm_tc16_vm_heap_frame, vm_heap_frame_mark);
scm_tc16_vm_cont = scm_make_smob_type ("vm-cont", 0); scm_tc16_vm_cont = scm_make_smob_type ("vm-cont", 0);
scm_set_smob_mark (scm_tc16_vm_cont, vm_cont_mark); scm_set_smob_mark (scm_tc16_vm_cont, vm_cont_mark);

View file

@ -44,76 +44,6 @@
#include <libguile.h> #include <libguile.h>
#include "config.h" #include "config.h"
#include "programs.h"
/*
* VM Address
*/
#define SCM_VM_MAKE_STACK_ADDRESS(ptr) SCM_PACK (ptr)
#define SCM_VM_STACK_ADDRESS(addr) ((SCM *) SCM_UNPACK (addr))
#define SCM_VM_MAKE_BYTE_ADDRESS(ptr) SCM_PACK (ptr)
#define SCM_VM_BYTE_ADDRESS(addr) ((scm_byte_t *) SCM_UNPACK (addr))
/*
* VM Stack frame
*/
/*
| | <- fp + bp->nargs + bp->nlocs + 3
+------------------+ = SCM_VM_FRAME_UPPER_ADDRESS (fp)
| Return address |
| Dynamic link |
| External link | <- fp + bp->nargs + bp->nlocs
| Local varialbe 1 | = SCM_VM_FRAME_DATA_ADDRESS (fp)
| Local variable 0 | <- fp + bp->nargs
| Argument 1 |
| Argument 0 | <- fp
| Program | <- fp - 1
+------------------+ = SCM_VM_FRAME_LOWER_ADDRESS (fp)
| |
*/
#define SCM_VM_FRAME_DATA_ADDRESS(fp) \
(fp + SCM_PROGRAM_NARGS (SCM_VM_FRAME_PROGRAM (fp)) \
+ SCM_PROGRAM_NLOCS (SCM_VM_FRAME_PROGRAM (fp)))
#define SCM_VM_FRAME_UPPER_ADDRESS(fp) \
(SCM_VM_FRAME_DATA_ADDRESS (fp) + 3)
#define SCM_VM_FRAME_LOWER_ADDRESS(fp) (fp - 1)
#define SCM_VM_FRAME_RETURN_ADDRESS(fp) SCM_VM_FRAME_DATA_ADDRESS (fp)[2]
#define SCM_VM_FRAME_DYNAMIC_LINK(fp) SCM_VM_FRAME_DATA_ADDRESS (fp)[1]
#define SCM_VM_FRAME_EXTERNAL_LINK(fp) SCM_VM_FRAME_DATA_ADDRESS (fp)[0]
#define SCM_VM_FRAME_VARIABLE(fp,i) fp[i]
#define SCM_VM_FRAME_PROGRAM(fp) fp[-1]
/*
* VM Heap frame
*/
struct scm_vm_heap_frame {
SCM *fp;
SCM program;
SCM variables;
SCM dynamic_link;
SCM external_link;
};
extern scm_bits_t scm_tc16_vm_heap_frame;
#define SCM_VM_HEAP_FRAME_P(x) SCM_SMOB_PREDICATE (scm_tc16_vm_heap_frame, x)
#define SCM_VM_HEAP_FRAME_DATA(f) ((struct scm_vm_heap_frame *) SCM_SMOB_DATA (f))
#define SCM_VALIDATE_VM_HEAP_FRAME(p,x) SCM_MAKE_VALIDATE (p, x, VM_HEAP_FRAME_P)
#define SCM_VM_HEAP_FRAME_PROGRAM(f) SCM_VM_HEAP_FRAME_DATA (f)->program
#define SCM_VM_HEAP_FRAME_VARIABLES(f) SCM_VM_HEAP_FRAME_DATA (f)->variables
#define SCM_VM_HEAP_FRAME_DYNAMIC_LINK(f) SCM_VM_HEAP_FRAME_DATA (f)->dynamic_link
#define SCM_VM_HEAP_FRAME_EXTERNAL_LINK(f) SCM_VM_HEAP_FRAME_DATA (f)->external_link
/*
* VM
*/
#define SCM_VM_BOOT_HOOK 0 #define SCM_VM_BOOT_HOOK 0
#define SCM_VM_HALT_HOOK 1 #define SCM_VM_HALT_HOOK 1
@ -133,6 +63,7 @@ struct scm_vm {
SCM *stack_limit; /* stack limit address */ SCM *stack_limit; /* stack limit address */
SCM hooks[SCM_VM_NUM_HOOKS]; /* hooks */ SCM hooks[SCM_VM_NUM_HOOKS]; /* hooks */
SCM options; /* options */ SCM options; /* options */
SCM last_frame; /* last frame */
unsigned long time; /* time spent */ unsigned long time; /* time spent */
unsigned long clock; /* bogos clock */ unsigned long clock; /* bogos clock */
}; };

View file

@ -88,7 +88,7 @@ vm_run (SCM vm, SCM program, SCM args)
/* Boot program */ /* Boot program */
scm_byte_t bytes[3] = {scm_op_call, 0, scm_op_halt}; scm_byte_t bytes[3] = {scm_op_call, 0, scm_op_halt};
bytes[1] = scm_ilength (args); bytes[1] = scm_ilength (args); /* FIXME: argument overflow */
program = scm_c_make_program (bytes, 3, SCM_BOOL_T); program = scm_c_make_program (bytes, 3, SCM_BOOL_T);
/* Initial frame */ /* Initial frame */
@ -167,10 +167,8 @@ vm_run (SCM vm, SCM program, SCM args)
vm_error: vm_error:
SYNC_ALL (); SYNC_ALL ();
scm_ithrow (sym_vm_error, vp->last_frame = scm_vm_current_frame (vm);
SCM_LIST4 (sym_vm_run, err_msg, err_args, scm_ithrow (sym_vm_error, SCM_LIST3 (sym_vm_run, err_msg, err_args), 1);
scm_vm_current_frame (vm)),
1);
} }
abort (); /* never reached */ abort (); /* never reached */

View file

@ -286,7 +286,7 @@ do { \
} \ } \
} }
/* See vm.h for the layout of stack frames */ /* See frames.h for the layout of stack frames */
#define NEW_FRAME() \ #define NEW_FRAME() \
{ \ { \

View file

@ -109,18 +109,27 @@ VM_DEFINE_LOADER (load_program, "load-program")
{ {
size_t len; size_t len;
SCM prog, x; SCM prog, x;
struct scm_program *p;
FETCH_LENGTH (len); FETCH_LENGTH (len);
prog = scm_c_make_program (ip, len, program); prog = scm_c_make_program (ip, len, program);
p = SCM_PROGRAM_DATA (prog);
ip += len; ip += len;
POP (x);
/* init meta data */
if (SCM_CONSP (x))
{
p->meta = x;
POP (x);
}
/* init object table */ /* init object table */
x = *sp;
if (SCM_VECTORP (x)) if (SCM_VECTORP (x))
{ {
SCM_PROGRAM_OBJS (prog) = x; p->objs = x;
DROP (); POP (x);
x = *sp;
} }
/* init parameters */ /* init parameters */
@ -131,31 +140,31 @@ VM_DEFINE_LOADER (load_program, "load-program")
if (-128 <= i && i <= 127) if (-128 <= i && i <= 127)
{ {
/* 8-bit representation */ /* 8-bit representation */
SCM_PROGRAM_NARGS (prog) = (i >> 6) & 0x03; /* 7-6 bits */ p->nargs = (i >> 6) & 0x03; /* 7-6 bits */
SCM_PROGRAM_NREST (prog) = (i >> 5) & 0x01; /* 5 bit */ p->nrest = (i >> 5) & 0x01; /* 5 bit */
SCM_PROGRAM_NLOCS (prog) = (i >> 2) & 0x07; /* 4-2 bits */ p->nlocs = (i >> 2) & 0x07; /* 4-2 bits */
SCM_PROGRAM_NEXTS (prog) = i & 0x03; /* 1-0 bits */ p->nexts = i & 0x03; /* 1-0 bits */
} }
else else
{ {
/* 16-bit representation */ /* 16-bit representation */
SCM_PROGRAM_NARGS (prog) = (i >> 12) & 0x07; /* 15-12 bits */ p->nargs = (i >> 12) & 0x07; /* 15-12 bits */
SCM_PROGRAM_NREST (prog) = (i >> 11) & 0x01; /* 11 bit */ p->nrest = (i >> 11) & 0x01; /* 11 bit */
SCM_PROGRAM_NLOCS (prog) = (i >> 4) & 0x7f; /* 10-04 bits */ p->nlocs = (i >> 4) & 0x7f; /* 10-04 bits */
SCM_PROGRAM_NEXTS (prog) = i & 0x0f; /* 03-00 bits */ p->nexts = i & 0x0f; /* 03-00 bits */
} }
} }
else else
{ {
/* Other cases */ /* Other cases */
sp -= 4; sp -= 4;
SCM_PROGRAM_NARGS (prog) = SCM_INUM (sp[1]); p->nargs = SCM_INUM (sp[0]);
SCM_PROGRAM_NREST (prog) = SCM_INUM (sp[2]); p->nrest = SCM_INUM (sp[1]);
SCM_PROGRAM_NLOCS (prog) = SCM_INUM (sp[3]); p->nlocs = SCM_INUM (sp[2]);
SCM_PROGRAM_NEXTS (prog) = SCM_INUM (sp[4]); p->nexts = SCM_INUM (sp[3]);
} }
*sp = prog; PUSH (prog);
NEXT; NEXT;
} }

View file

@ -187,8 +187,8 @@ VM_DEFINE_INSTRUCTION (list_break, "list-break", 0, 0, 0)
#define OBJECT_REF(i) objects[i] #define OBJECT_REF(i) objects[i]
#define OBJECT_SET(i,o) objects[i] = o #define OBJECT_SET(i,o) objects[i] = o
#define LOCAL_REF(i) SCM_VM_FRAME_VARIABLE (fp, i) #define LOCAL_REF(i) SCM_STACK_FRAME_VARIABLE (fp, i)
#define LOCAL_SET(i,o) SCM_VM_FRAME_VARIABLE (fp, i) = o #define LOCAL_SET(i,o) SCM_STACK_FRAME_VARIABLE (fp, i) = o
#define VARIABLE_REF(v) SCM_CDR (v) #define VARIABLE_REF(v) SCM_CDR (v)
#define VARIABLE_SET(v,o) SCM_SETCDR (v, o) #define VARIABLE_SET(v,o) SCM_SETCDR (v, o)
@ -379,7 +379,7 @@ VM_DEFINE_INSTRUCTION (call, "call", 1, -1, 1)
EXIT_HOOK (); EXIT_HOOK ();
reinstate_vm_cont (vp, x); reinstate_vm_cont (vp, x);
CACHE_REGISTER (); CACHE_REGISTER ();
program = SCM_VM_FRAME_PROGRAM (fp); program = SCM_STACK_FRAME_PROGRAM (fp);
CACHE_PROGRAM (); CACHE_PROGRAM ();
NEXT; NEXT;
} }
@ -496,7 +496,7 @@ VM_DEFINE_INSTRUCTION (return, "return", 0, 0, 1)
FREE_FRAME (); FREE_FRAME ();
/* Restore the last program */ /* Restore the last program */
program = SCM_VM_FRAME_PROGRAM (fp); program = SCM_STACK_FRAME_PROGRAM (fp);
CACHE_PROGRAM (); CACHE_PROGRAM ();
external = fp[bp->nargs + bp->nlocs]; external = fp[bp->nargs + bp->nlocs];
PUSH (ret); PUSH (ret);