[add documentation for the multi-return ccall extension, clean up code.
John Meacham <john@repetae.net>**20120209201351
 Ignore-this: 47504b653ee9f71bde40e91959238292
] hunk ./docs/unboxed.mkd 9
+# foreign imports with multiple return values.
+
+foreign C imports may return multiple values. To indicate this is the case, use
+an unboxed tuple as the return value. The first return value will be the value
+the function directly returns, the rest will be passed as pointers at the end
+of the functions argument list. Only pure (non IO) functions may return multiple values.
+
+~~~~
+-- frexp has C prototype
+-- double frexp(double x, int *exp);
+-- so it would normally have an import like so, requiring the IO module and
+-- Storable to call what is otherwise a pure function.
+
+foreign import ccall "math.h frexp"  c_frexp :: Double -> Ptr CInt -> IO Double
+
+-- This extension allows it to be declared as so
+foreign import ccall "math.h frexp"  c_frexp2 :: Double -> (# Double, CInt #)
+
+-- The second return value is added as the last 'exp' parameter then read out
+-- of the allocated memory. The contents of the memory passed into the function
+-- is undefined.
+~~~~
hunk ./docs/unboxed.mkd 53
-other Haskell values. The convention is to suffix such types with '_' to
+haskell identifiers. The convention is to suffix such types with '_' to
hunk ./docs/unboxed.mkd 55
-are enabled by the -funboxed-value flag. For compatibility with GHC, the 
+are enabled by the -funboxed-value flag. For compatibility with GHC, the
hunk ./docs/unboxed.mkd 62
-Unboxed tuples are kind-polymorphic, able to hold both boxed and unboxed values. 
+Unboxed tuples are kind-polymorphic, able to hold both boxed and unboxed values.
hunk ./docs/unboxed.mkd 73
-Unboxed characters can be expressed by putting a hash after a normal character 
+Unboxed characters can be expressed by putting a hash after a normal character
hunk ./docs/unboxed.mkd 95
-the right Bits32_ primitive. imported primitives are normal haskell declarations so may be 
+the right Bits32_ primitive. imported primitives are normal haskell declarations so may be
hunk ./lib/jhc/Prelude/Float.hs 1
-{-# OPTIONS_JHC -fno-prelude -fffi -fm4  #-}
+{-# OPTIONS_JHC -fno-prelude -fffi -fm4  -funboxed-tuples #-}
hunk ./lib/jhc/Prelude/Float.hs 5
-import Foreign.Marshal.Alloc
-import Foreign.Ptr
-import Foreign.Storable
hunk ./lib/jhc/Prelude/Float.hs 6
+import Jhc.Class.Real
hunk ./lib/jhc/Prelude/Float.hs 9
-import Jhc.Monad
hunk ./lib/jhc/Prelude/Float.hs 10
+import Jhc.Numeric((^),(^^))
hunk ./lib/jhc/Prelude/Float.hs 14
-import Jhc.Numeric((^),(^^))
hunk ./lib/jhc/Prelude/Float.hs 15
-import System.IO.Unsafe
-import Jhc.Class.Real
hunk ./lib/jhc/Prelude/Float.hs 101
-foreign import ccall "math.h frexp$3"  c_frexp$3 :: $1 -> Ptr CInt -> IO $1
+foreign import ccall "math.h frexp$3"  c_frexp$3 :: $1 -> (# $1, CInt #)
hunk ./lib/jhc/Prelude/Float.hs 133
-    decodeFloatf x = unsafePerformIO $ alloca $ \ptr -> do
-        x' <- c_frexpf x ptr
-        exp <- peek ptr
-        return (x', fromIntegral exp)
+    decodeFloatf x = case c_frexpf x of
+        (# x', exp #) -> (x', fromIntegral exp)
hunk ./lib/jhc/Prelude/Float.hs 137
-    decodeFloat x = unsafePerformIO $ alloca $ \ptr -> do
-        x' <- c_frexp (floatToDouble x) ptr
-        exp <- peek ptr
-        let x'' =  c_ldexp x' (fromInt $ floatDigits x)
-        return (double2integer x'', fromIntegral exp  - floatDigits x)
+    decodeFloat x = case c_frexpf x of
+        (# x', exp #) -> let x'' =  c_ldexp (floatToDouble x') (fromInt $ floatDigits x) in
+            (double2integer x'', fromIntegral exp  - floatDigits x)
hunk ./lib/jhc/Prelude/Float.hs 157
-    decodeFloatf x = unsafePerformIO $ alloca $ \ptr -> do
-        x' <- c_frexp x ptr
-        exp <- peek ptr
-        return (x', fromIntegral exp)
+    decodeFloatf x = case c_frexp x of
+        (# x', exp #) -> (x', fromIntegral exp)
hunk ./lib/jhc/Prelude/Float.hs 161
-    decodeFloat x = unsafePerformIO $ alloca $ \ptr -> do
-        x' <- c_frexp x ptr
-        exp <- peek ptr
-        let x'' = c_ldexp x' (fromInt $ floatDigits x)
-        return (double2integer x'', fromIntegral exp  - floatDigits x)
+    decodeFloat x = case c_frexp x of
+        (# x', exp #) -> let x'' = c_ldexp x' (fromInt $ floatDigits x) in
+            (double2integer x'', fromIntegral exp  - floatDigits x)
hunk ./src/C/FromGrin2.hs 608
-    tmp <- newVar (ptrType sptr_t)
-    let malloc = tmp =* jhc_malloc_ptrs  (operator "*" (sizeof sptr_t) c')
+    (malloc,tmp) <- jhc_malloc_ptrs  (operator "*" (sizeof sptr_t) c') =:: ptrType sptr_t
hunk ./src/C/FromGrin2.hs 619
-        tmp <- newVar (ptrType uintptr_t)
-        let malloc = tmp =* jhc_malloc_atomic (operator "*" (sizeof uintptr_t) c')
+        (malloc,tmp) <- jhc_malloc_atomic (operator "*" (sizeof uintptr_t) c') =:: ptrType uintptr_t
hunk ./src/C/FromGrin2.hs 697
-    | (Func _ n as r rs) <- p = do
-        vs' <- mapM convertVal vs
-        rt <- convertTypes ty
-        ras <- mapM (newVar . basicType') rs
-        return $ cast rt (functionCall (name $ unpackPS n) ([ cast (basicType' t) v | v <- vs' | t <- as ] ++ map reference ras))
hunk ./src/C/FromGrin2.hs 990
+x =:: y = newTmpVar y x
+