
Hey all, I'm trying to get started generating LLVM code, but I'm getting a rather cryptic error. I wanted to create a function that takes a string and generates a function calling to "puts" with that string as an argument: buildReaderFun :: String -> CodeGenModule (Function (IO ())) buildReaderFun nm = do puts <- newNamedFunction ExternalLinkage "puts" :: TFunction (Ptr Word8 -> IO Word32) greetz <- createStringNul nm func <- createFunction ExternalLinkage $ do tmp <- getElementPtr0 greetz (0 :: Word32, ()) call puts tmp -- Throw away return value. ret () return func (based off of some code at this blog post: http://augustss.blogspot.com/2009/01/llvm-llvm-low-level-virtual-machine-is.... ) But, I get this error: /research/phd/libmet/Listener.hs:16:11: Ambiguous type variable `n' in the constraint: `Data.TypeLevel.Num.Sets.NatI n' arising from a use of `getElementPtr0' at /research/phd/libmet/Listener.hs:16:11-49 Probable fix: add a type signature that fixes these type variable(s) My attempts at figuring out what type-level has to do with this, and how to satisfy it have so far proven unsuccessful. Can anyone shed a little light on what's going on? Or pointers to some documentation on any of this? Cheers, -Lally

On Sun, 5 Dec 2010, Lally Singh wrote:
Hey all, I'm trying to get started generating LLVM code, but I'm getting a rather cryptic error.
Btw. there is haskell-llvm@projects.haskell.org
buildReaderFun :: String -> CodeGenModule (Function (IO ())) buildReaderFun nm = do puts <- newNamedFunction ExternalLinkage "puts" :: TFunction (Ptr Word8 -> IO Word32) greetz <- createStringNul nm func <- createFunction ExternalLinkage $ do tmp <- getElementPtr0 greetz (0 :: Word32, ())
You have to add a type annotation to greetz like (greetz :: Array D42 Word8) which limits your string to a length of 42 bytes. If you do not know the length, better use withStringNul. I implemented the current behavior, because the former implementation was unsafe.
call puts tmp -- Throw away return value. ret () return func
My attempts at figuring out what type-level has to do with this, and how to satisfy it have so far proven unsuccessful.
type-level provides type level integers, and thus allows for static checking of sizes, such as the number of bits of an integer type.

Thanks for your help. Replying inline
On Sun, Dec 5, 2010 at 1:28 PM, Henning Thielemann
On Sun, 5 Dec 2010, Lally Singh wrote:
Hey all, I'm trying to get started generating LLVM code, but I'm getting a rather cryptic error.
Btw. there is haskell-llvm@projects.haskell.org
buildReaderFun :: String -> CodeGenModule (Function (IO ())) buildReaderFun nm = do puts <- newNamedFunction ExternalLinkage "puts" :: TFunction (Ptr Word8 -> IO Word32) greetz <- createStringNul nm func <- createFunction ExternalLinkage $ do tmp <- getElementPtr0 greetz (0 :: Word32, ())
You have to add a type annotation to greetz like (greetz :: Array D42 Word8) which limits your string to a length of 42 bytes.
If you do not know the length, better use withStringNul. I implemented the current behavior, because the former implementation was unsafe.
I'm sorry, the type signature for withStringNul is over my head. withStringNul :: String -> (forall n. (Nat n) => Global (Array n Word8) -> CodeGenModule a) -> CodeGenModule a On the LLVM side, I'm looking to simply create a string constant I can pass in, such as ConstantArray::get(..). I *think* withStringNul will generate code to build a runtime-length determined string? Sorry, I'm a little thick.
call puts tmp -- Throw away return value. ret () return func
My attempts at figuring out what type-level has to do with this, and how to satisfy it have so far proven unsuccessful.
type-level provides type level integers, and thus allows for static checking of sizes, such as the number of bits of an integer type.
Thanks -- sorry -- I'm guessing it's to make sure we're generating valid code? Cheers, -Lally

No wait, sorry.
buildReaderFun :: String -> CodeGenModule (Function (IO ()))
buildReaderFun nm = do
puts <- newNamedFunction ExternalLinkage "puts" :: TFunction (Ptr
Word8 -> IO Word32)
let callPuts greetz = createFunction ExternalLinkage $ do
tmp <- getElementPtr greetz (0 :: Word32,(0 :: Word32, ()))
call puts tmp -- Throw away return value.
ret ()
withStringNul nm callPuts
Is that how it's intended?
Cheers,
-Lally
On Sun, Dec 5, 2010 at 3:35 PM, Lally Singh
Thanks for your help. Replying inline
On Sun, Dec 5, 2010 at 1:28 PM, Henning Thielemann
wrote: On Sun, 5 Dec 2010, Lally Singh wrote:
Hey all, I'm trying to get started generating LLVM code, but I'm getting a rather cryptic error.
Btw. there is haskell-llvm@projects.haskell.org
buildReaderFun :: String -> CodeGenModule (Function (IO ())) buildReaderFun nm = do puts <- newNamedFunction ExternalLinkage "puts" :: TFunction (Ptr Word8 -> IO Word32) greetz <- createStringNul nm func <- createFunction ExternalLinkage $ do tmp <- getElementPtr0 greetz (0 :: Word32, ())
You have to add a type annotation to greetz like (greetz :: Array D42 Word8) which limits your string to a length of 42 bytes.
If you do not know the length, better use withStringNul. I implemented the current behavior, because the former implementation was unsafe.
I'm sorry, the type signature for withStringNul is over my head. withStringNul :: String -> (forall n. (Nat n) => Global (Array n Word8) -> CodeGenModule a) -> CodeGenModule a
On the LLVM side, I'm looking to simply create a string constant I can pass in, such as ConstantArray::get(..).
I *think* withStringNul will generate code to build a runtime-length determined string? Sorry, I'm a little thick.
call puts tmp -- Throw away return value. ret () return func
My attempts at figuring out what type-level has to do with this, and how to satisfy it have so far proven unsuccessful.
type-level provides type level integers, and thus allows for static checking of sizes, such as the number of bits of an integer type.
Thanks -- sorry -- I'm guessing it's to make sure we're generating valid code?
Cheers, -Lally

On Sun, Dec 5, 2010 at 12:45 PM, Lally Singh
Is that how it's intended?
I think that's correct, (it at least fits the pattern for 'with' functions in Haskell). They're idiomatically used with syntax like this:
buildReaderFun :: String -> CodeGenModule (Function (IO ())) buildReaderFun nm = do puts <- newNamedFunction ExternalLinkage "puts" :: TFunction (Ptr Word8 -> IO Word32) withStringNul nm $ \greetz -> createFunction ExternalLinkage $ do tmp <- getElementPtr greetz (0 :: Word32,(0 :: Word32, ())) call puts tmp -- Throw away return value. ret ()
participants (3)
-
Henning Thielemann
-
Lally Singh
-
Ryan Ingram