1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-01 12:20:26 +02:00

Replace ice-9 match's structures with guile's records

* module/system/base/syntax.scm (define-record): Rebase to implement on
  top of Guile's records, which are the substrate of srfi-9's records.
  (%compute-initargs): Rename from %make-struct, just return the list of
  values.
  (get-slot, set-slot!, slot): Removed, no longer used.
  (record-case): Allow slots of the form (MYNAME SLOTNAME), which binds
  SLOTNAME to MYNAME (instead of SLOTNAME to SLOTNAME).
  (record-case, record?): No more ice-9 match!

* module/system/il/compile.scm (codegen): Tweaks so that the new record
  code works.

* module/system/il/ghil.scm: Fix some slot references.

* module/system/vm/assemble.scm (preprocess, codegen): Remove calls to
  `slot'.
  (codegen): Fix some slot references.
This commit is contained in:
Andy Wingo 2008-05-04 17:25:13 +02:00
parent a27bf0b7f6
commit f540e3271b
4 changed files with 54 additions and 83 deletions

View file

@ -53,8 +53,12 @@
(define-macro (define-record def) (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 '(#\< #\>))))) (slot-names (map (lambda (slot) (if (pair? slot) (car slot) slot))
slots))
(stem (symbol-trim-both name (list->char-set '(#\< #\>))))
(type (make-record-type (symbol->string name) slot-names)))
`(begin `(begin
(define ,name ,type)
(define ,(symbol-append 'make- stem) (define ,(symbol-append 'make- stem)
(let ((slots (list ,@(map (lambda (slot) (let ((slots (list ,@(map (lambda (slot)
(if (pair? slot) (if (pair? slot)
@ -62,36 +66,28 @@
`',slot)) `',slot))
slots)))) slots))))
(lambda args (lambda args
(vector ',name (%make-struct args slots))))) (apply ,(record-constructor type)
(define (,(symbol-append name '?) x) (,%compute-initargs args slots)))))
(and (vector? x) (eq? (vector-ref x 0) ',name))) (define ,(symbol-append name '?) ,(record-predicate type))
,@(do ((n 1 (1+ n)) ,@(map (lambda (sname)
(slots (cdr def) (cdr slots)) `(define ,(symbol-append stem '- sname)
(ls '() (append (let* ((sdef (car slots))
(sname (if (pair? sdef) (car sdef) sdef)))
`((define ,(string->symbol
(format #f "~A-~A" name n))
(lambda (x) (slot x ',sname)))
(define ,(symbol-append stem '- sname)
,(make-procedure-with-setter ,(make-procedure-with-setter
(lambda (x) (get-slot x sname)) (record-accessor type sname)
(lambda (x v) (set-slot! x sname v)))))) (record-modifier type sname))))
ls))) slot-names))))
((null? slots) (reverse! ls))))))
(define (%make-struct args slots) (define (%compute-initargs args slots)
(define (finish-bindings out) (define (finish out)
(map (lambda (slot) (map (lambda (slot)
(let ((name (if (pair? slot) (car slot) slot))) (let ((name (if (pair? slot) (car slot) slot)))
(or (assq name out) (cond ((assq name out) => cdr)
(if (pair? slot) ((pair? slot) (cdr slot))
(cons name (cdr slot)) (else (error "unbound slot" args slots name)))))
(error "unbound slot" args slots name)))))
slots)) slots))
(let lp ((in args) (positional slots) (out '())) (let lp ((in args) (positional slots) (out '()))
(cond (cond
((null? in) ((null? in)
(finish-bindings out)) (finish out))
((keyword? (car in)) ((keyword? (car in))
(let ((sym (keyword->symbol (car in)))) (let ((sym (keyword->symbol (car in))))
(cond (cond
@ -106,21 +102,6 @@
(lp (cdr in) (cdr positional) (lp (cdr in) (cdr positional)
(acons (car positional) (car in) out)))))) (acons (car positional) (car in) out))))))
(define (get-slot struct name . names)
(let ((data (assq name (vector-ref struct 1))))
(cond ((not data) (error "unknown slot" name))
((null? names) (cdr data))
(else (apply get-slot (cdr data) names)))))
(define (set-slot! struct name . rest)
(let ((data (assq name (vector-ref struct 1))))
(cond ((not data) (error "unknown slot" name))
((null? (cdr rest)) (set-cdr! data (car rest)))
(else (apply set-slot! (cdr data) rest)))))
(define slot
(make-procedure-with-setter get-slot set-slot!))
;;; ;;;
;;; Variants ;;; Variants
@ -142,33 +123,23 @@
(define-macro (record-case record . clauses) (define-macro (record-case record . clauses)
(let ((r (gensym))) (let ((r (gensym)))
(define (process-clause clause) (define (process-clause clause)
(if (eq? (car clause) 'else)
clause
(let ((record-type (caar clause)) (let ((record-type (caar clause))
(slots (cdar clause)) (slots (cdar clause))
(body (cdr clause))) (body (cdr clause)))
`(((record-predicate ,record-type) ,r) `(((record-predicate ,record-type) ,r)
(let ,(map (lambda (slot) (let ,(map (lambda (slot)
`(,slot ((record-accessor ,record-type ',slot) ,r))) (if (pair? slot)
`(,(car slot) ((record-accessor ,record-type ',(cadr slot)) ,r))
`(,slot ((record-accessor ,record-type ',slot) ,r))))
slots) slots)
,@body)))) ,@body)))))
`(let ((,r ,record)) `(let ((,r ,record))
(cond ,@(map process-clause clauses) (cond ,@(let ((clauses (map process-clause clauses)))
(else (error "unhandled record" ,r)))))) (if (assq 'else clauses)
clauses
;; These are short-lived, and headed to the chopping block. (append clauses `((else (error "unhandled record" ,r))))))))))
(use-modules (ice-9 match))
(define-macro (record-case record . clauses)
(define (process-clause clause)
(if (eq? (car clause) 'else)
clause
`(($ ,@(car clause)) ,@(cdr clause))))
`(,match ,record ,@(map process-clause clauses)))
(define (record? x)
(and (vector? x)
(not (zero? (vector-length x)))
(symbol? (vector-ref x 0))
(eqv? (string-ref (symbol->string (vector-ref x 0)) 0) #\<)))
(export record?)
;;; ;;;

View file

@ -276,10 +276,10 @@
((<ghil-lambda> env loc vars rest body) ((<ghil-lambda> env loc vars rest body)
(return-code! (codegen tree))) (return-code! (codegen tree)))
((<ghil-inline> env loc inst args) ((<ghil-inline> env loc inline args)
;; ARGS... ;; ARGS...
;; (INST NARGS) ;; (INST NARGS)
(push-call! loc inst args) (push-call! loc inline args)
(maybe-drop) (maybe-drop)
(maybe-return)) (maybe-return))
@ -293,19 +293,19 @@
;; ;;
;; main ;; main
(record-case ghil (record-case ghil
((<ghil-lambda> env loc args rest body) ((<ghil-lambda> env loc vars rest body)
(let* ((vars (ghil-env-variables env)) (let* ((evars (ghil-env-variables env))
(locs (pick (lambda (v) (eq? (ghil-var-kind v) 'local)) vars)) (locs (pick (lambda (v) (eq? (ghil-var-kind v) 'local)) evars))
(exts (pick (lambda (v) (eq? (ghil-var-kind v) 'external)) vars))) (exts (pick (lambda (v) (eq? (ghil-var-kind v) 'external)) evars)))
;; initialize variable indexes ;; initialize variable indexes
(finalize-index! args) (finalize-index! vars)
(finalize-index! locs) (finalize-index! locs)
(finalize-index! exts) (finalize-index! exts)
;; meta bindings ;; meta bindings
(push-bindings! args) (push-bindings! vars)
;; export arguments ;; export arguments
(do ((n 0 (1+ n)) (do ((n 0 (1+ n))
(l args (cdr l))) (l vars (cdr l)))
((null? l)) ((null? l))
(let ((v (car l))) (let ((v (car l)))
(case (ghil-var-kind v) (case (ghil-var-kind v)
@ -315,7 +315,7 @@
;; compile body ;; compile body
(comp body #t #f) (comp body #t #f)
;; create GLIL ;; create GLIL
(let ((vars (make-glil-vars :nargs (length args) (let ((vars (make-glil-vars :nargs (length vars)
:nrest (if rest 1 0) :nrest (if rest 1 0)
:nlocs (length locs) :nlocs (length locs)
:nexts (length exts)))) :nexts (length exts))))

View file

@ -155,7 +155,7 @@
(define-public (make-ghil-env e) (define-public (make-ghil-env e)
(record-case e (record-case e
((<ghil-mod>) (%make-ghil-env :mod e :parent e)) ((<ghil-mod>) (%make-ghil-env :mod e :parent e))
((<ghil-env> m) (%make-ghil-env :mod m :parent e)))) ((<ghil-env> mod) (%make-ghil-env :mod mod :parent e))))
(define (ghil-env-toplevel? e) (define (ghil-env-toplevel? e)
(eq? (ghil-env-mod e) (gil-env-parent e))) (eq? (ghil-env-mod e) (gil-env-parent e)))

View file

@ -54,14 +54,14 @@
(define (preprocess x e) (define (preprocess x e)
(record-case x (record-case x
((<glil-asm> vars body) ((<glil-asm> vars body)
(let* ((venv (make-venv :parent e :nexts (slot vars 'nexts) :closure? #f)) (let* ((venv (make-venv :parent e :nexts (glil-vars-nexts vars) :closure? #f))
(body (map (lambda (x) (preprocess x venv)) body))) (body (map (lambda (x) (preprocess x venv)) body)))
(make-vm-asm :venv venv :glil x :body body))) (make-vm-asm :venv venv :glil x :body body)))
((<glil-external> op depth index) ((<glil-external> op depth index)
(do ((d depth (- d 1)) (do ((d depth (- d 1))
(e e (slot e 'parent))) (e e (venv-parent e)))
((= d 0)) ((= d 0))
(set! (slot e 'closure?) #t)) (set! (venv-closure? e) #t))
x) x)
(else x))) (else x)))
@ -100,9 +100,9 @@
(record-case x (record-case x
((<vm-asm> venv) ((<vm-asm> venv)
(push-object! (codegen x #f)) (push-object! (codegen x #f))
(if (slot venv 'closure?) (push-code! `(make-closure)))) (if (venv-closure? venv) (push-code! `(make-closure))))
((<glil-bind> binds) ((<glil-bind> (binds vars))
(let ((bindings (let ((bindings
(map (lambda (v) (map (lambda (v)
(let ((name (car v)) (type (cadr v)) (i (caddr v))) (let ((name (car v)) (type (cadr v)) (i (caddr v)))
@ -123,8 +123,8 @@
((<glil-void>) ((<glil-void>)
(push-code! '(void))) (push-code! '(void)))
((<glil-const> x) ((<glil-const> obj)
(push-object! x)) (push-object! obj))
((<glil-argument> op index) ((<glil-argument> op index)
(if (eq? op 'ref) (if (eq? op 'ref)