Concurrent Clean : CleanJ : ccall

Directoryモジュールを移植するにあたって、ccallというABCマシン命令の仕様を調査中。

ccall Cの関数名 "型指定"

という形式で記述され(型指定はクォートされる)、これがC言語の関数の呼び出しに置き換えられる。
型指定の部分は、次のような形式になる。

入力の型:出力の型:Cの関数に渡さない値の型

となっていて、1つの値に対する型は1文字で表現される。

I 整数(Int)
R 実数(Real)
S 文字列(String)
V void
A ノード(A-value)

ただし、voidは、出力にしか使えない。出力が複数ある場合には、1つ目が返値で、2つ目移行は引数のポインタ渡しを利用して、値の受け渡しを行う。

void g (int,int *,int *);

f :: !Int !*Int -> (!Int,!Int,!*Int);
f a1 a2
    = code {
        ccall g "I:VII:I"
    }; 

とある場合、「f :: a1 a2 -> b1 b2 b3」のように名前を付けると、「g (a1, *b1, *b2)」のように関数呼び出しが行われ、a2は何も変更されないままb3になる。

      • -

さて、これをCleanJで実装するには、Javaにはポインタはないので、全て返値で値を返してやる必要がある。最も単純で汎用的なのは、返値を配列にしてやることだろう。ただし、返値が1つだけの場合は配列化しないで返す方が効率的だし、同じ種類の基本値だけを複数返す場合はObject[]よりも基本値の配列を使う方が効率的だ。
ただし、そういうやり方だと、メソッドの型からhtocleanのように自動的にccallを生成することは難しくなる。