(let ((loc (location exp))
(retrans (lambda (x) (parse-ghil env x))))
(pmatch exp
- (,exp (guard (symbol? exp))
- (make-ghil-ref env #f (ghil-var-for-ref! env exp)))
-
- (,exp (guard (not (pair? exp)))
- (make-ghil-quote #:env env #:loc #f #:obj exp))
+ ((ref ,sym) (guard (symbol? sym))
+ (make-ghil-ref env #f (ghil-var-for-ref! env sym)))
(('quote ,exp) (make-ghil-quote #:env env #:loc loc #:obj exp))
(let ((vals (map (lambda (exp) (parse-ghil env exp)) exprs)))
(make-ghil-bind env loc vars vals (retrans `(begin ,@body)))))))
- ((set! ,sym ,val)
+ ((set ,sym ,val)
(make-ghil-set env loc (ghil-var-for-set! env sym) (retrans val)))
((define ,sym ,val)
((<ghil-void> env loc)
'(void))
((<ghil-quote> env loc obj)
- (if (symbol? obj)
- `(,'quote ,obj)
- obj))
+ `(,'quote ,obj))
((<ghil-quasiquote> env loc exp)
`(,'quasiquote ,(map unparse-ghil exp)))
((<ghil-unquote> env loc exp)
`(,'unquote-splicing ,(unparse-ghil exp)))
;; Variables
((<ghil-ref> env loc var)
- (ghil-var-name var))
+ `(ref ,(ghil-var-name var)))
((<ghil-set> env loc var val)
- `(set! ,(ghil-var-name var) ,(unparse-ghil val)))
+ `(set ,(ghil-var-name var) ,(unparse-ghil val)))
((<ghil-define> env loc var val)
`(define ,(ghil-var-name var) ,(unparse-ghil val)))
;; Controls
(maybe-drop)
(maybe-return))
+ ((<ghil-unquote> env loc exp)
+ (error "unquote outside of quasiquote" exp))
+
+ ((<ghil-unquote-splicing> env loc exp)
+ (error "unquote-splicing outside of quasiquote" exp))
+
((<ghil-ref> env loc var)
(return-code! loc (make-glil-var 'ref env var)))
;; compile body
(comp body #t #f)
;; create GLIL
- (let ((vars (make-glil-vars #:nargs (length vars)
- #:nrest (if rest 1 0)
- #:nlocs (length locs)
- #:nexts (length exts))))
- (make-glil-asm vars meta (reverse! stack))))))))
+ (make-glil-asm
+ (length vars) (if rest 1 0) (length locs) (length exts)
+ meta (reverse! stack)))))))
(define (finalize-index! list)
(do ((n 0 (1+ n))
(apply write (unparse-ghil exp) port))
(define (parse x)
- (call-with-ghil-environment (make-ghil-toplevel-env e) '()
+ (call-with-ghil-environment (make-ghil-toplevel-env (current-module)) '()
(lambda (env vars)
(make-ghil-lambda env #f vars #f '() (parse-ghil env x)))))
#:use-module (system base syntax)
#:use-module (system base pmatch)
#:export
- (<glil-vars> make-glil-vars
- glil-vars-nargs glil-vars-nrest glil-vars-nlocs glil-vars-nexts
-
- <glil-asm> make-glil-asm glil-asm?
- glil-asm-vars glil-asm-meta glil-asm-body
+ (<glil-asm> make-glil-asm glil-asm?
+ glil-asm-nargs glil-asm-nrest glil-asm-nlocs glil-asm-nexts
+ glil-asm-meta glil-asm-body
<glil-bind> make-glil-bind glil-bind?
glil-bind-vars
parse-glil unparse-glil))
-(define-record <glil-vars> nargs nrest nlocs nexts)
-
(define (print-glil x port)
(format port "#<glil ~s>" (unparse-glil x)))
(define-type (<glil> #:printer print-glil)
;; Meta operations
- (<glil-asm> vars meta body)
+ (<glil-asm> nargs nrest nlocs nexts meta body)
(<glil-bind> vars)
(<glil-mv-bind> vars rest)
(<glil-unbind>)
\f
(define (parse-glil x)
(pmatch x
- ((asm (,nargs ,nrest ,nlocs ,next) ,meta . ,body)
- (make-glil-asm (make-glil-vars nargs nrest nlocs next)
- meta (map parse-glil body)))
+ ((asm ,nargs ,nrest ,nlocs ,nexts ,meta . ,body)
+ (make-glil-asm nargs nrest nlocs nexts meta (map parse-glil body)))
((bind . ,vars) (make-glil-bind vars))
((mv-bind ,vars . ,rest) (make-glil-mv-bind vars (map parse-glil rest)))
((unbind) (make-glil-unbind))
(define (unparse-glil glil)
(record-case glil
;; meta
- ((<glil-asm> vars meta body)
- `(asm (,(glil-vars-nargs vars) ,(glil-vars-nrest vars)
- ,(glil-vars-nlocs vars) ,(glil-vars-nexts vars))
- ,meta
- ,@(map unparse-glil body)))
+ ((<glil-asm> nargs nrest nlocs nexts meta body)
+ `(asm ,nargs ,nrest ,nlocs ,nexts ,meta ,@(map unparse-glil body)))
((<glil-bind> vars) `(bind ,@vars))
((<glil-mv-bind> vars rest) `(mv-bind ,vars ,@rest))
((<glil-unbind>) `(unbind))
(define-record <vlink-now> key)
(define-record <vlink-later> key)
(define-record <vdefine> name)
-(define-record <bytespec> vars bytes meta objs closure?)
+(define-record <bytespec> nargs nrest nlocs nexts bytes meta objs closure?)
\f
;;;
(define (preprocess x e)
(record-case x
- ((<glil-asm> vars meta body)
- (let* ((venv (make-venv #:parent e #:nexts (glil-vars-nexts vars) #:closure? #f))
+ ((<glil-asm> nargs nrest nlocs nexts meta body)
+ (let* ((venv (make-venv #:parent e #:nexts nexts #:closure? #f))
(body (map (lambda (x) (preprocess x venv)) body)))
(make-vm-asm #:venv venv #:glil x #:body body)))
((<glil-external> op depth index)
(push (code->bytes code) stack))
(dump-object! push-code! `(,bindings ,sources ,@tail))
(push-code! '(return))
- (make-bytespec #:vars (make-glil-vars 0 0 0 0)
+ (make-bytespec #:nargs 0 #:nrest 0 #:nlocs 0 #:nexts 0
#:bytes (stack->bytes (reverse! stack) '())
#:meta #f #:objs #f #:closure? #f))))
(define (codegen glil toplevel)
(record-case glil
- ((<vm-asm> venv glil body) (record-case glil ((<glil-asm> vars meta) ; body?
+ ((<vm-asm> venv glil body) (record-case glil ((<glil-asm> nargs nrest nlocs nexts meta) ; body?
(let ((stack '())
(open-bindings '())
(closed-bindings '())
(push-object! (codegen x #f))
(if (venv-closure? venv) (push-code! `(make-closure))))
- ((<glil-bind> (binds vars))
- (push-bindings! (munge-bindings binds (glil-vars-nargs vars))))
+ ((<glil-bind> vars)
+ (push-bindings! (munge-bindings vars nargs)))
- ((<glil-mv-bind> (binds vars) rest)
- (push-bindings! (munge-bindings binds (glil-vars-nargs vars)))
+ ((<glil-mv-bind> vars rest)
+ (push-bindings! (munge-bindings vars nargs))
(push-code! `(truncate-values ,(length binds) ,(if rest 1 0))))
((<glil-unbind>)
((<glil-local> op index)
(if (eq? op 'ref)
- (push-code! `(local-ref ,(+ (glil-vars-nargs vars) index)))
- (push-code! `(local-set ,(+ (glil-vars-nargs vars) index)))))
+ (push-code! `(local-ref ,(+ nargs index)))
+ (push-code! `(local-set ,(+ nargs index)))))
((<glil-external> op depth index)
(do ((e venv (venv-parent e))
; (format #t "codegen: stack = ~a~%" (reverse stack))
(let ((bytes (stack->bytes (reverse! stack) label-alist)))
(if toplevel
- (bytecode->objcode bytes (glil-vars-nlocs vars) (glil-vars-nexts vars))
- (make-bytespec #:vars vars #:bytes bytes
+ (bytecode->objcode bytes nlocs nexts)
+ (make-bytespec #:nargs nargs #:nrest nrest #:nlocs nlocs
+ #:nexts nexts #:bytes bytes
#:meta (make-meta closed-bindings
(reverse! source-alist)
meta)
((object->code x) => push-code!)
((record? x)
(record-case x
- ((<bytespec> vars bytes meta objs closure?)
- ;; dump parameters
- (let ((nargs (glil-vars-nargs vars)) (nrest (glil-vars-nrest vars))
- (nlocs (glil-vars-nlocs vars)) (nexts (glil-vars-nexts vars)))
- (cond
- ((and (< nargs 16) (< nlocs 128) (< nexts 16))
- ;; 16-bit representation
- (let ((x (logior
- (ash nargs 12) (ash nrest 11) (ash nlocs 4) nexts)))
- (push-code! `(make-int16 ,(ash x -8) ,(logand x (1- (ash 1 8)))))))
- (else
- ;; Other cases
- (if (> (+ nargs nlocs) 255)
- (error "too many locals" nargs nlocs))
- ;; really it should be a flag..
- (if (> nrest 1) (error "nrest should be 0 or 1" nrest))
- (if (> nexts 255) (error "too many externals" nexts))
- (push-code! (object->code nargs))
- (push-code! (object->code nrest))
- (push-code! (object->code nlocs))
- (push-code! (object->code nexts))
- (push-code! (object->code #f)))))
+ ((<bytespec> nargs nrest nlocs nexts bytes meta objs closure?)
+ ;; dump parameters
+ (cond
+ ((and (< nargs 16) (< nlocs 128) (< nexts 16))
+ ;; 16-bit representation
+ (let ((x (logior
+ (ash nargs 12) (ash nrest 11) (ash nlocs 4) nexts)))
+ (push-code! `(make-int16 ,(ash x -8) ,(logand x (1- (ash 1 8)))))))
+ (else
+ ;; Other cases
+ (if (> (+ nargs nlocs) 255)
+ (error "too many locals" nargs nlocs))
+ ;; really it should be a flag..
+ (if (> nrest 1) (error "nrest should be 0 or 1" nrest))
+ (if (> nexts 255) (error "too many externals" nexts))
+ (push-code! (object->code nargs))
+ (push-code! (object->code nrest))
+ (push-code! (object->code nlocs))
+ (push-code! (object->code nexts))
+ (push-code! (object->code #f))))
;; dump object table
(if objs (dump! objs))
;; dump meta data