4

haskell-llvm バインディングを始めようとしていますが、よくわからないコンパイル エラーが発生します。

コード:

module ModuleMaker where

import LLVM.Core
import LLVM.FFI.Core
import Data.Int

main :: IO ()
main = do
  m <- newNamedModule "test"

  fns <- defineModule m buildMod

  writeBitcodeToFile "ModuleMaker.bc" m

  return ()

buildMod :: CodeGenModule (Function (IO Int32))
buildMod = do 
  main <- createNamedFunction ExternalLinkage "main" $ do
    addResult <- iadd (2::Int32) (3::Int32)
    ret addResult

  return main

次の 2 つのエラーが発生します。

ModuleMaker.hs:20:18:
    No instance for (ABinOp Int32 Int32 (v0 c0))
      arising from a use of `iadd'
    Possible fix:
      add an instance declaration for (ABinOp Int32 Int32 (v0 c0))
    In a stmt of a 'do' block:
      addResult <- iadd (2 :: Int32) (3 :: Int32)
    In the second argument of `($)', namely
      `do { addResult <- iadd (2 :: Int32) (3 :: Int32);
            ret addResult }'
    In a stmt of a 'do' block:
      main <- createNamedFunction ExternalLinkage "main"
              $ do { addResult <- iadd (2 :: Int32) (3 :: Int32);
                     ret addResult }

ModuleMaker.hs:21:5:
    No instance for (Ret (v0 c0) Int32) arising from a use of `ret'
    The type variables `v0', `c0' are ambiguous
    Possible fix: add a type signature that fixes these type variable(s)
    Note: there is a potential instance available:
      instance [overlap ok] Ret (LLVM.Core.Value a) a
        -- Defined in `llvm-3.2.0.2:LLVM.Core.Instructions'
    Possible fix: add an instance declaration for (Ret (v0 c0) Int32)
    In a stmt of a 'do' block: ret addResult
    In the second argument of `($)', namely
      `do { addResult <- iadd (2 :: Int32) (3 :: Int32);
            ret addResult }'
    In a stmt of a 'do' block:
      main <- createNamedFunction ExternalLinkage "main"
              $ do { addResult <- iadd (2 :: Int32) (3 :: Int32);
                     ret addResult }

最初のエラーで、それが に特化し(ABinOp Int32 Int32た命令であることがわかりますが、どこから来ているのか、どのような値であるべきかがわかりません。私が見た haskell-llvm の例は、それ以上の引数を提供していないように見えるので、少し混乱しています...iaddInt32(v0 c0)add

表示される 2 番目のエラーは、最初のエラーに関連しています (v0およびc0変数が原因でしょうか?)。最初のエラーを修正すると、2番目のエラーが修正されると思います。これらのエラーの原因は何ですか?

4

3 に答える 3

3

ソースを見ると、それがありiadd :: (IsInteger c, ABinOp a b (v c)) => a -> b -> CodeGenFunction r (v c)ます。次に、 の最初の 2 つの引数はiadd、型クラスのメンバーでなければなりませんABinOp- しかし、GHC によると、このことはすでにご存じでした。

それは問題ではないと思います(v0 c0)。ソースを見ると、ABinOpと定義されていclass ABinOp a b c | a b -> c whereます。最後の型引数cは、任意の 2 つの入力引数を指定すると、型チェッカーによって自動的に決定されます (それらの型は、ABinOp制約を使用して関数に渡す引数の型から推測されます)。これは、クラス宣言の関数依存によるものです。また、2 番目のエラーが 1 番目のエラーに直接関係していると思われます。

今問題に。GHC;の最初の 2 つの型引数が であるインスタンスは存在しないと主張しABinOpますInt32。実際、ソースを見てみると、GHC は完全に正しいと言えます。私が見る唯一の例は次のABinOpとおりです。

instance ABinOp (Value a) (Value a) (Value a) where
    abinop _ op (Value a1) (Value a2) = buildBinOp op a1 a2

instance ABinOp (ConstValue a) (Value a) (Value a) where
    abinop _ op (ConstValue a1) (Value a2) = buildBinOp op a1 a2

instance ABinOp (Value a) (ConstValue a) (Value a) where
    abinop _ op (Value a1) (ConstValue a2) = buildBinOp op a1 a2

instance ABinOp (ConstValue a) (ConstValue a) (ConstValue a) where
    abinop cop _ (ConstValue a1) (ConstValue a2) =
        return $ ConstValue $ cop a1 a2

instance (IsConst a) => ABinOp (Value a) a (Value a) where
    abinop cop op a1 a2 = abinop cop op a1 (constOf a2)

instance (IsConst a) => ABinOp a (Value a) (Value a) where
    abinop cop op a1 a2 = abinop cop op (constOf a1) a2

当然のことながら、 の使用はiaddこれらのいずれかに一致する必要があります (どこかに隠されている場合を除きます)。ご覧のとおりInt32、それらのいずれにも含まれていません。では、Valueとを見てみましょうConstValue

newtype Value a = Value { unValue :: FFI.ValueRef }
    deriving (Show, Typeable)

newtype ConstValue a = ConstValue { unConstValue :: FFI.ValueRef }
    deriving (Show, Typeable)

FFI( のエイリアス)をさらに詳しく調べると、次のLLVM.FFI.Coreことがわかります。

data Value
    deriving (Typeable)
type ValueRef = Ptr Value

iaddこれで、タイプValue Ptrorの引数が必要であると推測できますConstValue Ptr。それらの違いは私にはわかりません。

Ptr個人的には、Haskellについてはほとんど知りません。編集:この事実に照らして、を適切にインスタンス化する方法を言うことはできませんPtrが、私の下の答えはそうです。上記のすべてがまだ保持されます。

于 2013-06-05T02:47:18.580 に答える
3

user2407038 は、ABinOp のインスタンスに関する重要な点を指摘しています。最終的に問題は、iadd少なくとも 1 つのConstValue aorが必要であるにもかかわらずValue a、2 つInt32の s が指定されていることです。修正は次のとおりです。

createNamedFunction ExternalLinkage "main" $ do
  addResult <- iadd (valueOf (5 :: Int32)) (5 :: Int32)
  ret addResult

iadd引数の 1 つだけが値でなければならないことに注意してください。もう 1 つはインスタンスInt32のため、ストレートにすることができます。ABinop (Value a) a (Value a)

于 2013-06-05T03:36:29.863 に答える