mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-17 01:00:20 +02:00
*** empty log message ***
This commit is contained in:
parent
c722838216
commit
cb4cca12e7
23 changed files with 434 additions and 439 deletions
|
@ -1,8 +1,6 @@
|
||||||
misc
|
misc
|
||||||
libtool
|
libtool
|
||||||
config.log
|
config.*
|
||||||
config.cache
|
|
||||||
config.status
|
|
||||||
configure
|
configure
|
||||||
Makefile
|
Makefile
|
||||||
Makefile.in
|
Makefile.in
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
AC_INIT(src/guile-vm.c)
|
AC_INIT(src/guile-vm.c)
|
||||||
AM_INIT_AUTOMAKE(guile-vm, 0.4)
|
AM_INIT_AUTOMAKE(guile-vm, 0.5)
|
||||||
AM_CONFIG_HEADER(src/config.h)
|
AM_CONFIG_HEADER(src/config.h)
|
||||||
|
|
||||||
GUILE_FLAGS
|
GUILE_FLAGS
|
||||||
|
@ -12,4 +12,4 @@ 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)
|
AC_OUTPUT(Makefile src/Makefile doc/Makefile module/Makefile src/guilec)
|
||||||
|
|
|
@ -1,5 +1,13 @@
|
||||||
DISTDIRS = $(srcdir)/language $(srcdir)/system
|
DISTDIRS = $(srcdir)/language $(srcdir)/system $(srcdir)/slib
|
||||||
EXCLUDES = --exclude=CVS --exclude='*~'
|
EXCLUDES = --exclude=CVS --exclude='*~'
|
||||||
|
|
||||||
|
all: slibcat
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f slibcat slib/*.go
|
||||||
|
|
||||||
|
slibcat:
|
||||||
|
guile -s slib-comp.scm
|
||||||
|
|
||||||
dist-hook:
|
dist-hook:
|
||||||
$(TAR) cf - $(EXCLUDES) $(DISTDIRS) | (cd $(distdir); $(TAR) xf -)
|
$(TAR) cf - $(EXCLUDES) $(DISTDIRS) | (cd $(distdir); $(TAR) xf -)
|
||||||
|
|
48
module/system/base/compile.scm
Normal file
48
module/system/base/compile.scm
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
;;; High-level compiler interface
|
||||||
|
|
||||||
|
;; 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 base compile)
|
||||||
|
:use-module (system base language)
|
||||||
|
:use-module (ice-9 regex)
|
||||||
|
:export (compile-file object-file-name))
|
||||||
|
|
||||||
|
(define scheme (lookup-language 'scheme))
|
||||||
|
|
||||||
|
(define (compile-file file)
|
||||||
|
(let ((comp (object-file-name file)))
|
||||||
|
(call-with-compile-error-catch
|
||||||
|
(lambda ()
|
||||||
|
(catch #t
|
||||||
|
(lambda ()
|
||||||
|
(call-with-output-file comp
|
||||||
|
(lambda (port)
|
||||||
|
(uniform-array-write (compile-file-in file scheme) port))))
|
||||||
|
(lambda (key . args)
|
||||||
|
(format #t "ERROR: In ~A:\n" file)
|
||||||
|
(display "ERROR: ")
|
||||||
|
(format #t (cadr args) (caddr args))
|
||||||
|
(newline)
|
||||||
|
(delete-file comp)))))
|
||||||
|
(format #t "Wrote ~A\n" comp)))
|
||||||
|
|
||||||
|
(define (object-file-name file)
|
||||||
|
(let ((m (string-match "\\.[^.]*$" file)))
|
||||||
|
(string-append (if m (match:prefix m) file) ".go")))
|
|
@ -26,8 +26,8 @@
|
||||||
: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)
|
||||||
:export (define-language lookup-language
|
:export (define-language lookup-language read-in compile-in print-in
|
||||||
read-in compile-in print-in compile-file-in load-file-in))
|
compile-file-in))
|
||||||
|
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
|
@ -37,10 +37,11 @@
|
||||||
(define-vm-class <language> ()
|
(define-vm-class <language> ()
|
||||||
name title version environment
|
name title version environment
|
||||||
(reader)
|
(reader)
|
||||||
(expander (lambda (x) x))
|
(expander (lambda (x e) x))
|
||||||
(translator (lambda (x) x))
|
(translator (lambda (x e) x))
|
||||||
(evaler #f)
|
(evaluator #f)
|
||||||
(printer)
|
(printer)
|
||||||
|
(compiler)
|
||||||
)
|
)
|
||||||
|
|
||||||
(define-method (write (lang <language>) port)
|
(define-method (write (lang <language>) port)
|
||||||
|
@ -65,41 +66,34 @@
|
||||||
(define (read-in lang . port)
|
(define (read-in lang . port)
|
||||||
(lang.reader (if (null? port) (current-input-port) (car port))))
|
(lang.reader (if (null? port) (current-input-port) (car port))))
|
||||||
|
|
||||||
(define (compile-in form env lang . opts)
|
(define (compile-in x e lang . opts)
|
||||||
(catch 'result
|
(catch 'result
|
||||||
(lambda ()
|
(lambda ()
|
||||||
;; expand
|
;; expand
|
||||||
(set! form (lang.expander form))
|
(set! x (lang.expander x e))
|
||||||
(if (memq :e opts) (throw 'result form))
|
(if (memq :e opts) (throw 'result x))
|
||||||
;; translate
|
;; translate
|
||||||
(set! form (lang.translator form))
|
(set! x (lang.translator x e))
|
||||||
(if (memq :t opts) (throw 'result form))
|
(if (memq :t opts) (throw 'result x))
|
||||||
;; compile
|
;; compile
|
||||||
(set! form (apply compile form env opts))
|
(set! x (apply compile x e opts))
|
||||||
(if (memq :c opts) (throw 'result form))
|
(if (memq :c opts) (throw 'result x))
|
||||||
;; assemble
|
;; assemble
|
||||||
(apply assemble form env opts))
|
(apply assemble x e opts))
|
||||||
(lambda (key val) val)))
|
(lambda (key val) val)))
|
||||||
|
|
||||||
(define (print-in val lang . port)
|
(define (print-in val lang . port)
|
||||||
(lang.printer val (if (null? port) (current-output-port) (car port))))
|
(lang.printer val (if (null? port) (current-output-port) (car port))))
|
||||||
|
|
||||||
(define (compile-file-in file env lang . opts)
|
(define (compile-file-in file lang . opts)
|
||||||
(let* ((code (call-with-input-file file
|
(call-with-input-file file
|
||||||
(lambda (in)
|
(lambda (port) (apply lang.compiler port (current-module) opts))))
|
||||||
(do ((x (read-in lang in) (read-in lang in))
|
|
||||||
(l '() (cons (lang.translator (lang.expander x)) l)))
|
|
||||||
((eof-object? x) (reverse! l))))))
|
|
||||||
(asm (apply compile (cons '@begin code) env opts)))
|
|
||||||
(save-dumpcode (apply assemble asm env opts) (object-file-name file))))
|
|
||||||
|
|
||||||
(define (load-file-in file env lang . opts)
|
(define-public (syntax-error loc msg exp)
|
||||||
(let ((compiled (object-file-name file)))
|
(throw 'syntax-error loc msg exp))
|
||||||
(if (or (not (file-exists? compiled))
|
|
||||||
(> (stat:mtime (stat file)) (stat:mtime (stat compiled))))
|
|
||||||
(compile-file-in file env lang :O))
|
|
||||||
(load-dumpcode compiled)))
|
|
||||||
|
|
||||||
(define (object-file-name file)
|
(define-public (call-with-compile-error-catch thunk)
|
||||||
(let ((m (string-match "\\.[^.]*$" file)))
|
(catch 'syntax-error
|
||||||
(string-append (if m (match:prefix m) file) ".go")))
|
thunk
|
||||||
|
(lambda (key loc msg exp)
|
||||||
|
(format #t "~A:~A: ~A: ~A" (car loc) (cdr loc) msg exp))))
|
||||||
|
|
|
@ -24,11 +24,11 @@
|
||||||
: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)
|
||||||
|
:use-module (ice-9 match)
|
||||||
:use-module (ice-9 common-list)
|
:use-module (ice-9 common-list)
|
||||||
:export (compile))
|
:export (compile))
|
||||||
|
|
||||||
(define (compile x e . opts)
|
(define (compile x e . opts)
|
||||||
(set! x (parse-ghil x e))
|
|
||||||
(if (memq :O opts) (set! x (optimize x)))
|
(if (memq :O opts) (set! x (optimize x)))
|
||||||
(codegen x))
|
(codegen x))
|
||||||
|
|
||||||
|
@ -103,36 +103,75 @@
|
||||||
(define (push-code! code)
|
(define (push-code! code)
|
||||||
(set! stack (cons code stack)))
|
(set! stack (cons code stack)))
|
||||||
(define (comp tree tail drop)
|
(define (comp tree tail drop)
|
||||||
|
(define (push-label! label)
|
||||||
|
(push-code! (make-<glil-label> label)))
|
||||||
|
(define (push-branch! inst label)
|
||||||
|
(push-code! (make-<glil-branch> inst label)))
|
||||||
|
(define (push-call! inst args)
|
||||||
|
(for-each comp-push args)
|
||||||
|
(push-code! (make-<glil-call> inst (length args))))
|
||||||
;; 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
|
||||||
(define (comp-push tree) (comp tree #f #f))
|
(define (comp-push tree) (comp tree #f #f))
|
||||||
;; drop the result
|
;; drop the result
|
||||||
(define (comp-drop tree) (comp tree #f #t))
|
(define (comp-drop tree) (comp tree #f #t))
|
||||||
|
;; drop the result if unnecessary
|
||||||
|
(define (maybe-drop)
|
||||||
|
(if drop (push-code! *ia-drop*)))
|
||||||
|
;; return here if necessary
|
||||||
|
(define (maybe-return)
|
||||||
|
(if tail (push-code! *ia-return*)))
|
||||||
;; return this code if necessary
|
;; return this code if necessary
|
||||||
(define (return-code! code)
|
(define (return-code! code)
|
||||||
(if (not drop) (push-code! code))
|
(if (not drop) (push-code! code))
|
||||||
(if tail (push-code! *ia-return*)))
|
(maybe-return))
|
||||||
;; return void if necessary
|
;; return void if necessary
|
||||||
(define (return-void!) (return-code! *ia-void*))
|
(define (return-void!)
|
||||||
|
(return-code! *ia-void*))
|
||||||
|
;; return object if necessary
|
||||||
|
(define (return-object! obj)
|
||||||
|
(return-code! (make-<glil-const> obj)))
|
||||||
;;
|
;;
|
||||||
;; dispatch
|
;; dispatch
|
||||||
(match tree
|
(match tree
|
||||||
(($ <ghil-void>)
|
(($ <ghil-void>)
|
||||||
(return-void!))
|
(return-void!))
|
||||||
|
|
||||||
(($ <ghil-quote> obj)
|
(($ <ghil-quote> env loc obj)
|
||||||
(return-code! (make-<glil-const> obj)))
|
(return-object! obj))
|
||||||
|
|
||||||
(($ <ghil-ref> env var)
|
(($ <ghil-quasiquote> env loc exp)
|
||||||
|
(let loop ((x exp))
|
||||||
|
(match x
|
||||||
|
((? list? ls)
|
||||||
|
(push-call! 'mark '())
|
||||||
|
(for-each loop ls)
|
||||||
|
(push-call! 'list-mark '()))
|
||||||
|
((? pair? pp)
|
||||||
|
(loop (car pp))
|
||||||
|
(loop (cdr pp))
|
||||||
|
(push-code! (make-<glil-call> 'cons 2)))
|
||||||
|
(($ <ghil-unquote> env loc exp)
|
||||||
|
(comp-push exp))
|
||||||
|
(($ <ghil-unquote-splicing> env loc exp)
|
||||||
|
(comp-push exp)
|
||||||
|
(push-call! 'list-break '()))
|
||||||
|
(else
|
||||||
|
(push-code! (make-<glil-const> x)))))
|
||||||
|
(maybe-drop)
|
||||||
|
(maybe-return))
|
||||||
|
|
||||||
|
(($ <ghil-ref> env loc var)
|
||||||
(return-code! (make-glil-var 'ref env var)))
|
(return-code! (make-glil-var 'ref env var)))
|
||||||
|
|
||||||
(($ <ghil-set> env var val)
|
((or ($ <ghil-set> env loc var val)
|
||||||
|
($ <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!))
|
||||||
|
|
||||||
(($ <ghil-if> test then else)
|
(($ <ghil-if> env loc test then else)
|
||||||
;; TEST
|
;; TEST
|
||||||
;; (br-if-not L1)
|
;; (br-if-not L1)
|
||||||
;; THEN
|
;; THEN
|
||||||
|
@ -141,14 +180,59 @@
|
||||||
;; L2:
|
;; L2:
|
||||||
(let ((L1 (make-label)) (L2 (make-label)))
|
(let ((L1 (make-label)) (L2 (make-label)))
|
||||||
(comp-push test)
|
(comp-push test)
|
||||||
(push-code! (make-<glil-branch> 'br-if-not L1))
|
(push-branch! 'br-if-not L1)
|
||||||
(comp-tail then)
|
(comp-tail then)
|
||||||
(if (not tail) (push-code! (make-<glil-branch> 'br L2)))
|
(if (not tail) (push-branch! 'br L2))
|
||||||
(push-code! (make-<glil-label> L1))
|
(push-label! L1)
|
||||||
(comp-tail else)
|
(comp-tail else)
|
||||||
(if (not tail) (push-code! (make-<glil-label> L2)))))
|
(if (not tail) (push-label! L2))))
|
||||||
|
|
||||||
(($ <ghil-begin> exps)
|
(($ <ghil-and> env loc exps)
|
||||||
|
;; EXP
|
||||||
|
;; (br-if-not L1)
|
||||||
|
;; ...
|
||||||
|
;; TAIL
|
||||||
|
;; (br L2)
|
||||||
|
;; L1: (const #f)
|
||||||
|
;; L2:
|
||||||
|
(let ((L1 (make-label)) (L2 (make-label)))
|
||||||
|
(if (null? exps)
|
||||||
|
(return-object! #t)
|
||||||
|
(do ((exps exps (cdr exps)))
|
||||||
|
((null? (cdr exps))
|
||||||
|
(comp-tail (car exps))
|
||||||
|
(if (not tail) (push-branch! 'br L2))
|
||||||
|
(push-label! L1)
|
||||||
|
(return-object! #f)
|
||||||
|
(if (not tail) (push-label! L2))
|
||||||
|
(maybe-drop)
|
||||||
|
(maybe-return))
|
||||||
|
(comp-push (car exps))
|
||||||
|
(push-branch! 'br-if-not L1)))))
|
||||||
|
|
||||||
|
(($ <ghil-or> env loc exps)
|
||||||
|
;; EXP
|
||||||
|
;; (dup)
|
||||||
|
;; (br-if L1)
|
||||||
|
;; (drop)
|
||||||
|
;; ...
|
||||||
|
;; TAIL
|
||||||
|
;; L1:
|
||||||
|
(let ((L1 (make-label)))
|
||||||
|
(if (null? exps)
|
||||||
|
(return-object! #f)
|
||||||
|
(do ((exps exps (cdr exps)))
|
||||||
|
((null? (cdr exps))
|
||||||
|
(comp-tail (car exps))
|
||||||
|
(push-label! L1)
|
||||||
|
(maybe-drop)
|
||||||
|
(maybe-return))
|
||||||
|
(comp-push (car exps))
|
||||||
|
(push-call! 'dup '())
|
||||||
|
(push-branch! 'br-if L1)
|
||||||
|
(push-call! 'drop '())))))
|
||||||
|
|
||||||
|
(($ <ghil-begin> env loc exps)
|
||||||
;; EXPS...
|
;; EXPS...
|
||||||
;; TAIL
|
;; TAIL
|
||||||
(if (null? exps)
|
(if (null? exps)
|
||||||
|
@ -158,7 +242,7 @@
|
||||||
(comp-tail (car exps)))
|
(comp-tail (car exps)))
|
||||||
(comp-drop (car exps)))))
|
(comp-drop (car exps)))))
|
||||||
|
|
||||||
(($ <ghil-bind> env vars vals body)
|
(($ <ghil-bind> env loc vars vals body)
|
||||||
;; VALS...
|
;; VALS...
|
||||||
;; (set VARS)...
|
;; (set VARS)...
|
||||||
;; BODY
|
;; BODY
|
||||||
|
@ -167,30 +251,27 @@
|
||||||
(reverse vars))
|
(reverse vars))
|
||||||
(comp-tail body))
|
(comp-tail body))
|
||||||
|
|
||||||
(($ <ghil-lambda> env vars rest body)
|
(($ <ghil-lambda> env loc vars rest body)
|
||||||
(return-code! (codegen tree)))
|
(return-code! (codegen tree)))
|
||||||
|
|
||||||
(($ <ghil-inst> inst args)
|
(($ <ghil-inline> env loc inst args)
|
||||||
;; ARGS...
|
;; ARGS...
|
||||||
;; (INST NARGS)
|
;; (INST NARGS)
|
||||||
(for-each comp-push args)
|
(push-call! inst args)
|
||||||
(push-code! (make-<glil-call> inst (length args)))
|
(maybe-drop)
|
||||||
(if drop (push-code! *ia-drop*))
|
(maybe-return))
|
||||||
(if tail (push-code! *ia-return*)))
|
|
||||||
|
|
||||||
(($ <ghil-call> env proc args)
|
(($ <ghil-call> env loc proc args)
|
||||||
;; PROC
|
;; PROC
|
||||||
;; ARGS...
|
;; ARGS...
|
||||||
;; ([tail-]call NARGS)
|
;; ([tail-]call NARGS)
|
||||||
(comp-push proc)
|
(comp-push proc)
|
||||||
(for-each comp-push args)
|
(push-call! (if tail 'tail-call 'call) args)
|
||||||
(let ((inst (if tail 'tail-call 'call)))
|
(maybe-drop))))
|
||||||
(push-code! (make-<glil-call> inst (length args))))
|
|
||||||
(if drop (push-code! *ia-drop*)))))
|
|
||||||
;;
|
;;
|
||||||
;; main
|
;; main
|
||||||
(match ghil
|
(match ghil
|
||||||
(($ <ghil-lambda> env args rest body)
|
(($ <ghil-lambda> env loc args rest body)
|
||||||
(let* ((vars env.variables)
|
(let* ((vars env.variables)
|
||||||
(locs (pick (lambda (v) (eq? v.kind 'local)) vars))
|
(locs (pick (lambda (v) (eq? v.kind 'local)) vars))
|
||||||
(exts (pick (lambda (v) (eq? v.kind 'external)) vars)))
|
(exts (pick (lambda (v) (eq? v.kind 'external)) vars)))
|
||||||
|
|
|
@ -26,19 +26,37 @@
|
||||||
:use-module (ice-9 regex)
|
:use-module (ice-9 regex)
|
||||||
:export
|
:export
|
||||||
(parse-ghil
|
(parse-ghil
|
||||||
ghil-primitive?
|
ghil-lookup ghil-primitive?
|
||||||
make-<ghil-void> <ghil-void>?
|
make-<ghil-void> <ghil-void>? <ghil-void>-1 <ghil-void>-2
|
||||||
make-<ghil-quote> <ghil-quote>? <ghil-quote>-1
|
make-<ghil-quote> <ghil-quote>? <ghil-quote>-1 <ghil-quote>-2 <ghil-quote>-3
|
||||||
make-<ghil-ref> <ghil-ref>? <ghil-ref>-1 <ghil-ref>-2
|
make-<ghil-quasiquote> <ghil-quasiquote>?
|
||||||
make-<ghil-set> <ghil-set>? <ghil-set>-1 <ghil-set>-2 <ghil-set>-3
|
<ghil-quasiquote>-1 <ghil-quasiquote>-2 <ghil-quasiquote>-3
|
||||||
make-<ghil-if> <ghil-if>? <ghil-if>-1 <ghil-if>-2 <ghil-if>-3
|
make-<ghil-unquote> <ghil-unquote>?
|
||||||
make-<ghil-begin> <ghil-begin>? <ghil-begin>-1
|
<ghil-unquote>-1 <ghil-unquote>-2 <ghil-unquote>-3
|
||||||
|
make-<ghil-unquote-splicing> <ghil-unquote-splicing>?
|
||||||
|
<ghil-unquote-splicing>-1 <ghil-unquote-splicing>-2
|
||||||
|
<ghil-unquote-splicing>-3
|
||||||
|
|
||||||
|
make-<ghil-ref> <ghil-ref>?
|
||||||
|
<ghil-ref>-1 <ghil-ref>-2 <ghil-ref>-3
|
||||||
|
make-<ghil-set> <ghil-set>?
|
||||||
|
<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
|
||||||
|
|
||||||
|
make-<ghil-if> <ghil-if>?
|
||||||
|
<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
|
||||||
|
make-<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
|
||||||
make-<ghil-bind> <ghil-bind>?
|
make-<ghil-bind> <ghil-bind>?
|
||||||
<ghil-bind>-1 <ghil-bind>-2 <ghil-bind>-3 <ghil-bind>-4
|
<ghil-bind>-1 <ghil-bind>-2 <ghil-bind>-3 <ghil-bind>-4 <ghil-bind>-5
|
||||||
make-<ghil-lambda> <ghil-lambda>?
|
make-<ghil-lambda> <ghil-lambda>? <ghil-lambda>-1 <ghil-lambda>-2
|
||||||
<ghil-lambda>-1 <ghil-lambda>-2 <ghil-lambda>-3 <ghil-lambda>-4
|
<ghil-lambda>-3 <ghil-lambda>-4 <ghil-lambda>-5
|
||||||
make-<ghil-call> <ghil-call>? <ghil-call>-1 <ghil-call>-2 <ghil-call>-3
|
make-<ghil-inline> <ghil-inline>?
|
||||||
make-<ghil-inst> <ghil-inst>? <ghil-inst>-1 <ghil-inst>-2
|
<ghil-inline>-1 <ghil-inline>-2 <ghil-inline>-3 <ghil-inline>-4
|
||||||
|
make-<ghil-call> <ghil-call>?
|
||||||
|
<ghil-call>-1 <ghil-call>-2 <ghil-call>-3 <ghil-call>-4
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,16 +64,27 @@
|
||||||
;;; Parse tree
|
;;; Parse tree
|
||||||
;;;
|
;;;
|
||||||
|
|
||||||
(define-structure (<ghil-void>))
|
(define-structure (<ghil-void> env loc))
|
||||||
(define-structure (<ghil-quote> obj))
|
(define-structure (<ghil-quote> env loc obj))
|
||||||
(define-structure (<ghil-ref> env var))
|
(define-structure (<ghil-quasiquote> env loc exp))
|
||||||
(define-structure (<ghil-set> env var val))
|
(define-structure (<ghil-unquote> env loc exp))
|
||||||
(define-structure (<ghil-if> test then else))
|
(define-structure (<ghil-unquote-splicing> env loc exp))
|
||||||
(define-structure (<ghil-begin> exps))
|
|
||||||
(define-structure (<ghil-bind> env vars vals body))
|
(define-structure (<ghil-ref> env loc var))
|
||||||
(define-structure (<ghil-lambda> env vars rest body))
|
(define-structure (<ghil-set> env loc var val))
|
||||||
(define-structure (<ghil-call> env proc args))
|
(define-structure (<ghil-define> env loc var val))
|
||||||
(define-structure (<ghil-inst> inst args))
|
|
||||||
|
(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))
|
||||||
|
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
|
@ -86,9 +115,14 @@
|
||||||
(define-vm-class <ghil-var> ()
|
(define-vm-class <ghil-var> ()
|
||||||
env name kind type value index)
|
env name kind type value index)
|
||||||
|
|
||||||
(define (make-ghil-var env name kind)
|
(define-public (make-ghil-var env name kind)
|
||||||
(make <ghil-var> :env env :name name :kind kind))
|
(make <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
|
||||||
|
@ -99,9 +133,14 @@
|
||||||
(table '())
|
(table '())
|
||||||
(imports '()))
|
(imports '()))
|
||||||
|
|
||||||
(define (make-ghil-mod module)
|
(define-public (make-ghil-mod module)
|
||||||
(make <ghil-mod> :module module))
|
(make <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>))
|
(define-method (ghil-lookup (mod <ghil-mod>) (sym <symbol>))
|
||||||
(or (assq-ref mod.table sym)
|
(or (assq-ref mod.table sym)
|
||||||
;; (let ((var (make-ghil-var (env-identifier mod.module) sym 'module)))
|
;; (let ((var (make-ghil-var (env-identifier mod.module) sym 'module)))
|
||||||
|
@ -120,6 +159,7 @@
|
||||||
(table '())
|
(table '())
|
||||||
(variables '()))
|
(variables '()))
|
||||||
|
|
||||||
|
(export make-ghil-env)
|
||||||
(define-method (make-ghil-env (m <ghil-mod>))
|
(define-method (make-ghil-env (m <ghil-mod>))
|
||||||
(make <ghil-env> :mod m :parent m))
|
(make <ghil-env> :mod m :parent m))
|
||||||
|
|
||||||
|
@ -148,6 +188,23 @@
|
||||||
(lambda (var) (set! var.kind 'external) var))
|
(lambda (var) (set! var.kind 'external) var))
|
||||||
(else (loop e.parent))))))
|
(else (loop e.parent))))))
|
||||||
|
|
||||||
|
(define-public (call-with-ghil-environment e syms func)
|
||||||
|
(let* ((e (make-ghil-env e))
|
||||||
|
(vars (map (lambda (s)
|
||||||
|
(let ((v (make-ghil-var e s 'argument)))
|
||||||
|
(ghil-env-add! e v) v))
|
||||||
|
syms)))
|
||||||
|
(func e vars)))
|
||||||
|
|
||||||
|
(define-public (call-with-ghil-bindings e syms func)
|
||||||
|
(let* ((vars (map (lambda (s)
|
||||||
|
(let ((v (make-ghil-var e s 'local)))
|
||||||
|
(ghil-env-add! e v) v))
|
||||||
|
syms))
|
||||||
|
(ret (func vars)))
|
||||||
|
(for-each (lambda (v) (ghil-env-remove! e v)) vars)
|
||||||
|
ret))
|
||||||
|
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
;;; Parser
|
;;; Parser
|
||||||
|
@ -189,11 +246,11 @@
|
||||||
(receive (module name) (identifier-split identifier)
|
(receive (module name) (identifier-split identifier)
|
||||||
(make-<ghil-ref> e (make-ghil-var module name 'module))))))
|
(make-<ghil-ref> e (make-ghil-var module name 'module))))))
|
||||||
|
|
||||||
;; (@@ INST ARGS...)
|
;; (@@ OP ARGS...)
|
||||||
((@@)
|
((@@)
|
||||||
(match args
|
(match args
|
||||||
((inst . args)
|
((op . args)
|
||||||
(make-<ghil-inst> inst (map-parse args e)))))
|
(make-<ghil-inline> op (map-parse args e)))))
|
||||||
|
|
||||||
;; (@void)
|
;; (@void)
|
||||||
((@void)
|
((@void)
|
||||||
|
@ -272,17 +329,14 @@
|
||||||
|
|
||||||
;; (@eval-case CLAUSE...)
|
;; (@eval-case CLAUSE...)
|
||||||
((@eval-case)
|
((@eval-case)
|
||||||
(match args
|
(let loop ((clauses args))
|
||||||
((clause . rest)
|
(cond ((null? clauses) (make-<ghil-void>))
|
||||||
(match clause
|
((or (eq? (caar clauses) '@else)
|
||||||
(() (make-<ghil-void>))
|
(and (memq 'load-toplevel (caar clauses))
|
||||||
(((key ...) . body)
|
(ghil-env-toplevel? e)))
|
||||||
(cond ((and (ghil-env-toplevel? e) (memq 'load-toplevel key))
|
(parse-body (cdar clauses) e))
|
||||||
(parse-body body e))
|
(else
|
||||||
(else
|
(loop (cdr clauses))))))
|
||||||
(error "No match clause"))))
|
|
||||||
(else
|
|
||||||
(error "No match clause"))))))
|
|
||||||
|
|
||||||
(else (error "Unknown primitive:" prim))))
|
(else (error "Unknown primitive:" prim))))
|
||||||
|
|
||||||
|
|
|
@ -65,8 +65,8 @@
|
||||||
;;; 6.1 Equivalence predicates
|
;;; 6.1 Equivalence predicates
|
||||||
|
|
||||||
(define (@eq? x y) `(@@ eq? ,x ,y))
|
(define (@eq? x y) `(@@ eq? ,x ,y))
|
||||||
(define (@eqv? x y) `(@@ eqv? ,x ,y))
|
;(define (@eqv? x y) `(@@ eqv? ,x ,y))
|
||||||
(define (@equal? x y) `(@@ equal? ,x ,y))
|
;(define (@equal? x y) `(@@ equal? ,x ,y))
|
||||||
|
|
||||||
;;; 6.2 Numbers
|
;;; 6.2 Numbers
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@
|
||||||
(define (@exact? x) `((@ Core::exact?) ,x))
|
(define (@exact? x) `((@ Core::exact?) ,x))
|
||||||
(define (@inexact? x) `((@ Core::inexact?) ,x))
|
(define (@inexact? x) `((@ Core::inexact?) ,x))
|
||||||
|
|
||||||
(define (@= x y) `(@@ ee? ,x ,y))
|
;(define (@= x y) `(@@ ee? ,x ,y))
|
||||||
;(define (@< x y) `(@@ lt? ,x ,y))
|
;(define (@< x y) `(@@ lt? ,x ,y))
|
||||||
;(define (@> x y) `(@@ gt? ,x ,y))
|
;(define (@> x y) `(@@ gt? ,x ,y))
|
||||||
;(define (@<= x y) `(@@ le? ,x ,y))
|
;(define (@<= x y) `(@@ le? ,x ,y))
|
||||||
|
|
|
@ -20,19 +20,16 @@
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
(define-module (system repl command)
|
(define-module (system repl command)
|
||||||
: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 repl common)
|
:use-module (system repl common)
|
||||||
:use-module (system il glil)
|
:use-module (system il glil)
|
||||||
:use-module (system vm core)
|
:use-module (system vm core)
|
||||||
:use-module (system vm load)
|
:autoload (system vm trace) (vm-trace)
|
||||||
:use-module (system vm trace)
|
:autoload (system vm disasm) (disassemble-program disassemble-dumpcode)
|
||||||
:use-module (system vm disasm)
|
:autoload (system vm profile) (vm-profile)
|
||||||
:use-module (system vm profile)
|
|
||||||
:use-module (ice-9 format)
|
:use-module (ice-9 format)
|
||||||
:use-module (ice-9 session)
|
:use-module (ice-9 session)
|
||||||
:use-module (ice-9 debugger)
|
|
||||||
:export (meta-command))
|
:export (meta-command))
|
||||||
|
|
||||||
(define (puts x) (display x) (newline))
|
(define (puts x) (display x) (newline))
|
||||||
|
@ -318,8 +315,7 @@ Disassemble a program."
|
||||||
(define (disassemble-file repl file)
|
(define (disassemble-file repl file)
|
||||||
"disassemble-file FILE
|
"disassemble-file FILE
|
||||||
Disassemble a file."
|
Disassemble a file."
|
||||||
(disassemble-dumpcode
|
(disassemble-dumpcode (load-dumpcode (->string file))))
|
||||||
(load-file-in (->string file) repl.module repl.language)))
|
|
||||||
|
|
||||||
(define (->string x)
|
(define (->string x)
|
||||||
(object->string x display))
|
(object->string x display))
|
||||||
|
@ -388,37 +384,15 @@ Time execution."
|
||||||
(get id gc-start gc-end))
|
(get id gc-start gc-end))
|
||||||
result))
|
result))
|
||||||
|
|
||||||
;;;
|
|
||||||
;;; Statistics
|
|
||||||
;;;
|
|
||||||
|
|
||||||
(define guile-gc gc)
|
(define guile-gc gc)
|
||||||
(define (gc repl)
|
(define (gc repl)
|
||||||
"gc
|
"gc
|
||||||
Garbage collection."
|
Garbage collection."
|
||||||
(guile-gc))
|
(guile-gc))
|
||||||
|
|
||||||
(define (display-stat title flag field1 field2 unit)
|
;;;
|
||||||
(let ((str (format #f "~~20~AA ~~10@A /~~10@A ~~A~~%" (if flag "" "@"))))
|
;;; Statistics
|
||||||
(format #t str title field1 field2 unit)))
|
;;;
|
||||||
|
|
||||||
(define (display-stat-title title field1 field2)
|
|
||||||
(display-stat title #t field1 field2 ""))
|
|
||||||
|
|
||||||
(define (display-diff-stat title flag this last unit)
|
|
||||||
(display-stat title flag (- this last) this unit))
|
|
||||||
|
|
||||||
(define (display-time-stat title this last)
|
|
||||||
(define (conv num)
|
|
||||||
(format #f "~10,2F" (/ num internal-time-units-per-second)))
|
|
||||||
(display-stat title #f (conv (- this last)) (conv this) "s"))
|
|
||||||
|
|
||||||
(define (display-mips-stat title this-time this-clock last-time last-clock)
|
|
||||||
(define (mips time clock)
|
|
||||||
(if (= time 0) "----" (format #f "~10,2F" (/ clock time 1000000))))
|
|
||||||
(display-stat title #f
|
|
||||||
(mips (- this-time last-time) (- this-clock last-clock))
|
|
||||||
(mips this-time this-clock) "mips"))
|
|
||||||
|
|
||||||
(define (statistics repl)
|
(define (statistics repl)
|
||||||
"statistics
|
"statistics
|
||||||
|
@ -494,3 +468,25 @@ Display statistics."
|
||||||
(set! repl.tm-stats this-tms)
|
(set! repl.tm-stats this-tms)
|
||||||
(set! repl.vm-stats this-vms)
|
(set! repl.vm-stats this-vms)
|
||||||
(set! repl.gc-stats this-gcs)))
|
(set! repl.gc-stats this-gcs)))
|
||||||
|
|
||||||
|
(define (display-stat title flag field1 field2 unit)
|
||||||
|
(let ((str (format #f "~~20~AA ~~10@A /~~10@A ~~A~~%" (if flag "" "@"))))
|
||||||
|
(format #t str title field1 field2 unit)))
|
||||||
|
|
||||||
|
(define (display-stat-title title field1 field2)
|
||||||
|
(display-stat title #t field1 field2 ""))
|
||||||
|
|
||||||
|
(define (display-diff-stat title flag this last unit)
|
||||||
|
(display-stat title flag (- this last) this unit))
|
||||||
|
|
||||||
|
(define (display-time-stat title this last)
|
||||||
|
(define (conv num)
|
||||||
|
(format #f "~10,2F" (/ num internal-time-units-per-second)))
|
||||||
|
(display-stat title #f (conv (- this last)) (conv this) "s"))
|
||||||
|
|
||||||
|
(define (display-mips-stat title this-time this-clock last-time last-clock)
|
||||||
|
(define (mips time clock)
|
||||||
|
(if (= time 0) "----" (format #f "~10,2F" (/ clock time 1000000))))
|
||||||
|
(display-stat title #f
|
||||||
|
(mips (- this-time last-time) (- this-clock last-clock))
|
||||||
|
(mips this-time this-clock) "mips"))
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
(make <repl>
|
(make <repl>
|
||||||
:vm vm
|
:vm vm
|
||||||
:language (lookup-language lang)
|
:language (lookup-language lang)
|
||||||
:module #f ;; (global-ref 'user)
|
:module (current-module) ;; (global-ref 'user)
|
||||||
:value-count 0
|
:value-count 0
|
||||||
; :value-history (make-vmodule)
|
; :value-history (make-vmodule)
|
||||||
:tm-stats (times)
|
:tm-stats (times)
|
||||||
|
@ -66,9 +66,9 @@
|
||||||
(apply compile-in form repl.module repl.language opts))
|
(apply compile-in form repl.module repl.language opts))
|
||||||
|
|
||||||
(define (repl-eval repl form)
|
(define (repl-eval repl form)
|
||||||
(let ((evaler repl.language.evaler))
|
(let ((eval repl.language.evaluator))
|
||||||
(if evaler
|
(if eval
|
||||||
(evaler form repl.module)
|
(eval form repl.module)
|
||||||
(vm-load repl.vm (repl-compile repl form)))))
|
(vm-load repl.vm (repl-compile repl form)))))
|
||||||
|
|
||||||
(define (repl-print repl val)
|
(define (repl-print repl val)
|
||||||
|
@ -81,11 +81,11 @@
|
||||||
(newline)
|
(newline)
|
||||||
(set! repl.value-count num))))
|
(set! repl.value-count num))))
|
||||||
|
|
||||||
(define (repl-compile-file repl form . opts)
|
(define (repl-compile-file repl file . opts)
|
||||||
(apply compile-file-in form repl.module repl.language opts))
|
(apply compile-file-in file repl.language opts))
|
||||||
|
|
||||||
(define (repl-load-file repl file . opts)
|
(define (repl-load-file repl file . opts)
|
||||||
(let ((bytes (apply load-file-in file repl.module repl.language opts)))
|
(let ((bytes (apply repl-compile-file repl file opts)))
|
||||||
(if (memq :t opts)
|
(if (or (memq :b opts) (memq :r opts))
|
||||||
(vm-trace repl.vm bytes :a)
|
(apply vm-trace repl.vm bytes opts)
|
||||||
(vm-load repl.vm bytes))))
|
(vm-load repl.vm bytes))))
|
||||||
|
|
1
module/system/vm/.cvsignore
Normal file
1
module/system/vm/.cvsignore
Normal file
|
@ -0,0 +1 @@
|
||||||
|
*.go
|
|
@ -20,7 +20,6 @@
|
||||||
;;; 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)
|
||||||
|
@ -210,8 +209,7 @@
|
||||||
(push-code! `(load-program ,bytes)))))
|
(push-code! `(load-program ,bytes)))))
|
||||||
((vlink? x)
|
((vlink? x)
|
||||||
;;; (dump! (vlink-module x)) ;; FIXME: no module support now
|
;;; (dump! (vlink-module x)) ;; FIXME: no module support now
|
||||||
(dump! (vlink-name x))
|
(push-code! `(link ,(symbol->string (vlink-name x)))))
|
||||||
(push-code! `(link)))
|
|
||||||
((vmod? x)
|
((vmod? x)
|
||||||
(push-code! `(load-module ,(vmod-id x))))
|
(push-code! `(load-module ,(vmod-id x))))
|
||||||
((and (integer? x) (exact? x))
|
((and (integer? x) (exact? x))
|
||||||
|
|
|
@ -83,6 +83,7 @@
|
||||||
(('load-string s) s)
|
(('load-string s) s)
|
||||||
(('load-symbol s) (string->symbol s))
|
(('load-symbol s) (string->symbol s))
|
||||||
(('load-keyword s) (make-keyword-from-dash-symbol (string->symbol s)))
|
(('load-keyword s) (make-keyword-from-dash-symbol (string->symbol s)))
|
||||||
|
(('link s) (string->symbol s))
|
||||||
(else #f)))
|
(else #f)))
|
||||||
|
|
||||||
(define (code->bytes code)
|
(define (code->bytes code)
|
||||||
|
|
|
@ -20,22 +20,34 @@
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
(define-module (system vm load)
|
(define-module (system vm load)
|
||||||
|
:autoload (system base compile) (compile-file)
|
||||||
:use-module (system vm core)
|
:use-module (system vm core)
|
||||||
:autoload (system base language) (compile-file-in lookup-language)
|
|
||||||
:use-module (ice-9 regex)
|
:use-module (ice-9 regex)
|
||||||
:export (load/compile))
|
:export (load-compiled-file compile-and-load load/compile))
|
||||||
|
|
||||||
(define (load/compile file)
|
(define (load-compiled-file file . opts)
|
||||||
(let* ((file (file-name-full-name file))
|
(vm-load (the-vm) (load-dumpcode file)))
|
||||||
|
|
||||||
|
(define (compile-and-load file . opts)
|
||||||
|
(let ((comp (object-file-name file)))
|
||||||
|
(if (or (not (file-exists? comp))
|
||||||
|
(> (stat:mtime (stat file)) (stat:mtime (stat comp))))
|
||||||
|
(compile-file file))
|
||||||
|
(load-compiled-file comp)))
|
||||||
|
|
||||||
|
(define (load/compile file . opts)
|
||||||
|
(let* ((file (file-full-name file))
|
||||||
(compiled (object-file-name file)))
|
(compiled (object-file-name file)))
|
||||||
(if (or (not (file-exists? compiled))
|
(if (or (not (file-exists? compiled))
|
||||||
(> (stat:mtime (stat file)) (stat:mtime (stat compiled))))
|
(> (stat:mtime (stat file)) (stat:mtime (stat compiled))))
|
||||||
(compile-file-in file #f (lookup-language 'gscheme) #:O))
|
(apply compile-file file #f opts))
|
||||||
(vm-load (the-vm) (load-dumpcode compiled))))
|
(if (memq #:b opts)
|
||||||
|
(apply vm-trace (the-vm) (load-dumpcode compiled) opts)
|
||||||
|
(vm-load (the-vm) (load-dumpcode compiled)))))
|
||||||
|
|
||||||
(define (file-name-full-name filename)
|
(define (file-full-name filename)
|
||||||
(let ((oldname (and (current-load-port)
|
(let* ((port (current-load-port))
|
||||||
(port-filename (current-load-port)))))
|
(oldname (and port (port-filename port))))
|
||||||
(if (and oldname
|
(if (and oldname
|
||||||
(> (string-length filename) 0)
|
(> (string-length filename) 0)
|
||||||
(not (char=? (string-ref filename 0) #\/))
|
(not (char=? (string-ref filename 0) #\/))
|
||||||
|
@ -43,6 +55,6 @@
|
||||||
(string-append (dirname oldname) "/" filename)
|
(string-append (dirname oldname) "/" filename)
|
||||||
filename)))
|
filename)))
|
||||||
|
|
||||||
(define (object-file-name file)
|
(define-public (object-file-name file)
|
||||||
(let ((m (string-match "\\.[^.]*$" file)))
|
(let ((m (string-match "\\.[^.]*$" file)))
|
||||||
(string-append (if m (match:prefix m) file) ".go")))
|
(string-append (if m (match:prefix m) file) ".go")))
|
||||||
|
|
|
@ -1,251 +0,0 @@
|
||||||
;;;; slib.scm --- definitions needed to get SLIB to work with Guile
|
|
||||||
;;;;
|
|
||||||
;;;; Copyright (C) 1997, 1998, 2000 Free Software Foundation, Inc.
|
|
||||||
;;;;
|
|
||||||
;;;; This file is part of GUILE.
|
|
||||||
;;;;
|
|
||||||
;;;; GUILE 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 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; see the file COPYING. If not, write
|
|
||||||
;;;; to the Free Software Foundation, Inc., 59 Temple Place, Suite
|
|
||||||
;;;; 330, Boston, MA 02111-1307 USA
|
|
||||||
;;;;
|
|
||||||
(define-module (system vm slib)
|
|
||||||
:use-module (system vm load)
|
|
||||||
:no-backtrace)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(define (eval-load <filename> evl)
|
|
||||||
(if (not (file-exists? <filename>))
|
|
||||||
(set! <filename> (string-append <filename> (scheme-file-suffix))))
|
|
||||||
(call-with-input-file <filename>
|
|
||||||
(lambda (port)
|
|
||||||
(let ((old-load-pathname *load-pathname*))
|
|
||||||
(set! *load-pathname* <filename>)
|
|
||||||
(do ((o (read port) (read port)))
|
|
||||||
((eof-object? o))
|
|
||||||
(evl o))
|
|
||||||
(set! *load-pathname* old-load-pathname)))))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(define slib:exit quit)
|
|
||||||
(define slib:error error)
|
|
||||||
(define slib:warn warn)
|
|
||||||
(define slib:eval (lambda (x) (eval x slib-module)))
|
|
||||||
(define defmacro:eval (lambda (x) (eval x (interaction-environment))))
|
|
||||||
(define logical:logand logand)
|
|
||||||
(define logical:logior logior)
|
|
||||||
(define logical:logxor logxor)
|
|
||||||
(define logical:lognot lognot)
|
|
||||||
(define logical:ash ash)
|
|
||||||
(define logical:logcount logcount)
|
|
||||||
(define logical:integer-length integer-length)
|
|
||||||
(define logical:bit-extract bit-extract)
|
|
||||||
(define logical:integer-expt integer-expt)
|
|
||||||
(define logical:ipow-by-squaring ipow-by-squaring)
|
|
||||||
(define slib:eval-load eval-load)
|
|
||||||
(define slib:tab #\tab)
|
|
||||||
(define slib:form-feed #\page)
|
|
||||||
|
|
||||||
(define slib-module (current-module))
|
|
||||||
|
|
||||||
(define (defined? symbol)
|
|
||||||
(module-defined? slib-module symbol))
|
|
||||||
|
|
||||||
(define slib:features
|
|
||||||
(append '(source
|
|
||||||
eval
|
|
||||||
abort
|
|
||||||
alist
|
|
||||||
defmacro
|
|
||||||
delay
|
|
||||||
dynamic-wind
|
|
||||||
full-continuation
|
|
||||||
hash
|
|
||||||
hash-table
|
|
||||||
line-i/o
|
|
||||||
logical
|
|
||||||
multiarg/and-
|
|
||||||
multiarg-apply
|
|
||||||
promise
|
|
||||||
rev2-procedures
|
|
||||||
rev4-optional-procedures
|
|
||||||
string-port
|
|
||||||
with-file)
|
|
||||||
|
|
||||||
(if (defined? 'getenv)
|
|
||||||
'(getenv)
|
|
||||||
'())
|
|
||||||
|
|
||||||
(if (defined? 'current-time)
|
|
||||||
'(current-time)
|
|
||||||
'())
|
|
||||||
|
|
||||||
(if (defined? 'system)
|
|
||||||
'(system)
|
|
||||||
'())
|
|
||||||
|
|
||||||
(if (defined? 'array?)
|
|
||||||
'(array)
|
|
||||||
'())
|
|
||||||
|
|
||||||
(if (defined? 'char-ready?)
|
|
||||||
'(char-ready?)
|
|
||||||
'())
|
|
||||||
|
|
||||||
(if (defined? 'array-for-each)
|
|
||||||
'(array-for-each)
|
|
||||||
'())
|
|
||||||
|
|
||||||
(if (and (string->number "0.0") (inexact? (string->number "0.0")))
|
|
||||||
'(inexact)
|
|
||||||
'())
|
|
||||||
|
|
||||||
(if (rational? (string->number "1/19"))
|
|
||||||
'(rational)
|
|
||||||
'())
|
|
||||||
|
|
||||||
(if (real? (string->number "0.0"))
|
|
||||||
'(real)
|
|
||||||
())
|
|
||||||
|
|
||||||
(if (complex? (string->number "1+i"))
|
|
||||||
'(complex)
|
|
||||||
'())
|
|
||||||
|
|
||||||
(let ((n (string->number "9999999999999999999999999999999")))
|
|
||||||
(if (and n (exact? n))
|
|
||||||
'(bignum)
|
|
||||||
'()))))
|
|
||||||
|
|
||||||
|
|
||||||
;;; FIXME: Because uers want require to search the path, this uses
|
|
||||||
;;; load-from-path, which probably isn't a hot idea. slib
|
|
||||||
;;; doesn't expect this function to search a path, so I expect to get
|
|
||||||
;;; bug reports at some point complaining that the wrong file gets
|
|
||||||
;;; loaded when something accidentally appears in the path before
|
|
||||||
;;; slib, etc. ad nauseum. However, the right fix seems to involve
|
|
||||||
;;; changing catalog:get in slib/require.scm, and I don't expect
|
|
||||||
;;; Aubrey will integrate such a change. So I'm just going to punt
|
|
||||||
;;; for the time being.
|
|
||||||
(define-public (slib:load name)
|
|
||||||
(save-module-excursion
|
|
||||||
(lambda ()
|
|
||||||
(define (try-load name)
|
|
||||||
(catch 'system-error
|
|
||||||
(lambda () (load/compile (%search-load-path name)) #f)
|
|
||||||
(lambda args args)))
|
|
||||||
;; (set-current-module slib-module)
|
|
||||||
(let ((errinfo (try-load name)))
|
|
||||||
(if (and errinfo (try-load (string-append name ".scm")))
|
|
||||||
(apply throw errinfo))))))
|
|
||||||
|
|
||||||
(define slib:load-source slib:load)
|
|
||||||
(define defmacro:load slib:load)
|
|
||||||
|
|
||||||
(define slib-parent-dir
|
|
||||||
(let* ((path (%search-load-path "slib/require.scm")))
|
|
||||||
(if path
|
|
||||||
(substring path 0 (- (string-length path) 17))
|
|
||||||
(error "Could not find slib/require.scm in " %load-path))))
|
|
||||||
|
|
||||||
(define-public (implementation-vicinity)
|
|
||||||
(string-append slib-parent-dir "/"))
|
|
||||||
(define-public (library-vicinity)
|
|
||||||
(string-append (implementation-vicinity) "slib/"))
|
|
||||||
(define-public home-vicinity
|
|
||||||
(let ((home-path (getenv "HOME")))
|
|
||||||
(lambda () home-path)))
|
|
||||||
(define-public (scheme-implementation-type) 'guile)
|
|
||||||
(define-public (scheme-implementation-version) "")
|
|
||||||
|
|
||||||
(define (output-port-width . arg) 80)
|
|
||||||
(define (output-port-height . arg) 24)
|
|
||||||
(define (identity x) x)
|
|
||||||
|
|
||||||
;;; {Random numbers}
|
|
||||||
;;;
|
|
||||||
(define-public (make-random-state . args)
|
|
||||||
(let ((seed (if (null? args) *random-state* (car args))))
|
|
||||||
(cond ((string? seed))
|
|
||||||
((number? seed) (set! seed (number->string seed)))
|
|
||||||
(else (let ()
|
|
||||||
(require 'object->string)
|
|
||||||
(set! seed (object->limited-string seed 50)))))
|
|
||||||
(seed->random-state seed)))
|
|
||||||
|
|
||||||
;;; {Time}
|
|
||||||
;;;
|
|
||||||
|
|
||||||
(define difftime -)
|
|
||||||
(define offset-time +)
|
|
||||||
|
|
||||||
|
|
||||||
(define %system-define define)
|
|
||||||
|
|
||||||
(define define
|
|
||||||
(procedure->memoizing-macro
|
|
||||||
(lambda (exp env)
|
|
||||||
(if (= (length env) 1)
|
|
||||||
`(define-public ,@(cdr exp))
|
|
||||||
`(%system-define ,@(cdr exp))))))
|
|
||||||
|
|
||||||
;;; Hack to make syncase macros work in the slib module
|
|
||||||
(if (nested-ref the-root-module '(app modules ice-9 syncase))
|
|
||||||
(set-object-property! (module-local-variable (current-module) 'define)
|
|
||||||
'*sc-expander*
|
|
||||||
'(define)))
|
|
||||||
|
|
||||||
(define (software-type)
|
|
||||||
"Return a symbol describing the current platform's operating system.
|
|
||||||
This may be one of AIX, VMS, UNIX, COHERENT, WINDOWS, MS-DOS, OS/2,
|
|
||||||
THINKC, AMIGA, ATARIST, MACH, or ACORN.
|
|
||||||
|
|
||||||
Note that most varieties of Unix are considered to be simply \"UNIX\".
|
|
||||||
That is because when a program depends on features that are not present
|
|
||||||
on every operating system, it is usually better to test for the presence
|
|
||||||
or absence of that specific feature. The return value of
|
|
||||||
@code{software-type} should only be used for this purpose when there is
|
|
||||||
no other easy or unambiguous way of detecting such features."
|
|
||||||
'UNIX)
|
|
||||||
|
|
||||||
(slib:load (in-vicinity (library-vicinity) "require.scm"))
|
|
||||||
|
|
||||||
(define-public require require:require)
|
|
||||||
|
|
||||||
;; {Extensions to the require system so that the user can add new
|
|
||||||
;; require modules easily.}
|
|
||||||
|
|
||||||
(define *vicinity-table*
|
|
||||||
(list
|
|
||||||
(cons 'implementation (implementation-vicinity))
|
|
||||||
(cons 'library (library-vicinity))))
|
|
||||||
|
|
||||||
(define (install-require-vicinity name vicinity)
|
|
||||||
(let ((entry (assq name *vicinity-table*)))
|
|
||||||
(if entry
|
|
||||||
(set-cdr! entry vicinity)
|
|
||||||
(set! *vicinity-table*
|
|
||||||
(acons name vicinity *vicinity-table*)))))
|
|
||||||
|
|
||||||
(define (install-require-module name vicinity-name file-name)
|
|
||||||
(if (not *catalog*) ;Fix which loads catalog in slib
|
|
||||||
(catalog:get 'random)) ;(doesn't load the feature 'random)
|
|
||||||
(let ((entry (assq name *catalog*))
|
|
||||||
(vicinity (cdr (assq vicinity-name *vicinity-table*))))
|
|
||||||
(let ((path-name (in-vicinity vicinity file-name)))
|
|
||||||
(if entry
|
|
||||||
(set-cdr! entry path-name)
|
|
||||||
(set! *catalog*
|
|
||||||
(acons name path-name *catalog*))))))
|
|
|
@ -1,5 +1,6 @@
|
||||||
.libs
|
.libs
|
||||||
.deps
|
.deps
|
||||||
|
guilec
|
||||||
guile-vm
|
guile-vm
|
||||||
stamp-h
|
stamp-h
|
||||||
config.h
|
config.h
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
bin_PROGRAMS = guile-vm
|
bin_PROGRAMS = guile-vm
|
||||||
|
bin_SCRIPTS = guilec
|
||||||
guile_vm_SOURCES = guile-vm.c
|
guile_vm_SOURCES = guile-vm.c
|
||||||
guile_vm_LDADD = libguilevm.la
|
guile_vm_LDADD = libguilevm.la
|
||||||
guile_vm_LDFLAGS = $(GUILE_LDFLAGS)
|
guile_vm_LDFLAGS = $(GUILE_LDFLAGS)
|
||||||
|
|
5
src/guilec.in
Executable file
5
src/guilec.in
Executable file
|
@ -0,0 +1,5 @@
|
||||||
|
#!@bindir@/guile -*- scheme -*-
|
||||||
|
!#
|
||||||
|
|
||||||
|
(use-modules (system base compile))
|
||||||
|
(for-each compile-file (cdr (command-line)))
|
|
@ -219,6 +219,19 @@ do { \
|
||||||
PUSH (l); \
|
PUSH (l); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define POP_LIST_MARK() \
|
||||||
|
do { \
|
||||||
|
SCM o; \
|
||||||
|
SCM l = SCM_EOL; \
|
||||||
|
POP (o); \
|
||||||
|
while (!SCM_UNBNDP (o)) \
|
||||||
|
{ \
|
||||||
|
CONS (l, o, l); \
|
||||||
|
POP (o); \
|
||||||
|
} \
|
||||||
|
PUSH (l); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Instruction operation
|
* Instruction operation
|
||||||
|
@ -256,7 +269,6 @@ do { \
|
||||||
#define ARGS1(a1) SCM a1 = sp[0];
|
#define ARGS1(a1) SCM a1 = sp[0];
|
||||||
#define ARGS2(a1,a2) SCM a1 = sp[-1], a2 = sp[0]; sp--;
|
#define ARGS2(a1,a2) SCM a1 = sp[-1], a2 = sp[0]; sp--;
|
||||||
#define ARGS3(a1,a2,a3) SCM a1 = sp[-2], a2 = sp[-1], a3 = sp[0]; sp -= 2;
|
#define ARGS3(a1,a2,a3) SCM a1 = sp[-2], a2 = sp[-1], a3 = sp[0]; sp -= 2;
|
||||||
#define ARGSN(an) int an = FETCH ();
|
|
||||||
|
|
||||||
#define RETURN(x) do { *sp = x; NEXT; } while (0)
|
#define RETURN(x) do { *sp = x; NEXT; } while (0)
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@
|
||||||
#define VM_DEFINE_INSTRUCTION(tag,name,len,npop,npush) \
|
#define VM_DEFINE_INSTRUCTION(tag,name,len,npop,npush) \
|
||||||
{VM_OPCODE (tag), name, len, npop, npush},
|
{VM_OPCODE (tag), name, len, npop, npush},
|
||||||
#define VM_DEFINE_FUNCTION(tag,name,nargs) \
|
#define VM_DEFINE_FUNCTION(tag,name,nargs) \
|
||||||
{VM_OPCODE (tag), name, (nargs < 0) ? 1 : 0, nargs, 1},
|
{VM_OPCODE (tag), name, 0, nargs, 1},
|
||||||
#define VM_DEFINE_LOADER(tag,name) \
|
#define VM_DEFINE_LOADER(tag,name) \
|
||||||
{VM_OPCODE (tag), name, -1, 0, 1},
|
{VM_OPCODE (tag), name, -1, 0, 1},
|
||||||
|
|
||||||
|
|
|
@ -159,22 +159,30 @@ VM_DEFINE_LOADER (load_program, "load-program")
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
VM_DEFINE_INSTRUCTION (link, "link", 0, 1, 1)
|
VM_DEFINE_LOADER (link, "link")
|
||||||
{
|
{
|
||||||
|
SCM sym;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
FETCH_LENGTH (len);
|
||||||
|
sym = scm_mem2symbol (ip, len);
|
||||||
|
ip += len;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
sp[-1] = scm_c_env_vcell (sp[-1], sp[0], 1);
|
*sp = scm_c_env_vcell (*sp, sym, 1);
|
||||||
sp--;
|
|
||||||
#endif
|
#endif
|
||||||
/* Temporary hack that supports the current module system */
|
{
|
||||||
SCM mod = scm_current_module ();
|
/* Temporary hack that supports the current module system */
|
||||||
SCM var = scm_eval_closure_lookup (scm_standard_eval_closure (mod),
|
SCM mod = scm_current_module ();
|
||||||
*sp, SCM_BOOL_F);
|
SCM var = scm_eval_closure_lookup (scm_standard_eval_closure (mod),
|
||||||
if (SCM_FALSEP (var))
|
sym, SCM_BOOL_F);
|
||||||
/* Create a new variable if not defined yet */
|
if (SCM_FALSEP (var))
|
||||||
var = scm_eval_closure_lookup (scm_standard_eval_closure (mod),
|
/* Create a new variable if not defined yet */
|
||||||
*sp, SCM_BOOL_T);
|
var = scm_eval_closure_lookup (scm_standard_eval_closure (mod),
|
||||||
*sp = SCM_VARVCELL (var);
|
sym, SCM_BOOL_T);
|
||||||
NEXT;
|
PUSH (SCM_VARVCELL (var));
|
||||||
|
NEXT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -158,20 +158,6 @@ VM_DEFINE_FUNCTION (set_cdr, "set-cdr!", 2)
|
||||||
RETURN (SCM_UNSPECIFIED);
|
RETURN (SCM_UNSPECIFIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
VM_DEFINE_FUNCTION (list, "list", -1)
|
|
||||||
{
|
|
||||||
ARGSN (n);
|
|
||||||
POP_LIST (n);
|
|
||||||
NEXT;
|
|
||||||
}
|
|
||||||
|
|
||||||
VM_DEFINE_FUNCTION (vector, "vector", -1)
|
|
||||||
{
|
|
||||||
ARGSN (n);
|
|
||||||
POP_LIST (n);
|
|
||||||
RETURN (scm_vector (*sp));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Numeric relational tests
|
* Numeric relational tests
|
||||||
|
|
|
@ -68,6 +68,12 @@ VM_DEFINE_INSTRUCTION (drop, "drop", 0, 0, 0)
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VM_DEFINE_INSTRUCTION (mark, "mark", 0, 0, 1)
|
||||||
|
{
|
||||||
|
PUSH (SCM_UNDEFINED);
|
||||||
|
NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
VM_DEFINE_INSTRUCTION (dup, "dup", 0, 0, 1)
|
VM_DEFINE_INSTRUCTION (dup, "dup", 0, 0, 1)
|
||||||
{
|
{
|
||||||
SCM x = *sp;
|
SCM x = *sp;
|
||||||
|
@ -136,6 +142,43 @@ VM_DEFINE_INSTRUCTION (make_char8, "make-char8", 1, 0, 1)
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VM_DEFINE_INSTRUCTION (list, "list", 1, -1, 1)
|
||||||
|
{
|
||||||
|
int n = FETCH ();
|
||||||
|
POP_LIST (n);
|
||||||
|
NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
VM_DEFINE_INSTRUCTION (vector, "vector", 1, -1, 1)
|
||||||
|
{
|
||||||
|
int n = FETCH ();
|
||||||
|
POP_LIST (n);
|
||||||
|
*sp = scm_vector (*sp);
|
||||||
|
NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
VM_DEFINE_INSTRUCTION (list_mark, "list-mark", 0, 0, 0)
|
||||||
|
{
|
||||||
|
POP_LIST_MARK ();
|
||||||
|
NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
VM_DEFINE_INSTRUCTION (vector_mark, "vector-mark", 0, 0, 0)
|
||||||
|
{
|
||||||
|
POP_LIST_MARK ();
|
||||||
|
*sp = scm_vector (*sp);
|
||||||
|
NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
VM_DEFINE_INSTRUCTION (list_break, "list-break", 0, 0, 0)
|
||||||
|
{
|
||||||
|
SCM l;
|
||||||
|
POP (l);
|
||||||
|
for (; !SCM_NULLP (l); l = SCM_CDR (l))
|
||||||
|
PUSH (SCM_CAR (l));
|
||||||
|
NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Variable access
|
* Variable access
|
||||||
|
@ -180,7 +223,6 @@ VM_DEFINE_INSTRUCTION (variable_ref, "variable-ref", 0, 0, 1)
|
||||||
SCM o = VARIABLE_REF (x);
|
SCM o = VARIABLE_REF (x);
|
||||||
if (SCM_UNBNDP (o))
|
if (SCM_UNBNDP (o))
|
||||||
{
|
{
|
||||||
/* Try autoload here */
|
|
||||||
err_args = SCM_LIST1 (SCM_CAR (x));
|
err_args = SCM_LIST1 (SCM_CAR (x));
|
||||||
goto vm_error_unbound;
|
goto vm_error_unbound;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue