From 849cefacf15c265a091aa7d582d14b84f82ddcda Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Sat, 3 May 2008 18:32:46 +0200 Subject: [PATCH] unify variant types and records; also make-foo instead of * module/system/base/syntax.scm (define-record): Rework to separate the type and its constructor. Now (define-record ( bar)) will create `make-foo' as the constructor, not `'. Also the constructor now takes either keyword or positional arguments, so that it can be used as the implementation of variant types as well. (|): Map directly to define-record instead of rolling our own thing. * module/language/scheme/translate.scm: * module/system/base/language.scm: * module/system/il/compile.scm: * module/system/il/ghil.scm: * module/system/il/glil.scm: * module/system/repl/common.scm: * module/system/vm/assemble.scm: * module/system/vm/debug.scm: Change instances of record creation to use the make-foo procedures instead of . Adjust module exports as necessary. --- module/language/scheme/translate.scm | 44 ++++++++-------- module/system/base/language.scm | 2 +- module/system/base/syntax.scm | 79 ++++++++++++++-------------- module/system/il/compile.scm | 64 +++++++++++----------- module/system/il/ghil.scm | 47 ++++++++--------- module/system/il/glil.scm | 28 +++++----- module/system/repl/common.scm | 11 ++-- module/system/vm/assemble.scm | 24 ++++----- module/system/vm/debug.scm | 3 +- 9 files changed, 151 insertions(+), 151 deletions(-) diff --git a/module/language/scheme/translate.scm b/module/language/scheme/translate.scm index 843a8472a..9757c08f0 100644 --- a/module/language/scheme/translate.scm +++ b/module/language/scheme/translate.scm @@ -52,7 +52,7 @@ (call-with-ghil-environment (make-ghil-mod e) '() (lambda (env vars) - ( env #f vars #f (trans env #f x)))))) + (make-ghil-lambda env #f vars #f (trans env #f x)))))) ;;; @@ -139,9 +139,9 @@ ((symbol? x) (let ((y (symbol-expand x))) (if (symbol? y) - ( e l (ghil-lookup e y)) + (make-ghil-ref e l (ghil-lookup e y)) (trans e l y)))) - (else ( e l x)))) + (else (make-ghil-quote e l x)))) (define (symbol-expand x) (let loop ((s (symbol->string x))) @@ -155,7 +155,7 @@ (define (trans:x x) (trans e l x)) (define (trans:pair x) (trans-pair e l (car x) (cdr x))) (define (trans:body body) (trans-body e l body)) - (define (make:void) ( e l)) + (define (make:void) (make-ghil-void e l)) (define (bad-syntax) (syntax-error l (format #f "bad ~A" head) (cons head tail))) (case head @@ -168,26 +168,26 @@ ;; (quote OBJ) ((quote) (match tail - ((obj) ( e l obj)) + ((obj) (make-ghil-quote e l obj)) (else (bad-syntax)))) ;; (quasiquote OBJ) ((quasiquote) (match tail - ((obj) ( e l (trans-quasiquote e l obj))) + ((obj) (make-ghil-quasiquote e l (trans-quasiquote e l obj))) (else (bad-syntax)))) ((define define-private) (match tail ;; (define NAME VAL) (((? symbol? name) val) - ( e l (ghil-lookup e name) (trans:x val))) + (make-ghil-define e l (ghil-lookup e name) (trans:x val))) ;; (define (NAME FORMALS...) BODY...) ((((? symbol? name) . formals) . body) ;; -> (define NAME (lambda FORMALS BODY...)) (let ((val (trans:x `(lambda ,formals ,@body)))) - ( e l (ghil-lookup e name) val))) + (make-ghil-define e l (ghil-lookup e name) val))) (else (bad-syntax)))) @@ -203,7 +203,7 @@ (match tail ;; (set! NAME VAL) (((? symbol? name) val) - ( e l (ghil-lookup e name) (trans:x val))) + (make-ghil-set e l (ghil-lookup e name) (trans:x val))) ;; (set! (NAME ARGS...) VAL) ((((? symbol? name) . args) val) @@ -216,22 +216,22 @@ ((if) (match tail ((test then) - ( e l (trans:x test) (trans:x then) (make:void))) + (make-ghil-if e l (trans:x test) (trans:x then) (make:void))) ((test then else) - ( e l (trans:x test) (trans:x then) (trans:x else))) + (make-ghil-if e l (trans:x test) (trans:x then) (trans:x else))) (else (bad-syntax)))) ;; (and EXPS...) ((and) - ( e l (map trans:x tail))) + (make-ghil-and e l (map trans:x tail))) ;; (or EXPS...) ((or) - ( e l (map trans:x tail))) + (make-ghil-or e l (map trans:x tail))) ;; (begin EXPS...) ((begin) - ( e l (map trans:x tail))) + (make-ghil-begin e l (map trans:x tail))) ((let) (match tail @@ -243,14 +243,14 @@ ;; (let () BODY...) ((() body ...) ;; NOTE: This differs from `begin' - ( e l (list (trans:body body)))) + (make-ghil-begin e l (list (trans:body body)))) ;; (let ((SYM VAL) ...) BODY...) (((((? symbol? sym) val) ...) body ...) (let ((vals (map trans:x val))) (call-with-ghil-bindings e sym (lambda (vars) - ( e l vars vals (trans:body body)))))) + (make-ghil-bind e l vars vals (trans:body body)))))) (else (bad-syntax)))) @@ -270,7 +270,7 @@ (call-with-ghil-bindings e sym (lambda (vars) (let ((vals (map trans:x val))) - ( e l vars vals (trans:body body)))))) + (make-ghil-bind e l vars vals (trans:body body)))))) (else (bad-syntax)))) ;; (cond (CLAUSE BODY...) ...) @@ -321,7 +321,7 @@ (receive (syms rest) (parse-formals formals) (call-with-ghil-environment e syms (lambda (env vars) - ( env l vars rest (trans-body env l body)))))) + (make-ghil-lambda env l vars rest (trans-body env l body)))))) (else (bad-syntax)))) ((eval-case) @@ -339,11 +339,11 @@ (else (if (memq head %scheme-primitives) - ( e l head (map trans:x tail)) + (make-ghil-inline e l head (map trans:x tail)) (if (memq head %forbidden-primitives) (syntax-error l (format #f "`~a' is forbidden" head) (cons head tail)) - ( e l (trans:x head) (map trans:x tail))))))) + (make-ghil-call e l (trans:x head) (map trans:x tail))))))) (define (trans-quasiquote e l x) (cond ((not (pair? x)) x) @@ -352,8 +352,8 @@ (match (cdr x) ((obj) (if (eq? (car x) 'unquote) - ( e l (trans e l obj)) - ( e l (trans e l obj)))) + (make-ghil-unquote e l (trans e l obj)) + (make-ghil-unquote-splicing e l (trans e l obj)))) (else (syntax-error l (format #f "bad ~A" (car x)) x))))) (else (cons (trans-quasiquote e l (car x)) (trans-quasiquote e l (cdr x)))))) diff --git a/module/system/base/language.scm b/module/system/base/language.scm index 44dda1f64..57396e340 100644 --- a/module/system/base/language.scm +++ b/module/system/base/language.scm @@ -36,7 +36,7 @@ )) (define-macro (define-language name . spec) - `(define ,name (, :name ',name ,@spec))) + `(define ,name (,make-language :name ',name ,@spec))) (define (lookup-language name) (let ((m (resolve-module `(language ,name spec)))) diff --git a/module/system/base/syntax.scm b/module/system/base/syntax.scm index 3a61ea6f6..8599d99fc 100644 --- a/module/system/base/syntax.scm +++ b/module/system/base/syntax.scm @@ -73,17 +73,22 @@ ;;; Record ;;; +(define (symbol-trim-both sym pred) + (string->symbol (string-trim-both (symbol->string sym) pred))) + + (define-macro (define-record def) - (let ((name (car def)) (slots (cdr def))) + (let* ((name (car def)) (slots (cdr def)) + (stem (symbol-trim-both name (list->char-set '(#\< #\>))))) `(begin - (define (,name . args) - (vector ',name (%make-struct - args - (list ,@(map (lambda (slot) - (if (pair? slot) - `(cons ',(car slot) ,(cadr slot)) - `',slot)) - slots))))) + (define ,(symbol-append 'make- stem) + (let ((slots (list ,@(map (lambda (slot) + (if (pair? slot) + `(cons ',(car slot) ,(cadr slot)) + `',slot)) + slots)))) + (lambda args + (vector ',name (%make-struct args slots))))) (define (,(symbol-append name '?) x) (and (vector? x) (eq? (vector-ref x 0) ',name))) ,@(do ((n 1 (1+ n)) @@ -96,22 +101,32 @@ ls))) ((null? slots) (reverse! ls)))))) -(define *unbound* "#") - (define (%make-struct args slots) - (map (lambda (slot) - (let* ((key (if (pair? slot) (car slot) slot)) - (def (if (pair? slot) (cdr slot) *unbound*)) - (val (get-key args (symbol->keyword key) def))) - (if (eq? val *unbound*) - (error "slot unbound" key) - (cons key val)))) - slots)) - -(define (get-key klist key def) - (do ((ls klist (cddr ls))) - ((or (null? ls) (eq? (car ls) key)) - (if (null? ls) def (cadr ls))))) + (define (finish-bindings out) + (map (lambda (slot) + (let ((name (if (pair? slot) (car slot) slot))) + (or (assq name out) + (if (pair? slot) + (cons name (cdr slot)) + (error "unbound slot" args slots name))))) + slots)) + (let lp ((in args) (positional slots) (out '())) + (cond + ((null? in) + (finish-bindings out)) + ((keyword? (car in)) + (let ((sym (keyword->symbol (car in)))) + (cond + ((and (not (memq sym slots)) + (not (assq sym (filter pair? slots)))) + (error "unknown slot" sym)) + ((assq sym out) (error "slot already set" sym out)) + (else (lp (cddr in) '() (acons sym (cadr in) out)))))) + ((null? positional) + (error "too many initargs" args slots)) + (else + (lp (cdr in) (cdr positional) + (acons (car positional) (car in) out)))))) (define (get-slot struct name . names) (let ((data (assq name (vector-ref struct 1)))) @@ -134,21 +149,7 @@ ;;; (define-macro (| . rest) - `(begin ,@(map %make-variant-type rest))) - -(define (%make-variant-type def) - (let ((name (car def)) (slots (cdr def))) - `(begin - (define ,def (vector ',name ,@slots)) - (define (,(symbol-append name '?) x) - (and (vector? x) (eq? (vector-ref x 0) ',name))) - ,@(do ((n 1 (1+ n)) - (slots slots (cdr slots)) - (ls '() (cons `(define ,(string->symbol - (format #f "~A-~A" name n)) - ,(string->symbol (format #f "%slot-~A" n))) - ls))) - ((null? slots) (reverse! ls)))))) + `(begin ,@(map (lambda (def) `(define-record ,def)) rest))) (define (%slot-1 x) (vector-ref x 1)) (define (%slot-2 x) (vector-ref x 2)) diff --git a/module/system/il/compile.scm b/module/system/il/compile.scm index eab25d600..549dd2e80 100644 --- a/module/system/il/compile.scm +++ b/module/system/il/compile.scm @@ -39,23 +39,23 @@ (define (optimize x) (match x (($ env var val) - ( env var (optimize val))) + (make-ghil-set env var (optimize val))) (($ test then else) - ( (optimize test) (optimize then) (optimize else))) + (make-ghil-if (optimize test) (optimize then) (optimize else))) (($ exps) - ( (map optimize exps))) + (make-ghil-begin (map optimize exps))) (($ env vars vals body) - ( env vars (map optimize vals) (optimize body))) + (make-ghil-bind env vars (map optimize vals) (optimize body))) (($ env vars rest body) - ( env vars rest (optimize body))) + (make-ghil-lambda env vars rest (optimize body))) ;; FIXME: does not exist. -- Ludo'. ; (($ inst args) -; ( inst (map optimize args))) +; (make-ghil-inst inst (map optimize args))) (($ env proc args) (match proc @@ -67,9 +67,9 @@ (set! v.env env) (ghil-env-add! env v)) lambda-env.variables) - (optimize ( env vars args body))) + (optimize (make-ghil-bind env vars args body))) (else - ( env (optimize proc) (map optimize args))))) + (make-ghil-call env (optimize proc) (map optimize args))))) (else x))) @@ -77,25 +77,25 @@ ;;; Stage 3: Code generation ;;; -(define *ia-void* ()) -(define *ia-drop* ( 'drop 0)) -(define *ia-return* ( 'return 0)) +(define *ia-void* (make-glil-void)) +(define *ia-drop* (make-glil-call 'drop 0)) +(define *ia-return* (make-glil-call 'return 0)) (define (make-label) (gensym ":L")) (define (make-glil-var op env var) (case var.kind ((argument) - ( op var.index)) + (make-glil-argument op var.index)) ((local) - ( op var.index)) + (make-glil-local op var.index)) ((external) (do ((depth 0 (1+ depth)) (e env e.parent)) ((eq? e var.env) - ( op depth var.index)))) + (make-glil-external op depth var.index)))) ((module) - ( op var.env var.name)) + (make-glil-module op var.env var.name)) (else (error "Unknown kind of variable:" var)))) (define (codegen ghil) @@ -104,13 +104,13 @@ (set! stack (cons code stack))) (define (comp tree tail drop) (define (push-label! label) - (push-code! ( label))) + (push-code! (make-glil-label label))) (define (push-branch! inst label) - (push-code! ( inst label))) + (push-code! (make-glil-branch inst label))) (define (push-call! loc inst args) (for-each comp-push args) - (push-code! ( inst (length args))) - (push-code! ( loc))) + (push-code! (make-glil-call inst (length args))) + (push-code! (make-glil-source loc))) ;; possible tail position (define (comp-tail tree) (comp tree tail drop)) ;; push the result @@ -132,7 +132,7 @@ (return-code! *ia-void*)) ;; return object if necessary (define (return-object! obj) - (return-code! ( obj))) + (return-code! (make-glil-const obj))) ;; ;; dispatch (match tree @@ -152,14 +152,14 @@ ((? pair? pp) (loop (car pp)) (loop (cdr pp)) - (push-code! ( 'cons 2))) + (push-code! (make-glil-call 'cons 2))) (($ env loc exp) (comp-push exp)) (($ env loc exp) (comp-push exp) (push-call! #f 'list-break '())) (else - (push-code! ( x))))) + (push-code! (make-glil-const x))))) (maybe-drop) (maybe-return)) @@ -253,11 +253,11 @@ ;; BODY (for-each comp-push vals) (let ((vars (map (lambda (v) (list v.name v.kind v.index)) vars))) - (if (not (null? vars)) (push-code! ( vars)))) + (if (not (null? vars)) (push-code! (make-glil-bind vars)))) (for-each (lambda (var) (push-code! (make-glil-var 'set env var))) (reverse vars)) (comp-tail body) - (push-code! ())) + (push-code! (make-glil-unbind))) (($ env loc vars rest body) (return-code! (codegen tree))) @@ -289,23 +289,23 @@ (finalize-index! exts) ;; meta bindings (let ((vars (map (lambda (v) (list v.name v.kind v.index)) args))) - (if (not (null? vars)) (push-code! ( vars)))) + (if (not (null? vars)) (push-code! (make-glil-bind vars)))) ;; export arguments (do ((n 0 (1+ n)) (l args (cdr l))) ((null? l)) (let ((v (car l))) (cond ((eq? v.kind 'external) - (push-code! ( 'ref n)) - (push-code! ( 'set 0 v.index)))))) + (push-code! (make-glil-argument 'ref n)) + (push-code! (make-glil-external 'set 0 v.index)))))) ;; compile body (comp body #t #f) ;; create GLIL - (let ((vars ( :nargs (length args) - :nrest (if rest 1 0) - :nlocs (length locs) - :nexts (length exts)))) - ( vars (reverse! stack)))))))) + (let ((vars (make-glil-vars :nargs (length args) + :nrest (if rest 1 0) + :nlocs (length locs) + :nexts (length exts)))) + (make-glil-asm vars (reverse! stack)))))))) (define (finalize-index! list) (do ((n 0 (1+ n)) diff --git a/module/system/il/ghil.scm b/module/system/il/ghil.scm index ea3d66e4e..84814bd13 100644 --- a/module/system/il/ghil.scm +++ b/module/system/il/ghil.scm @@ -25,33 +25,33 @@ :use-module (ice-9 regex) :export ( - ? -1 -2 - ? -1 -2 -3 - ? + make-ghil-void ? -1 -2 + make-ghil-quote ? -1 -2 -3 + make-ghil-quasiquote ? -1 -2 -3 - ? + make-ghil-unquote ? -1 -2 -3 - ? + make-ghil-unquote-splicing ? -1 -2 -3 - ? -1 -2 -3 - ? -1 -2 -3 -4 - ? + make-ghil-ref ? -1 -2 -3 + make-ghil-set ? -1 -2 -3 -4 + make-ghil-define ? -1 -2 -3 -4 - ? + make-ghil-if ? -1 -2 -3 -4 -5 - ? -1 -2 -3 - ? -1 -2 -3 - ? -1 -2 -3 - ? + make-ghil-and ? -1 -2 -3 + make-ghil-or ? -1 -2 -3 + make-ghil-begin ? -1 -2 -3 + make-ghil-bind ? -1 -2 -3 -4 -5 - ? -1 -2 + make-ghil-lambda ? -1 -2 -3 -4 -5 - ? + make-ghil-inline ? -1 -2 -3 -4 - ? + make-ghil-call ? -1 -2 -3 -4 )) @@ -112,9 +112,7 @@ ;;; (define-record ( env name kind (type #f) (value #f) (index #f))) - -(define-public (make-ghil-var env name kind) - ( :env env :name name :kind kind)) +(export make-ghil-var) ;;; @@ -122,9 +120,7 @@ ;;; (define-record ( module (table '()) (imports '()))) - -(define-public (make-ghil-mod module) - ( :module module)) +(export make-ghil-mod) ;;; @@ -133,10 +129,11 @@ (define-record ( mod parent (table '()) (variables '()))) +(define %make-ghil-env make-ghil-env) (define-public (make-ghil-env e) - (match e - (($ ) ( :mod e :parent e)) - (($ m) ( :mod m :parent e)))) + (record-case e + (() (%make-ghil-env :mod e :parent e)) + (( m) (%make-ghil-env :mod m :parent e)))) (define (ghil-env-toplevel? e) (eq? e.mod e.parent)) diff --git a/module/system/il/glil.scm b/module/system/il/glil.scm index f4a5c560d..8b10c4b4b 100644 --- a/module/system/il/glil.scm +++ b/module/system/il/glil.scm @@ -24,26 +24,26 @@ :use-module (ice-9 match) :export (pprint-glil - - ? + make-glil-vars + make-glil-asm ? -1 -2 -3 -4 -5 - ? -1 - ? - ? -1 -2 + make-glil-bind ? -1 + make-glil-unbind ? + make-glil-source ? -1 -2 - ? - ? -1 + make-glil-void ? + make-glil-const ? -1 - ? -1 -2 - ? -1 -2 - ? + make-glil-argument ? -1 -2 + make-glil-local ? -1 -2 + make-glil-external ? -1 -2 -3 - ? + make-glil-module ? -1 -2 -3 - ? -1 - ? -1 -2 - ? -1 -2 + make-glil-label ? -1 + make-glil-branch ? -1 -2 + make-glil-call ? -1 -2 )) (define-record ( nargs nrest nlocs nexts)) diff --git a/module/system/repl/common.scm b/module/system/repl/common.scm index ba3fe5aa5..eb2ad601c 100644 --- a/module/system/repl/common.scm +++ b/module/system/repl/common.scm @@ -35,15 +35,16 @@ (define repl-default-options '((trace . #f))) +(define %make-repl make-repl) (define-public (make-repl lang) (let ((cenv (make-cenv :vm (the-vm) :language (lookup-language lang) :module (current-module)))) - ( :env cenv - :options repl-default-options - :tm-stats (times) - :gc-stats (gc-stats) - :vm-stats (vm-stats cenv.vm)))) + (%make-repl :env cenv + :options repl-default-options + :tm-stats (times) + :gc-stats (gc-stats) + :vm-stats (vm-stats cenv.vm)))) (define-public (repl-welcome repl) (format #t "~A interpreter ~A on Guile ~A\n" diff --git a/module/system/vm/assemble.scm b/module/system/vm/assemble.scm index 47e7b8a69..a885e571e 100644 --- a/module/system/vm/assemble.scm +++ b/module/system/vm/assemble.scm @@ -55,9 +55,9 @@ (define (preprocess x e) (record-case x (( vars body) - (let* ((venv ( :parent e :nexts (slot vars 'nexts) :closure? #f)) + (let* ((venv (make-venv :parent e :nexts (slot vars 'nexts) :closure? #f)) (body (map (lambda (x) (preprocess x venv)) body))) - ( :venv venv :glil x :body body))) + (make-vm-asm :venv venv :glil x :body body))) (( op depth index) (do ((d depth (- d 1)) (e e (slot e 'parent))) @@ -147,7 +147,7 @@ (push-code! `(external-set ,(+ n index))))))) (( op module name) - (push-object! ( :module #f :name name)) + (push-object! (make-vlink :module #f :name name)) (if (eq? op 'ref) (push-code! '(variable-ref)) (push-code! '(variable-set)))) @@ -175,15 +175,15 @@ (let ((bytes (stack->bytes (reverse! stack) label-alist))) (if toplevel (bytecode->objcode bytes vars.nlocs vars.nexts) - ( :vars vars :bytes bytes - :meta (if (and (null? binding-alist) - (null? source-alist)) - #f - (cons (reverse! binding-alist) - (reverse! source-alist))) - :objs (let ((objs (map car (reverse! object-alist)))) - (if (null? objs) #f (list->vector objs))) - :closure? venv.closure?))))))))) + (make-bytespec :vars vars :bytes bytes + :meta (if (and (null? binding-alist) + (null? source-alist)) + #f + (cons (reverse! binding-alist) + (reverse! source-alist))) + :objs (let ((objs (map car (reverse! object-alist)))) + (if (null? objs) #f (list->vector objs))) + :closure? venv.closure?))))))))) (define (object-assoc x alist) (record-case x diff --git a/module/system/vm/debug.scm b/module/system/vm/debug.scm index c78f28aa4..686d89714 100644 --- a/module/system/vm/debug.scm +++ b/module/system/vm/debug.scm @@ -38,7 +38,8 @@ (let ((chain (vm-last-frame-chain vm))) (if (null? chain) (display "Nothing to debug\n") - (debugger-repl ( :vm vm :chain chain :index (length chain)))))) + (debugger-repl (make-debugger + :vm vm :chain chain :index (length chain)))))) (define (debugger-repl db) (let loop ()