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

Convert assemble.scm to use record-case.

* module/system/base/syntax.scm (record?): Temporarily export this thing,
  so that code will remain correct when I change to srfi-9 records.

* module/system/vm/assemble.scm: Convert to use record-case.
This commit is contained in:
Andy Wingo 2008-05-03 14:52:36 +02:00
parent 7ef8d0a008
commit 1aa0dd2b45
2 changed files with 72 additions and 60 deletions

View file

@ -175,11 +175,21 @@
(cond ,@(map process-clause clauses) (cond ,@(map process-clause clauses)
(else (error "unhandled record" ,r)))))) (else (error "unhandled record" ,r))))))
;; These are short-lived, and headed to the chopping block.
(use-modules (ice-9 match)) (use-modules (ice-9 match))
(define-macro (record-case record . clauses) (define-macro (record-case record . clauses)
(define (process-clause clause) (define (process-clause clause)
`(($ ,@(car clause)) ,@(cdr clause))) (if (eq? (car clause) 'else)
`(match ,record ,(map process-clause clauses))) 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

@ -53,12 +53,12 @@
;;; ;;;
(define (preprocess x e) (define (preprocess x e)
(match x (record-case x
(($ <glil-asm> vars body) ((<glil-asm> vars body)
(let* ((venv (<venv> :parent e :nexts (slot vars 'nexts) :closure? #f)) (let* ((venv (<venv> :parent e :nexts (slot vars 'nexts) :closure? #f))
(body (map (lambda (x) (preprocess x venv)) body))) (body (map (lambda (x) (preprocess x venv)) body)))
(<vm-asm> :venv venv :glil x :body body))) (<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 (slot e 'parent)))
((= d 0)) ((= d 0))
@ -72,8 +72,8 @@
;;; ;;;
(define (codegen glil toplevel) (define (codegen glil toplevel)
(match glil (record-case glil
(($ <vm-asm> venv ($ <glil-asm> vars _) body) ((<vm-asm> venv glil body) (record-case glil ((<glil-asm> vars)
(let ((stack '()) (let ((stack '())
(binding-alist '()) (binding-alist '())
(source-alist '()) (source-alist '())
@ -98,12 +98,12 @@
(else 3))) (else 3)))
(apply + (map byte-length stack))) (apply + (map byte-length stack)))
(define (generate-code x) (define (generate-code x)
(match 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 (slot venv 'closure?) (push-code! `(make-closure))))
(($ <glil-bind> binds) ((<glil-bind> binds)
(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)))
@ -115,29 +115,29 @@
(set! binding-alist (set! binding-alist
(acons (current-address) bindings binding-alist)))) (acons (current-address) bindings binding-alist))))
(($ <glil-unbind>) ((<glil-unbind>)
(set! binding-alist (acons (current-address) #f binding-alist))) (set! binding-alist (acons (current-address) #f binding-alist)))
(($ <glil-source> loc) ((<glil-source> loc)
(set! source-alist (acons (current-address) loc source-alist))) (set! source-alist (acons (current-address) loc source-alist)))
(($ <glil-void>) ((<glil-void>)
(push-code! '(void))) (push-code! '(void)))
(($ <glil-const> x) ((<glil-const> x)
(push-object! x)) (push-object! x))
(($ <glil-argument> op index) ((<glil-argument> op index)
(if (eq? op 'ref) (if (eq? op 'ref)
(push-code! `(local-ref ,index)) (push-code! `(local-ref ,index))
(push-code! `(local-set ,index)))) (push-code! `(local-set ,index))))
(($ <glil-local> op index) ((<glil-local> op index)
(if (eq? op 'ref) (if (eq? op 'ref)
(push-code! `(local-ref ,(+ vars.nargs index))) (push-code! `(local-ref ,(+ vars.nargs index)))
(push-code! `(local-set ,(+ vars.nargs index))))) (push-code! `(local-set ,(+ vars.nargs index)))))
(($ <glil-external> op depth index) ((<glil-external> op depth index)
(do ((e venv e.parent) (do ((e venv e.parent)
(d depth (1- d)) (d depth (1- d))
(n 0 (+ n e.nexts))) (n 0 (+ n e.nexts)))
@ -146,19 +146,19 @@
(push-code! `(external-ref ,(+ n index))) (push-code! `(external-ref ,(+ n index)))
(push-code! `(external-set ,(+ n index))))))) (push-code! `(external-set ,(+ n index)))))))
(($ <glil-module> op module name) ((<glil-module> op module name)
(push-object! (<vlink> :module #f :name name)) (push-object! (<vlink> :module #f :name name))
(if (eq? op 'ref) (if (eq? op 'ref)
(push-code! '(variable-ref)) (push-code! '(variable-ref))
(push-code! '(variable-set)))) (push-code! '(variable-set))))
(($ <glil-label> label) ((<glil-label> label)
(set! label-alist (assq-set! label-alist label (current-address)))) (set! label-alist (assq-set! label-alist label (current-address))))
(($ <glil-branch> inst label) ((<glil-branch> inst label)
(set! stack (cons (list inst label) stack))) (set! stack (cons (list inst label) stack)))
(($ <glil-call> inst nargs) ((<glil-call> inst nargs)
(if (instruction? inst) (if (instruction? inst)
(let ((pops (instruction-pops inst))) (let ((pops (instruction-pops inst)))
(cond ((< pops 0) (cond ((< pops 0)
@ -183,11 +183,11 @@
(reverse! source-alist))) (reverse! source-alist)))
:objs (let ((objs (map car (reverse! object-alist)))) :objs (let ((objs (map car (reverse! object-alist))))
(if (null? objs) #f (list->vector objs))) (if (null? objs) #f (list->vector objs)))
:closure? venv.closure?))))))) :closure? venv.closure?)))))))))
(define (object-assoc x alist) (define (object-assoc x alist)
(match x (record-case x
(($ <vlink>) (assoc x alist)) ((<vlink>) (assoc x alist))
(else (assq x alist)))) (else (assq x alist))))
(define (stack->bytes stack label-alist) (define (stack->bytes stack label-alist)
@ -222,9 +222,9 @@
(let dump! ((x x)) (let dump! ((x x))
(cond (cond
((object->code x) => push-code!) ((object->code x) => push-code!)
(else ((record? x)
(match x (record-case x
(($ <bytespec> vars bytes meta objs closure?) ((<bytespec> vars bytes meta objs closure?)
;; dump parameters ;; dump parameters
(let ((nargs vars.nargs) (nrest vars.nrest) (let ((nargs vars.nargs) (nrest vars.nrest)
(nlocs vars.nlocs) (nexts vars.nexts)) (nlocs vars.nlocs) (nexts vars.nexts))
@ -250,39 +250,41 @@
(if meta (dump! meta)) (if meta (dump! meta))
;; dump bytecode ;; dump bytecode
(push-code! `(load-program ,bytes))) (push-code! `(load-program ,bytes)))
(($ <vlink> module name) ((<vlink> module name)
;; FIXME: dump module ;; FIXME: dump module
(push-code! `(link ,(symbol->string name)))) (push-code! `(link ,(symbol->string name))))
(($ <vmod> id) ((<vmod> id)
(push-code! `(load-module ,id))) (push-code! `(load-module ,id)))
((and ($ integer) ($ exact)) (else
(error "assemble: unknown record type"))))
((and (integer? x) (exact? x))
(let ((str (do ((n x (quotient n 256)) (let ((str (do ((n x (quotient n 256))
(l '() (cons (modulo n 256) l))) (l '() (cons (modulo n 256) l)))
((= n 0) ((= n 0)
(apply u8vector l))))) (apply u8vector l)))))
(push-code! `(load-integer ,str)))) (push-code! `(load-integer ,str))))
(($ number) ((number? x)
(push-code! `(load-number ,(number->string x)))) (push-code! `(load-number ,(number->string x))))
(($ string) ((string? x)
(push-code! `(load-string ,x))) (push-code! `(load-string ,x)))
(($ symbol) ((symbol? x)
(push-code! `(load-symbol ,(symbol->string x)))) (push-code! `(load-symbol ,(symbol->string x))))
(($ keyword) ((keyword? x)
(push-code! `(load-keyword (push-code! `(load-keyword
,(symbol->string (keyword-dash-symbol x))))) ,(symbol->string (keyword-dash-symbol x)))))
(($ list) ((list? x)
(for-each dump! x) (for-each dump! x)
(let ((len (length x))) (let ((len (length x)))
(if (>= len 65536) (too-long 'list)) (if (>= len 65536) (too-long 'list))
(push-code! `(list ,(quotient len 256) ,(modulo len 256))))) (push-code! `(list ,(quotient len 256) ,(modulo len 256)))))
(($ pair) ((pair? x)
(dump! (car x)) (dump! (car x))
(dump! (cdr x)) (dump! (cdr x))
(push-code! `(cons))) (push-code! `(cons)))
(($ vector) ((vector? x)
(for-each dump! (vector->list x)) (for-each dump! (vector->list x))
(let ((len (vector-length x))) (let ((len (vector-length x)))
(if (>= len 65536) (too-long 'vector)) (if (>= len 65536) (too-long 'vector))
(push-code! `(vector ,(quotient len 256) ,(modulo len 256))))) (push-code! `(vector ,(quotient len 256) ,(modulo len 256)))))
(else (else
(error "assemble: unrecognized object" x))))))) (error "assemble: unrecognized object" x)))))