| 1 | #!/usr/local/bin/gosh |
|---|
| 2 | |
|---|
| 3 | (use util.match) |
|---|
| 4 | |
|---|
| 5 | (define-macro (replace-rule code . ls) |
|---|
| 6 | `(match ,code |
|---|
| 7 | ,@(map (lambda (e) |
|---|
| 8 | `((,@(car e) . %rest) (values ,(caddr e) %rest))) |
|---|
| 9 | ls) |
|---|
| 10 | (else (values #f code)))) |
|---|
| 11 | |
|---|
| 12 | |
|---|
| 13 | ;;;; �u���������[�� |
|---|
| 14 | (define (get-replace-rule code) |
|---|
| 15 | (replace-rule code |
|---|
| 16 | (('GREF f 'APPLY n) => `(GREF-APPLY ,f ,n)) |
|---|
| 17 | (('GREF f 'SHIFT m 'APPLY n) => `(GREF-SHIFT-APPLY ,f ,n)) |
|---|
| 18 | (('SHIFT m 'APPLY n) => `(SHIFT-APPLY ,n)) |
|---|
| 19 | (('CONST obj 'ARG) => `(CONST-ARG ,obj)) |
|---|
| 20 | )) |
|---|
| 21 | |
|---|
| 22 | |
|---|
| 23 | (define optbl |
|---|
| 24 | '((HALT ()) |
|---|
| 25 | (LREF (n . $x)) |
|---|
| 26 | (FREF (n . $x)) |
|---|
| 27 | (GREF (sym . $x)) |
|---|
| 28 | (UNBOX $x) |
|---|
| 29 | (CONST (obj . $x)) |
|---|
| 30 | (CLOSE (argnum n $body . $x)) |
|---|
| 31 | (BOX (n . $x)) |
|---|
| 32 | (TEST ($then . $else)) |
|---|
| 33 | (LSET (n . $x)) |
|---|
| 34 | (FSET (n . $x)) |
|---|
| 35 | (GSET (sym . $x)) |
|---|
| 36 | (CONTI (tail$ . $x)) |
|---|
| 37 | (NUATE (stack . $x)) |
|---|
| 38 | (FRAME ($x . $ret)) |
|---|
| 39 | (ARG $x) |
|---|
| 40 | (SHIFT (n . $x)) |
|---|
| 41 | (APPLY (argnum)) |
|---|
| 42 | (RET ()) |
|---|
| 43 | (EXPAND (argnum . $x)) |
|---|
| 44 | (SHRINK (n . $x)) |
|---|
| 45 | )) |
|---|
| 46 | |
|---|
| 47 | (define *h* (make-hash-table)) |
|---|
| 48 | |
|---|
| 49 | (dolist (e optbl) |
|---|
| 50 | (let ((sym (car e)) |
|---|
| 51 | (args (cadr e))) |
|---|
| 52 | (hash-table-put! *h* sym args))) |
|---|
| 53 | |
|---|
| 54 | (define (next-ops code) |
|---|
| 55 | (define (op? sym) |
|---|
| 56 | (eq? (string-ref (symbol->string sym) 0) |
|---|
| 57 | #\$)) |
|---|
| 58 | (define (check sym x f) |
|---|
| 59 | (if (op? sym) |
|---|
| 60 | (f x) |
|---|
| 61 | (f #f))) |
|---|
| 62 | (define (scons x xs) |
|---|
| 63 | (if x (cons x xs) xs)) |
|---|
| 64 | |
|---|
| 65 | (let* ((op (car code)) |
|---|
| 66 | (e (and (hash-table-exists? *h* op) |
|---|
| 67 | (hash-table-get *h* op)))) |
|---|
| 68 | (if e |
|---|
| 69 | (reverse! |
|---|
| 70 | (let loop ((p e) |
|---|
| 71 | (q (cdr code)) |
|---|
| 72 | (acc '())) |
|---|
| 73 | (cond ((pair? p) |
|---|
| 74 | (check (car p) (car q) |
|---|
| 75 | (lambda (x) (loop (cdr p) (cdr q) (scons x acc))))) |
|---|
| 76 | ((null? p) acc) |
|---|
| 77 | (else |
|---|
| 78 | (check p q |
|---|
| 79 | (lambda (x) (scons x acc))))))) |
|---|
| 80 | '()))) |
|---|
| 81 | |
|---|
| 82 | (define (replace pair newpair) |
|---|
| 83 | (set-car! pair (car newpair)) |
|---|
| 84 | (set-cdr! pair (cdr newpair))) |
|---|
| 85 | |
|---|
| 86 | (define (optimize! code) |
|---|
| 87 | (when (not (null? code)) |
|---|
| 88 | (receive (rep rest) (get-replace-rule code) |
|---|
| 89 | (if rep |
|---|
| 90 | (replace code (append rep (optimize! rest))) |
|---|
| 91 | (begin |
|---|
| 92 | (dolist (x (next-ops code)) |
|---|
| 93 | (optimize! x)))))) |
|---|
| 94 | code) |
|---|
| 95 | |
|---|
| 96 | (define (main args) |
|---|
| 97 | (until (read) eof-object? => code |
|---|
| 98 | (optimize! code) |
|---|
| 99 | (write/ss code) |
|---|
| 100 | (newline))) |
|---|