実は以前から構文としてはdefine-constantをサポートしてはいたんだけど、何もしない単なるサポートにしかなっていなかった。
っで、せっかくライブラリのインライン化とかやったので定数も畳み込んでしまおうと思い立ってやってみた。
基本方針は以下の通り。
- 定数のみ。
- exportで定義されていない。
- コンパイラの最適化で定数になるものは含める。例えばこんなの
(define a (car '(a b c))) ;; コンパイラは'aをaに定義する。
- define-constantで定義されたものはライブラリ外でも参照する
(define-constant a (car '(a b c))) ;; carはコンパイル時に計算される(可能なら)
(define (test)
(print a))
(disasm test)
;; size: 5
;; 0: CONST_PUSH a <-- シンボルaがそのまま渡されている
;; 2: GREF_TAIL_CALL(1) #<identifier print#user(0x5fd1e0)> ;; print
;; 4: RET
(library (inner)
(export const-value)
;; define-constant は(sagittarius)ライブラリにて提供
(import (sagittarius))
(define-constant const-value 10)
)
(library (test)
(export test2)
(import (rnrs)
(inner))
(define a (+ 1 2 3)) ;; a はexportされていない
(define (test2)
(display a)
(display const-value)
(newline))
)
(import (test))
(disasm test2)
;; size: 13
;; 0: FRAME 4
;; 2: CONSTI_PUSH(6) <-- 計算された後の定数になっている
;; 3: GREF_CALL(1) #<identifier display#|(test)|(0x73d018)> ;; display
;; 5: FRAME 4
;; 7: CONSTI_PUSH(10) <-- GREF const-valueではない
;; 8: GREF_CALL(1) #<identifier display#|(test)|(0x73efa8)> ;; display
;; 10: GREF_TAIL_CALL(0) #<identifier newline#|(test)|(0x73ef30)> ;; newline
;; 12: RET
ま、まずまずでしょう。Gambitのベンチマークにはなんら影響が出ないところが多少以上に悲しいが。(あれらはR6RSのライブラリを使ってないから、最適化がかからん)もう少し寝かせてから0.2.2をリリースしよう。
No comments:
Post a Comment