可変個の引数に対応する - Scheme VM を書く

可変個の引数に対応する。
こういうの。

(lambda (a b . c) ...)
(lambda a ...)
(define (a . b) ...)

これはいろいろ面倒。

  • (a 1 2 3) というコードがあってこの手続きが実際は何個の引数を受け取る手続きなのかをコンパイル時に知るのは難しい。
    • 実行時に調整が必要
  • 可変個部分は1つのリストにまとめなければいけない。
  • 可変個部分に引数が渡らない場合は '() にしなければならない。


参考になる実装も見つからなかったので自分で考えて

  • closure 作成時に可変個の引数を受け取るクロージャの場合はマーキング
  • closure 作成時に引数の数を保持
  • apply 時に可変個の引数をうけとるクロージャの場合はリストにまとめて、更に return でずらすスタックの数も変更
  • '() を返すときはスタックを shift してうめこむ

などで実装。

ちなみに今の実装では可変個数の引数をうけとるクロージャを作ると apply 時にチェックやずらしが必要なので実効速度のペナルティがある。
固定個数であればこれらのペナルティは受けない。