;;; 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) :use-module (ice-9 match) :export (pprint-glil ? -1 -2 -3 -4 -5 ? -1 ? ? -1 -2 ? ? -1 ? -1 -2 ? -1 -2 ? -1 -2 -3 ? -1 -2 -3 ? -1 ? -1 -2 ? -1 -2 )) (define-record ( nargs nrest nlocs nexts)) (define-type (| ;; Meta operations ( vars body) ( vars) () ( loc) ;; Objects () ( obj) ;; Variables ( op index) ( op index) ( op depth index) ( op module name) ;; Controls ( label) ( inst label) ( inst nargs))) ;;; ;;; 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 'tail-call) n) ;;; (make-instn (car x) n)) ;;; ;; (INST) ;;; ((inst) ;;; (if (instruction? inst) ;;; (make-inst inst) ;;; (error "Unknown instruction:" inst))))) ;;; ;;; Unparser ;;; (define (unparse glil) (match glil ;; meta (($ vars body) `(@asm (,vars.nargs ,vars.nrest ,vars.nlocs ,vars.nexts) ,@(map unparse body))) (($ vars) `(@bind ,@vars)) (($ ) `(@unbind)) (($ loc) `(@source ,(car loc) ,(cdr 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 module name) `(,(symbol-append 'module- op) ,module ,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)))