summaryrefslogtreecommitdiff
path: root/module/system/il/glil.scm
diff options
context:
space:
mode:
Diffstat (limited to 'module/system/il/glil.scm')
-rw-r--r--module/system/il/glil.scm211
1 files changed, 211 insertions, 0 deletions
diff --git a/module/system/il/glil.scm b/module/system/il/glil.scm
new file mode 100644
index 000000000..6a3ec4c17
--- /dev/null
+++ b/module/system/il/glil.scm
@@ -0,0 +1,211 @@
+;;; 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
+ <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-body
+
+ <glil-bind> make-glil-bind glil-bind?
+ glil-bind-vars
+
+ <glil-unbind> make-glil-unbind glil-unbind?
+
+ <glil-source> make-glil-source glil-source?
+ glil-source-loc
+
+ <glil-void> make-glil-void glil-void?
+
+ <glil-const> make-glil-const glil-const?
+ glil-const-obj
+
+ <glil-argument> make-glil-argument glil-argument?
+ glil-argument-op glil-argument-index
+
+ <glil-local> make-glil-local glil-local?
+ glil-local-op glil-local-index
+
+ <glil-external> make-glil-external glil-external?
+ glil-external-op glil-external-depth glil-external-index
+
+ <glil-module> make-glil-module glil-module?
+ glil-module-op glil-module-module glil-module-index
+
+ <glil-late-bound> make-glil-late-bound glil-late-bound?
+ glil-late-bound-op glil-late-bound-name
+
+ <glil-label> make-glil-label glil-label?
+ glil-label-label
+
+ <glil-branch> make-glil-branch glil-branch?
+ glil-branch-int glil-branch-label
+
+ <glil-call> make-glil-call glil-call?
+ glil-call-int glil-call-nargs))
+
+(define-record (<glil-vars> nargs nrest nlocs nexts))
+
+(define-type <glil>
+ (|
+ ;; Meta operations
+ (<glil-asm> vars body)
+ (<glil-bind> vars)
+ (<glil-unbind>)
+ (<glil-source> loc)
+ ;; Objects
+ (<glil-void>)
+ (<glil-const> obj)
+ ;; Variables
+ (<glil-argument> op index)
+ (<glil-local> op index)
+ (<glil-external> op depth index)
+ (<glil-module> op module name)
+ (<glil-late-bound> op name)
+ ;; Controls
+ (<glil-label> label)
+ (<glil-branch> inst label)
+ (<glil-call> 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)
+ (record-case glil
+ ;; meta
+ ((<glil-asm> vars body)
+ `(@asm (,(glil-vars-nargs vars) ,(glil-vars-nrest vars)
+ ,(glil-vars-nlocs vars) ,(glil-vars-nexts vars))
+ ,@(map unparse body)))
+ ((<glil-bind> vars) `(@bind ,@vars))
+ ((<glil-unbind>) `(@unbind))
+ ((<glil-source> loc) `(@source ,(car loc) ,(cdr loc)))
+ ;; constants
+ ((<glil-void>) `(void))
+ ((<glil-const> obj) `(const ,obj))
+ ;; variables
+ ((<glil-argument> op index)
+ `(,(symbol-append 'argument- op) ,index))
+ ((<glil-local> op index)
+ `(,(symbol-append 'local- op) ,index))
+ ((<glil-external> op depth index)
+ `(,(symbol-append 'external- op) ,depth ,index))
+ ((<glil-module> op module name)
+ `(,(symbol-append 'module- op) ,module ,name))
+ ;; controls
+ ((<glil-label> label) label)
+ ((<glil-branch> inst label) `(,inst ,label))
+ ((<glil-call> 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)))