;;; Guile Low Intermediate Language ;; 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 il glil) #:use-syntax (system base syntax) #:export (pprint-glil make-glil-vars glil-vars-nargs glil-vars-nrest glil-vars-nlocs glil-vars-nexts make-glil-asm glil-asm? glil-asm-vars glil-asm-meta glil-asm-body make-glil-bind glil-bind? glil-bind-vars make-glil-mv-bind glil-mv-bind? glil-mv-bind-vars glil-mv-bind-rest make-glil-unbind glil-unbind? make-glil-source glil-source? glil-source-loc make-glil-void glil-void? make-glil-const glil-const? glil-const-obj make-glil-argument glil-argument? glil-argument-op glil-argument-index make-glil-local glil-local? glil-local-op glil-local-index make-glil-external glil-external? glil-external-op glil-external-depth glil-external-index make-glil-toplevel glil-toplevel? glil-toplevel-op glil-toplevel-name make-glil-module glil-module? glil-module-op glil-module-mod glil-module-name glil-module-public? make-glil-label glil-label? glil-label-label make-glil-branch glil-branch? glil-branch-inst glil-branch-label make-glil-call glil-call? glil-call-inst glil-call-nargs make-glil-mv-call glil-mv-call? glil-mv-call-nargs glil-mv-call-ra)) (define-record ( nargs nrest nlocs nexts)) (define-type (| ;; Meta operations ( vars meta body) ( vars) ( vars rest) () ( loc) ;; Objects () ( obj) ;; Variables ( op index) ( op index) ( op depth index) ( op name) ( op mod name public?) ;; Controls ( label) ( inst label) ( inst nargs) ( nargs ra))) ;;; ;;; Parser ;;; ;;; (define (parse-glil x) ;;; (match x ;;; (('@asm args . body) ;;; (let* ((env (make-new-env e)) ;;; (args (parse-args args env))) ;;; (make-asm env args (map-parse body env)))) ;;; (else ;;; (error "Invalid assembly code:" x)))) ;;; ;;; (define (parse-args x e) ;;; (let ((args (cond ((symbol? x) (make-args (list (make-local-var x)) #t)) ;;; ((list? x) (make-args (map make-local-var x) #f)) ;;; (else (let loop ((l x) (v '())) ;;; (if (pair? l) ;;; (loop (cdr l) (cons (car l) v)) ;;; (make-args (map make-local-var ;;; (reverse! (cons l v))) ;;; #t))))))) ;;; (for-each (lambda (v) (env-add! e v)) (args-vars args)) ;;; args)) ;;; ;;; (define (map-parse x e) ;;; (map (lambda (x) (parse x e)) x)) ;;; ;;; (define (parse x e) ;;; (match x ;;; ;; (@asm ARGS BODY...) ;;; (('@asm args . body) ;;; (parse-asm x e)) ;;; ;; (@bind VARS BODY...) ;;; ;; (@block VARS BODY...) ;;; (((or '@bind '@block) vars . body) ;;; (let* ((offset (env-nvars e)) ;;; (vars (args-vars (parse-args vars e))) ;;; (block (make-block (car x) offset vars (map-parse body e)))) ;;; (for-each (lambda (v) (env-remove! e)) vars) ;;; block)) ;;; ;; (void) ;;; (('void) ;;; (make-void)) ;;; ;; (const OBJ) ;;; (('const obj) ;;; (make-const obj)) ;;; ;; (ref NAME) ;;; ;; (set NAME) ;;; (((or 'ref 'set) name) ;;; (make-access (car x) (env-ref e name))) ;;; ;; (label LABEL) ;;; (('label label) ;;; (make-label label)) ;;; ;; (br-if LABEL) ;;; ;; (jump LABEL) ;;; (((or 'br-if 'jump) label) ;;; (make-instl (car x) label)) ;;; ;; (call NARGS) ;;; ;; (tail-call NARGS) ;;; (((or 'call 'goto/args) n) ;;; (make-instn (car x) n)) ;;; ;; (INST) ;;; ((inst) ;;; (if (instruction? inst) ;;; (make-inst inst) ;;; (error "Unknown instruction:" inst))))) ;;; ;;; Unparser ;;; (define (unparse glil) (record-case glil ;; meta (( vars meta body) `(@asm (,(glil-vars-nargs vars) ,(glil-vars-nrest vars) ,(glil-vars-nlocs vars) ,(glil-vars-nexts vars)) ,meta ,@(map unparse body))) (( vars) `(@bind ,@vars)) (() `(@unbind)) (( loc) `(@source ,loc)) ;; constants (() `(void)) (( obj) `(const ,obj)) ;; variables (( op index) `(,(symbol-append 'argument- op) ,index)) (( op index) `(,(symbol-append 'local- op) ,index)) (( op depth index) `(,(symbol-append 'external- op) ,depth ,index)) (( op name) `(,(symbol-append 'toplevel- op) ,name)) (( op mod name public?) `(,(symbol-append (if public? 'public 'private) '- op) ,mod ,name)) ;; controls (( label) label) (( inst label) `(,inst ,label)) (( inst nargs) `(,inst ,nargs)))) ;;; ;;; Printer ;;; (define (pprint-glil glil . port) (let ((port (if (pair? port) (car port) (current-output-port)))) (let print ((code (unparse glil)) (column 0)) (display (make-string column #\space) port) (cond ((and (pair? code) (eq? (car code) '@asm)) (format port "(@asm ~A\n" (cadr code)) (let ((col (+ column 2))) (let loop ((l (cddr code))) (print (car l) col) (if (null? (cdr l)) (display ")" port) (begin (newline port) (loop (cdr l))))))) (else (write code port)))) (newline port)))