Compare commits
10 Commits
569fae5d32
...
24359a519c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
24359a519c | ||
|
|
aa05650ec8 | ||
|
|
34ce6078ba | ||
|
|
e53fb108f4 | ||
|
|
14ef0237cb | ||
|
|
96daf482ca | ||
|
|
ad78170066 | ||
|
|
b1d8b6e1bf | ||
|
|
7e572b75ee | ||
|
|
bc21f9e79f |
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,3 +1,3 @@
|
||||
dist*
|
||||
dist*/
|
||||
result
|
||||
target
|
||||
|
||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "inputs/real"]
|
||||
path = inputs/private
|
||||
url = git@github.com:georgefst/aoc-private-inputs.git
|
||||
@ -1,4 +1,4 @@
|
||||
packages: .
|
||||
packages: haskell
|
||||
|
||||
-- TODO a total hack
|
||||
package garnet
|
||||
@ -15,7 +15,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
|
||||
|
||||
@ -1,41 +0,0 @@
|
||||
-- TODO automate this sort of high level wrapper boilerplate
|
||||
-- or look at upstream plans: https://github.com/well-typed/hs-bindgen/issues?q=state%3Aopen%20label%3A%22highlevel%22
|
||||
module GarnetRs.Wrapped (
|
||||
T (..),
|
||||
Shape (..),
|
||||
hello,
|
||||
helloStruct,
|
||||
helloShape,
|
||||
) where
|
||||
|
||||
import Data.ByteString
|
||||
import Data.Word
|
||||
import Foreign
|
||||
import Foreign.C
|
||||
import GarnetRs qualified as Raw
|
||||
import GarnetRs.Safe qualified as Raw
|
||||
import HsBindgen.Runtime.PtrConst
|
||||
|
||||
data T = T
|
||||
{ a :: Bool
|
||||
, b :: Word8
|
||||
}
|
||||
convertT :: T -> Raw.T
|
||||
convertT T{a, b} = Raw.T{a = CBool $ fromBool a, b}
|
||||
|
||||
data Shape
|
||||
= Circle CDouble
|
||||
| Rectangle CDouble CDouble
|
||||
convertShape :: Shape -> Raw.Shape
|
||||
convertShape = \case
|
||||
Circle r -> Raw.Shape (Raw.Shape_Tag 0) $ Raw.set_shape_body_circle $ Raw.Circle_Body r
|
||||
Rectangle w h -> Raw.Shape (Raw.Shape_Tag 1) $ Raw.set_shape_body_rectangle $ Raw.Rectangle_Body w h
|
||||
|
||||
hello :: ByteString -> IO ()
|
||||
hello s = useAsCString s $ Raw.hello . unsafeFromPtr
|
||||
|
||||
helloStruct :: T -> IO ()
|
||||
helloStruct = Raw.hello_struct . convertT
|
||||
|
||||
helloShape :: Shape -> IO ()
|
||||
helloShape = Raw.hello_shape . convertShape
|
||||
11
exe/Main.hs
11
exe/Main.hs
@ -1,11 +0,0 @@
|
||||
module Main (main) where
|
||||
|
||||
import GarnetRs.Wrapped
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
hello "Haskell"
|
||||
helloStruct T{a = True, b = 42}
|
||||
helloStruct T{a = False, b = maxBound}
|
||||
helloShape $ Circle 3.14
|
||||
helloShape $ Rectangle 10.0 5.0
|
||||
132
flake.lock
generated
132
flake.lock
generated
@ -85,11 +85,11 @@
|
||||
},
|
||||
"crane": {
|
||||
"locked": {
|
||||
"lastModified": 1771438068,
|
||||
"narHash": "sha256-nGBbXvEZVe/egCPVPFcu89RFtd8Rf6J+4RFoVCFec0A=",
|
||||
"lastModified": 1771121070,
|
||||
"narHash": "sha256-aIlv7FRXF9q70DNJPI237dEDAznSKaXmL5lfK/Id/bI=",
|
||||
"owner": "ipetkov",
|
||||
"repo": "crane",
|
||||
"rev": "b5090e53e9d68c523a4bb9ad42b4737ee6747597",
|
||||
"rev": "a2812c19f1ed2e5ed5ce2ef7109798b575c180e1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -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"
|
||||
@ -154,11 +136,11 @@
|
||||
"hackage": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1771461386,
|
||||
"narHash": "sha256-93hCxhNOq9/HAggfTTurLhllI0IiEWZ35jk6i/X/qEo=",
|
||||
"lastModified": 1771289625,
|
||||
"narHash": "sha256-ySABvJf2NaxGc1mPSkwKjC8So9S906UgOYZVzX35Ng8=",
|
||||
"owner": "input-output-hk",
|
||||
"repo": "hackage.nix",
|
||||
"rev": "b4f4537825a4db29c10541a50d7eb6c848bf0dca",
|
||||
"rev": "808af568b7e14e1eced115e65825d2f50a608008",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -170,11 +152,11 @@
|
||||
"hackage-for-stackage": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1771461376,
|
||||
"narHash": "sha256-aEuZkBpTaU0XBFiaIomicJDoWQaw84rYfKXI/r17V/w=",
|
||||
"lastModified": 1771288450,
|
||||
"narHash": "sha256-2tCS6CXMHPo4Jsh4JopbYBoQXnTTp8MdZVAqPVmOIq4=",
|
||||
"owner": "input-output-hk",
|
||||
"repo": "hackage.nix",
|
||||
"rev": "ca611068e77f15b96ecf71fae827e491c0b2dc3b",
|
||||
"rev": "3049efd880816a3bb98b7b5fb4062045fcddd474",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -200,7 +182,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"haskell-nix": {
|
||||
"haskellNix": {
|
||||
"inputs": {
|
||||
"HTTP": "HTTP",
|
||||
"cabal-32": "cabal-32",
|
||||
@ -228,7 +210,7 @@
|
||||
"hpc-coveralls": "hpc-coveralls",
|
||||
"iserv-proxy": "iserv-proxy",
|
||||
"nixpkgs": [
|
||||
"haskell-nix",
|
||||
"haskellNix",
|
||||
"nixpkgs-unstable"
|
||||
],
|
||||
"nixpkgs-2305": "nixpkgs-2305",
|
||||
@ -242,11 +224,11 @@
|
||||
"stackage": "stackage"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1771462666,
|
||||
"narHash": "sha256-z+pJFzbYa1ulNDUZdb0qLVVAdE0dqpnE51jqh2chA7c=",
|
||||
"lastModified": 1771289806,
|
||||
"narHash": "sha256-s60Kb3cYr0t6LDQ/LmJr5vQN8Z4IY1Vfwq2keZW0VOM=",
|
||||
"owner": "input-output-hk",
|
||||
"repo": "haskell.nix",
|
||||
"rev": "857ba7b65d9c1a8765ad1599834a8fe71cb09981",
|
||||
"rev": "3331ba591ae02a41c638aeb6bea91d268b34cf8e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -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,
|
||||
@ -744,11 +657,10 @@
|
||||
"inputs": {
|
||||
"crane": "crane",
|
||||
"flake-utils": "flake-utils",
|
||||
"haskell-nix": "haskell-nix",
|
||||
"haskellNix": "haskellNix",
|
||||
"hls-2-13": "hls-2-13",
|
||||
"hs-bindgen": "hs-bindgen",
|
||||
"nixpkgs": [
|
||||
"haskell-nix",
|
||||
"haskellNix",
|
||||
"nixpkgs-2511"
|
||||
],
|
||||
"rust-overlay": "rust-overlay"
|
||||
@ -761,11 +673,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1771470520,
|
||||
"narHash": "sha256-PvytHcaYN5cPUll7FB70mXv1rRsIBRmu47fFfq3haxA=",
|
||||
"lastModified": 1771297684,
|
||||
"narHash": "sha256-wieWskQxZLPlNXX06JEB0bMoS/ZYQ89xBzF0RL9lyLs=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "a1d4cc1f264c45d3745af0d2ca5e59d460e58777",
|
||||
"rev": "755d3669699a7c62aef35af187d75dc2728cfd85",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -777,11 +689,11 @@
|
||||
"stackage": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1771460325,
|
||||
"narHash": "sha256-RRsGO7QVyuBtUTVqDiB7CYvFruj0Z/yxZK1JarkTqI4=",
|
||||
"lastModified": 1771287554,
|
||||
"narHash": "sha256-76Kd5c2D4O8yL48eAejlGZlpQ/Exxnsz3V7qW+RkFzE=",
|
||||
"owner": "input-output-hk",
|
||||
"repo": "stackage.nix",
|
||||
"rev": "29c0dcc517e04be238023064412312ad4443ddb2",
|
||||
"rev": "e62b9d6269c6abfd8b976826da0dcc37f0a57010",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
35
flake.nix
35
flake.nix
@ -1,22 +1,28 @@
|
||||
{
|
||||
inputs = {
|
||||
haskell-nix.url = "github:input-output-hk/haskell.nix";
|
||||
haskellNix.url = "github:input-output-hk/haskell.nix";
|
||||
hls-2-13 = { url = "github:haskell/haskell-language-server/2.13.0.0"; flake = false; };
|
||||
nixpkgs.follows = "haskell-nix/nixpkgs-2511";
|
||||
nixpkgs.follows = "haskellNix/nixpkgs-2511";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
crane.url = "github:ipetkov/crane";
|
||||
rust-overlay = {
|
||||
url = "github:oxalica/rust-overlay";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
hs-bindgen.url = "github:well-typed/hs-bindgen/release-0.1-alpha";
|
||||
};
|
||||
outputs =
|
||||
inputs@{ nixpkgs, ... }:
|
||||
inputs.flake-utils.lib.eachSystem [ "x86_64-linux" ] (system:
|
||||
{ self
|
||||
, nixpkgs
|
||||
, flake-utils
|
||||
, haskellNix
|
||||
, hls-2-13
|
||||
, crane
|
||||
, rust-overlay
|
||||
}:
|
||||
flake-utils.lib.eachSystem [ "x86_64-linux" ] (system:
|
||||
let
|
||||
overlays = [
|
||||
inputs.haskell-nix.overlay
|
||||
haskellNix.overlay
|
||||
(final: _prev: {
|
||||
hixProject =
|
||||
final.haskell-nix.hix.project {
|
||||
@ -27,18 +33,20 @@
|
||||
shell.tools.cabal = "latest";
|
||||
shell.withHoogle = false;
|
||||
shell.tools.haskell-language-server = {
|
||||
src = inputs.hls-2-13;
|
||||
src = hls-2-13;
|
||||
sha256map = {
|
||||
"https://github.com/snowleopard/alga"."d4e43fb42db05413459fb2df493361d5a666588a" = "0s1mlnl64wj7pkg3iipv5bb4syy3bhxwqzqv93zqlvkyfn64015i";
|
||||
};
|
||||
};
|
||||
};
|
||||
})
|
||||
(import inputs.rust-overlay)
|
||||
(import rust-overlay)
|
||||
];
|
||||
pkgs = import nixpkgs { inherit system overlays; inherit (inputs.haskell-nix) config; };
|
||||
pkgs = import nixpkgs { inherit system overlays; inherit (haskellNix) config; };
|
||||
haskell = pkgs.hixProject.flake { };
|
||||
rust = (inputs.crane.mkLib pkgs).overrideToolchain (p: p.rust-bin.selectLatestNightlyWith (
|
||||
# TODO we're not getting Rust libs from Nix
|
||||
# i.e. running `cargo clean && cargo build` rebuilds dependencies
|
||||
rust = (crane.mkLib pkgs).overrideToolchain (p: p.rust-bin.selectLatestNightlyWith (
|
||||
toolchain: toolchain.default.override {
|
||||
extensions = [ "rust-src" ];
|
||||
targets = [ "x86_64-unknown-linux-gnu" ];
|
||||
@ -52,12 +60,13 @@
|
||||
(rust.devShell { })
|
||||
];
|
||||
packages = with pkgs; [
|
||||
llvmPackages.libclang
|
||||
llvmPackages.llvm
|
||||
bacon
|
||||
ghcid
|
||||
inputs.hs-bindgen.packages.${system}.hs-bindgen-cli
|
||||
rust-analyzer
|
||||
rust-cbindgen
|
||||
];
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@ -3,15 +3,23 @@ set -euo pipefail
|
||||
|
||||
# TODO this is a complete vibe-coded hack, but the header patching at least is crucial
|
||||
|
||||
# TODO fully-vibed hack
|
||||
# we should do a few things quite differently anyway
|
||||
|
||||
# generated Haskell code shouldn't be checked in as it's not portable
|
||||
# does the TH way of using `hs-bindgen` help here?
|
||||
# I guess we shouldn't check in the generated C header either
|
||||
|
||||
# Generate Haskell FFI bindings from Rust source code.
|
||||
#
|
||||
# Pipeline: cargo build -> cbindgen -> patch header -> hs-bindgen
|
||||
#
|
||||
# Prerequisites: run inside the Nix dev shell (provides gcc, cabal, cbindgen, hs-bindgen-cli).
|
||||
# Prerequisites: run inside the Nix dev shell (provides gcc, cabal, etc.)
|
||||
# cbindgen is fetched via `nix run nixpkgs#rust-cbindgen`.
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
RUST_DIR="$SCRIPT_DIR/rust"
|
||||
HASKELL_DIR="$SCRIPT_DIR"
|
||||
HASKELL_DIR="$SCRIPT_DIR/haskell"
|
||||
HEADER_NAME="garnet_rs.h"
|
||||
HEADER="$RUST_DIR/$HEADER_NAME"
|
||||
|
||||
@ -21,7 +29,7 @@ cargo build --manifest-path "$RUST_DIR/Cargo.toml"
|
||||
|
||||
# --- Step 2: Generate C header with cbindgen ---
|
||||
echo "=== Running cbindgen ==="
|
||||
cbindgen \
|
||||
nix run nixpkgs#rust-cbindgen -- \
|
||||
--lang c \
|
||||
--crate garnet-rs \
|
||||
--output "$HEADER" \
|
||||
@ -89,7 +97,8 @@ pending_enum && /^typedef [A-Za-z0-9_]+ / {
|
||||
}
|
||||
|
||||
{ print }
|
||||
' "$HEADER" > "${HEADER}.tmp" && mv "${HEADER}.tmp" "$HEADER"
|
||||
' "$HEADER" > "${HEADER}.tmp"
|
||||
mv "${HEADER}.tmp" "$HEADER"
|
||||
|
||||
echo " Patched header at $HEADER"
|
||||
|
||||
@ -115,7 +124,7 @@ fi
|
||||
|
||||
# --- Step 5: Run hs-bindgen ---
|
||||
echo "=== Running hs-bindgen ==="
|
||||
hs-bindgen-cli preprocess \
|
||||
cabal run -- hs-bindgen-cli preprocess \
|
||||
--overwrite-files --create-output-dirs \
|
||||
--unique-id com.garnet --enable-record-dot \
|
||||
--hs-output-dir "$HASKELL_DIR/generated" --module GarnetRs \
|
||||
@ -124,4 +133,4 @@ hs-bindgen-cli preprocess \
|
||||
|
||||
echo "=== Done ==="
|
||||
echo "Generated Haskell bindings in $HASKELL_DIR/generated/"
|
||||
echo "Run 'cabal run' to test."
|
||||
echo "Run 'cabal run garnet' to test."
|
||||
|
||||
30
haskell/LICENSE
Normal file
30
haskell/LICENSE
Normal file
@ -0,0 +1,30 @@
|
||||
Copyright (c) 2025, George Thomas
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
|
||||
* Neither the name of George Thomas nor the names of other
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
32
haskell/exe/Main.hs
Normal file
32
haskell/exe/Main.hs
Normal file
@ -0,0 +1,32 @@
|
||||
module Main (main) where
|
||||
|
||||
import Data.ByteString
|
||||
import Data.Word
|
||||
import Foreign.C
|
||||
import GarnetRs
|
||||
import GarnetRs.Safe
|
||||
import HsBindgen.Runtime.PtrConst
|
||||
import Unsafe.Coerce
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
useAsCString "Haskell" $ hello . unsafeFromPtr
|
||||
hello_struct $ convertT T'{a = True, b = 42}
|
||||
hello_struct $ convertT T'{a = False, b = 42}
|
||||
hello_shape $ convertShape $ Circle 3.14
|
||||
hello_shape $ convertShape $ Rectangle 10.0 5.0
|
||||
|
||||
data T' = T'
|
||||
{ a :: Bool
|
||||
, b :: Word8
|
||||
}
|
||||
convertT T'{a, b} =
|
||||
-- T{a = CBool $ unsafeCoerce @Bool @Word8 a, b}
|
||||
T{a = CBool $ fromIntegral $ fromEnum a, b}
|
||||
|
||||
data Shape'
|
||||
= Circle CDouble
|
||||
| Rectangle CDouble CDouble
|
||||
convertShape = \case
|
||||
Circle r -> Shape (Shape_Tag 0) $ set_shape_body_circle $ Circle_Body r
|
||||
Rectangle w h -> Shape (Shape_Tag 1) $ set_shape_body_rectangle $ Rectangle_Body w h
|
||||
@ -1,11 +1,9 @@
|
||||
cabal-version: 3.0
|
||||
name: garnet
|
||||
version: 0.1.0.0
|
||||
license: BSD-3-Clause
|
||||
license-file: LICENSE
|
||||
author: Patrick Aldis
|
||||
maintainer:
|
||||
george.thomas@obsidian.systems
|
||||
patrick.aldis@obsidian.systems
|
||||
maintainer: patricktaldis@gmail.com
|
||||
|
||||
library garnet-generated
|
||||
hs-source-dirs: generated
|
||||
@ -23,8 +21,6 @@ library garnet-generated
|
||||
|
||||
executable garnet
|
||||
main-is: Main.hs
|
||||
other-modules:
|
||||
GarnetRs.Wrapped
|
||||
hs-source-dirs: exe
|
||||
default-language: GHC2024
|
||||
default-extensions:
|
||||
@ -1,5 +1,3 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::ffi::{CStr, c_char};
|
||||
|
||||
fn say_hello(name: &str) {
|
||||
@ -23,6 +21,7 @@ extern "C" fn hello_struct(t: T) -> () {
|
||||
}
|
||||
|
||||
#[repr(C, u8)]
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug)]
|
||||
enum Shape {
|
||||
Circle { radius: f64 },
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user