プログラミング言語SML#解説 4.1.0版
16 SML#の構造

16.2 分割コンパイルモードのプログラム

分割コンパイルモードのプログラムは,ソースファイル とそのインターフェイスを記述したインターフェイスファ イルの集合である. ソースファイルの内容⟨source⟩は以下の通りである.

⟨source⟩ ::= (⟨interfaceFileSpec⟩)?  ⟨sourceProgram⟩
⟨interfaceFileSpec⟩ ::= _interface  "⟨filePath⟩"
⟨sourceProgram⟩ ::=
 | ⟨decl⟩  ⟨sourceProgram⟩
 | ⟨topdecl⟩  ⟨sourceProgram⟩

ソースファイルに対応するインタフェイスファイルの指定 ⟨interfaceFileSpec⟩指定しない場合でかつ,ソースファイルS.smlと同一ディレクトリにサフィクスが.smiの同一の名の ファイルS.smiがあれば,そのファイルが暗黙に インタフェイスファイルとして指定される. ⟨filePath⟩は相対パスであり, OSによらず,ディレクトリの区切り文字には/(スラッシュ)を用いる.

インターフェイスファイルの内容⟨interface⟩は,ソースファ イルが必要とする他のコンパイル単位の参照宣言の列⟨requireList⟩と, ソースファイルが他のコンパイル単位に提供する仕様の列⟨provideList⟩を記述する.

⟨interface⟩ ::= ⟨requireList⟩  ⟨provideList⟩
⟨requireList⟩ ::=
 | _require  (local)?  ⟨interfaceName⟩  ⟨requireList⟩  (init)?
 | _require  (local)?  ⟨sigFilePath⟩  ⟨requireList⟩  (init)?
⟨interfaceName⟩ ::= ⟨smiFilePath⟩
 | ⟨librarySmiFilePath⟩
⟨provideList⟩ ::=
 | ⟨provide⟩  ⟨provideList⟩
⟨provide⟩ ::= ⟨provideInfix⟩
 | ⟨provideVal⟩
 | ⟨provideType⟩
 | ⟨provideDatatype⟩
 | ⟨provideException⟩
 | ⟨provideStr⟩
 | ⟨provideFun⟩

⟨requireList⟩は,ソースファイルが参照する他の ソースファイルのインターフェイスファイル(smiファイル)パス, ライブラリのsmiファイル名, またはシグネチャファイルのパス名を指定する. _requireに続くlocalは, その_requireで指定されたインターフェースファイルが ソースファイルからのみ参照され, ⟨provideList⟩からは参照されないことを表す. このlocalを適切に加えることによって,不要なインターフェース ファイルの読み込みを抑止し,コンパイル時間を短縮することができる. initは,指定されたインターフェースファイルに対応する プログラムが,_requireが書かれたプログラムよりも先に必ず評価 されることを表す注釈である. ⟨provideList⟩は,ソースファイルが,他のコンパイル単位 に提供する宣言の仕様である.

⟨smiFilePath⟩,⟨sigFilePath⟩,および ⟨librarySmiFilePath⟩は,_requireが書かれたファイルから 他のファイルへの相対パスである. OSによらず,ディレクトリの区切り文字には/(スラッシュ)を 用いる. パスが.(ピリオド)から始まっておらずかつファイルが存在 しない場合は,コマンドラインで与えられたロードパスからファイルを検索する.

SML#が提供する代表的なライブラリのインターフェイスファイ ルには以下のものがある.

ライブラリsmiファイル名 内容
basis.smi Standard ML基本ライブラリ
ml-yacc-lib.smi yacc, lexツール
smlformat-lib.smi SMLFormatフォーマッタ生成ツール
smlnj-lib.smi Standard ML of New Jerseyライブラリ
ffi.smi Cとの連携サポートライブラリ
thread.smi マルチスレッドサポートライブラリ
reify.smi 動的型付けサポートライブラリ
smlunit-lib.smi 単体テストツール

宣言に対応するプロバイドは以下の通りである.

  • •

    核言語の宣言とインタフェイスの対応

    宣言 (⟨decl⟩) 対応するプロバイド (⟨provide⟩)
    ⟨infixDecl⟩ ⟨provideInfix⟩
    ⟨valDecl⟩ ⟨provideVal⟩
    ⟨valRecDecl⟩ ⟨provideVal⟩
    ⟨funDecl⟩ ⟨provideVal⟩
    ⟨datatypeDecl⟩ ⟨provideData⟩
    ⟨typeDecl⟩ ⟨provideType⟩
    ⟨exceptionDecl⟩ ⟨provideException⟩
    ⟨localDecl⟩
  • •

    モジュール言語の宣言とインタフェイスの対応

    宣言 (⟨topdecl⟩) 対応するプロバイド (⟨provide⟩)
    ⟨strDecl⟩ ⟨provideStr⟩
    ⟨sigDecl⟩
    ⟨functorDecl⟩ ⟨provideFun⟩
    ⟨localTopdecl⟩

    シグネチャファイルは,インタフェイスに直接 _require ⟨sigFilePath⟩ 宣言で参照する.

以下に簡単なプログラム例を示す.

  • •

    例1(基本ライブラリの使用)

    ファイル コード
    hello.sml val _ = print "こんにちは,SML#へようこそ\n"
    hello.smi _require "basis.smi"

    コンパイルと実行例

    $ smlsharp hello.sml
    $ ./a.out
    こんにちは,SML#へようこそ
    $

  • •

    例2(分割コンパイル)

    ファイル コード
    hello.sml val _ = puts "こんにちは,SML#へようこそ"
    hello.smi _require "puts.smi"
    puts.sml val puts = _import "puts" : string -> int
    puts.smi val puts : string -> int

    コンパイルと実行例

    $ smlsharp -c hello.sml
    $ smlsharp -c puts.sml
    $ smlsharp -o hello hello.smi
    $ ./hello
    こんにちは,SML#へようこそ
    $