# Godwit
A compiler for a functional pattern language (based on simply-typed lambda calculus with Tidal-inspired maxi-notation syntax) to C via cartesian closed categories.
# 1 Bird
https://www.rspb.org.uk/birds-and-wildlife/black-tailed-godwit
# 2 Code
git clone https://code.mathr.co.uk/godwit.git
Very early days so far, don’t expect much.
# 3 Bootstrap
This is a script I use to install/update Godwit using MicroHs (a Haskell compiler that is much smaller than GHC, and more up to date than Hugs). It fetches the latest MicroHs, dependencies of Godwit, and Godwit itself, and rebuilds it all if the fetched version is newer than the currently installed MicroHs.
The script has some bugs re git stash
(might pop an old one..),
and will have to be updated if/when the loadDeps
PR is merged.
Download: bootstrap.sh.
#!/bin/sh
set -ev
FORCE="${1}"
OLD="$(mhs --numeric-version || echo none)"
( git clone https://github.com/augustss/MicroHs.git && cd MicroHs && patch -p1 <<'EOF' ||
diff --git a/src/MicroHs/Compile.hs b/src/MicroHs/Compile.hs
index 936d1431..1708d59f 100644
--- a/src/MicroHs/Compile.hs
+++ b/src/MicroHs/Compile.hs
@@ -432,16 +432,16 @@ loadDependencies flags = do
loadedPkgs <- gets getPkgs
let deps = concatMap pkgDepends loadedPkgs
loaded = map pkgName loadedPkgs
- deps' = [ p | (p, _v) <- deps, p `notElem` loaded ]
+ deps' = [ pv | pv@(p, _v) <- deps, p `notElem` loaded ]
if null deps' then
return ()
else do
mapM_ (loadDeps flags) deps'
loadDependencies flags -- loadDeps can add new dependencies
-loadDeps :: Flags -> IdentPackage -> CM ()
-loadDeps flags pid = do
- mres <- liftIO $ openFilePath (pkgPath flags) (packageDir </> unIdent pid <.> packageSuffix)
+loadDeps :: Flags -> (IdentPackage, Version) -> CM ()
+loadDeps flags (pid, pver) = do
+ mres <- liftIO $ openFilePath (pkgPath flags) (packageDir </> unIdent pid ++ "-" ++ showVersion pver <.> packageSuffix)
case mres of
Nothing -> error $ "Cannot find package " ++ showIdent pid
Just (pfn, hdl) -> do
diff --git a/src/runtime/config.h b/src/runtime/config.h
index c7386fb9..6d099000 100644
--- a/src/runtime/config.h
+++ b/src/runtime/config.h
@@ -5,7 +5,7 @@
* In here are items that can be configured, but that does not depend on the platform.
*/
-#define HEAP_CELLS 50000000
+#define HEAP_CELLS 30000000
#define STACK_SIZE 100000
#endif // CONFIG_H
diff --git a/src/runtime/eval.c b/src/runtime/eval.c
index b0344877..1bde33ba 100644
--- a/src/runtime/eval.c
+++ b/src/runtime/eval.c
@@ -242,7 +242,7 @@ iswindows(void)
#define HIGH_INT 256
#if !defined(HEAP_CELLS)
-#define HEAP_CELLS 50000000
+#define HEAP_CELLS 30000000
#endif
#if !defined(STACK_SIZE)
EOF
(cd MicroHs && git stash && git pull && (git stash pop || true)) )
( git clone https://github.com/augustss/mtl.git || (cd mtl && git stash && git pull && (git stash pop || true)) )
( git clone https://github.com/haskell/containers.git || (cd containers && git stash && git pull && (git stash pop || true)) )
( git clone https://code.mathr.co.uk/godwit.git || (cd godwit && git stash && git pull && (git stash pop || true)) )
NEW="$(grep '^version:' MicroHs/MicroHs.cabal | sed -e 's/^version: *//')"
if [ "x$OLD" != "x$NEW" -o "x$FORCE" = "x--force" ]
then
rm -rf "${HOME}/.mcabal/mhs-$OLD"
( cd MicroHs && make clean && make install )
PATH="${HOME}/.mcabal/bin:${PATH}"
( mcabal install transformers )
( cd mtl && mcabal install )
( cd containers/containers && mcabal install )
( cd godwit && make HC=mhs clean && make HC=mhs -j "$(nproc)" )
fi
# 4 Usage
Example pattern (needs to be all on one line):
cps (pure $ 0.18 `fmul` 1.8 `fmul` 1.8) `u`
_early (qi 18) (sound [bd*18,[~ sn]*9,[~ ht/3 mt]*6]) `u`
shape [0.8] `u`
gain [0.18] `u`
let seq = [18] `isubR` run 18
in (seq `imulL` _slow (qi 18) (seq `imulL` _slow (qi 18) seq)) `bind`
\x -> stack (map
(\y -> let z = imod x y in ifte (igt z 0) (pure z) silence)
(empty : 2 : 3 : 6 : 9 : 18)) `bind`
\x -> n (pure (ffromi x)) `u`
speed (flip fdiv 18.0 . ffromi . iadd (imul 18 2)
. flip imod 18 . iadd (imul 13 x) . imul 5 $$ _slow (qi 18) seq)
Based on my Strudel looptober 2024 #18.