Compare commits
8 Commits
2a80e5b219
...
96ec5c1cb1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
96ec5c1cb1 | ||
|
|
20b47594c6 | ||
|
|
71e4ffaede | ||
|
|
58005ee261 | ||
|
|
ca063b1dd6 | ||
|
|
261acca8a4 | ||
|
|
55a781eeb8 | ||
|
|
06767e17ea |
@ -7,7 +7,7 @@ source-repository-package
|
||||
type: git
|
||||
location: https://github.com/well-typed/hs-bindgen
|
||||
tag: e2a9260678d9fa76dab602a5a07927acada3be4f
|
||||
subdir: c-expr-dsl c-expr-runtime hs-bindgen-runtime
|
||||
subdir: c-expr-dsl c-expr-runtime hs-bindgen hs-bindgen-runtime
|
||||
--sha256: 0nrs3iq0l5ha5kxyhqnlmvgi7734pmzyp3zf7p8s1gb21ylh4sy0
|
||||
source-repository-package
|
||||
type: git
|
||||
|
||||
@ -10,3 +10,4 @@ main = do
|
||||
helloShape $ Circle 3.14
|
||||
helloShape $ Rectangle 10.0 5.0
|
||||
putStrLn $ "3 + 4 = " <> show (add 3 4)
|
||||
putStrLn $ "Tree sum: " <> show (sumTree (Fork (Fork (Leaf 1) (Fork (Leaf 2) (Leaf 3))) (Leaf 4)))
|
||||
|
||||
88
flake.lock
generated
88
flake.lock
generated
@ -115,24 +115,6 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-parts": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": "nixpkgs-lib"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1769996383,
|
||||
"narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "57928607ea566b5db3ad13af0e57e921e6b12381",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
@ -525,27 +507,6 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"hs-bindgen": {
|
||||
"inputs": {
|
||||
"flake-parts": "flake-parts",
|
||||
"libclang-bindings-src": "libclang-bindings-src",
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1770394582,
|
||||
"narHash": "sha256-erbj5xqqJ/M0c99G0vjZvJtvoxYJ1PG7DDkw15MVLK8=",
|
||||
"owner": "well-typed",
|
||||
"repo": "hs-bindgen",
|
||||
"rev": "e2a9260678d9fa76dab602a5a07927acada3be4f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "well-typed",
|
||||
"ref": "release-0.1-alpha",
|
||||
"repo": "hs-bindgen",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"iserv-proxy": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
@ -563,39 +524,6 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"libclang-bindings-src": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1770274896,
|
||||
"narHash": "sha256-JnxJBo2L4URFD8JbpjnPG/ej/xKFe7y5ZpjnvIztwAM=",
|
||||
"owner": "well-typed",
|
||||
"repo": "libclang",
|
||||
"rev": "155642a4a4a9f0414a058a8f08f39aa6c7bb57ed",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "well-typed",
|
||||
"repo": "libclang",
|
||||
"rev": "155642a4a4a9f0414a058a8f08f39aa6c7bb57ed",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1770169770,
|
||||
"narHash": "sha256-awR8qIwJxJJiOmcEGgP2KUqYmHG4v/z8XpL9z8FnT1A=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "aa290c9891fa4ebe88f8889e59633d20cc06a5f2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-2305": {
|
||||
"locked": {
|
||||
"lastModified": 1705033721,
|
||||
@ -692,21 +620,6 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-lib": {
|
||||
"locked": {
|
||||
"lastModified": 1769909678,
|
||||
"narHash": "sha256-cBEymOf4/o3FD5AZnzC3J9hLbiZ+QDT/KDuyHXVJOpM=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"rev": "72716169fe93074c333e8d0173151350670b824c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-unstable": {
|
||||
"locked": {
|
||||
"lastModified": 1764587062,
|
||||
@ -746,7 +659,6 @@
|
||||
"flake-utils": "flake-utils",
|
||||
"haskell-nix": "haskell-nix",
|
||||
"hls-2-13": "hls-2-13",
|
||||
"hs-bindgen": "hs-bindgen",
|
||||
"nixpkgs": [
|
||||
"haskell-nix",
|
||||
"nixpkgs-2511"
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
url = "github:oxalica/rust-overlay";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
hs-bindgen.url = "github:well-typed/hs-bindgen/release-0.1-alpha";
|
||||
};
|
||||
outputs =
|
||||
inputs@{ nixpkgs, ... }:
|
||||
@ -54,7 +53,7 @@
|
||||
packages = with pkgs; [
|
||||
bacon
|
||||
ghcid
|
||||
inputs.hs-bindgen.packages.${system}.hs-bindgen-cli
|
||||
llvmPackages.libclang
|
||||
rust-analyzer
|
||||
rust-cbindgen
|
||||
];
|
||||
|
||||
52
garnet.cabal
52
garnet.cabal
@ -7,25 +7,7 @@ maintainer:
|
||||
george.thomas@obsidian.systems
|
||||
patrick.aldis@obsidian.systems
|
||||
|
||||
library garnet-generated
|
||||
hs-source-dirs: generated
|
||||
exposed-modules:
|
||||
GarnetRs
|
||||
GarnetRs.Safe
|
||||
GarnetRs.Unsafe
|
||||
GarnetRs.FunPtr
|
||||
default-language: Haskell2010
|
||||
extra-bundled-libraries: garnet_rs
|
||||
build-depends:
|
||||
base,
|
||||
hs-bindgen-runtime,
|
||||
primitive,
|
||||
|
||||
executable garnet
|
||||
main-is: Main.hs
|
||||
other-modules:
|
||||
GarnetRs.Wrapped
|
||||
hs-source-dirs: exe
|
||||
common common
|
||||
default-language: GHC2024
|
||||
default-extensions:
|
||||
BlockArguments
|
||||
@ -45,11 +27,35 @@ executable garnet
|
||||
ghc-options:
|
||||
-Wall
|
||||
-fdefer-type-errors
|
||||
build-depends:
|
||||
bytestring,
|
||||
extra,
|
||||
mtl,
|
||||
process,
|
||||
text,
|
||||
|
||||
library
|
||||
import: common
|
||||
exposed-modules:
|
||||
GarnetRs.Raw
|
||||
GarnetRs.Wrapped
|
||||
hs-source-dirs: lib
|
||||
extra-bundled-libraries: garnet_rs
|
||||
build-depends:
|
||||
base,
|
||||
hs-bindgen,
|
||||
hs-bindgen-runtime,
|
||||
primitive,
|
||||
template-haskell,
|
||||
|
||||
executable garnet
|
||||
import: common
|
||||
main-is: Main.hs
|
||||
hs-source-dirs: exe
|
||||
ghc-options:
|
||||
-threaded
|
||||
-rtsopts
|
||||
-with-rtsopts=-N
|
||||
build-depends:
|
||||
base >= 4.14,
|
||||
bytestring,
|
||||
garnet-generated,
|
||||
hs-bindgen-runtime,
|
||||
base,
|
||||
garnet,
|
||||
|
||||
@ -3,20 +3,21 @@ set -euo pipefail
|
||||
|
||||
# TODO this is a complete vibe-coded hack, but the header patching at least is crucial
|
||||
|
||||
# Generate Haskell FFI bindings from Rust source code.
|
||||
# Prepare Rust artifacts and C header for hs-bindgen.
|
||||
#
|
||||
# Pipeline:
|
||||
# 1. cargo build - build the Rust static library
|
||||
# 2. cbindgen - generate a C header from the Rust source
|
||||
# 3. awk - patch the header for hs-bindgen compatibility
|
||||
# 4. hs-bindgen-cli - generate Haskell FFI modules from the C header
|
||||
# 5. cabal configure - point Cabal at the Rust build artifacts
|
||||
# 4. cabal configure - point Cabal at the Rust build artifacts
|
||||
#
|
||||
# Prerequisites: run inside the Nix dev shell (provides gcc, cabal, cbindgen, hs-bindgen-cli).
|
||||
# System include paths (needed by libclang on NixOS) are detected
|
||||
# automatically at TH compile time by GarnetRs.Raw — no env vars needed.
|
||||
#
|
||||
# Prerequisites: run inside the Nix dev shell (provides gcc, cabal, cbindgen).
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
RUST_DIR="$SCRIPT_DIR/rust"
|
||||
HASKELL_DIR="$SCRIPT_DIR"
|
||||
HEADER_NAME="garnet_rs.h"
|
||||
HEADER="$RUST_DIR/$HEADER_NAME"
|
||||
|
||||
@ -57,36 +58,7 @@ awk '
|
||||
|
||||
echo " Patched header at $HEADER"
|
||||
|
||||
# --- Step 4: Derive system include paths for hs-bindgen's libclang ---
|
||||
#
|
||||
# hs-bindgen uses libclang directly, which doesn't know about NixOS's
|
||||
# non-standard include locations. We extract them from cpp -v and pass
|
||||
# all of them — extra paths are harmless.
|
||||
echo "=== Detecting system include paths ==="
|
||||
CLANG_OPTIONS=()
|
||||
while IFS= read -r dir; do
|
||||
CLANG_OPTIONS+=("--clang-option" "-isystem$dir")
|
||||
done < <(echo | cpp -v 2>&1 | awk '/#include <\.\.\.> search starts here:/{f=1;next}/End of search list/{f=0}f{gsub(/^ +/,"");print}')
|
||||
|
||||
if [ ${#CLANG_OPTIONS[@]} -eq 0 ]; then
|
||||
echo " WARNING: No system include paths detected. hs-bindgen may fail."
|
||||
else
|
||||
echo " Found ${#CLANG_OPTIONS[@]} clang options:"
|
||||
for ((i=0; i<${#CLANG_OPTIONS[@]}; i+=2)); do
|
||||
echo " ${CLANG_OPTIONS[i+1]}"
|
||||
done
|
||||
fi
|
||||
|
||||
# --- Step 5: Run hs-bindgen ---
|
||||
echo "=== Running hs-bindgen ==="
|
||||
hs-bindgen-cli preprocess \
|
||||
--overwrite-files --create-output-dirs \
|
||||
--unique-id com.garnet --enable-record-dot \
|
||||
--hs-output-dir "$HASKELL_DIR/generated" --module GarnetRs \
|
||||
"${CLANG_OPTIONS[@]}" \
|
||||
-I "$RUST_DIR" "$HEADER_NAME"
|
||||
|
||||
# --- Step 6: Configure Cabal ---
|
||||
# --- Step 4: Configure Cabal ---
|
||||
#
|
||||
# Point Cabal at the Rust static library and C header. This writes
|
||||
# cabal.project.local (gitignored) with absolute paths derived from
|
||||
@ -97,5 +69,4 @@ cabal configure \
|
||||
--extra-include-dirs="$RUST_DIR"
|
||||
|
||||
echo "=== Done ==="
|
||||
echo "Generated Haskell bindings in $HASKELL_DIR/generated/"
|
||||
echo "Run 'cabal run' to test."
|
||||
|
||||
@ -1,526 +0,0 @@
|
||||
{-# LANGUAGE DataKinds #-}
|
||||
{-# LANGUAGE DeriveGeneric #-}
|
||||
{-# LANGUAGE DerivingStrategies #-}
|
||||
{-# LANGUAGE DerivingVia #-}
|
||||
{-# LANGUAGE DuplicateRecordFields #-}
|
||||
{-# LANGUAGE FlexibleContexts #-}
|
||||
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
||||
{-# LANGUAGE MagicHash #-}
|
||||
{-# LANGUAGE MultiParamTypeClasses #-}
|
||||
{-# LANGUAGE NoImplicitPrelude #-}
|
||||
{-# LANGUAGE PatternSynonyms #-}
|
||||
{-# LANGUAGE StandaloneDeriving #-}
|
||||
{-# LANGUAGE TypeApplications #-}
|
||||
{-# LANGUAGE TypeFamilies #-}
|
||||
{-# LANGUAGE TypeOperators #-}
|
||||
{-# LANGUAGE UnboxedTuples #-}
|
||||
{-# LANGUAGE UndecidableInstances #-}
|
||||
|
||||
module GarnetRs where
|
||||
|
||||
import qualified Data.Array.Byte
|
||||
import qualified Data.List.NonEmpty
|
||||
import qualified Data.Primitive.Types
|
||||
import qualified Data.Proxy
|
||||
import qualified Foreign as F
|
||||
import qualified Foreign.C as FC
|
||||
import qualified GHC.Generics
|
||||
import qualified GHC.Ptr as Ptr
|
||||
import qualified GHC.Records
|
||||
import qualified HsBindgen.Runtime.CEnum
|
||||
import qualified HsBindgen.Runtime.HasCField
|
||||
import qualified HsBindgen.Runtime.Internal.ByteArray
|
||||
import qualified HsBindgen.Runtime.Internal.HasFFIType
|
||||
import qualified HsBindgen.Runtime.Internal.SizedByteArray
|
||||
import qualified HsBindgen.Runtime.LibC
|
||||
import qualified HsBindgen.Runtime.Marshal
|
||||
import qualified Text.Read
|
||||
import HsBindgen.Runtime.Internal.TypeEquality (TyEq)
|
||||
import Prelude ((<*>), (>>), Eq, Int, Ord, Read, Show, pure, showsPrec)
|
||||
|
||||
{-| __C declaration:__ @struct T@
|
||||
|
||||
__defined at:__ @garnet_rs.h 6:8@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
data T = T
|
||||
{ a :: FC.CBool
|
||||
{- ^ __C declaration:__ @a@
|
||||
|
||||
__defined at:__ @garnet_rs.h 7:8@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
, b :: HsBindgen.Runtime.LibC.Word8
|
||||
{- ^ __C declaration:__ @b@
|
||||
|
||||
__defined at:__ @garnet_rs.h 8:11@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
}
|
||||
deriving stock (GHC.Generics.Generic)
|
||||
deriving stock (Eq, Show)
|
||||
|
||||
instance HsBindgen.Runtime.Marshal.StaticSize T where
|
||||
|
||||
staticSizeOf = \_ -> (2 :: Int)
|
||||
|
||||
staticAlignment = \_ -> (1 :: Int)
|
||||
|
||||
instance HsBindgen.Runtime.Marshal.ReadRaw T where
|
||||
|
||||
readRaw =
|
||||
\ptr0 ->
|
||||
pure T
|
||||
<*> HsBindgen.Runtime.HasCField.readRaw (Data.Proxy.Proxy @"a") ptr0
|
||||
<*> HsBindgen.Runtime.HasCField.readRaw (Data.Proxy.Proxy @"b") ptr0
|
||||
|
||||
instance HsBindgen.Runtime.Marshal.WriteRaw T where
|
||||
|
||||
writeRaw =
|
||||
\ptr0 ->
|
||||
\s1 ->
|
||||
case s1 of
|
||||
T a2 b3 ->
|
||||
HsBindgen.Runtime.HasCField.writeRaw (Data.Proxy.Proxy @"a") ptr0 a2
|
||||
>> HsBindgen.Runtime.HasCField.writeRaw (Data.Proxy.Proxy @"b") ptr0 b3
|
||||
|
||||
deriving via HsBindgen.Runtime.Marshal.EquivStorable T instance F.Storable T
|
||||
|
||||
instance HsBindgen.Runtime.HasCField.HasCField T "a" where
|
||||
|
||||
type CFieldType T "a" = FC.CBool
|
||||
|
||||
offset# = \_ -> \_ -> 0
|
||||
|
||||
instance ( TyEq ty ((HsBindgen.Runtime.HasCField.CFieldType T) "a")
|
||||
) => GHC.Records.HasField "a" (Ptr.Ptr T) (Ptr.Ptr ty) where
|
||||
|
||||
getField =
|
||||
HsBindgen.Runtime.HasCField.fromPtr (Data.Proxy.Proxy @"a")
|
||||
|
||||
instance HsBindgen.Runtime.HasCField.HasCField T "b" where
|
||||
|
||||
type CFieldType T "b" = HsBindgen.Runtime.LibC.Word8
|
||||
|
||||
offset# = \_ -> \_ -> 1
|
||||
|
||||
instance ( TyEq ty ((HsBindgen.Runtime.HasCField.CFieldType T) "b")
|
||||
) => GHC.Records.HasField "b" (Ptr.Ptr T) (Ptr.Ptr ty) where
|
||||
|
||||
getField =
|
||||
HsBindgen.Runtime.HasCField.fromPtr (Data.Proxy.Proxy @"b")
|
||||
|
||||
{-| __C declaration:__ @enum Shape_Tag@
|
||||
|
||||
__defined at:__ @garnet_rs.h 11:6@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
newtype Shape_Tag = Shape_Tag
|
||||
{ unwrap :: FC.CUInt
|
||||
}
|
||||
deriving stock (GHC.Generics.Generic)
|
||||
deriving stock (Eq, Ord)
|
||||
deriving newtype (HsBindgen.Runtime.Internal.HasFFIType.HasFFIType)
|
||||
|
||||
instance HsBindgen.Runtime.Marshal.StaticSize Shape_Tag where
|
||||
|
||||
staticSizeOf = \_ -> (4 :: Int)
|
||||
|
||||
staticAlignment = \_ -> (4 :: Int)
|
||||
|
||||
instance HsBindgen.Runtime.Marshal.ReadRaw Shape_Tag where
|
||||
|
||||
readRaw =
|
||||
\ptr0 ->
|
||||
pure Shape_Tag
|
||||
<*> HsBindgen.Runtime.Marshal.readRawByteOff ptr0 (0 :: Int)
|
||||
|
||||
instance HsBindgen.Runtime.Marshal.WriteRaw Shape_Tag where
|
||||
|
||||
writeRaw =
|
||||
\ptr0 ->
|
||||
\s1 ->
|
||||
case s1 of
|
||||
Shape_Tag unwrap2 ->
|
||||
HsBindgen.Runtime.Marshal.writeRawByteOff ptr0 (0 :: Int) unwrap2
|
||||
|
||||
deriving via HsBindgen.Runtime.Marshal.EquivStorable Shape_Tag instance F.Storable Shape_Tag
|
||||
|
||||
deriving via FC.CUInt instance Data.Primitive.Types.Prim Shape_Tag
|
||||
|
||||
instance HsBindgen.Runtime.CEnum.CEnum Shape_Tag where
|
||||
|
||||
type CEnumZ Shape_Tag = FC.CUInt
|
||||
|
||||
toCEnum = Shape_Tag
|
||||
|
||||
fromCEnum = GHC.Records.getField @"unwrap"
|
||||
|
||||
declaredValues =
|
||||
\_ ->
|
||||
HsBindgen.Runtime.CEnum.declaredValuesFromList [ (0, Data.List.NonEmpty.singleton "Circle")
|
||||
, (1, Data.List.NonEmpty.singleton "Rectangle")
|
||||
]
|
||||
|
||||
showsUndeclared =
|
||||
HsBindgen.Runtime.CEnum.showsWrappedUndeclared "Shape_Tag"
|
||||
|
||||
readPrecUndeclared =
|
||||
HsBindgen.Runtime.CEnum.readPrecWrappedUndeclared "Shape_Tag"
|
||||
|
||||
isDeclared = HsBindgen.Runtime.CEnum.seqIsDeclared
|
||||
|
||||
mkDeclared = HsBindgen.Runtime.CEnum.seqMkDeclared
|
||||
|
||||
instance HsBindgen.Runtime.CEnum.SequentialCEnum Shape_Tag where
|
||||
|
||||
minDeclaredValue = Circle
|
||||
|
||||
maxDeclaredValue = Rectangle
|
||||
|
||||
instance Show Shape_Tag where
|
||||
|
||||
showsPrec = HsBindgen.Runtime.CEnum.shows
|
||||
|
||||
instance Read Shape_Tag where
|
||||
|
||||
readPrec = HsBindgen.Runtime.CEnum.readPrec
|
||||
|
||||
readList = Text.Read.readListDefault
|
||||
|
||||
readListPrec = Text.Read.readListPrecDefault
|
||||
|
||||
instance ( TyEq ty ((HsBindgen.Runtime.HasCField.CFieldType Shape_Tag) "unwrap")
|
||||
) => GHC.Records.HasField "unwrap" (Ptr.Ptr Shape_Tag) (Ptr.Ptr ty) where
|
||||
|
||||
getField =
|
||||
HsBindgen.Runtime.HasCField.fromPtr (Data.Proxy.Proxy @"unwrap")
|
||||
|
||||
instance HsBindgen.Runtime.HasCField.HasCField Shape_Tag "unwrap" where
|
||||
|
||||
type CFieldType Shape_Tag "unwrap" = FC.CUInt
|
||||
|
||||
offset# = \_ -> \_ -> 0
|
||||
|
||||
{-| __C declaration:__ @Circle@
|
||||
|
||||
__defined at:__ @garnet_rs.h 12:3@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
pattern Circle :: Shape_Tag
|
||||
pattern Circle = Shape_Tag 0
|
||||
|
||||
{-| __C declaration:__ @Rectangle@
|
||||
|
||||
__defined at:__ @garnet_rs.h 13:3@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
pattern Rectangle :: Shape_Tag
|
||||
pattern Rectangle = Shape_Tag 1
|
||||
|
||||
{-| __C declaration:__ @struct Circle_Body@
|
||||
|
||||
__defined at:__ @garnet_rs.h 16:8@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
data Circle_Body = Circle_Body
|
||||
{ radius :: FC.CDouble
|
||||
{- ^ __C declaration:__ @radius@
|
||||
|
||||
__defined at:__ @garnet_rs.h 17:10@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
}
|
||||
deriving stock (GHC.Generics.Generic)
|
||||
deriving stock (Eq, Show)
|
||||
|
||||
instance HsBindgen.Runtime.Marshal.StaticSize Circle_Body where
|
||||
|
||||
staticSizeOf = \_ -> (8 :: Int)
|
||||
|
||||
staticAlignment = \_ -> (8 :: Int)
|
||||
|
||||
instance HsBindgen.Runtime.Marshal.ReadRaw Circle_Body where
|
||||
|
||||
readRaw =
|
||||
\ptr0 ->
|
||||
pure Circle_Body
|
||||
<*> HsBindgen.Runtime.HasCField.readRaw (Data.Proxy.Proxy @"radius") ptr0
|
||||
|
||||
instance HsBindgen.Runtime.Marshal.WriteRaw Circle_Body where
|
||||
|
||||
writeRaw =
|
||||
\ptr0 ->
|
||||
\s1 ->
|
||||
case s1 of
|
||||
Circle_Body radius2 ->
|
||||
HsBindgen.Runtime.HasCField.writeRaw (Data.Proxy.Proxy @"radius") ptr0 radius2
|
||||
|
||||
deriving via HsBindgen.Runtime.Marshal.EquivStorable Circle_Body instance F.Storable Circle_Body
|
||||
|
||||
instance HsBindgen.Runtime.HasCField.HasCField Circle_Body "radius" where
|
||||
|
||||
type CFieldType Circle_Body "radius" = FC.CDouble
|
||||
|
||||
offset# = \_ -> \_ -> 0
|
||||
|
||||
instance ( TyEq ty ((HsBindgen.Runtime.HasCField.CFieldType Circle_Body) "radius")
|
||||
) => GHC.Records.HasField "radius" (Ptr.Ptr Circle_Body) (Ptr.Ptr ty) where
|
||||
|
||||
getField =
|
||||
HsBindgen.Runtime.HasCField.fromPtr (Data.Proxy.Proxy @"radius")
|
||||
|
||||
{-| __C declaration:__ @struct Rectangle_Body@
|
||||
|
||||
__defined at:__ @garnet_rs.h 20:8@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
data Rectangle_Body = Rectangle_Body
|
||||
{ width :: FC.CDouble
|
||||
{- ^ __C declaration:__ @width@
|
||||
|
||||
__defined at:__ @garnet_rs.h 21:10@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
, height :: FC.CDouble
|
||||
{- ^ __C declaration:__ @height@
|
||||
|
||||
__defined at:__ @garnet_rs.h 22:10@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
}
|
||||
deriving stock (GHC.Generics.Generic)
|
||||
deriving stock (Eq, Show)
|
||||
|
||||
instance HsBindgen.Runtime.Marshal.StaticSize Rectangle_Body where
|
||||
|
||||
staticSizeOf = \_ -> (16 :: Int)
|
||||
|
||||
staticAlignment = \_ -> (8 :: Int)
|
||||
|
||||
instance HsBindgen.Runtime.Marshal.ReadRaw Rectangle_Body where
|
||||
|
||||
readRaw =
|
||||
\ptr0 ->
|
||||
pure Rectangle_Body
|
||||
<*> HsBindgen.Runtime.HasCField.readRaw (Data.Proxy.Proxy @"width") ptr0
|
||||
<*> HsBindgen.Runtime.HasCField.readRaw (Data.Proxy.Proxy @"height") ptr0
|
||||
|
||||
instance HsBindgen.Runtime.Marshal.WriteRaw Rectangle_Body where
|
||||
|
||||
writeRaw =
|
||||
\ptr0 ->
|
||||
\s1 ->
|
||||
case s1 of
|
||||
Rectangle_Body width2 height3 ->
|
||||
HsBindgen.Runtime.HasCField.writeRaw (Data.Proxy.Proxy @"width") ptr0 width2
|
||||
>> HsBindgen.Runtime.HasCField.writeRaw (Data.Proxy.Proxy @"height") ptr0 height3
|
||||
|
||||
deriving via HsBindgen.Runtime.Marshal.EquivStorable Rectangle_Body instance F.Storable Rectangle_Body
|
||||
|
||||
instance HsBindgen.Runtime.HasCField.HasCField Rectangle_Body "width" where
|
||||
|
||||
type CFieldType Rectangle_Body "width" = FC.CDouble
|
||||
|
||||
offset# = \_ -> \_ -> 0
|
||||
|
||||
instance ( TyEq ty ((HsBindgen.Runtime.HasCField.CFieldType Rectangle_Body) "width")
|
||||
) => GHC.Records.HasField "width" (Ptr.Ptr Rectangle_Body) (Ptr.Ptr ty) where
|
||||
|
||||
getField =
|
||||
HsBindgen.Runtime.HasCField.fromPtr (Data.Proxy.Proxy @"width")
|
||||
|
||||
instance HsBindgen.Runtime.HasCField.HasCField Rectangle_Body "height" where
|
||||
|
||||
type CFieldType Rectangle_Body "height" = FC.CDouble
|
||||
|
||||
offset# = \_ -> \_ -> 8
|
||||
|
||||
instance ( TyEq ty ((HsBindgen.Runtime.HasCField.CFieldType Rectangle_Body) "height")
|
||||
) => GHC.Records.HasField "height" (Ptr.Ptr Rectangle_Body) (Ptr.Ptr ty) where
|
||||
|
||||
getField =
|
||||
HsBindgen.Runtime.HasCField.fromPtr (Data.Proxy.Proxy @"height")
|
||||
|
||||
{-| __C declaration:__ @union \@Shape_body@
|
||||
|
||||
__defined at:__ @garnet_rs.h 27:3@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
newtype Shape_body = Shape_body
|
||||
{ unwrap :: Data.Array.Byte.ByteArray
|
||||
}
|
||||
deriving stock (GHC.Generics.Generic)
|
||||
|
||||
deriving via (HsBindgen.Runtime.Internal.SizedByteArray.SizedByteArray 16) 8 instance HsBindgen.Runtime.Marshal.StaticSize Shape_body
|
||||
|
||||
deriving via (HsBindgen.Runtime.Internal.SizedByteArray.SizedByteArray 16) 8 instance HsBindgen.Runtime.Marshal.ReadRaw Shape_body
|
||||
|
||||
deriving via (HsBindgen.Runtime.Internal.SizedByteArray.SizedByteArray 16) 8 instance HsBindgen.Runtime.Marshal.WriteRaw Shape_body
|
||||
|
||||
deriving via HsBindgen.Runtime.Marshal.EquivStorable Shape_body instance F.Storable Shape_body
|
||||
|
||||
{-|
|
||||
|
||||
__See:__ 'set_shape_body_circle'
|
||||
|
||||
__C declaration:__ @circle@
|
||||
|
||||
__defined at:__ @garnet_rs.h 28:24@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
get_shape_body_circle ::
|
||||
Shape_body
|
||||
-> Circle_Body
|
||||
get_shape_body_circle =
|
||||
HsBindgen.Runtime.Internal.ByteArray.getUnionPayload
|
||||
|
||||
{-|
|
||||
|
||||
__See:__ 'get_shape_body_circle'
|
||||
|
||||
-}
|
||||
set_shape_body_circle ::
|
||||
Circle_Body
|
||||
-> Shape_body
|
||||
set_shape_body_circle =
|
||||
HsBindgen.Runtime.Internal.ByteArray.setUnionPayload
|
||||
|
||||
{-|
|
||||
|
||||
__See:__ 'set_shape_body_rectangle'
|
||||
|
||||
__C declaration:__ @rectangle@
|
||||
|
||||
__defined at:__ @garnet_rs.h 29:27@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
get_shape_body_rectangle ::
|
||||
Shape_body
|
||||
-> Rectangle_Body
|
||||
get_shape_body_rectangle =
|
||||
HsBindgen.Runtime.Internal.ByteArray.getUnionPayload
|
||||
|
||||
{-|
|
||||
|
||||
__See:__ 'get_shape_body_rectangle'
|
||||
|
||||
-}
|
||||
set_shape_body_rectangle ::
|
||||
Rectangle_Body
|
||||
-> Shape_body
|
||||
set_shape_body_rectangle =
|
||||
HsBindgen.Runtime.Internal.ByteArray.setUnionPayload
|
||||
|
||||
instance HsBindgen.Runtime.HasCField.HasCField Shape_body "circle" where
|
||||
|
||||
type CFieldType Shape_body "circle" = Circle_Body
|
||||
|
||||
offset# = \_ -> \_ -> 0
|
||||
|
||||
instance ( TyEq ty ((HsBindgen.Runtime.HasCField.CFieldType Shape_body) "circle")
|
||||
) => GHC.Records.HasField "circle" (Ptr.Ptr Shape_body) (Ptr.Ptr ty) where
|
||||
|
||||
getField =
|
||||
HsBindgen.Runtime.HasCField.fromPtr (Data.Proxy.Proxy @"circle")
|
||||
|
||||
instance HsBindgen.Runtime.HasCField.HasCField Shape_body "rectangle" where
|
||||
|
||||
type CFieldType Shape_body "rectangle" =
|
||||
Rectangle_Body
|
||||
|
||||
offset# = \_ -> \_ -> 0
|
||||
|
||||
instance ( TyEq ty ((HsBindgen.Runtime.HasCField.CFieldType Shape_body) "rectangle")
|
||||
) => GHC.Records.HasField "rectangle" (Ptr.Ptr Shape_body) (Ptr.Ptr ty) where
|
||||
|
||||
getField =
|
||||
HsBindgen.Runtime.HasCField.fromPtr (Data.Proxy.Proxy @"rectangle")
|
||||
|
||||
{-| __C declaration:__ @struct Shape@
|
||||
|
||||
__defined at:__ @garnet_rs.h 25:8@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
data Shape = Shape
|
||||
{ tag :: Shape_Tag
|
||||
{- ^ __C declaration:__ @tag@
|
||||
|
||||
__defined at:__ @garnet_rs.h 26:18@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
, body :: Shape_body
|
||||
{- ^ __C declaration:__ @body@
|
||||
|
||||
__defined at:__ @garnet_rs.h 30:5@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
}
|
||||
deriving stock (GHC.Generics.Generic)
|
||||
|
||||
instance HsBindgen.Runtime.Marshal.StaticSize Shape where
|
||||
|
||||
staticSizeOf = \_ -> (24 :: Int)
|
||||
|
||||
staticAlignment = \_ -> (8 :: Int)
|
||||
|
||||
instance HsBindgen.Runtime.Marshal.ReadRaw Shape where
|
||||
|
||||
readRaw =
|
||||
\ptr0 ->
|
||||
pure Shape
|
||||
<*> HsBindgen.Runtime.HasCField.readRaw (Data.Proxy.Proxy @"tag") ptr0
|
||||
<*> HsBindgen.Runtime.HasCField.readRaw (Data.Proxy.Proxy @"body") ptr0
|
||||
|
||||
instance HsBindgen.Runtime.Marshal.WriteRaw Shape where
|
||||
|
||||
writeRaw =
|
||||
\ptr0 ->
|
||||
\s1 ->
|
||||
case s1 of
|
||||
Shape tag2 body3 ->
|
||||
HsBindgen.Runtime.HasCField.writeRaw (Data.Proxy.Proxy @"tag") ptr0 tag2
|
||||
>> HsBindgen.Runtime.HasCField.writeRaw (Data.Proxy.Proxy @"body") ptr0 body3
|
||||
|
||||
deriving via HsBindgen.Runtime.Marshal.EquivStorable Shape instance F.Storable Shape
|
||||
|
||||
instance HsBindgen.Runtime.HasCField.HasCField Shape "tag" where
|
||||
|
||||
type CFieldType Shape "tag" = Shape_Tag
|
||||
|
||||
offset# = \_ -> \_ -> 0
|
||||
|
||||
instance ( TyEq ty ((HsBindgen.Runtime.HasCField.CFieldType Shape) "tag")
|
||||
) => GHC.Records.HasField "tag" (Ptr.Ptr Shape) (Ptr.Ptr ty) where
|
||||
|
||||
getField =
|
||||
HsBindgen.Runtime.HasCField.fromPtr (Data.Proxy.Proxy @"tag")
|
||||
|
||||
instance HsBindgen.Runtime.HasCField.HasCField Shape "body" where
|
||||
|
||||
type CFieldType Shape "body" = Shape_body
|
||||
|
||||
offset# = \_ -> \_ -> 8
|
||||
|
||||
instance ( TyEq ty ((HsBindgen.Runtime.HasCField.CFieldType Shape) "body")
|
||||
) => GHC.Records.HasField "body" (Ptr.Ptr Shape) (Ptr.Ptr ty) where
|
||||
|
||||
getField =
|
||||
HsBindgen.Runtime.HasCField.fromPtr (Data.Proxy.Proxy @"body")
|
||||
@ -1,134 +0,0 @@
|
||||
{-# LANGUAGE CApiFFI #-}
|
||||
{-# LANGUAGE NoImplicitPrelude #-}
|
||||
{-# LANGUAGE TemplateHaskell #-}
|
||||
{-# OPTIONS_HADDOCK prune #-}
|
||||
|
||||
module GarnetRs.FunPtr where
|
||||
|
||||
import qualified Foreign.C as FC
|
||||
import qualified GHC.IO.Unsafe
|
||||
import qualified GHC.Ptr as Ptr
|
||||
import qualified HsBindgen.Runtime.Internal.CAPI
|
||||
import qualified HsBindgen.Runtime.Internal.HasFFIType
|
||||
import qualified HsBindgen.Runtime.LibC
|
||||
import qualified HsBindgen.Runtime.PtrConst
|
||||
import Data.Void (Void)
|
||||
import GarnetRs
|
||||
import Prelude (IO)
|
||||
|
||||
$(HsBindgen.Runtime.Internal.CAPI.addCSource (HsBindgen.Runtime.Internal.CAPI.unlines
|
||||
[ "#include <garnet_rs.h>"
|
||||
, "/* com_garnet_GarnetRs_get_hello */"
|
||||
, "__attribute__ ((const))"
|
||||
, "void (*hs_bindgen_faf62265b53521d3 (void)) ("
|
||||
, " char const *arg1"
|
||||
, ")"
|
||||
, "{"
|
||||
, " return &hello;"
|
||||
, "}"
|
||||
, "/* com_garnet_GarnetRs_get_hello_struct */"
|
||||
, "__attribute__ ((const))"
|
||||
, "void (*hs_bindgen_0f8c37ef19b17a6d (void)) ("
|
||||
, " struct T arg1"
|
||||
, ")"
|
||||
, "{"
|
||||
, " return &hello_struct;"
|
||||
, "}"
|
||||
, "/* com_garnet_GarnetRs_get_hello_shape */"
|
||||
, "__attribute__ ((const))"
|
||||
, "void (*hs_bindgen_287ff3ac660f333b (void)) ("
|
||||
, " struct Shape arg1"
|
||||
, ")"
|
||||
, "{"
|
||||
, " return &hello_shape;"
|
||||
, "}"
|
||||
, "/* com_garnet_GarnetRs_get_add */"
|
||||
, "__attribute__ ((const))"
|
||||
, "int64_t (*hs_bindgen_bbabdbe61cd1eeb2 (void)) ("
|
||||
, " int64_t arg1,"
|
||||
, " int64_t arg2"
|
||||
, ")"
|
||||
, "{"
|
||||
, " return &add;"
|
||||
, "}"
|
||||
]))
|
||||
|
||||
-- __unique:__ @com_garnet_GarnetRs_get_hello@
|
||||
foreign import ccall unsafe "hs_bindgen_faf62265b53521d3" hs_bindgen_faf62265b53521d3_base ::
|
||||
IO (Ptr.FunPtr Void)
|
||||
|
||||
-- __unique:__ @com_garnet_GarnetRs_get_hello@
|
||||
hs_bindgen_faf62265b53521d3 :: IO (Ptr.FunPtr ((HsBindgen.Runtime.PtrConst.PtrConst FC.CChar) -> IO ()))
|
||||
hs_bindgen_faf62265b53521d3 =
|
||||
HsBindgen.Runtime.Internal.HasFFIType.fromFFIType hs_bindgen_faf62265b53521d3_base
|
||||
|
||||
{-# NOINLINE hello #-}
|
||||
{-| __C declaration:__ @hello@
|
||||
|
||||
__defined at:__ @garnet_rs.h 33:6@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
hello :: Ptr.FunPtr ((HsBindgen.Runtime.PtrConst.PtrConst FC.CChar) -> IO ())
|
||||
hello =
|
||||
GHC.IO.Unsafe.unsafePerformIO hs_bindgen_faf62265b53521d3
|
||||
|
||||
-- __unique:__ @com_garnet_GarnetRs_get_hello_struct@
|
||||
foreign import ccall unsafe "hs_bindgen_0f8c37ef19b17a6d" hs_bindgen_0f8c37ef19b17a6d_base ::
|
||||
IO (Ptr.FunPtr Void)
|
||||
|
||||
-- __unique:__ @com_garnet_GarnetRs_get_hello_struct@
|
||||
hs_bindgen_0f8c37ef19b17a6d :: IO (Ptr.FunPtr (T -> IO ()))
|
||||
hs_bindgen_0f8c37ef19b17a6d =
|
||||
HsBindgen.Runtime.Internal.HasFFIType.fromFFIType hs_bindgen_0f8c37ef19b17a6d_base
|
||||
|
||||
{-# NOINLINE hello_struct #-}
|
||||
{-| __C declaration:__ @hello_struct@
|
||||
|
||||
__defined at:__ @garnet_rs.h 35:6@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
hello_struct :: Ptr.FunPtr (T -> IO ())
|
||||
hello_struct =
|
||||
GHC.IO.Unsafe.unsafePerformIO hs_bindgen_0f8c37ef19b17a6d
|
||||
|
||||
-- __unique:__ @com_garnet_GarnetRs_get_hello_shape@
|
||||
foreign import ccall unsafe "hs_bindgen_287ff3ac660f333b" hs_bindgen_287ff3ac660f333b_base ::
|
||||
IO (Ptr.FunPtr Void)
|
||||
|
||||
-- __unique:__ @com_garnet_GarnetRs_get_hello_shape@
|
||||
hs_bindgen_287ff3ac660f333b :: IO (Ptr.FunPtr (Shape -> IO ()))
|
||||
hs_bindgen_287ff3ac660f333b =
|
||||
HsBindgen.Runtime.Internal.HasFFIType.fromFFIType hs_bindgen_287ff3ac660f333b_base
|
||||
|
||||
{-# NOINLINE hello_shape #-}
|
||||
{-| __C declaration:__ @hello_shape@
|
||||
|
||||
__defined at:__ @garnet_rs.h 37:6@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
hello_shape :: Ptr.FunPtr (Shape -> IO ())
|
||||
hello_shape =
|
||||
GHC.IO.Unsafe.unsafePerformIO hs_bindgen_287ff3ac660f333b
|
||||
|
||||
-- __unique:__ @com_garnet_GarnetRs_get_add@
|
||||
foreign import ccall unsafe "hs_bindgen_bbabdbe61cd1eeb2" hs_bindgen_bbabdbe61cd1eeb2_base ::
|
||||
IO (Ptr.FunPtr Void)
|
||||
|
||||
-- __unique:__ @com_garnet_GarnetRs_get_add@
|
||||
hs_bindgen_bbabdbe61cd1eeb2 :: IO (Ptr.FunPtr (HsBindgen.Runtime.LibC.Int64 -> HsBindgen.Runtime.LibC.Int64 -> IO HsBindgen.Runtime.LibC.Int64))
|
||||
hs_bindgen_bbabdbe61cd1eeb2 =
|
||||
HsBindgen.Runtime.Internal.HasFFIType.fromFFIType hs_bindgen_bbabdbe61cd1eeb2_base
|
||||
|
||||
{-# NOINLINE add #-}
|
||||
{-| __C declaration:__ @add@
|
||||
|
||||
__defined at:__ @garnet_rs.h 39:32@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
add :: Ptr.FunPtr (HsBindgen.Runtime.LibC.Int64 -> HsBindgen.Runtime.LibC.Int64 -> IO HsBindgen.Runtime.LibC.Int64)
|
||||
add =
|
||||
GHC.IO.Unsafe.unsafePerformIO hs_bindgen_bbabdbe61cd1eeb2
|
||||
@ -1,155 +0,0 @@
|
||||
{-# LANGUAGE CApiFFI #-}
|
||||
{-# LANGUAGE NoImplicitPrelude #-}
|
||||
{-# LANGUAGE TemplateHaskell #-}
|
||||
{-# OPTIONS_HADDOCK prune #-}
|
||||
|
||||
module GarnetRs.Safe where
|
||||
|
||||
import qualified Foreign as F
|
||||
import qualified Foreign.C as FC
|
||||
import qualified GHC.Int
|
||||
import qualified GHC.Ptr as Ptr
|
||||
import qualified HsBindgen.Runtime.Internal.CAPI
|
||||
import qualified HsBindgen.Runtime.Internal.HasFFIType
|
||||
import qualified HsBindgen.Runtime.LibC
|
||||
import qualified HsBindgen.Runtime.PtrConst
|
||||
import Data.Void (Void)
|
||||
import GarnetRs
|
||||
import Prelude (IO)
|
||||
|
||||
$(HsBindgen.Runtime.Internal.CAPI.addCSource (HsBindgen.Runtime.Internal.CAPI.unlines
|
||||
[ "#include <garnet_rs.h>"
|
||||
, "void hs_bindgen_433ea2a26af4e593 ("
|
||||
, " char const *arg1"
|
||||
, ")"
|
||||
, "{"
|
||||
, " hello(arg1);"
|
||||
, "}"
|
||||
, "void hs_bindgen_51157946af5519c9 ("
|
||||
, " struct T *arg1"
|
||||
, ")"
|
||||
, "{"
|
||||
, " hello_struct(*arg1);"
|
||||
, "}"
|
||||
, "void hs_bindgen_7de06f1fd827ca60 ("
|
||||
, " struct Shape *arg1"
|
||||
, ")"
|
||||
, "{"
|
||||
, " hello_shape(*arg1);"
|
||||
, "}"
|
||||
, "int64_t hs_bindgen_1c0c71fa74c428a9 ("
|
||||
, " int64_t arg1,"
|
||||
, " int64_t arg2"
|
||||
, ")"
|
||||
, "{"
|
||||
, " return add(arg1, arg2);"
|
||||
, "}"
|
||||
]))
|
||||
|
||||
-- __unique:__ @com_garnet_GarnetRs_Safe_hello@
|
||||
foreign import ccall safe "hs_bindgen_433ea2a26af4e593" hs_bindgen_433ea2a26af4e593_base ::
|
||||
Ptr.Ptr Void
|
||||
-> IO ()
|
||||
|
||||
-- __unique:__ @com_garnet_GarnetRs_Safe_hello@
|
||||
hs_bindgen_433ea2a26af4e593 ::
|
||||
HsBindgen.Runtime.PtrConst.PtrConst FC.CChar
|
||||
-> IO ()
|
||||
hs_bindgen_433ea2a26af4e593 =
|
||||
HsBindgen.Runtime.Internal.HasFFIType.fromFFIType hs_bindgen_433ea2a26af4e593_base
|
||||
|
||||
{-| __C declaration:__ @hello@
|
||||
|
||||
__defined at:__ @garnet_rs.h 33:6@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
hello ::
|
||||
HsBindgen.Runtime.PtrConst.PtrConst FC.CChar
|
||||
-- ^ __C declaration:__ @c@
|
||||
-> IO ()
|
||||
hello = hs_bindgen_433ea2a26af4e593
|
||||
|
||||
-- __unique:__ @com_garnet_GarnetRs_Safe_hello_struct@
|
||||
foreign import ccall safe "hs_bindgen_51157946af5519c9" hs_bindgen_51157946af5519c9_base ::
|
||||
Ptr.Ptr Void
|
||||
-> IO ()
|
||||
|
||||
-- __unique:__ @com_garnet_GarnetRs_Safe_hello_struct@
|
||||
hs_bindgen_51157946af5519c9 ::
|
||||
Ptr.Ptr T
|
||||
-> IO ()
|
||||
hs_bindgen_51157946af5519c9 =
|
||||
HsBindgen.Runtime.Internal.HasFFIType.fromFFIType hs_bindgen_51157946af5519c9_base
|
||||
|
||||
{-| __C declaration:__ @hello_struct@
|
||||
|
||||
__defined at:__ @garnet_rs.h 35:6@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
hello_struct ::
|
||||
T
|
||||
-- ^ __C declaration:__ @t@
|
||||
-> IO ()
|
||||
hello_struct =
|
||||
\t0 ->
|
||||
F.with t0 (\t1 -> hs_bindgen_51157946af5519c9 t1)
|
||||
|
||||
-- __unique:__ @com_garnet_GarnetRs_Safe_hello_shape@
|
||||
foreign import ccall safe "hs_bindgen_7de06f1fd827ca60" hs_bindgen_7de06f1fd827ca60_base ::
|
||||
Ptr.Ptr Void
|
||||
-> IO ()
|
||||
|
||||
-- __unique:__ @com_garnet_GarnetRs_Safe_hello_shape@
|
||||
hs_bindgen_7de06f1fd827ca60 ::
|
||||
Ptr.Ptr Shape
|
||||
-> IO ()
|
||||
hs_bindgen_7de06f1fd827ca60 =
|
||||
HsBindgen.Runtime.Internal.HasFFIType.fromFFIType hs_bindgen_7de06f1fd827ca60_base
|
||||
|
||||
{-| __C declaration:__ @hello_shape@
|
||||
|
||||
__defined at:__ @garnet_rs.h 37:6@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
hello_shape ::
|
||||
Shape
|
||||
-- ^ __C declaration:__ @s@
|
||||
-> IO ()
|
||||
hello_shape =
|
||||
\s0 ->
|
||||
F.with s0 (\s1 -> hs_bindgen_7de06f1fd827ca60 s1)
|
||||
|
||||
-- __unique:__ @com_garnet_GarnetRs_Safe_add@
|
||||
foreign import ccall safe "hs_bindgen_1c0c71fa74c428a9" hs_bindgen_1c0c71fa74c428a9_base ::
|
||||
GHC.Int.Int64
|
||||
-> GHC.Int.Int64
|
||||
-> GHC.Int.Int64
|
||||
|
||||
-- __unique:__ @com_garnet_GarnetRs_Safe_add@
|
||||
hs_bindgen_1c0c71fa74c428a9 ::
|
||||
HsBindgen.Runtime.LibC.Int64
|
||||
-> HsBindgen.Runtime.LibC.Int64
|
||||
-> HsBindgen.Runtime.LibC.Int64
|
||||
hs_bindgen_1c0c71fa74c428a9 =
|
||||
HsBindgen.Runtime.Internal.HasFFIType.fromFFIType hs_bindgen_1c0c71fa74c428a9_base
|
||||
|
||||
{-|
|
||||
|
||||
Marked @__attribute((const))__@
|
||||
|
||||
__C declaration:__ @add@
|
||||
|
||||
__defined at:__ @garnet_rs.h 39:32@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
add ::
|
||||
HsBindgen.Runtime.LibC.Int64
|
||||
-- ^ __C declaration:__ @a@
|
||||
-> HsBindgen.Runtime.LibC.Int64
|
||||
-- ^ __C declaration:__ @b@
|
||||
-> HsBindgen.Runtime.LibC.Int64
|
||||
add = hs_bindgen_1c0c71fa74c428a9
|
||||
@ -1,155 +0,0 @@
|
||||
{-# LANGUAGE CApiFFI #-}
|
||||
{-# LANGUAGE NoImplicitPrelude #-}
|
||||
{-# LANGUAGE TemplateHaskell #-}
|
||||
{-# OPTIONS_HADDOCK prune #-}
|
||||
|
||||
module GarnetRs.Unsafe where
|
||||
|
||||
import qualified Foreign as F
|
||||
import qualified Foreign.C as FC
|
||||
import qualified GHC.Int
|
||||
import qualified GHC.Ptr as Ptr
|
||||
import qualified HsBindgen.Runtime.Internal.CAPI
|
||||
import qualified HsBindgen.Runtime.Internal.HasFFIType
|
||||
import qualified HsBindgen.Runtime.LibC
|
||||
import qualified HsBindgen.Runtime.PtrConst
|
||||
import Data.Void (Void)
|
||||
import GarnetRs
|
||||
import Prelude (IO)
|
||||
|
||||
$(HsBindgen.Runtime.Internal.CAPI.addCSource (HsBindgen.Runtime.Internal.CAPI.unlines
|
||||
[ "#include <garnet_rs.h>"
|
||||
, "void hs_bindgen_2dfe97662a4d6377 ("
|
||||
, " char const *arg1"
|
||||
, ")"
|
||||
, "{"
|
||||
, " hello(arg1);"
|
||||
, "}"
|
||||
, "void hs_bindgen_29d823ada2bc7302 ("
|
||||
, " struct T *arg1"
|
||||
, ")"
|
||||
, "{"
|
||||
, " hello_struct(*arg1);"
|
||||
, "}"
|
||||
, "void hs_bindgen_b3f40a03f07eaa85 ("
|
||||
, " struct Shape *arg1"
|
||||
, ")"
|
||||
, "{"
|
||||
, " hello_shape(*arg1);"
|
||||
, "}"
|
||||
, "int64_t hs_bindgen_20eb651f0a8faf48 ("
|
||||
, " int64_t arg1,"
|
||||
, " int64_t arg2"
|
||||
, ")"
|
||||
, "{"
|
||||
, " return add(arg1, arg2);"
|
||||
, "}"
|
||||
]))
|
||||
|
||||
-- __unique:__ @com_garnet_GarnetRs_Unsafe_hello@
|
||||
foreign import ccall unsafe "hs_bindgen_2dfe97662a4d6377" hs_bindgen_2dfe97662a4d6377_base ::
|
||||
Ptr.Ptr Void
|
||||
-> IO ()
|
||||
|
||||
-- __unique:__ @com_garnet_GarnetRs_Unsafe_hello@
|
||||
hs_bindgen_2dfe97662a4d6377 ::
|
||||
HsBindgen.Runtime.PtrConst.PtrConst FC.CChar
|
||||
-> IO ()
|
||||
hs_bindgen_2dfe97662a4d6377 =
|
||||
HsBindgen.Runtime.Internal.HasFFIType.fromFFIType hs_bindgen_2dfe97662a4d6377_base
|
||||
|
||||
{-| __C declaration:__ @hello@
|
||||
|
||||
__defined at:__ @garnet_rs.h 33:6@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
hello ::
|
||||
HsBindgen.Runtime.PtrConst.PtrConst FC.CChar
|
||||
-- ^ __C declaration:__ @c@
|
||||
-> IO ()
|
||||
hello = hs_bindgen_2dfe97662a4d6377
|
||||
|
||||
-- __unique:__ @com_garnet_GarnetRs_Unsafe_hello_struct@
|
||||
foreign import ccall unsafe "hs_bindgen_29d823ada2bc7302" hs_bindgen_29d823ada2bc7302_base ::
|
||||
Ptr.Ptr Void
|
||||
-> IO ()
|
||||
|
||||
-- __unique:__ @com_garnet_GarnetRs_Unsafe_hello_struct@
|
||||
hs_bindgen_29d823ada2bc7302 ::
|
||||
Ptr.Ptr T
|
||||
-> IO ()
|
||||
hs_bindgen_29d823ada2bc7302 =
|
||||
HsBindgen.Runtime.Internal.HasFFIType.fromFFIType hs_bindgen_29d823ada2bc7302_base
|
||||
|
||||
{-| __C declaration:__ @hello_struct@
|
||||
|
||||
__defined at:__ @garnet_rs.h 35:6@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
hello_struct ::
|
||||
T
|
||||
-- ^ __C declaration:__ @t@
|
||||
-> IO ()
|
||||
hello_struct =
|
||||
\t0 ->
|
||||
F.with t0 (\t1 -> hs_bindgen_29d823ada2bc7302 t1)
|
||||
|
||||
-- __unique:__ @com_garnet_GarnetRs_Unsafe_hello_shape@
|
||||
foreign import ccall unsafe "hs_bindgen_b3f40a03f07eaa85" hs_bindgen_b3f40a03f07eaa85_base ::
|
||||
Ptr.Ptr Void
|
||||
-> IO ()
|
||||
|
||||
-- __unique:__ @com_garnet_GarnetRs_Unsafe_hello_shape@
|
||||
hs_bindgen_b3f40a03f07eaa85 ::
|
||||
Ptr.Ptr Shape
|
||||
-> IO ()
|
||||
hs_bindgen_b3f40a03f07eaa85 =
|
||||
HsBindgen.Runtime.Internal.HasFFIType.fromFFIType hs_bindgen_b3f40a03f07eaa85_base
|
||||
|
||||
{-| __C declaration:__ @hello_shape@
|
||||
|
||||
__defined at:__ @garnet_rs.h 37:6@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
hello_shape ::
|
||||
Shape
|
||||
-- ^ __C declaration:__ @s@
|
||||
-> IO ()
|
||||
hello_shape =
|
||||
\s0 ->
|
||||
F.with s0 (\s1 -> hs_bindgen_b3f40a03f07eaa85 s1)
|
||||
|
||||
-- __unique:__ @com_garnet_GarnetRs_Unsafe_add@
|
||||
foreign import ccall unsafe "hs_bindgen_20eb651f0a8faf48" hs_bindgen_20eb651f0a8faf48_base ::
|
||||
GHC.Int.Int64
|
||||
-> GHC.Int.Int64
|
||||
-> GHC.Int.Int64
|
||||
|
||||
-- __unique:__ @com_garnet_GarnetRs_Unsafe_add@
|
||||
hs_bindgen_20eb651f0a8faf48 ::
|
||||
HsBindgen.Runtime.LibC.Int64
|
||||
-> HsBindgen.Runtime.LibC.Int64
|
||||
-> HsBindgen.Runtime.LibC.Int64
|
||||
hs_bindgen_20eb651f0a8faf48 =
|
||||
HsBindgen.Runtime.Internal.HasFFIType.fromFFIType hs_bindgen_20eb651f0a8faf48_base
|
||||
|
||||
{-|
|
||||
|
||||
Marked @__attribute((const))__@
|
||||
|
||||
__C declaration:__ @add@
|
||||
|
||||
__defined at:__ @garnet_rs.h 39:32@
|
||||
|
||||
__exported by:__ @garnet_rs.h@
|
||||
-}
|
||||
add ::
|
||||
HsBindgen.Runtime.LibC.Int64
|
||||
-- ^ __C declaration:__ @a@
|
||||
-> HsBindgen.Runtime.LibC.Int64
|
||||
-- ^ __C declaration:__ @b@
|
||||
-> HsBindgen.Runtime.LibC.Int64
|
||||
add = hs_bindgen_20eb651f0a8faf48
|
||||
46
lib/GarnetRs/Raw.hs
Normal file
46
lib/GarnetRs/Raw.hs
Normal file
@ -0,0 +1,46 @@
|
||||
{-# LANGUAGE CApiFFI #-}
|
||||
{-# LANGUAGE DerivingVia #-}
|
||||
{-# LANGUAGE FieldSelectors #-}
|
||||
{-# LANGUAGE MagicHash #-}
|
||||
{-# LANGUAGE PatternSynonyms #-}
|
||||
{-# LANGUAGE TemplateHaskell #-}
|
||||
{-# LANGUAGE TypeFamilies #-}
|
||||
{-# LANGUAGE UnboxedTuples #-}
|
||||
{-# LANGUAGE UndecidableInstances #-}
|
||||
{-# OPTIONS_GHC -Wno-unused-imports #-}
|
||||
|
||||
module GarnetRs.Raw where
|
||||
|
||||
-- TODO this causes HLS to panic, and isn't yet supported by Ormolu/Fourmolu
|
||||
-- {-# LANGUAGE ExplicitLevelImports #-}
|
||||
-- import HsBindgen.Runtime.LibC qualified
|
||||
-- import splice Data.List
|
||||
-- import splice Data.Tuple.Extra
|
||||
-- import splice HsBindgen.TH
|
||||
-- import splice Language.Haskell.TH
|
||||
-- import splice System.Process
|
||||
-- import splice Prelude
|
||||
|
||||
import Data.List
|
||||
import Data.Text qualified as T
|
||||
import Data.Tuple.Extra
|
||||
import HsBindgen.Runtime.LibC qualified
|
||||
import HsBindgen.TH
|
||||
import Language.Haskell.TH
|
||||
import System.Process
|
||||
|
||||
do
|
||||
systemDirs <- -- TODO bit of a hack
|
||||
map (Dir . T.unpack . T.strip)
|
||||
. concatMap (takeWhile (maybe False ((== ' ') . fst) . T.uncons) . dropWhile T.null . T.lines)
|
||||
. drop 1
|
||||
. T.splitOn "search starts here:"
|
||||
. T.pack
|
||||
. thd3
|
||||
<$> runIO (readProcessWithExitCode "cpp" ["-v"] "")
|
||||
withHsBindgen
|
||||
def
|
||||
{ clang = def{extraIncludeDirs = Pkg "rust" : systemDirs}
|
||||
}
|
||||
def
|
||||
$ hashInclude "garnet_rs.h"
|
||||
@ -3,26 +3,31 @@
|
||||
module GarnetRs.Wrapped (
|
||||
T (..),
|
||||
Shape (..),
|
||||
BTree (..),
|
||||
hello,
|
||||
helloStruct,
|
||||
helloShape,
|
||||
add,
|
||||
sumTree,
|
||||
) where
|
||||
|
||||
import Control.Monad.Cont
|
||||
import Control.Monad.Trans
|
||||
import Data.ByteString
|
||||
import Data.Function
|
||||
import Data.Word
|
||||
import Foreign
|
||||
import Foreign.C
|
||||
import GarnetRs qualified as Raw
|
||||
import GarnetRs.Safe qualified as Raw
|
||||
import GarnetRs.Raw qualified as Raw
|
||||
import HsBindgen.Runtime.PtrConst
|
||||
import System.IO.Unsafe
|
||||
|
||||
data T = T
|
||||
{ a :: Bool
|
||||
, b :: Word8
|
||||
}
|
||||
convertT :: T -> Raw.T
|
||||
convertT T{a, b} = Raw.T{a = fromBool a, b}
|
||||
convertT T{a, b} = Raw.T{t_a = fromBool a, t_b = b}
|
||||
|
||||
data Shape
|
||||
= Circle CDouble
|
||||
@ -32,6 +37,22 @@ convertShape = \case
|
||||
Circle r -> Raw.Shape Raw.Circle $ Raw.set_shape_body_circle $ Raw.Circle_Body r
|
||||
Rectangle w h -> Raw.Shape Raw.Rectangle $ Raw.set_shape_body_rectangle $ Raw.Rectangle_Body w h
|
||||
|
||||
data BTree a
|
||||
= Leaf a
|
||||
| Fork (BTree a) (BTree a)
|
||||
withBTree :: BTree Int64 -> (Raw.BTreeC -> IO a) -> IO a
|
||||
withBTree =
|
||||
runContT . fix \f -> \case
|
||||
Leaf v -> pure $ Raw.BTreeC Raw.Leaf $ Raw.set_bTreeC_body_leaf $ Raw.Leaf_Body v
|
||||
Fork l r -> do
|
||||
lRaw <- f l
|
||||
rRaw <- f r
|
||||
lPtr <- ContT alloca
|
||||
rPtr <- ContT alloca
|
||||
lift $ poke lPtr lRaw >> poke rPtr rRaw
|
||||
pure . Raw.BTreeC Raw.Fork . Raw.set_bTreeC_body_fork $
|
||||
Raw.Fork_Body (unsafeFromPtr lPtr) (unsafeFromPtr rPtr)
|
||||
|
||||
hello :: ByteString -> IO ()
|
||||
hello s = useAsCString s $ Raw.hello . unsafeFromPtr
|
||||
|
||||
@ -43,3 +64,6 @@ helloShape = Raw.hello_shape . convertShape
|
||||
|
||||
add :: Int64 -> Int64 -> Int64
|
||||
add = Raw.add
|
||||
|
||||
sumTree :: BTree Int64 -> Int64
|
||||
sumTree = unsafePerformIO . flip withBTree Raw.sum_tree
|
||||
@ -30,6 +30,28 @@ struct Shape {
|
||||
} body;
|
||||
};
|
||||
|
||||
enum BTreeC_Tag {
|
||||
Leaf,
|
||||
Fork,
|
||||
};
|
||||
|
||||
struct Leaf_Body {
|
||||
int64_t value;
|
||||
};
|
||||
|
||||
struct Fork_Body {
|
||||
const struct BTreeC *left;
|
||||
const struct BTreeC *right;
|
||||
};
|
||||
|
||||
struct BTreeC {
|
||||
enum BTreeC_Tag tag;
|
||||
union {
|
||||
struct Leaf_Body leaf;
|
||||
struct Fork_Body fork;
|
||||
} body;
|
||||
};
|
||||
|
||||
void hello(const char *c);
|
||||
|
||||
void hello_struct(struct T t);
|
||||
@ -37,3 +59,5 @@ void hello_struct(struct T t);
|
||||
void hello_shape(struct Shape s);
|
||||
|
||||
__attribute__((const)) int64_t add(int64_t a, int64_t b);
|
||||
|
||||
int64_t sum_tree(struct BTreeC t);
|
||||
|
||||
44
rust/lib.rs
44
rust/lib.rs
@ -1,6 +1,9 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::ffi::{CStr, c_char};
|
||||
use std::{
|
||||
ffi::{CStr, c_char},
|
||||
ops::Add,
|
||||
};
|
||||
|
||||
fn say_hello(name: &str) {
|
||||
println!("Hello from Rust, {name}!");
|
||||
@ -17,6 +20,7 @@ struct T {
|
||||
a: bool,
|
||||
b: u8,
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
extern "C" fn hello_struct(t: T) -> () {
|
||||
say_hello(&format!("{:?}", t))
|
||||
@ -39,3 +43,41 @@ extern "C" fn hello_shape(s: Shape) -> () {
|
||||
extern "C" fn add(a: i64, b: i64) -> i64 {
|
||||
a + b
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
enum BTree<A> {
|
||||
Leaf {
|
||||
value: A,
|
||||
},
|
||||
Fork {
|
||||
left: Box<BTree<A>>,
|
||||
right: Box<BTree<A>>,
|
||||
},
|
||||
}
|
||||
impl<A> BTree<A>
|
||||
where
|
||||
A: Add<Output = A> + Copy,
|
||||
{
|
||||
fn sum(&self) -> A {
|
||||
match self {
|
||||
BTree::Leaf { value } => *value,
|
||||
BTree::Fork { left, right } => left.sum() + right.sum(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
enum BTreeC {
|
||||
Leaf {
|
||||
value: i64,
|
||||
},
|
||||
Fork {
|
||||
left: *const BTreeC,
|
||||
right: *const BTreeC,
|
||||
},
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
extern "C" fn sum_tree(t: BTreeC) -> i64 {
|
||||
(unsafe { std::mem::transmute::<_, &BTree<i64>>(&t) }).sum()
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user