Hatena::Groupxn--272ax3f

スクリプト言語の作り方 14日目

スクリプト言語の作り方 14日目

14 日目 : 静的型付け言語にして高速化

  • 13 日目まで : 動的型付け言語として作成
  • 14 日目 : 静的型付け言語に拡張 (?)
  • 仮想機械として JVM を使う (13 日目は独自実装)
  • 仮想機械内部で扱う値を Java の Object だけではなく int なども使えるように

14.1 変数の型を指定する

  • 利点
    • 型検査によって一定の範囲でのプログラムの正しさが保証される
    • 実行速度の向上に寄与しうる

構文

var x: Int = 7
var x = 7      // 変数の型指定を省略できる!

// 関数の型
def inc( n: Int ): Int { n + 1 }
  • 変数 (式?) の型は String, Int, Any の 3 つ
  • 変数の型指定を省略した場合 Any 型とする (とりあえず; 型推論導入時に変更)
    • Any 型に対して作用させることができる演算子は + のみ
  • リスト 14.1
    • type_tag を新たに導入
    • variable を新たに導入
    • param, def に type_tag を付けられるように変更

14.2 型検査でバグを見つける

  • eval 呼び出しの前に静的な型検査!
  • typeCheck メソッド (eval っぽい)
    • 抽象構文木の根からはじめて, プログラム中のすべての式に型をつけていく
    • 矛盾がないかチェックする
  • 型検査に通らなかった場合は TypeException 例外が発生

valueType.assertSubtypeOf( type, tenv, this );
  • 文の型検査も必要
    • if 文 : 真偽それぞれのブロックの型の共通のスーパータイプ
      • 条件式は Int 型
    • while 文 : ブロックの型ではなく, ブロックの型と Int 型のスーパータイプ
      • 条件式が 1 度も真にならなかった場合は, while 文の結果が 0 だから
    • def 文 : 関数の型

14.3 型検査つきでプログラムを実行する

  • eval 呼び出し前に typeCheck で型検査を行う
  • ネイティブ関数の型を与えておく必要がある
    • 環境に追加するときに型環境にも追加

14.4 省略された型を型推論でおぎなう

  • ここまでは型を省略した場合は Any と同じ扱いだった
  • 引き算の式があれば, オペランドは Int 型と決まる, というような推論
  • 型検査しながら型推論が行われる
  • 型が単純に決まらない場合もある
  • 型関係を表す方程式方程式を解いて型を決める
    • 解がない場合は型エラー
    • 解が複数存在する場合もある (Stone 言語では Any として扱う)
  • Stone 言語では, 方程式は不等式ではなく等式として扱う (簡単のため)

14.5 Java バイトコードに変換する