diff --git a/vm/.cvsignore b/vm/.cvsignore deleted file mode 100644 index 78ae5f382..000000000 --- a/vm/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -.cvsignore -Makefile -Makefile.in diff --git a/vm/Makefile.am b/vm/Makefile.am deleted file mode 100644 index 91d1b37cd..000000000 --- a/vm/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ -vmdatadir = $(datadir)/guile/vm -vmdata_DATA = utils.scm types.scm bytecomp.scm compile.scm shell.scm -noinst_DATA = libvm.so - -EXTRA_DIST = $(vmdata_DATA) -CLEANFILES = $(noinst_DATA) -MAINTAINERCLEANFILES = Makefile.in - -libvm.so: - $(LN_S) -f ../src/.libs/libguilevm.so ./libvm.so - -install-data-local: - rm -f $(vmdatadir)/libvm.so \ - && $(LN_S) $(libdir)/libguilevm.so $(vmdatadir)/libvm.so diff --git a/vm/bytecomp.scm b/vm/bytecomp.scm deleted file mode 100644 index 81bf6ec37..000000000 --- a/vm/bytecomp.scm +++ /dev/null @@ -1,496 +0,0 @@ -;;; bytecomp.scm --- convert an intermediate code to an assemble code - -;; Copyright (C) 2000 Free Software Foundation, Inc. - -;; This file is part of Guile VM. - -;; Guile VM 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. -;; -;; Guile VM 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 Guile VM; 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 (vm bytecomp) - :use-module (vm vm) - :use-module (vm utils) - :use-module (vm types) - :export (byte-compile)) - -(define (byte-compile nreqs restp code) - (vector (byte-header nreqs restp (code-env code)) - (byte-finalize (byte-optimize (byte-translate code))))) - - -;;; -;;; Bytecode header -;;; - -(define (byte-header nreqs restp env) - (list->vector (cons* nreqs restp (env-header env)))) - - -;;; -;;; Bytecode translation -;;; - -(define (byte-translate code) - (let ((stack '())) - ;; push opcode - (define (push-code! . args) - (set! stack (cons args stack))) - (let trans ((code code) (use-stack #f) (tail #t)) - (let ((tag (code-tag code)) - (env (code-env code)) - (args (code-args code))) - ;;; - ;;; Utilities - ;;; - ;; push the result into the stack - (define (trans-use-stack code) (trans code #t #f)) - ;; just set the accumulator - (define (trans-non-stack code) (trans code #f #f)) - ;; code can be a tail position - (define (trans-tail code) (trans code #f tail)) - ;; set unspecified when a tail position - (define (unspecified-position) (if tail (push-code! '%load-unspecified))) - ;; return here when a tail position - (define (return-position) (if tail (push-code! '%return))) - ;; push the result into the stack - (define (push-position) (if use-stack (push-code! '%push))) - ;; return or push - (define (return-or-push) (return-position) (push-position)) - - ;;; - ;;; Translators - ;;; - (define (translate-unspecified) - ;; #:unspecified - ;; %load-unspecified - (push-code! '%load-unspecified) - (return-or-push)) - - (define (translate-constant obj) - ;; #:constant OBJ - ;; %pushc OBJ (if use-stack) - ;; %loadc OBJ (if non-stack) - (if use-stack - (push-code! '%pushc obj) - (push-code! '%loadc obj)) - (return-position)) - - (define (translate-local-var name var) - (let* ((offset (env-variable-address env var)) - (abbrev (string->symbol (format #f "~A:~A" name offset)))) - (if (instruction-name? abbrev) - (push-code! abbrev) - (push-code! name offset)))) - - (define (translate-external-var name var) - (let* ((addr (env-variable-address env var)) - (depth (car addr)) - (offset (cdr addr)) - (abbrev1 (string->symbol - (format #f "~A:~A" name depth))) - (abbrev2 (string->symbol - (format #f "~A:~A:~A" name depth offset)))) - (cond ((instruction-name? abbrev2) (push-code! abbrev2)) - ((instruction-name? abbrev1) (push-code! abbrev1 offset)) - (else (push-code! name addr))))) - - (define (translate-top-level-var name var) - (push-code! name (variable-name var))) - - (define (translate-ref var) - (assert variable? var) - (cond - ((local-variable? var) - ;; #:ref # - ;; %pushl OFFSET (if use-stack) - ;; %loadl OFFSET (if non-stack) - (translate-local-var (if use-stack '%pushl '%loadl) var)) - ((external-variable? var) - ;; #:ref # - ;; %pushe (DEPTH . OFFSET) (if use-stack) - ;; %loade (DEPTH . OFFSET) (if non-stack) - (translate-external-var (if use-stack '%pushe '%loade) var)) - ((top-level-variable? var) - ;; #:ref # - ;; %pusht SYMBOL (if use-stack) - ;; %loadt SYMBOL (if non-stack) - (translate-top-level-var (if use-stack '%pusht '%loadt) var))) - (return-position)) - - (define (translate-set var obj) - (assert variable? var) - (trans-non-stack obj) - (cond - ((local-variable? var) - ;; #:set # OBJ - ;; OBJ - ;; %savel OFFSET - ;; %name NAME - (translate-local-var '%savel var)) - ((external-variable? var) - ;; #:set # OBJ - ;; OBJ - ;; %savee (DEPTH . OFFSET) - ;; %name NAME - (translate-external-var '%savee var)) - ((top-level-variable? var) - ;; #:set # OBJ - ;; OBJ - ;; %savet SYMBOL - ;; %name NAME - (translate-top-level-var '%savet var))) - ;; FIXME: Giving name to every objects is bad, but - ;; FIXME: this is useful for debugging. - (push-code! '%name (variable-name var)) - (unspecified-position) - (return-or-push)) - - (define (translate-and . args) - ;; #:and ARG1 ARG2... LAST - ;; ARG1 - ;; %br-if-not L0 - ;; ARG2 - ;; %br-if-not L0 - ;; ... - ;; LAST - ;; L0: - (assert-for-each code? args) - (let* ((list (reverse args)) - (last (car list)) - (args (reverse! (cdr list)))) - (let ((L0 (make-label))) - (for-each (lambda (arg) - (trans-non-stack arg) - (push-code! '%br-if-not L0)) - args) - (trans-tail last) - (push-code! #:label L0))) - (return-or-push)) - - (define (translate-or . args) - ;; #:or ARG1 ARG2... LAST - ;; ARG1 - ;; %br-if L0 - ;; ARG2 - ;; %br-if L0 - ;; ... - ;; LAST - ;; L0: - (assert-for-each code? args) - (let* ((list (reverse args)) - (last (car list)) - (args (reverse! (cdr list)))) - (let ((L0 (make-label))) - (for-each (lambda (arg) - (trans-non-stack arg) - (push-code! '%br-if L0)) - args) - (trans-tail last) - (push-code! #:label L0))) - (return-or-push)) - - (define (translate-program nreqs restp code) - ;; #:make-program NREQS RESTP CODE - ;; %make-program BYTECODE - (push-code! '%make-program (byte-compile nreqs restp code)) - (return-or-push)) - - (define (translate-label label) - ;; #:label is processed by byte-finalize - (assert label? label) - (push-code! #:label label)) - - (define (translate-goto label) - ;; #:goto LABEL - ;; %jump ADDR (calculated in byte-finalize) - (assert label? label) - (push-code! '%jump label)) - - (define (translate-if test then else) - ;; #:if TEST THEN ELSE - ;; TEST - ;; %br-if-not L1 - ;; THEN (tail position) - ;; %jump L2 (if not tail) - ;; L1: ELSE (tail position) - ;; L2: - (assert code? test) - (assert code? then) - (assert code? else) - (let ((L1 (make-label)) - (L2 (make-label))) - (trans-non-stack test) - (push-code! '%br-if-not L1) - (trans-tail then) - (if (not tail) - (push-code! '%jump L2)) - (push-code! #:label L1) - (trans-tail else) - (push-code! #:label L2)) - (push-position)) - - (define (translate-until test . body) - ;; #:until TEST BODY... - ;; L0: TEST - ;; %br-if L1 - ;; BODY... - ;; %jump L0 - ;; L1: - (assert code? test) - (assert-for-each code? body) - (let ((L0 (make-label)) - (L1 (make-label))) - (push-code! #:label L0) - (trans-non-stack test) - (push-code! '%br-if L1) - (for-each trans-non-stack body) - (push-code! '%jump L0) - (push-code! #:label L1)) - (unspecified-position) - (return-position)) - - (define (translate-begin . body) - ;; #:begin BODY... TAIL - ;; BODY... - ;; TAIL (tail position) - (assert-for-each code? body) - (let* ((list (reverse body)) - (tail (car list)) - (body (reverse! (cdr list)))) - (for-each trans-non-stack body) - (trans-tail tail)) - (push-position)) - - (define (translate-regular-call code . args) - ;; #:call CODE ARGS... - ;; ARGS... (-> stack) - ;; CODE - ;; %(tail-)call NARGS - (let ((nargs (length args))) - (for-each trans-use-stack args) - (trans-non-stack code) - (if tail - (push-code! '%tail-call nargs) - (push-code! '%call nargs))) - (push-position)) - - (define (translate-function-call inst . args) - ;; #:call INST ARGS... - (let ((name (instruction-name inst)) - (nargs (length args))) - (cond - ((cadr (instruction-arity inst)) - ;; ARGS... (-> stack) - ;; INST NARGS - (for-each trans-use-stack args) - (push-code! name nargs)) - (else - (case nargs - ((0) - ;; INST - (push-code! name)) - ((1) - ;; ARG1 - ;; INST - (trans-non-stack (car args)) - (push-code! name)) - ((2) - ;; ARG1 (-> stack) - ;; ARG2 - ;; INST - (trans-use-stack (car args)) - (trans-non-stack (cadr args)) - (push-code! name)) - ((3) - ;; ARG1 (-> stack) - ;; ARG2 (-> stack) - ;; ARG3 - ;; INST - (trans-use-stack (car args)) - (trans-use-stack (cadr args)) - (trans-non-stack (caddr args)) - (push-code! name)))))) - (return-or-push)) - - (define (translate-call obj . args) - (assert-for-each code? args) - (if (variable? obj) - (if (eq? (variable-type obj) 'function) - (cond - ((and (variable-bound? obj) - (and-let* ((obj (variable-value obj)) - (def (assq-ref *vm-function-table* obj))) - (or (list-ref def (min (length args) 4)) - (error "Wrong number of arguments")))) - => (lambda (inst) - (apply translate-function-call inst args))) - ((top-level-variable? obj) - (apply translate-regular-call - (make-code #:ref env obj) args))) - (apply translate-regular-call - (make-code #:ref env obj) args)) - (apply translate-regular-call obj args))) - - ;;; - ;;; Dispatch - ;;; - (case tag - ((#:unspecified) - ;; #:unspecified - (check-nargs args = 0) - (translate-unspecified)) - ((#:constant) - ;; #:constant OBJ - (check-nargs args = 1) - (translate-constant (car args))) - ((#:ref) - ;; #:ref VAR - (check-nargs args = 1) - (translate-ref (car args))) - ((#:set) - ;; #:set VAR OBJ - (check-nargs args = 2) - (translate-set (car args) (cadr args))) - ((#:and) - ;; #:and ARGS... - (apply translate-and args)) - ((#:or) - ;; #:or ARGS... - (apply translate-or args)) - ((#:make-program) - ;; #:make-program NREQS RESTP CODE - (check-nargs args = 3) - (translate-program (car args) (cadr args) (caddr args))) - ((#:label) - ;; #:label LABEL - (check-nargs args = 1) - (translate-label (car args))) - ((#:goto) - ;; #:goto LABEL - (check-nargs args = 1) - (translate-goto (car args))) - ((#:if) - ;; #:if TEST THEN ELSE - (check-nargs args = 3) - (translate-if (car args) (cadr args) (caddr args))) - ((#:until) - ;; #:until TEST BODY... - (check-nargs args >= 2) - (apply translate-until (car args) (cdr args))) - ((#:begin) - ;; #:begin BODY... - (check-nargs args >= 1) - (apply translate-begin args)) - ((#:call) - ;; #:call OBJ ARGS... - (check-nargs args >= 1) - (apply translate-call (car args) (cdr args))) - (else - (error "Unknown tag:" tag))))) - ;; that's it for this stage - (reverse! stack))) - - -;;; -;;; Bytecode optimization -;;; - -(define (byte-optimize code) - (let loop ((last (car code)) (code (cdr code)) (result '())) - (define (continue) (loop (car code) (cdr code) (cons last result))) - (if (null? code) - (reverse! (cons last result)) - (let ((this (car code))) - (case (car this) - ((%br-if) - (case (car last) - ((null?) - (loop (cons '%br-if-null (cdr this)) (cdr code) result)) - (else - (continue)))) - ((%br-if-not) - (case (car last) - ((null?) - (loop (cons '%br-if-not-null (cdr this)) (cdr code) result)) - (else - (continue)))) - (else - (continue))))))) - - -;;; -;;; Bytecode finalization -;;; - -(define (byte-finalize code) - (let loop ((code code) (result '())) - (cond - ((null? code) - ;; Return the final assemble code - (let ((finalize (lambda (obj) - (if (label? obj) - (label-position obj) - obj)))) - (list->vector (reverse! (map finalize result))))) - ((eq? (caar code) #:label) - ;; Calculate the label position - (set! (label-position (cadar code)) (length result)) - (loop (cdr code) result)) - (else - ;; Append to the result - (loop (cdr code) (append! (reverse! (car code)) result)))))) - - -;;; -;;; Function table -;;; - -(define (functional-instruction-alist) - (let ((alist '())) - (define (add! name inst) - (let ((pair (assq name alist))) - (if pair - (set-cdr! pair (cons inst (cdr pair))) - (set! alist (acons name (list inst) alist))))) - (for-each (lambda (inst) - (and-let* ((name (instruction-scheme-name inst))) - (add! name inst))) - (instruction-list)) - alist)) - -(define (build-table-data pair) - (let ((name (car pair)) (insts (cdr pair))) - (let ((vec (make-vector 5 #f))) - (define (build-data! inst) - (let ((arity (instruction-arity inst))) - (let ((nargs (car arity)) - (restp (cadr arity))) - (if restp - (do ((i nargs (1+ i))) - ((>= i 4) - (vector-set! vec 4 inst)) - (if (not (vector-ref vec i)) - (vector-set! vec i inst))) - (vector-set! vec nargs inst))))) - (for-each build-data! insts) - (let ((func (eval name (interaction-environment)))) - (cons func (vector->list vec)))))) - -(define *vm-function-table* - (map build-table-data (functional-instruction-alist))) - -;;; bytecomp.scm ends here diff --git a/vm/compile.scm b/vm/compile.scm deleted file mode 100644 index cc7bc07cc..000000000 --- a/vm/compile.scm +++ /dev/null @@ -1,311 +0,0 @@ -;;; compile.scm --- Compile Scheme codes - -;; Copyright (C) 2000 Free Software Foundation, Inc. - -;; This file is part of Guile VM. - -;; Guile VM 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. -;; -;; Guile VM 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 Guile VM; 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 (vm compile) - :use-module (vm vm) - :use-module (vm utils) - :use-module (vm types) - :use-module (vm bytecomp) - :use-module (ice-9 syncase) - :export (compile compile-file)) - -(define (compile form . opts) - (catch 'result - (lambda () - (let ((x (syncase form))) - (if (or (memq #:e opts) (memq #:expand-only opts)) - (throw 'result x)) - (set! x (parse x (make-env '() (make-top-level-env)))) - (if (or (memq #:p opts) (memq #:parse-only opts)) - (throw 'result x)) - (set! x (byte-compile 0 #f x)) - (if (or (memq #:c opts) (memq #:compile-only opts)) - (throw 'result x)) - (make-program (make-bytecode x) #f))) - (lambda (key arg) arg))) - -(define (compile-file file) - (let ((out-file (string-append (substring file 0 (1- (string-length file))) - "c"))) - (with-input-from-file file - (lambda () - (with-output-to-file out-file - (lambda () - (format #t ";;; Compiled from ~A\n\n" file) - (display "(use-modules (vm vm))\n\n") - (display "(let ((vm (make-vm)))\n") - (display "(define (vm-exec code)") - (display "(vm-run vm (make-program (make-bytecode code) #f)))\n") - (do ((input (read) (read))) - ((eof-object? input)) - (display "(vm-exec ") - (write (compile input #:compile-only)) - (display ")\n")) - (display ")\n"))))))) - - -;;; -;;; Parser -;;; - -(define (parse x env) - (cond ((pair? x) (parse-pair x env)) - ((symbol? x) (make-code:ref env (env-ref env x))) - (else (make-code:constant env x)))) - -(define (parse-pair x env) - (let ((name (car x)) (args (cdr x))) - (if (assq name *syntax-alist*) - ;; syntax - ((assq-ref *syntax-alist* name) args env) - ;; procedure - (let ((proc (if (symbol? name) - (env-ref env name) - (parse name env)))) - (if (and (variable? proc) - (variable-bound? proc) - (assq (variable-value proc) *procedure-alist*)) - ;; procedure macro - ((assq-ref *procedure-alist* (variable-value proc)) args env) - ;; procedure call - (apply make-code:call env proc (map-parse args env))))))) - -(define (map-parse x env) - (map (lambda (x) (parse x env)) x)) - - -;;; -;;; Syntax -;;; - -(define *syntax-list* - '(quote lambda set! define if cond and or begin let let* letrec - local-set! until)) - -(define (parse-quote args env) - (make-code:constant env (car args))) - -(define (canon-formals formals) - ;; foo -> (), foo - ;; (foo bar baz) -> (foo bar baz), #f - ;; (foo bar . baz) -> (foo bar), baz - (cond ((symbol? formals) - (values '() formals)) - ((or (null? formals) - (null? (cdr (last-pair formals)))) - (values formals #f)) - (else - (let* ((copy (list-copy formals)) - (pair (last-pair copy)) - (last (cdr pair))) - (set-cdr! pair '()) - (values copy last))))) - -(define (parse-lambda args env) - (let ((formals (car args)) (body (cdr args))) - (call-with-values (lambda () (canon-formals formals)) - (lambda (reqs rest) - (let* ((syms (append reqs (if rest (list rest) '()))) - (new-env (make-env syms env))) - (make-code:program env (length reqs) (if rest #t #f) - (parse-begin body new-env))))))) - -(define (parse-set! args env) - (let ((var (env-ref env (car args))) - (val (parse (cadr args) env))) - (variable-externalize! var) - (make-code:set env var val))) - -(define (parse-local-set! args env) - (let ((var (env-ref env (car args))) - (val (parse (cadr args) env))) - (make-code:set env var val))) - -(define (parse-define args env) - (parse-set! args env)) - -(define (parse-if args env) - (let ((test (parse (car args) env)) - (consequent (parse (cadr args) env)) - (alternate (if (null? (cddr args)) - (make-code:unspecified env) - (parse (caddr args) env)))) - (make-code:if env test consequent alternate))) - -;; FIXME: This should be expanded by syncase. -(define (parse-cond args env) - (cond ((null? args) (make-code:unspecified env)) - ((eq? (caar args) 'else) - (parse-begin (cdar args) env)) - (else - (let* ((clause (car args)) - (test (parse (car clause) env)) - (body (parse-begin (cdr clause) env)) - (alternate (parse-cond (cdr args) env))) - (make-code:if env test body alternate))))) - -(define (parse-and args env) - (apply make-code:and env (map-parse args env))) - -(define (parse-or args env) - (apply make-code:or env (map-parse args env))) - -(define (parse-begin args env) - (apply make-code:begin env (map-parse args env))) - -(define (%parse-let:finish env bindings init body) - (for-each (lambda (binding) - (env-remove-variable! env (car binding))) - bindings) - (apply make-code:begin env (append! init body))) - -(define (parse-let args env) - (if (symbol? (car args)) - ;; named let - (let ((tag (car args)) (bindings (cadr args)) (body (cddr args))) - (let* ((var (env-add-variable! env tag)) - (proc (parse-lambda (cons (map car bindings) body) env)) - (init (make-code:set env var proc)) - (call (apply make-code:call env var - (map-parse (map cadr bindings) env)))) - (env-remove-variable! env tag) - (make-code:begin env init call))) - ;; normal let - (let ((bindings (car args)) (body (cdr args))) - (let* (;; create values before binding - (vals (map-parse (map cadr bindings) env)) - ;; create bindings - (init (map (lambda (sym val) - (let ((var (env-add-variable! env sym))) - (make-code:set env var val))) - (map car bindings) vals))) - (%parse-let:finish env bindings init (map-parse body env)))))) - -(define (parse-let* args env) - (let ((bindings (car args)) (body (cdr args))) - (let (;; create values and bindings one after another - (init (map (lambda (binding) - (let* ((val (parse (cadr binding) env)) - (var (env-add-variable! env (car binding)))) - (make-code:set env var val))) - bindings))) - (%parse-let:finish env bindings init (map-parse body env))))) - -(define (parse-letrec args env) - (let ((bindings (car args)) (body (cdr args))) - (let* (;; create all variables before values - (vars (map (lambda (sym) - (env-add-variable! env sym)) - (map car bindings))) - ;; create and set values - (init (map (lambda (var val) - (make-code:set env var (parse val env))) - vars (map cadr bindings)))) - (%parse-let:finish env bindings init (map-parse body env))))) - -(define (parse-until args env) - (apply make-code:until env (parse (car args) env) - (map-parse (cdr args) env))) - -(define *syntax-alist* - (map (lambda (name) - (cons name (eval (symbol-append 'parse- name) (current-module)))) - *syntax-list*)) - - -;;; -;;; Procedure -;;; - -(define *procedure-list* - '(caar cadr cdar cddr caaar caadr cadar caddr cdaar cdadr cddar cdddr - caaaar caaadr caadar caaddr cadaar cadadr caddar cadddr - cdaaar cdaadr cdadar cdaddr cddaar cddadr cdddar cddddr - ;;map for-each - )) - -(define (parse-caar args env) (parse `(car (car ,@args)) env)) -(define (parse-cadr args env) (parse `(car (cdr ,@args)) env)) -(define (parse-cdar args env) (parse `(cdr (car ,@args)) env)) -(define (parse-cddr args env) (parse `(cdr (cdr ,@args)) env)) - -(define (parse-caaar args env) (parse `(car (car (car ,@args))) env)) -(define (parse-caadr args env) (parse `(car (car (cdr ,@args))) env)) -(define (parse-cadar args env) (parse `(car (cdr (car ,@args))) env)) -(define (parse-caddr args env) (parse `(car (cdr (cdr ,@args))) env)) -(define (parse-cdaar args env) (parse `(cdr (car (car ,@args))) env)) -(define (parse-cdadr args env) (parse `(cdr (car (cdr ,@args))) env)) -(define (parse-cddar args env) (parse `(cdr (cdr (car ,@args))) env)) -(define (parse-cdddr args env) (parse `(cdr (cdr (cdr ,@args))) env)) - -(define (parse-caaaar args env) (parse `(car (car (car (car ,@args)))) env)) -(define (parse-caaadr args env) (parse `(car (car (car (cdr ,@args)))) env)) -(define (parse-caadar args env) (parse `(car (car (cdr (car ,@args)))) env)) -(define (parse-caaddr args env) (parse `(car (car (cdr (cdr ,@args)))) env)) -(define (parse-cadaar args env) (parse `(car (cdr (car (car ,@args)))) env)) -(define (parse-cadadr args env) (parse `(car (cdr (car (cdr ,@args)))) env)) -(define (parse-caddar args env) (parse `(car (cdr (cdr (car ,@args)))) env)) -(define (parse-cadddr args env) (parse `(car (cdr (cdr (cdr ,@args)))) env)) -(define (parse-cdaaar args env) (parse `(cdr (car (car (car ,@args)))) env)) -(define (parse-cdaadr args env) (parse `(cdr (car (car (cdr ,@args)))) env)) -(define (parse-cdadar args env) (parse `(cdr (car (cdr (car ,@args)))) env)) -(define (parse-cdaddr args env) (parse `(cdr (car (cdr (cdr ,@args)))) env)) -(define (parse-cddaar args env) (parse `(cdr (cdr (car (car ,@args)))) env)) -(define (parse-cddadr args env) (parse `(cdr (cdr (car (cdr ,@args)))) env)) -(define (parse-cdddar args env) (parse `(cdr (cdr (cdr (car ,@args)))) env)) -(define (parse-cddddr args env) (parse `(cdr (cdr (cdr (cdr ,@args)))) env)) - -;(define (parse-map args env) -; (check-nargs args >= 2) -; (case (length args) -; ((2) -; (let ((proc (car args)) (list (cadr args))) -; (parse `(let ((list ,list) (result '())) -; (until (null? list) -; (local-set! result (cons (,proc (car list)) result)) -; (local-set! list (cdr list))) -; (reverse! result)) -; env))) -; (else -; (error "Not implemented yet")))) -; -;(define (parse-for-each args env) -; (check-nargs args >= 2) -; (case (length args) -; ((2) -; (let ((proc (car args)) (list (cadr args))) -; (parse `(let ((list ,list)) -; (until (null? list) -; (,proc (car list)) -; (local-set! list (cdr list)))) -; env))) -; (else -; (error "Not implemented yet")))) - -(define *procedure-alist* - (map (lambda (name) - (cons (eval name (current-module)) - (eval (symbol-append 'parse- name) (current-module)))) - *procedure-list*)) - -;;; compile.scm ends here diff --git a/vm/shell.scm b/vm/shell.scm deleted file mode 100644 index d3c09fe47..000000000 --- a/vm/shell.scm +++ /dev/null @@ -1,221 +0,0 @@ -;;; shell.scm --- interactive VM operations - -;; Copyright (C) 2000 Free Software Foundation, Inc. - -;; This file is part of Guile VM. - -;; Guile VM 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. -;; -;; Guile VM 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 Guile VM; 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 (vm shell) - :use-module (vm vm) - :use-module (vm utils) - :use-module (vm compile) - :use-module (ice-9 format)) - -;;; -;;; VM Shell -;;; - -(define *vm-default-prompt* "VM> ") - -(define *vm-boot-message* "\ -Copyright (C) 2000 Free Software Foundation, Inc. -Guile VM is free software, covered by the GNU General Public License, -and you are welcome to change it and/or distribute copies of it under -certain conditions. There is absolutely no warranty for Guile VM.\n") - -(define (vm-init vm) - (vm-set-option! vm 'prompt *vm-default-prompt*) - (vm-set-option! vm 'verbose #f) - (vm-set-option! vm 'history-count 1)) - -(define-public (vm-boot vm) - (format #t "Guile Virtual Machine ~A\n" (vm-version)) - (display *vm-boot-message*) - (display "\nType \"help\" for information\n") - (vm-shell vm)) - -(define-public (vm-shell vm) - (vm-init vm) - (let ((read-expr (lambda () (read (current-input-port))))) - (let loop () - (display (or (vm-option vm 'prompt) *vm-default-prompt*)) - (let ((cmd (read-expr))) - (if (not (eof-object? cmd)) - (case cmd - ((eval) (vm-eval vm (read-expr)) (loop)) - ((trace) (vm-trace vm (read-expr)) (loop)) - ((parse) (vm-parse vm (read-expr)) (loop)) - ((compile) (vm-compile vm (read-expr)) (loop)) - ((set) (vm-set-option! vm (read-expr) (read-expr)) (loop)) - (else - (error "Unknown command: ~S" cmd)))))))) - -(define-public (vm-repl vm) - (vm-init vm) - (let loop () - (display (or (vm-option vm 'prompt) *vm-default-prompt*)) - (let ((form (read (current-input-port)))) - (if (not (eof-object? form)) - (begin - (vm-eval vm form) - (loop)))))) - -(define (vm-eval vm form) - (let ((result (vm-run vm (compile form)))) - (if (not (eq? result *unspecified*)) - (let* ((n (or (vm-option vm 'history-count) 1)) - (var (symbol-append "$" (number->string n)))) - (intern-symbol #f var) - (symbol-set! #f var result) - (format #t "~A = ~S\n" var result) - (vm-set-option! vm 'history-count (1+ n)) - result)))) - -(define (vm-parse vm form) - (parse form (make-top-level-env))) - -(define (vm-compile vm form) - #f) - - -;;; -;;; Step -;;; - -(define (vm-step-boot vm) - (format #t "VM: Starting a program ~S:~%" - (frame-program (vm-current-frame vm)))) - -(define (vm-step-halt vm) - (display "VM: Program terminated with the return value: ") - (display (vm:ac vm)) - (newline)) - -(define (vm-step-next vm) - (if (vm-option vm 'verbose) - (let ((frame (vm-current-frame vm))) - (display "--------------------------------------------------\n") - (format #t "PC = 0x~X SP = 0x~X FP = 0x~X AC = ~S~%" - (vm:pc vm) (vm:sp vm) (vm:fp vm) (vm:ac vm)) - (do ((frame frame (frame-dynamic-link frame)) - (frames '() (cons frame frames))) - ((not frame) - (for-each (lambda (frame) - (format #t "Frame = [~S 0x~X 0x~X]~%" - (frame-program frame) - (frame-stack-pointer frame) - (frame-return-address frame))) - frames))) - (format #t "Local variables = ~S~%" (frame-variables frame)) - (format #t "External variables = ~S~%" (frame-external-link frame)) - (format #t "Stack = ~S~%" (vm-stack->list vm)))) - (format #t "0x~X:" (vm:pc vm)) - (for-each (lambda (obj) (display " ") (write obj)) - (vm-fetch-code vm (vm:pc vm))) - (newline)) - -(define-public (vm-step vm form . opts) - (let ((debug-flag (vm-option vm 'debug))) - (dynamic-wind - (lambda () - (add-hook! (vm-boot-hook vm) vm-step-boot) - (add-hook! (vm-halt-hook vm) vm-step-halt) - (add-hook! (vm-next-hook vm) vm-step-next) - (vm-set-option! vm 'debug #t)) - (lambda () - (if (pair? opts) - (vm-set-option! vm 'verbose #t)) - (vm-run vm (compile form))) - (lambda () - (remove-hook! (vm-boot-hook vm) vm-step-boot) - (remove-hook! (vm-halt-hook vm) vm-step-halt) - (remove-hook! (vm-next-hook vm) vm-step-next) - (vm-set-option! vm 'debug debug-flag))))) - - -;;; -;;; Trace -;;; - -(define (vm-trace-prefix frame) - (and-let* ((link (frame-dynamic-link frame))) - (display "| ") - (vm-trace-prefix link))) - -(define (vm-frame->call frame) - (define (truncate! list n) - (let loop ((list list) (n n)) - (if (<= n 1) - (set-cdr! list '()) - (loop (cdr list) (1- n)))) - list) - (let* ((prog (frame-program frame)) - (name (or (name prog) prog))) - (cons name (reverse! (vector->list (frame-variables frame)))))) - -(define (vm-trace-apply vm) - (let ((frame (vm-current-frame vm))) - (vm-trace-prefix frame) - (display (vm-frame->call frame)) - (newline))) - -(define (vm-trace-return vm) - (vm-trace-prefix (vm-current-frame vm)) - (display (vm:ac vm)) - (newline)) - -(define-public (vm-trace vm form) - (let ((debug-flag (vm-option vm 'debug))) - (dynamic-wind - (lambda () - (add-hook! (vm-apply-hook vm) vm-trace-apply) - (add-hook! (vm-return-hook vm) vm-trace-return) - (vm-set-option! vm 'debug #t)) - (lambda () - (vm-run vm (compile form))) - (lambda () - (remove-hook! (vm-apply-hook vm) vm-trace-apply) - (remove-hook! (vm-return-hook vm) vm-trace-return) - (vm-set-option! vm 'debug debug-flag))))) - - -;;; -;;; Disassemble -;;; - -(define-public (disassemble program) - (format #t "Program at ~X:" (program-base program)) - (let ((subprogs '()) - (list (vector->list (bytecode-decode (program-code program))))) - (for-each (lambda (obj) - (cond ((opcode? obj) - (newline) - (display obj)) - ((program? obj) - (set! subprogs (cons subprogs obj)) - (display " ") - (display obj)) - (else - (display " ") - (display obj)))) - list) - (newline) - (for-each disassemble (reverse! subprogs)))) - -;;; shell.scm ends here diff --git a/vm/types.scm b/vm/types.scm deleted file mode 100644 index f0d4c60f6..000000000 --- a/vm/types.scm +++ /dev/null @@ -1,374 +0,0 @@ -;;; types.scm --- data types used in the compiler and assembler - -;; Copyright (C) 2000 Free Software Foundation, Inc. - -;; This file is part of Guile VM. - -;; Guile VM 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. -;; -;; Guile VM 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 Guile VM; 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 (vm types) - :use-module (vm vm) - :use-module (vm utils) - :use-module (oop goops)) - - -;;; -;;; VM code -;;; - -(define-class () - (tag #:accessor code-tag #:init-keyword #:tag) - (env #:accessor code-env #:init-keyword #:env) - (args #:accessor code-args #:init-keyword #:args) - (type #:accessor code-type #:init-value #f)) - -(export code-tag code-env code-args code-type) - -(define-method (write (obj ) port) - (display "#symbol (code-tag obj))) - (map (lambda (obj) (display " ") (write obj port)) - (code-args obj)) - (display ">")) - -(define-public (code? obj) - (is-a? obj )) - -(define-public (make-code tag env . args) - (assert keyword? tag) - (assert env? env) - (make #:tag tag #:env env #:args args)) - - -;;; -;;; VM label -;;; - -(define-class () - (pos #:accessor label-position)) - -(export label-position) - -(define-public (label? obj) - (is-a? obj )) - -(define-public (make-label) - (make )) - - -;;; -;;; VM location -;;; - -(define-class ()) - -(define (make-location) - (make )) - - -;;; -;;; VM variable -;;; - -(define-class () - (name #:accessor variable-name #:init-keyword #:name) - (type #:accessor variable-type #:init-value #f) - (value #:accessor variable-value) - (loc #:accessor variable-location #:init-keyword #:location) - (count #:accessor variable-count #:init-value 0)) - -(define-class ()) -(define-class ()) -(define-class ()) - -(export variable-name variable-type variable-value variable-count) - -(define-method (write (obj ) port) - (display "#") - (display (class-name (class-of obj))) - (display " ") - (display (variable-name obj)) - (display ">")) - -(define-public (make-local-variable name location) - (make #:name name #:location location)) - -(define-public (make-top-level-variable name) - (make #:name name)) - -(define-public (variable? obj) - (is-a? obj )) - -(define-public (local-variable? obj) - (is-a? obj )) - -(define-public (external-variable? obj) - (is-a? obj )) - -(define-public (top-level-variable? obj) - (is-a? obj )) - -(define-public (variable-bound? var) - (assert variable? var) - (slot-bound? var 'value)) - -(define-public (variable-externalize! var) - (assert variable? var) - (if (local-variable? var) - (change-class var ))) - - -;;; -;;; VM environment -;;; - -(define-class () - (space #:accessor env-name-space #:init-value '()) - (args #:accessor env-arguments #:init-keyword #:args) - (vars #:accessor env-variables #:init-value '()) - (locs #:accessor env-locations #:init-value '()) - (exts #:accessor env-externals #:init-value #f) - (link #:accessor env-external-link #:init-keyword #:link)) - -(define-public (make-env syms link) - (let* ((syms (reverse syms)) - (args (map (lambda (sym) - (make-local-variable sym (make-location))) - syms)) - (env (make #:args args #:link link))) - (for-each (lambda (sym var) - (set! (env-name-space env) - (acons sym var (env-name-space env)))) - syms args) - env)) - -(define-public (make-top-level-env) - (make-env '() #f)) - -(define-public (env? obj) (is-a? obj )) - -(define-public (top-level-env? obj) - (and (env? obj) (not (env-external-link obj)))) - -(define-public (env-finalized? env) - (if (env-externals env) #t #f)) - -(define-public (env-add-variable! env sym) - (assert env? env) - (assert symbol? sym) - (if (env-finalized? env) - (error "You may not add a variable after finalization")) - (let ((var (if (top-level-env? env) - (make-top-level-variable sym) - (let* ((locs (env-locations env)) - (loc (if (null? locs) - (make-location) - (begin - (set! (env-locations env) (cdr locs)) - (car locs))))) - (make-local-variable sym loc))))) - (set! (env-name-space env) (acons sym var (env-name-space env))) - (set! (env-variables env) (cons var (env-variables env))) - var)) - -(define-public (env-remove-variable! env sym) - (assert env? env) - (assert symbol? sym) - (if (env-finalized? env) - (error "You may not remove a variable after finalization")) - (let ((var (assq-ref (env-name-space env) sym))) - (if (not var) - (error "No such variable: ~A\n" sym)) - (if (local-variable? var) - (set! (env-locations env) - (cons (variable-location var) (env-locations env)))) - (set! (env-name-space env) - (delq! (assq sym (env-name-space env)) (env-name-space env))) - var)) - -;; Find a varialbe in the environment - -(define-public (env-ref env sym) - (assert env? env) - (assert symbol? sym) - (if (env-finalized? env) - (error "You may not find a variable after finalization")) - (or (env-local-ref env sym) - (env-external-ref env sym) - (env-top-level-ref env sym) - (error "No way!"))) - -(define (env-local-ref env sym) - (if (assq sym (env-name-space env)) - (let ((var (assq-ref (env-name-space env) sym))) - (set! (variable-count var) (1+ (variable-count var))) - var) - #f)) - -(define (env-external-ref env sym) - (let ((ext-env (env-external-link env))) - (if (not ext-env) - #f - (let ((var (env-local-ref ext-env sym))) - (if var - (begin - (variable-externalize! var) - var) - (env-external-ref ext-env sym)))))) - -(define (env-top-level-ref env sym) - (let ((var (make-top-level-variable sym))) - (if (defined? sym) - ;; Get the value in the top-level - (let ((obj (eval sym (interaction-environment)))) - (set! (variable-value var) obj) - (set! (variable-type var) - (cond ((macro? obj) 'macro) - ((program? obj) 'program) - ((procedure? obj) 'function) - (else #f))))) - var)) - -;; Finalization - -(define-public (env-finalize! env) - (if (not (env-finalized? env)) - (let ((locs (uniq! (map variable-location - (append (filter local-variable? - (env-variables env)) - (env-arguments env))))) - (exts (filter external-variable? - (append (env-variables env) (env-arguments env))))) - (set! (env-locations env) locs) - (set! (env-externals env) (reverse! exts))))) - -(define-public (env-header env) - (env-finalize! env) - (let ((nvars (length (uniq! (map variable-location - (filter local-variable? - (env-variables env)))))) - (nexts (length (env-externals env))) - (exts (list->vector - (map (lambda (var) - (env-local-variable-address env var)) - (filter external-variable? - (reverse (env-arguments env))))))) - (list nvars nexts exts))) - -(define (get-offset obj list) - (- (length list) (length (memq obj list)))) - -(define-public (env-variable-address env var) - (env-finalize! env) - (cond ((local-variable? var) - (env-local-variable-address env var)) - ((external-variable? var) - (env-external-variable-address env var)) - (else - (error "Wrong type argument: ~S" var)))) - -(define (env-local-variable-address env var) - (get-offset (variable-location var) (env-locations env))) - -(define (env-external-variable-address env var) - (let loop ((depth 0) (env env)) - (let ((list (env-externals env))) - (cond ((null? list) - (loop depth (env-external-link env))) - ((memq var list) - (cons depth (get-offset var list))) - (else (loop (1+ depth) (env-external-link env))))))) - - -;;; -;;; Intermediate codes -;;; - -(define-public (make-code:unspecified env) - (assert env? env) - (make-code #:unspecified env)) - -(define-public (make-code:constant env obj) - (assert env? env) - (make-code #:constant env obj)) - -(define-public (make-code:ref env var) - (assert env? env) - (assert variable? var) - (let ((code (make-code #:ref env var))) - (set! (code-type code) (variable-type var)) - code)) - -(define-public (make-code:set env var val) - (assert env? env) - (assert variable? var) - (assert code? val) - (let ((code (make-code #:set env var val))) - (set! (variable-type var) (code-type val)) - (set! (code-type code) (variable-type var)) - code)) - -(define-public (make-code:program env nreqs restp body) - (assert env? env) - (assert integer? nreqs) - (assert boolean? restp) - (assert code? body) - (let ((code (make-code #:make-program env nreqs restp body))) - (set! (code-type code) 'program) - code)) - -(define-public (make-code:call env proc . args) - (assert env? env) - (assert (lambda (x) (or (variable? x) (code? x))) proc) - (assert-for-each code? args) - (apply make-code #:call env proc args)) - -(define-public (make-code:if env test consequent alternate) - (assert env? env) - (assert code? test) - (assert code? consequent) - (assert code? alternate) - (let ((code (make-code #:if env test consequent alternate))) - (if (eq? (code-type consequent) (code-type alternate)) - (set! (code-type code) (code-type consequent))) - code)) - -(define-public (make-code:and env . args) - (assert env? env) - (assert-for-each code? args) - (apply make-code #:and env args)) - -(define-public (make-code:or env . args) - (assert env? env) - (assert-for-each code? args) - (apply make-code #:or env args)) - -(define-public (make-code:begin env . body) - (assert env? env) - (assert-for-each code? body) - (let ((code (apply make-code #:begin env body))) - (set! (code-type code) (code-type (last body))) - code)) - -(define-public (make-code:until env test . body) - (assert env? env) - (assert code? test) - (assert-for-each code? body) - (apply make-code #:until env test body)) - -;;; types.scm ends here diff --git a/vm/utils.scm b/vm/utils.scm deleted file mode 100644 index 4a43375a3..000000000 --- a/vm/utils.scm +++ /dev/null @@ -1,106 +0,0 @@ -;;; utils.scm --- - -;; Copyright (C) 2000 Free Software Foundation, Inc. - -;; This file is part of Guile VM. - -;; Guile VM 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. -;; -;; Guile VM 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 Guile VM; 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 (vm utils) - :use-module (ice-9 and-let*) - :use-module (ice-9 format)) - -(export and-let*) - -(define-public (assert predicate obj) - (if (not (predicate obj)) - (scm-error 'wrong-type-arg #f - "Wrong type argument: ~S, ~S" - (list (procedure-name predicate) obj) #f))) - -(define-public (assert-for-each predicate list) - (for-each (lambda (x) (assert predicate x)) list)) - -(define-public (check-nargs args pred n) - (if (not (pred (length args) n)) - (error "Too many or few arguments"))) - -(define-public (last list) - (car (last-pair list))) - -(define-public (rassq key alist) - (let loop ((alist alist)) - (cond ((null? alist) #f) - ((eq? key (cdar alist)) (car alist)) - (else (loop (cdr alist)))))) - -(define-public (rassq-ref alist key) - (let ((obj (rassq key alist))) - (if obj (car obj) #f))) - -(define-public (map-if pred func list) - (let loop ((list list) (result '())) - (if (null? list) - (reverse! result) - (if (pred (car list)) - (loop (cdr list) (cons (func (car list)) result)) - (loop (cdr list) result))))) - -(define-public (map-tree func tree) - (cond ((null? tree) '()) - ((pair? tree) - (cons (map-tree func (car tree)) (map-tree func (cdr tree)))) - (else (func tree)))) - -(define-public (filter pred list) - (let loop ((list list) (result '())) - (if (null? list) - (reverse! result) - (if (pred (car list)) - (loop (cdr list) (cons (car list) result)) - (loop (cdr list) result))))) - -(define-public (uniq! list) - (do ((rest list (begin (set-cdr! rest (delq! (car rest) (cdr rest))) - (cdr rest)))) - ((null? rest) list))) - -(define-public (finalize obj) - (if (promise? obj) (force obj) obj)) - -(export time) -(define-macro (time form) - `(let* ((gc-start (gc-run-time)) - (tms-start (times)) - (result ,form) - (tms-end (times)) - (gc-end (gc-run-time)) - (get (lambda (proc start end) - (/ (- (proc end) (proc start)) - internal-time-units-per-second)))) - (display "clock utime stime cutime cstime gc\n") - (format #t "~5a ~5a ~5a ~6a ~6a ~a~%" - (get tms:clock tms-start tms-end) - (get tms:utime tms-start tms-end) - (get tms:stime tms-start tms-end) - (get tms:cutime tms-start tms-end) - (get tms:cstime tms-start tms-end) - (get id gc-start gc-end)) - result)) - -;;; utils.scm ends here