wip
authorJulien Moutinho <julm+symantic-parser@sourcephile.fr>
Tue, 6 Oct 2020 22:49:48 +0000 (00:49 +0200)
committerJulien Moutinho <julm+symantic-parser@sourcephile.fr>
Tue, 6 Oct 2020 22:49:48 +0000 (00:49 +0200)
12 files changed:
default.nix [new file with mode: 0644]
flake.lock [new file with mode: 0644]
flake.nix [new file with mode: 0644]
shell.nix [new file with mode: 0644]
src/Symantic/Parser.hs
src/Symantic/Parser/Automaton.hs [new file with mode: 0644]
src/Symantic/Parser/Automaton/Instructions.hs [new file with mode: 0644]
src/Symantic/Parser/Grammar/Combinators.hs
src/Symantic/Parser/Grammar/Observations.hs [new file with mode: 0644]
src/Symantic/Parser/Grammar/Optimizations.hs
src/Symantic/Parser/Staging.hs
symantic-parser.cabal

diff --git a/default.nix b/default.nix
new file mode 100644 (file)
index 0000000..374c257
--- /dev/null
@@ -0,0 +1,29 @@
+{ pkgs ? import <nixpkgs> {}
+, ghc ? null
+}:
+let
+  haskellPackages =
+    if ghc == null
+    then pkgs.haskellPackages
+    else pkgs.haskell.packages.${ghc};
+  hs = haskellPackages.extend (with pkgs.haskell.lib;
+    packageSourceOverrides {
+      symantic-parser = ./.;
+    }
+  );
+in hs.symantic-parser // {
+  shell = hs.shellFor {
+    packages = p: [ p.symantic-parser ];
+    nativeBuildInputs = [
+      hs.cabal-install
+      hs.hie
+    ];
+    buildInputs = [
+      #hs.ghcid
+      hs.ormolu
+      hs.hlint
+      #pkgs.nixpkgs-fmt
+    ];
+    #withHoogle = true;
+  };
+}
diff --git a/flake.lock b/flake.lock
new file mode 100644 (file)
index 0000000..5c4606c
--- /dev/null
@@ -0,0 +1,72 @@
+{
+  "nodes": {
+    "all-hies": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1597070901,
+        "narHash": "sha256-IgZ/SSxfDXYEcl/vKOEQRaMiARVy9mWzbQGuzi+lgS8=",
+        "owner": "infinisil",
+        "repo": "all-hies",
+        "rev": "534ac517b386821b787d1edbd855b9966d0c0775",
+        "type": "github"
+      },
+      "original": {
+        "owner": "infinisil",
+        "repo": "all-hies",
+        "type": "github"
+      }
+    },
+    "flake-utils": {
+      "locked": {
+        "lastModified": 1601282935,
+        "narHash": "sha256-WQAFV6sGGQxrRs3a+/Yj9xUYvhTpukQJIcMbIi7LCJ4=",
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "rev": "588973065fce51f4763287f0fda87a174d78bf48",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "type": "github"
+      }
+    },
+    "nixpkgs": {
+      "locked": {
+        "narHash": "sha256-QD8y4XCl1aZ6SWWtIUyuF7OsRwSfcw/2zoXS0LFPb6s=",
+        "path": "/nix/store/hlxc12hk8gl24fml3n7q9xlrr78cqf1r-nixpkgs-patched",
+        "type": "path"
+      },
+      "original": {
+        "id": "nixpkgs",
+        "type": "indirect"
+      }
+    },
+    "nixpkgs-2003": {
+      "locked": {
+        "lastModified": 1601475821,
+        "narHash": "sha256-7AI8j/xq5slauMGwC3Dp2K9TKDyDtBXBebeyWsE9euE=",
+        "owner": "nixos",
+        "repo": "nixpkgs",
+        "rev": "b4db68ff563895eea6aab4ff24fa04ef403dfe14",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nixos",
+        "ref": "nixos-20.03",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "root": {
+      "inputs": {
+        "all-hies": "all-hies",
+        "flake-utils": "flake-utils",
+        "nixpkgs": "nixpkgs",
+        "nixpkgs-2003": "nixpkgs-2003"
+      }
+    }
+  },
+  "root": "root",
+  "version": 7
+}
diff --git a/flake.nix b/flake.nix
new file mode 100644 (file)
index 0000000..f92d9f7
--- /dev/null
+++ b/flake.nix
@@ -0,0 +1,114 @@
+{
+# Update inputs with:
+# nix flake update --recreate-lock-file
+inputs.nixpkgs.url = "flake:nixpkgs";
+# This is needed until all-hies supports glibc-2.31
+inputs.nixpkgs-2003.url = "github:nixos/nixpkgs/nixos-20.03";
+inputs.flake-utils.url = "github:numtide/flake-utils";
+#inputs.haskell-nix.url = "github:input-output-hk/haskell.nix";
+inputs.all-hies.url = "github:infinisil/all-hies";
+inputs.all-hies.flake = false;
+outputs = inputs: let
+  in inputs.flake-utils.lib.eachDefaultSystem (system: let
+    pkgs = inputs.nixpkgs.legacyPackages.${system};
+    /*
+    projectName = "symantic-parser";
+    pkgs = import inputs.haskell-nix.sources.nixpkgs (inputs.haskell-nix.nixpkgsArgs // {
+      localSystem = { inherit system; };
+      overlays = inputs.haskell-nix.nixpkgsArgs.overlays ++ [
+        (import inputs.all-hies {}).overlay
+      ];
+    });
+    compiler-nix-name = "ghc865";
+    project = pkgs.haskell-nix.cabalProject {
+      src = pkgs.haskell-nix.haskellLib.cleanGit {
+        name = projectName;
+        src = ./.;
+      };
+      inherit compiler-nix-name;
+      #index-state = "2020-08-31T00:00:00Z";
+      # To be kept up to date with source-repository-package entries in cabal.project
+      sha256map = {
+      };
+      # Update by commenting materialized and running:
+      # nix run .#materialize
+      #materialized = ./plan-nix;
+    };
+    */
+    in {
+      defaultPackage = import ./default.nix { inherit pkgs; };
+      devShell = (import ./default.nix {
+        ghc = "ghc883";
+        pkgs = import inputs.nixpkgs-2003 {
+          inherit system;
+          overlays = [
+            (import inputs.all-hies {}).overlay
+            /*
+            (self: super: {
+              inherit (inputs.nixpkgs-2003.legacyPackages.${system}) glibc texinfo gmp;
+              glibc = super.glibc.overrideAttrs (_: rec {
+                name = "glibc-${version}";
+                version = "2.30";
+                src = pkgs.fetchurl {
+                  url = "mirror://gnu/glibc/glibc-${version}.tar.xz";
+                  inherit sha256;
+                };
+              });
+            })
+            */
+          ];
+        };
+      }).shell;
+    /*
+    # Build with: nix build
+    defaultPackage = project.${projectName}.components.exes."playground";
+    #packages.${projectName} = project;
+    # Run with: nix run .#benchmarks
+    apps."benchmarks" = {
+      type = "app";
+      program = "${project.${projectName}.components.exes."benchmarks"}/bin/benchmarks";
+    };
+    # Run with: nix run .#playground
+    apps."playground" = {
+      type = "app";
+      program = "${inputs.self.defaultPackage.${system}}/bin/playground";
+    };
+    # Run with: nix run .#materialize
+    apps.materialize = {
+      type = "app";
+      program = (pkgs.writeShellScript "materialize" ''
+        ${pkgs.rsync}/bin/rsync --delete -ai ${project.plan-nix}/ plan-nix/
+      '').outPath;
+    };
+    # Run with: nix run .#register
+    apps.register = {
+      type = "app";
+      program = (pkgs.writeShellScript "register" ''
+        set -x
+        nix-store --add-root nix.root --indirect --realise ${project.roots}
+      '').outPath;
+    };
+    # Get a development environment with: nix shell
+    devShell = project.shellFor {
+      packages = hpkgs: [
+        hpkgs."${projectName}"
+      ];
+      #components = hpkgs: [];
+      #additional = hpkgs: [];
+      withHoogle = false;
+      tools = {
+        cabal = "3.2.0.0";
+        #hie = "unstable";
+        #hlint = "2.2.11";
+      };
+      builtInputs = with project.haskellPackages; [
+      ];
+      exactDeps = true;
+      shellHook = ''
+        nix-store --add-root nix.root --indirect --realise ${project.roots}
+      '';
+    };
+    */
+    }
+  );
+}
diff --git a/shell.nix b/shell.nix
new file mode 100644 (file)
index 0000000..0d9af5e
--- /dev/null
+++ b/shell.nix
@@ -0,0 +1 @@
+(import ./. {}).shell
index 9f536560aa922a1d5790f23cfaf17819c7d1f101..288c6f8a02135e24d4eda20b574a7cffbda9fcb8 100644 (file)
@@ -5,19 +5,20 @@ module Symantic.Parser
  , module Symantic.Parser
  ) where
 import Symantic.Parser.Grammar
-import qualified Symantic.Parser.Staging as S
+import qualified Symantic.Parser.Staging as Hask
 
 --import Prelude hiding (fmap, pure, (<*), (*>), (<*>), (<$>), (<$), pred, repeat)
 import Data.Int (Int)
-import Data.Char (Char)
+-- import Data.Char (Char)
+import Prelude (undefined)
 import Data.String (String)
 import Text.Show (Show)
 import Data.Eq (Eq)
-import Control.Monad (liftM)
-import Data.Char (isAlpha, isAlphaNum, isSpace, isUpper, isDigit, digitToInt, chr, ord)
-import Data.Set (fromList, member)
-import Data.Maybe (catMaybes)
-import Text.Read (readMaybe)
+-- import Control.Monad (liftM)
+-- import Data.Char (isAlpha, isAlphaNum, isSpace, isUpper, isDigit, digitToInt, chr, ord)
+-- import Data.Set (fromList, member)
+-- import Data.Maybe (catMaybes)
+-- import Text.Read (readMaybe)
 import Language.Haskell.TH (TExpQ)
 
 import qualified Prelude
@@ -48,7 +49,7 @@ cinput = m --try (string "aaa") <|> string "db" --(string "aab" <|> string "aac"
     m = bf <* item
     -- match :: Eq a => [Pure repr a] -> repr a -> (Pure repr a -> repr b) -> repr b -> repr b
     bf = match [char '>'] item op empty
-    op (S.Runtime '>' _) = string ">"
+    op (Hask.Runtime '>' _) = string ">"
 -}
 
 --defuncTest = runtime Just <$> (runtime (+) <$> (item $> runtime 1) <*> (item $> runtime 8))
@@ -65,11 +66,11 @@ boom =
        let goo = (-- newRegister_ unit (\r1 ->
              let hoo = {-get r0 <~> get r1 *>-} goo *> hoo in hoo
             ) *> goo
-       in goo) *> pure S.unit
+       in goo) *> pure Hask.unit
   in foo *> foo
 
-runtime :: a -> TExpQ a -> S.Runtime a
-runtime e c = S.Runtime (S.Eval e) (S.Code c)
+runtime :: a -> TExpQ a -> Hask.Runtime a
+runtime e c = Hask.Runtime (Hask.Eval e) (Hask.Code c)
 
 brainfuck ::
  forall repr.
@@ -90,7 +91,7 @@ brainfuck = whitespace *> bf
     bf :: repr [BrainFuckOp]
     bf = many (lexeme (match ((\c -> runtime c [||c||]) Prelude.<$> "><+-.,[") (look item) op empty))
     -- op :: Pure repr Char -> repr BrainFuckOp
-    op (S.Runtime (S.Eval c) _) = case c of
+    op (Hask.Runtime (Hask.Eval c) _) = case c of
      '>' -> item $> runtime RightPointer [||RightPointer||]
      '<' -> item $> runtime LeftPointer  [||LeftPointer||]
      '+' -> item $> runtime Increment    [||Increment||]
@@ -98,4 +99,5 @@ brainfuck = whitespace *> bf
      '.' -> item $> runtime Output       [||Output||]
      ',' -> item $> runtime Input        [||Input||]
      '[' -> between (lexeme item) (char ']') (runtime Loop [||Loop||] <$> bf)
+     _ -> undefined
 
diff --git a/src/Symantic/Parser/Automaton.hs b/src/Symantic/Parser/Automaton.hs
new file mode 100644 (file)
index 0000000..163ee65
--- /dev/null
@@ -0,0 +1,4 @@
+module Symantic.Parser.Automaton
+ ( module Symantic.Parser.Automaton.Instructions
+ ) where
+import Symantic.Parser.Automaton.Instructions
diff --git a/src/Symantic/Parser/Automaton/Instructions.hs b/src/Symantic/Parser/Automaton/Instructions.hs
new file mode 100644 (file)
index 0000000..c6209e5
--- /dev/null
@@ -0,0 +1,2 @@
+module Symantic.Parser.Automaton.Instructions where
+
index 2e1a7d32516eeeea4559704d013e9c3989f71982..9673de407e30935be7f0646825c82fb4e82b65e7 100644 (file)
@@ -8,36 +8,36 @@ import Data.Char (Char)
 import Data.Either (Either(..))
 import Data.Eq (Eq(..))
 import Data.Int (Int)
-import Data.Kind (Type)
+-- import Data.Kind (Type)
 import Data.Maybe (Maybe(..))
 import Data.String (String)
 import Language.Haskell.TH (TExpQ)
-import qualified Data.Functor as F
+-- import qualified Data.Functor as F
 import qualified Prelude as Pre
 import qualified Data.List as List
 
 import Symantic.Base.Univariant
-import qualified Symantic.Parser.Staging as S
+import qualified Symantic.Parser.Staging as Hask
 
 -- * Class 'Applicable'
 class Applicable repr where
-  (<$>) :: S.Runtime (a -> b) -> repr a -> repr b
+  (<$>) :: Hask.Runtime (a -> b) -> repr a -> repr b
   (<$>) f = (pure f <*>)
 
-  (<&>) :: repr a -> S.Runtime (a -> b) -> repr b
+  (<&>) :: repr a -> Hask.Runtime (a -> b) -> repr b
   (<&>) = flip (<$>)
 
-  (<$) :: S.Runtime a -> repr b -> repr a
+  (<$) :: Hask.Runtime a -> repr b -> repr a
   (<$) x = (pure x <*)
 
-  ($>) :: repr a -> S.Runtime b -> repr b
+  ($>) :: repr a -> Hask.Runtime b -> repr b
   ($>) = flip (<$)
 
   --type Pure repr :: Type -> Type
-  pure :: S.Runtime a -> repr a
+  pure :: Hask.Runtime a -> repr a
   default pure ::
     Liftable repr => Applicable (Unlift repr) =>
-    S.Runtime a -> repr a
+    Hask.Runtime a -> repr a
   pure = lift . pure
 
   (<*>) :: repr (a -> b) -> repr a -> repr b
@@ -46,14 +46,14 @@ class Applicable repr where
     repr (a -> b) -> repr a -> repr b
   (<*>) = lift2 (<*>)
 
-  liftA2 :: S.Runtime (a -> b -> c) -> repr a -> repr b -> repr c
+  liftA2 :: Hask.Runtime (a -> b -> c) -> repr a -> repr b -> repr c
   liftA2 f x = (<*>) (f <$> x)
 
   (*>) :: repr a -> repr b -> repr b
-  x *> y = (S.id <$ x) <*> y
+  x *> y = (Hask.id <$ x) <*> y
 
   (<*) :: repr a -> repr b -> repr a
-  (<*) = liftA2 S.const
+  (<*) = liftA2 Hask.const
 
   {-
   (<**>) :: repr a -> repr (a -> b) -> repr b
@@ -63,7 +63,7 @@ infixl 4 <$>, <&>, <$, $>, <*>, <*, *>
 
 infixl 4 <**>
 (<**>) :: Applicable repr => repr a -> repr (a -> b) -> repr b
-(<**>) = liftA2 (S.flip S..@ (S.$))
+(<**>) = liftA2 (Hask.flip Hask..@ (Hask.$))
 
 -- * Class 'Alternable'
 class Alternable repr where
@@ -86,27 +86,27 @@ infixl 3 <|>
 
 infixl 3 <+>
 (<+>) :: Applicable repr => Alternable repr => repr a -> repr b -> repr (Either a b)
-p <+> q = S.Runtime (S.Eval Left) (S.Code [||Left||]) <$> p <|>
-          S.Runtime (S.Eval Right) (S.Code [||Right||]) <$> q
+p <+> q = Hask.Runtime (Hask.Eval Left) (Hask.Code [||Left||]) <$> p <|>
+          Hask.Runtime (Hask.Eval Right) (Hask.Code [||Right||]) <$> q
 
-optionally :: Applicable repr => Alternable repr => repr a -> S.Runtime b -> repr b
+optionally :: Applicable repr => Alternable repr => repr a -> Hask.Runtime b -> repr b
 optionally p x = p $> x <|> pure x
 
 optional :: Applicable repr => Alternable repr => repr a -> repr ()
-optional = flip optionally S.unit
+optional = flip optionally Hask.unit
 
-option :: Applicable repr => Alternable repr => S.Runtime a -> repr a -> repr a
+option :: Applicable repr => Alternable repr => Hask.Runtime a -> repr a -> repr a
 option x p = p <|> pure x
 
 choice :: Alternable repr => [repr a] -> repr a
 choice = List.foldr (<|>) empty
 
 maybeP :: Applicable repr => Alternable repr => repr a -> repr (Maybe a)
-maybeP p = option (S.Runtime (S.Eval Nothing) (S.Code [||Nothing||]))
-                  (S.Runtime (S.Eval Just) (S.Code [||Just||]) <$> p)
+maybeP p = option (Hask.Runtime (Hask.Eval Nothing) (Hask.Code [||Nothing||]))
+                  (Hask.Runtime (Hask.Eval Just) (Hask.Code [||Just||]) <$> p)
 
 manyTill :: Applicable repr => Alternable repr => repr a -> repr b -> repr [a]
-manyTill p end = let go = end $> S.nil <|> p <:> go in go
+manyTill p end = let go = end $> Hask.nil <|> p <:> go in go
 
 -- * Class 'Selectable'
 class Selectable repr where
@@ -114,18 +114,18 @@ class Selectable repr where
   default branch ::
     Liftable repr => Selectable (Unlift repr) =>
     repr (Either a b) -> repr (a -> c) -> repr (b -> c) -> repr c
-  branch  = lift3 branch
+  branch = lift3 branch
 
 class Matchable repr where
   conditional ::
-    Eq a => [S.Runtime (a -> Bool)] -> [repr b] -> repr a -> repr b -> repr b
+    Eq a => [Hask.Runtime (a -> Bool)] -> [repr b] -> repr a -> repr b -> repr b
   default conditional ::
     Unliftable repr => Liftable repr => Matchable (Unlift repr) =>
-    Eq a => [S.Runtime (a -> Bool)] -> [repr b] -> repr a -> repr b -> repr b
+    Eq a => [Hask.Runtime (a -> Bool)] -> [repr b] -> repr a -> repr b -> repr b
   conditional cs bs = lift2 (conditional cs (unlift Pre.<$> bs))
 
-  match :: Eq a => [S.Runtime a] -> repr a -> (S.Runtime a -> repr b) -> repr b -> repr b
-  match as a a2b b = conditional (S.eq Pre.<$> as) (a2b Pre.<$> as) a b
+  match :: Eq a => [Hask.Runtime a] -> repr a -> (Hask.Runtime a -> repr b) -> repr b -> repr b
+  match as a a2b = conditional (Hask.eq Pre.<$> as) (a2b Pre.<$> as) a
 
 -- * Class 'Foldable'
 class Foldable repr where
@@ -141,35 +141,35 @@ class Foldable repr where
   chainPost = lift2 chainPost
 
 {-
-conditional :: Selectable repr => [(S.Runtime (a -> Bool), repr b)] -> repr a -> repr b -> repr b
+conditional :: Selectable repr => [(Hask.Runtime (a -> Bool), repr b)] -> repr a -> repr b -> repr b
 conditional cs p def = match p fs qs def
   where (fs, qs) = List.unzip cs
 -}
 
 -- * Class 'Charable'
 class Charable repr where
-  satisfy :: S.Runtime (Char -> Bool) -> repr Char
+  satisfy :: Hask.Runtime (Char -> Bool) -> repr Char
   default satisfy ::
     Liftable repr => Charable (Unlift repr) =>
-    S.Runtime (Char -> Bool) -> repr Char
+    Hask.Runtime (Char -> Bool) -> repr Char
   satisfy = lift . satisfy
 
 -- * Class 'Lookable'
 class Lookable repr where
   look :: repr a -> repr a
   negLook :: repr a -> repr ()
-  default look    :: Liftable repr => Lookable (Unlift repr) => repr a -> repr a
+  default look :: Liftable repr => Lookable (Unlift repr) => repr a -> repr a
   default negLook :: Liftable repr => Lookable (Unlift repr) => repr a -> repr ()
-  look    = lift1 look
+  look = lift1 look
   negLook = lift1 negLook
 
 {-# INLINE (<:>) #-}
 infixl 4 <:>
 (<:>) :: Applicable repr => repr a -> repr [a] -> repr [a]
-(<:>) = liftA2 S.cons
+(<:>) = liftA2 Hask.cons
 
 sequence :: Applicable repr => [repr a] -> repr [a]
-sequence = List.foldr (<:>) (pure S.nil)
+sequence = List.foldr (<:>) (pure Hask.nil)
 
 traverse :: Applicable repr => (a -> repr b) -> [a] -> repr [b]
 traverse f = sequence . List.map f
@@ -186,10 +186,10 @@ string = traverse char
 -- oneOf :: [Char] -> repr Char
 -- oneOf cs = satisfy (makeQ (flip elem cs) [||\c -> $$(ofChars cs [||c||])||])
 
-noneOf :: Charable repr => [Char] -> repr Char
-noneOf cs = satisfy ((S.Runtime (S.Eval (not . flip List.elem cs)) (S.Code [||\c -> not $$(ofChars cs [||c||])||])))
+noneOf :: Charable repr => String -> repr Char
+noneOf cs = satisfy (Hask.Runtime (Hask.Eval (not . flip List.elem cs)) (Hask.Code [||\c -> not $$(ofChars cs [||c||])||]))
 
-ofChars :: [Char] -> TExpQ Char -> TExpQ Bool
+ofChars :: String -> TExpQ Char -> TExpQ Bool
 ofChars = List.foldr (\c rest qc -> [|| c == $$qc || $$(rest qc) ||]) (const [||False||])
 
 token :: Applicable repr => Alternable repr => Charable repr => String -> repr String
@@ -202,10 +202,10 @@ more :: Applicable repr => Charable repr => Lookable repr => repr ()
 more = look (void item)
 
 char :: Applicable repr => Charable repr => Char -> repr Char
-char c = satisfy (S.eq (S.char c)) $> S.char c
+char c = satisfy (Hask.eq (Hask.char c)) $> Hask.char c
 
 item :: Charable repr => repr Char
-item = satisfy (S.const S..@ S.bool True)
+item = satisfy (Hask.const Hask..@ Hask.bool True)
 
 -- Composite Combinators
 -- someTill :: repr a -> repr b -> repr [a]
@@ -215,12 +215,12 @@ void :: Applicable repr => repr a -> repr ()
 void p = p *> unit
 
 unit :: Applicable repr => repr ()
-unit = pure S.unit
+unit = pure Hask.unit
 
 {-
 
 constp :: Applicable repr => repr a -> repr (b -> a)
-constp = (S.const <$>)
+constp = (Hask.const <$>)
 
 
 -- Alias Operations
@@ -232,7 +232,7 @@ infixl 1 >>
 
 infixl 4 <~>
 (<~>) :: Applicable repr => repr a -> repr b -> repr (a, b)
-(<~>) = liftA2 (S.runtime (,))
+(<~>) = liftA2 (Hask.runtime (,))
 
 infixl 4 <~
 (<~) :: Applicable repr => repr a -> repr b -> repr a
@@ -245,12 +245,12 @@ infixl 4 ~>
 -- Lift Operations
 liftA2 ::
  Applicable repr =>
S.Runtime (a -> b -> c) -> repr a -> repr b -> repr c
Hask.Runtime (a -> b -> c) -> repr a -> repr b -> repr c
 liftA2 f x = (<*>) (fmap f x)
 
 liftA3 ::
  Applicable repr =>
S.Runtime (a -> b -> c -> d) -> repr a -> repr b -> repr c -> repr d
Hask.Runtime (a -> b -> c -> d) -> repr a -> repr b -> repr c -> repr d
 liftA3 f a b c = liftA2 f a b <*> c
 
 -}
@@ -258,60 +258,60 @@ liftA3 f a b c = liftA2 f a b <*> c
 -- Parser Folds
 pfoldr ::
  Applicable repr => Foldable repr =>
S.Runtime (a -> b -> b) -> S.Runtime b -> repr a -> repr b
Hask.Runtime (a -> b -> b) -> Hask.Runtime b -> repr a -> repr b
 pfoldr f k p = chainPre (f <$> p) (pure k)
 
 pfoldr1 ::
  Applicable repr => Foldable repr =>
S.Runtime (a -> b -> b) -> S.Runtime b -> repr a -> repr b
Hask.Runtime (a -> b -> b) -> Hask.Runtime b -> repr a -> repr b
 pfoldr1 f k p = f <$> p <*> pfoldr f k p
 
 pfoldl ::
  Applicable repr => Foldable repr =>
S.Runtime (b -> a -> b) -> S.Runtime b -> repr a -> repr b
-pfoldl f k p = chainPost (pure k) ((S.flip <$> pure f) <*> p)
Hask.Runtime (b -> a -> b) -> Hask.Runtime b -> repr a -> repr b
+pfoldl f k p = chainPost (pure k) ((Hask.flip <$> pure f) <*> p)
 
 pfoldl1 ::
  Applicable repr => Foldable repr =>
S.Runtime (b -> a -> b) -> S.Runtime b -> repr a -> repr b
-pfoldl1 f k p = chainPost (f <$> pure k <*> p) ((S.flip <$> pure f) <*> p)
Hask.Runtime (b -> a -> b) -> Hask.Runtime b -> repr a -> repr b
+pfoldl1 f k p = chainPost (f <$> pure k <*> p) ((Hask.flip <$> pure f) <*> p)
 
 -- Chain Combinators
 chainl1' ::
  Applicable repr => Foldable repr =>
S.Runtime (a -> b) -> repr a -> repr (b -> a -> b) -> repr b
-chainl1' f p op = chainPost (f <$> p) (S.flip <$> op <*> p)
Hask.Runtime (a -> b) -> repr a -> repr (b -> a -> b) -> repr b
+chainl1' f p op = chainPost (f <$> p) (Hask.flip <$> op <*> p)
 
 chainl1 ::
  Applicable repr => Foldable repr =>
  repr a -> repr (a -> a -> a) -> repr a
-chainl1 = chainl1' S.id
+chainl1 = chainl1' Hask.id
 
 {-
 chainr1' :: ParserOps rep => rep (a -> b) -> repr a -> repr (a -> b -> b) -> repr b
-chainr1' f p op = newRegister_ S.id $ \acc ->
+chainr1' f p op = newRegister_ Hask.id $ \acc ->
   let go = bind p $ \x ->
-           modify acc (S.flip (S..@) <$> (op <*> x)) *> go
+           modify acc (Hask.flip (Hask..@) <$> (op <*> x)) *> go
        <|> f <$> x
   in go <**> get acc
 
 chainr1 :: repr a -> repr (a -> a -> a) -> repr a
-chainr1 = chainr1' S.id
+chainr1 = chainr1' Hask.id
 
-chainr :: repr a -> repr (a -> a -> a) -> S.Runtime a -> repr a
+chainr :: repr a -> repr (a -> a -> a) -> Hask.Runtime a -> repr a
 chainr p op x = option x (chainr1 p op)
 -}
 
 chainl ::
  Applicable repr => Alternable repr => Foldable repr =>
- repr a -> repr (a -> a -> a) -> S.Runtime a -> repr a
+ repr a -> repr (a -> a -> a) -> Hask.Runtime a -> repr a
 chainl p op x = option x (chainl1 p op)
 
 -- Derived Combinators
 many ::
  Applicable repr => Foldable repr =>
  repr a -> repr [a]
-many = pfoldr S.cons S.nil
+many = pfoldr Hask.cons Hask.nil
 
 manyN ::
  Applicable repr => Foldable repr =>
@@ -327,7 +327,7 @@ skipMany ::
  Applicable repr => Foldable repr =>
  repr a -> repr ()
 --skipMany p = let skipManyp = p *> skipManyp <|> unit in skipManyp
-skipMany = void . pfoldl S.const S.unit -- the void here will encourage the optimiser to recognise that the register is unused
+skipMany = void . pfoldl Hask.const Hask.unit -- the void here will encourage the optimiser to recognise that the register is unused
 
 skipManyN ::
  Applicable repr => Foldable repr =>
@@ -342,7 +342,7 @@ skipSome = skipManyN 1
 sepBy ::
  Applicable repr => Alternable repr => Foldable repr =>
  repr a -> repr b -> repr [a]
-sepBy p sep = option S.nil (sepBy1 p sep)
+sepBy p sep = option Hask.nil (sepBy1 p sep)
 
 sepBy1 ::
  Applicable repr => Alternable repr => Foldable repr =>
@@ -362,20 +362,20 @@ endBy1 p sep = some (p <* sep)
 sepEndBy ::
  Applicable repr => Alternable repr => Foldable repr =>
  repr a -> repr b -> repr [a]
-sepEndBy p sep = option S.nil (sepEndBy1 p sep)
+sepEndBy p sep = option Hask.nil (sepEndBy1 p sep)
 
 sepEndBy1 ::
  Applicable repr => Alternable repr => Foldable repr =>
  repr a -> repr b -> repr [a]
 sepEndBy1 p sep =
-  let seb1 = p <**> (sep *> (S.flip S..@ S.cons <$> option S.nil seb1)
-                 <|> pure (S.flip S..@ S.cons S..@ S.nil))
+  let seb1 = p <**> (sep *> (Hask.flip Hask..@ Hask.cons <$> option Hask.nil seb1)
+                 <|> pure (Hask.flip Hask..@ Hask.cons Hask..@ Hask.nil))
   in seb1
 
 {-
 sepEndBy1 :: repr a -> repr b -> repr [a]
-sepEndBy1 p sep = newRegister_ S.id $ \acc ->
-  let go = modify acc ((S.flip (S..)) S..@ S.cons <$> p)
+sepEndBy1 p sep = newRegister_ Hask.id $ \acc ->
+  let go = modify acc ((Hask.flip (Hask..)) Hask..@ Hask.cons <$> p)
          *> (sep *> (go <|> get acc) <|> get acc)
-  in go <*> pure S.nil
+  in go <*> pure Hask.nil
 -}
diff --git a/src/Symantic/Parser/Grammar/Observations.hs b/src/Symantic/Parser/Grammar/Observations.hs
new file mode 100644 (file)
index 0000000..933b432
--- /dev/null
@@ -0,0 +1,275 @@
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE ExistentialQuantification #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE MultiWayIf #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# OPTIONS_GHC -Wno-incomplete-patterns #-}
+module Symantic.Parser.Grammar.Observations where
+
+import Control.Monad (Monad(..), mapM_, when)
+-- import Data.String (String)
+-- import Data.Array (Ix)
+-- import Data.Bool
+-- import Data.Dependent.Map (DMap)
+import Data.Eq (Eq(..))
+import Data.Function (($), id)
+import Data.Functor (Functor(..))
+-- import Data.Functor.Identity (Identity(..))
+-- import Data.GADT.Compare (GEq, GCompare, gcompare, geq, GOrdering(..))
+import Data.HashMap.Strict (HashMap)
+import Data.HashSet (HashSet)
+import Data.Hashable (Hashable, hashWithSalt, hash)
+-- import Data.IORef (IORef, newIORef, readIORef, writeIORef)
+-- import Data.Kind (Type)
+-- import Data.Functor.Constant (Constant(..))
+-- import Data.Functor.Compose (Compose(..))
+import Data.Maybe (Maybe(..), isNothing, maybe)
+import Data.Monoid (Monoid(..))
+import Data.Ord (Ord(..))
+-- import Data.Set (Set, foldr)
+-- import Data.Typeable ((:~:)(Refl))
+-- import Data.Word (Word64)
+-- import Debug.Trace (trace)
+import GHC.Exts (Int(..))
+import GHC.Prim (StableName#, unsafeCoerce#)
+import GHC.StableName (StableName(..), makeStableName, hashStableName, eqStableName)
+import Numeric (showHex)
+import Prelude ((+))
+-- import Prelude (Num(..), Enum(..))
+import System.IO.Unsafe (unsafePerformIO)
+import Text.Show (Show(..))
+-- import Unsafe.Coerce (unsafeCoerce)
+-- import Prelude (undefined)
+import qualified Control.Monad.Trans.Class as T
+import qualified Control.Monad.Trans.Reader as R
+-- import qualified Control.Monad.Trans.Writer as W
+import qualified Control.Monad.Trans.State as S
+
+-- import qualified Data.Dependent.Map  as DMap
+import qualified Data.HashMap.Strict as HM
+import qualified Data.HashSet        as HS
+--import qualified Data.Map            as Map
+--import qualified Data.Set            as Set
+
+import Symantic.Base.Univariant
+import qualified Symantic.Parser.Grammar.Combinators as P
+--import qualified Symantic.Parser.Staging as P
+
+{-
+newtype IMVar = IMVar Word64 deriving newtype (Ord, Eq, Num, Enum, Show, Ix)
+newtype MVar (a :: Type) = MVar IMVar
+instance Show (MVar a) where show (MVar m) = "m" <> show m
+
+instance GEq MVar where
+  geq (MVar u) (MVar v)
+    | u == v    = Just (unsafeCoerce Refl)
+    | otherwise = Nothing
+instance GCompare MVar where
+  gcompare m1@(MVar u) m2@(MVar v) =
+    case compare u v of
+      LT -> GLT
+      EQ -> case geq m1 m2 of Just Refl -> GEQ
+      GT -> GGT
+-}
+
+-- * Type 'ParserName'
+data ParserName = forall a. ParserName (StableName# a)
+makeParserName :: repr a -> ParserName
+-- Force evaluation of p to ensure that the stableName is correct first time
+makeParserName !p = unsafePerformIO $ fmap (\(StableName name) -> ParserName name) (makeStableName p)
+instance Eq ParserName where
+  (ParserName n) == (ParserName m) = eqStableName (StableName n) (StableName m)
+instance Hashable ParserName where
+  hash (ParserName n) = hashStableName (StableName n)
+  hashWithSalt salt (ParserName n) = hashWithSalt salt (StableName n)
+
+instance Show ParserName where showsPrec _ (ParserName n) = showHex (I# (unsafeCoerce# n))
+
+-- * Type 'Lets'
+-- | Interpret combinators as 'ParserName'
+newtype Lets a = Lets { unLets :: R.ReaderT (HashSet ParserName) (S.State LetsState) () }
+
+lets :: Lets a -> (HashSet ParserName, HashSet ParserName)
+lets (Lets m) =
+  let st = S.execState (R.runReaderT m mempty) emptyLetsState in
+  ( HM.keysSet (HM.filter (> 1) (lets_preds st))
+  , lets_recs st
+  )
+
+letsNode :: Lets a -> Lets a
+letsNode (Lets m) = Lets $ do
+  let name = makeParserName m
+  st <- T.lift S.get
+  let (before, preds) = HM.alterF (\v -> (v, Just (maybe 1 (+ 1) v))) name (lets_preds st)
+  seen <- R.ask
+  if --trace (ind<>"at:    "<>show name) $
+    HS.member name seen
+  then --trace (ind<>"skipR: "<>show name) $
+    T.lift $ S.put st
+     { lets_preds = preds
+     , lets_recs = HS.insert name (lets_recs st)
+     }
+  else do
+    T.lift $ S.put st{ lets_preds = preds }
+    when (isNothing before) $
+      R.local (HS.insert name) m
+    {-
+    if trace (ind<>"b?:    "<>show name) $ before /= Nothing
+     then trace (ind<>"SKIPB: "<>show name) $ return ()
+     else trace (ind<>"first: "<>show name) $
+        R.local (\(m,i) -> (HS.insert name m, ind<>"  ")) r
+    -}
+
+-- | This is an uncommon 'Unlift' definition which unlifts nothing,
+-- but it enables to leverage default definitions.
+type instance Unlift Lets = Lets
+instance Liftable Lets where
+  lift _x = letsNode (Lets (return ()))
+  lift1 _f x = letsNode (Lets (unLets x))
+  lift2 _f x y = letsNode (Lets (unLets x >> unLets y))
+  lift3 _f x y z = letsNode (Lets (unLets x >> unLets y >> unLets z))
+instance Unliftable Lets where
+  unlift = id
+instance P.Applicable Lets
+instance P.Alternable Lets
+instance P.Selectable Lets
+instance P.Matchable Lets where
+  -- Here the default definition does not fit since there is no lift* for its type and thus handles 'bs' itself, which is not the transformation wanted.
+  conditional _cs bs a b =
+    letsNode (Lets (mapM_ unLets bs >> unLets a >> unLets b))
+instance P.Foldable Lets
+instance P.Charable Lets
+instance P.Lookable Lets
+
+-- ** Type 'LetsState'
+data LetsState = LetsState
+ { lets_preds :: HashMap ParserName Int
+ , lets_recs  :: HashSet ParserName
+ } deriving (Show)
+
+emptyLetsState :: LetsState
+emptyLetsState = LetsState
+ { lets_preds = HM.empty
+ , lets_recs  = HS.empty
+ }
+
+
+
+{-
+type Binding o a x = Fix4 (Instr o) '[] One x a
+data LetBinding o a x = forall rs. LetBinding (Binding o a x) (Regs rs)
+deriving instance Show (LetBinding o a x)
+
+makeLetBinding :: Binding o a x -> Set IΣVar -> LetBinding o a x
+makeLetBinding m rs = LetBinding m (unsafeMakeRegs rs)
+
+data Regs (rs :: [Type]) where
+  NoRegs :: Regs '[]
+  FreeReg :: ΣVar r -> Regs rs -> Regs (r : rs)
+deriving instance Show (Regs rs)
+
+unsafeMakeRegs :: Set IΣVar -> Regs rs
+unsafeMakeRegs =  foldr (\σ rs -> unsafeCoerce (FreeReg (ΣVar σ) rs)) (unsafeCoerce NoRegs)
+
+compile :: forall compiled a. Parser a -> (forall x. Maybe (MVar x) -> Fix Combinator x -> Set IΣVar -> IMVar -> IΣVar -> compiled x) -> (compiled a, DMap MVar compiled)
+compile (Parser p) codeGen = trace ("COMPILING NEW PARSER WITH " ++ show (DMap.size μs') ++ " LET BINDINGS") $ (codeGen' Nothing p', DMap.mapWithKey (codeGen' . Just) μs')
+  where
+    (p', μs, maxV) = preprocess p
+    (μs', frs, maxΣ) = dependencyAnalysis p' μs
+
+    freeRegs :: Maybe (MVar x) -> Set IΣVar
+    freeRegs = maybe Set.empty (\(MVar v) -> frs Map.! v)
+
+    codeGen' :: Maybe (MVar x) -> Fix Combinator x -> compiled x
+    codeGen' letBound p = codeGen letBound (analyse (emptyFlags {letBound = isJust letBound}) p) (freeRegs letBound) (maxV + 1) (maxΣ + 1)
+
+preprocess :: Fix (Combinator :+: ScopeRegister) a -> (Fix Combinator a, DMap MVar (Fix Combinator), IMVar)
+preprocess p =
+  let q = tagParser p
+      (lets, recs) = findLets q
+      (p', μs, maxV) = letInsertion lets recs q
+  in (p', μs, maxV)
+
+data Tag t f (k :: Type -> Type) a = Tag {tag :: t, tagged :: f k a}
+
+tagParser :: Fix (Combinator :+: ScopeRegister) a -> Fix (Tag ParserName Combinator) a
+tagParser p = cata' tagAlg p
+  where
+    tagAlg p = In . Tag (makeParserName p) . (id \/ descope)
+    descope (ScopeRegister p f) = freshReg regMaker (\(reg@(Reg σ)) -> MakeRegister σ p (f reg))
+    regMaker :: IORef IΣVar
+    regMaker = newRegMaker p
+
+
+newtype LetInserter a =
+  LetInserter {
+      doLetInserter :: HFreshT IMVar
+                       (State ( HashMap ParserName IMVar
+                              , DMap MVar (Fix Combinator)))
+                       (Fix Combinator a)
+    }
+letInsertion :: HashSet ParserName -> HashSet ParserName -> Fix (Tag ParserName Combinator) a -> (Fix Combinator a, DMap MVar (Fix Combinator), IMVar)
+letInsertion lets recs p = (p', μs, μMax)
+  where
+    m = cata alg p
+    ((p', μMax), (_, μs)) = runState (runFreshT (doLetInserter m) 0) (HashMap.empty, DMap.empty)
+    alg :: Tag ParserName Combinator LetInserter a -> LetInserter a
+    alg p = LetInserter $ do
+      let name = tag p
+      let q = tagged p
+      (vs, μs) <- get
+      let bound = HashSet.member name lets
+      let recu = HashSet.member name recs
+      if bound || recu then case HashMap.lookup name vs of
+        Just v  -> let μ = MVar v in return $! optimise (Let recu μ (μs DMap.! μ))
+        Nothing -> mdo
+          v <- newVar
+          let μ = MVar v
+          put (HashMap.insert name v vs, DMap.insert μ q' μs)
+          q' <- doLetInserter (postprocess q)
+          return $! optimise (Let recu μ q')
+      else do doLetInserter (postprocess q)
+
+postprocess :: Combinator LetInserter a -> LetInserter a
+postprocess = LetInserter . fmap optimise . traverseCombinator doLetInserter
+
+getBefore :: MonadState LetsState m => m (HashSet ParserName)
+getBefore = gets before
+
+
+
+
+
+
+
+
+makeParserName :: Fix (Combinator :+: ScopeRegister) a -> ParserName
+-- Force evaluation of p to ensure that the stableName is correct first time
+makeParserName !p = unsafePerformIO (fmap (\(StableName name) -> ParserName name) (makeStableName p))
+
+-- The argument here stops GHC from floating it out, it should be provided something from the scope
+{-# NOINLINE newRegMaker #-}
+newRegMaker :: a -> IORef IΣVar
+newRegMaker x = x `seq` unsafePerformIO (newIORef 0)
+
+{-# NOINLINE freshReg #-}
+freshReg :: IORef IΣVar -> (forall r. Reg r a -> x) -> x
+freshReg maker scope = scope $ unsafePerformIO $ do
+  x <- readIORef maker
+  writeIORef maker (x + 1)
+  return $! Reg (ΣVar x)
+
+instance IFunctor f => IFunctor (Tag t f) where
+  imap f (Tag t k) = Tag t (imap f k)
+
+instance Eq ParserName where
+  (ParserName n) == (ParserName m) = eqStableName (StableName n) (StableName m)
+instance Hashable ParserName where
+  hash (ParserName n) = hashStableName (StableName n)
+  hashWithSalt salt (ParserName n) = hashWithSalt salt (StableName n)
+
+-- There is great evil in this world, and I'm probably responsible for half of it
+instance Show ParserName where showsPrec _ (ParserName n) = showHex (I# (unsafeCoerce# n))
+-}
index 70c29dc5fa28bd9683664901685685fc651cedc6..25c72af3b07157fdf471d7ed7c719e1c1818bff0 100644 (file)
@@ -8,69 +8,69 @@ import Data.Bool (Bool)
 import Data.Char (Char)
 import Data.Either (Either(..), either)
 import Data.Eq (Eq(..))
-import Data.Maybe (Maybe(..))
-import Data.Typeable
-import Prelude (undefined)
+-- import Data.Maybe (Maybe(..))
+-- import Data.Typeable
+-- import Prelude (undefined)
 import qualified Data.Function as Function
 import qualified Prelude as Pre
 
 import Symantic.Base.Univariant
 import Symantic.Parser.Grammar.Combinators
-import Symantic.Parser.Staging hiding (Runtimeable(..), OptRuntime(..))
-import qualified Symantic.Parser.Staging as S
-import qualified Language.Haskell.TH.Syntax as TH
+import Symantic.Parser.Staging hiding (Haskell(..))
+import qualified Symantic.Parser.Staging as Hask
+-- import qualified Language.Haskell.TH.Syntax as TH
 
--- * Type 'OptGram'
-data OptGram repr a where
- Pure :: S.OptRuntime S.Runtime a -> OptGram repr a
- Satisfy :: S.Runtime (Char -> Bool) -> OptGram repr Char
- Item :: OptGram repr Char
- Try :: OptGram repr a -> OptGram repr a
- Look :: OptGram repr a -> OptGram repr a
- NegLook :: OptGram repr a -> OptGram repr ()
- (:<*>) :: OptGram repr (a -> b) -> OptGram repr a -> OptGram repr b
- (:<|>) :: OptGram repr a -> OptGram repr a -> OptGram repr a
- Empty :: OptGram repr a
- Branch :: OptGram repr (Either a b) -> OptGram repr (a -> c) -> OptGram repr (b -> c) -> OptGram repr c
- Match :: Eq a => [S.Runtime (a -> Bool)] -> [OptGram repr b] -> OptGram repr a -> OptGram repr b -> OptGram repr b
- ChainPre :: OptGram repr (a -> a) -> OptGram repr a -> OptGram repr a
- ChainPost :: OptGram repr a -> OptGram repr (a -> a) -> OptGram repr a
+-- * Type 'Comb'
+data Comb repr a where
+ Pure :: Hask.Haskell Hask.Runtime a -> Comb repr a
+ Satisfy :: Hask.Runtime (Char -> Bool) -> Comb repr Char
+ Item :: Comb repr Char
+ Try :: Comb repr a -> Comb repr a
+ Look :: Comb repr a -> Comb repr a
+ NegLook :: Comb repr a -> Comb repr ()
+ (:<*>) :: Comb repr (a -> b) -> Comb repr a -> Comb repr b
+ (:<|>) :: Comb repr a -> Comb repr a -> Comb repr a
+ Empty :: Comb repr a
+ Branch :: Comb repr (Either a b) -> Comb repr (a -> c) -> Comb repr (b -> c) -> Comb repr c
+ Match :: Eq a => [Hask.Runtime (a -> Bool)] -> [Comb repr b] -> Comb repr a -> Comb repr b -> Comb repr b
+ ChainPre :: Comb repr (a -> a) -> Comb repr a -> Comb repr a
+ ChainPost :: Comb repr a -> Comb repr (a -> a) -> Comb repr a
 
-pattern (:<$>) :: S.OptRuntime S.Runtime (a -> b) -> OptGram repr a -> OptGram repr b
-pattern (:$>) :: OptGram repr a -> S.OptRuntime S.Runtime b -> OptGram repr b
-pattern (:<$) :: S.OptRuntime S.Runtime a -> OptGram repr b -> OptGram repr a
-pattern (:*>) :: OptGram repr a -> OptGram repr b -> OptGram repr b
-pattern (:<*) :: OptGram repr a -> OptGram repr b -> OptGram repr a
+pattern (:<$>) :: Hask.Haskell Hask.Runtime (a -> b) -> Comb repr a -> Comb repr b
+pattern (:$>) :: Comb repr a -> Hask.Haskell Hask.Runtime b -> Comb repr b
+pattern (:<$) :: Hask.Haskell Hask.Runtime a -> Comb repr b -> Comb repr a
+pattern (:*>) :: Comb repr a -> Comb repr b -> Comb repr b
+pattern (:<*) :: Comb repr a -> Comb repr b -> Comb repr a
 pattern x :<$> p = Pure x :<*> p
 pattern p :$> x = p :*> Pure x
 pattern x :<$ p = Pure x :<* p
-pattern x :<* p = S.Const :<$> x :<*> p
-pattern p :*> x = S.Id :<$ p :<*> x
+pattern x :<* p = Hask.Const :<$> x :<*> p
+pattern p :*> x = Hask.Id :<$ p :<*> x
 
 infixl 3 :<|>
 infixl 4 :<*>, :<*, :*>
 infixl 4 :<$>, :<$, :$>
 
-instance Applicable (OptGram Runtime) where
-  pure = Pure Function.. S.OptRuntime
+instance Applicable (Comb Runtime) where
+  pure = Pure Function.. Hask.Haskell
   (<*>) = (:<*>)
-instance Alternable (OptGram repr) where
+instance Alternable (Comb repr) where
   (<|>) = (:<|>)
   empty = Empty
   try = Try
-instance Selectable (OptGram repr) where
+instance Selectable (Comb repr) where
   branch = Branch
-instance Matchable (OptGram repr) where
+instance Matchable (Comb repr) where
   conditional = Match
-instance Foldable (OptGram repr) where
+instance Foldable (Comb repr) where
   chainPre = ChainPre
   chainPost = ChainPost
-instance Charable (OptGram repr) where
+instance Charable (Comb repr) where
   satisfy = Satisfy
-instance Lookable (OptGram repr) where
+instance Lookable (Comb repr) where
   look = Look
   negLook = NegLook
-type instance Unlift (OptGram repr) = repr
+type instance Unlift (Comb repr) = repr
 instance
  ( Applicable repr
  , Alternable repr
@@ -79,7 +79,7 @@ instance
  , Charable repr
  , Lookable repr
  , Matchable repr
- ) => Unliftable (OptGram repr) where
+ ) => Unliftable (Comb repr) where
   unlift = \case
     Pure a -> pure (unlift a)
     Satisfy p -> satisfy p
@@ -92,50 +92,52 @@ instance
     Empty -> empty
     Branch lr l r -> branch (unlift lr) (unlift l) (unlift r)
     Match cs bs a b -> conditional cs (unlift Pre.<$> bs) (unlift a) (unlift b)
+    ChainPre x y -> chainPre (unlift x) (unlift y)
+    ChainPost x y -> chainPost (unlift x) (unlift y)
 
-optGram ::
OptGram repr a -> OptGram repr a
-optGram = \case
+optComb ::
Comb repr a -> Comb repr a
+optComb = \case
   -- Applicable Right Absorption Law
   Empty :<*> _ -> Empty
   Empty  :*> _ -> Empty
   Empty :<*  _ -> Empty
   -- Applicable Failure Weakening Law
-  u :<*> Empty -> optGram (u :*> Empty)
-  u :<*  Empty -> optGram (u :*> Empty)
+  u :<*> Empty -> optComb (u :*> Empty)
+  u :<*  Empty -> optComb (u :*> Empty)
   -- Branch Absorption Law
   Branch Empty _ _ -> empty
   -- Branch Weakening Law
-  Branch b Empty Empty -> optGram (b :*> Empty)
+  Branch b Empty Empty -> optComb (b :*> Empty)
 
   -- Applicable Identity Law
-  S.Id :<$> x -> x
+  Hask.Id :<$> x -> x
   -- Flip const optimisation
-  S.Flip S.:@ S.Const :<$> u -> optGram (u :*> Pure S.Id)
+  Hask.Flip Hask.:@ Hask.Const :<$> u -> optComb (u :*> Pure Hask.Id)
   -- Homomorphism Law
-  f :<$> Pure x -> Pure (f S.:@ x)
+  f :<$> Pure x -> Pure (f Hask.:@ x)
   -- Functor Composition Law
   -- (a shortcut that could also have been be caught
   -- by the Composition Law and Homomorphism law)
-  f :<$> (g :<$> p) -> optGram ((S.:.) S.:@ f S.:@ g :<$> p)
+  f :<$> (g :<$> p) -> optComb ((Hask.:.) Hask.:@ f Hask.:@ g :<$> p)
   -- Composition Law
-  u :<*> (v :<*> w) -> optGram (optGram (optGram ((S.:.) :<$> u) :<*> v) :<*> w)
+  u :<*> (v :<*> w) -> optComb (optComb (optComb ((Hask.:.) :<$> u) :<*> v) :<*> w)
   -- Definition of *>
-  S.Flip S.:@ S.Const :<$> p :<*> q -> p :*> q
+  Hask.Flip Hask.:@ Hask.Const :<$> p :<*> q -> p :*> q
   -- Definition of <*
-  S.Const :<$> p :<*> q -> p :<* q
+  Hask.Const :<$> p :<*> q -> p :<* q
   -- Reassociation Law 1
-  (u :*> v) :<*> w -> optGram (u :*> (optGram (v :<*> w)))
+  (u :*> v) :<*> w -> optComb (u :*> optComb (v :<*> w))
   -- Interchange Law
-  u :<*> Pure x -> optGram (S.Flip S.:@ (S.:$) S.:@ x :<$> u)
+  u :<*> Pure x -> optComb (Hask.Flip Hask.:@ (Hask.:$) Hask.:@ x :<$> u)
   -- Right Absorption Law
   (_ :<$> p) :*> q -> p :*> q
   -- Left Absorption Law
   p :<* (_ :<$> q) -> p :<* q
   -- Reassociation Law 2
-  u :<*> (v :<* w) -> optGram (optGram (u :<*> v) :<* w)
+  u :<*> (v :<* w) -> optComb (optComb (u :<*> v) :<* w)
   -- Reassociation Law 3
-  u :<*> (v :$> x) -> optGram (optGram (u :<*> Pure x) :<* v)
+  u :<*> (v :$> x) -> optComb (optComb (u :<*> Pure x) :<* v)
 
   -- Left Catch Law
   p@Pure{} :<|> _ -> p
@@ -144,22 +146,22 @@ optGram = \case
   -- Right Neutral Law
   u :<|> Empty -> u
   -- Associativity Law
-  (u :<|> v) :<|> w -> u :<|> optGram (v :<|> w)
+  (u :<|> v) :<|> w -> u :<|> optComb (v :<|> w)
 
   -- Identity law
   Pure _ :*> u -> u
   -- Identity law
   (u :$> _) :*> v -> u :*> v
   -- Associativity Law
-  u :*> (v :*> w) -> optGram (optGram (u :*> v) :*> w)
+  u :*> (v :*> w) -> optComb (optComb (u :*> v) :*> w)
   -- Identity law
   u :<* Pure _ -> u
   -- Identity law
-  u :<* (v :$> _) -> optGram (u :<* v)
+  u :<* (v :$> _) -> optComb (u :<* v)
   -- Commutativity Law
-  x :<$ u -> optGram (u :$> x)
+  x :<$ u -> optComb (u :$> x)
   -- Associativity Law
-  (u :<* v) :<* w -> optGram (u :<* optGram (v :<* w))
+  (u :<* v) :<* w -> optComb (u :<* optComb (v :<* w))
 
   -- Pure lookahead
   Look p@Pure{} -> p
@@ -169,62 +171,62 @@ optGram = \case
   NegLook Pure{} -> Empty
 
   -- Dead negative-lookahead
-  NegLook Empty -> Pure S.unit
+  NegLook Empty -> Pure Hask.unit
   -- Double Negation Law
-  NegLook (NegLook p) -> optGram (Look (Try p) :*> Pure S.unit)
+  NegLook (NegLook p) -> optComb (Look (Try p) :*> Pure Hask.unit)
   -- Zero Consumption Law
-  NegLook (Try p) -> optGram (NegLook p)
+  NegLook (Try p) -> optComb (NegLook p)
   -- Idempotence Law
   Look (Look p) -> Look p
   -- Right Identity Law
-  NegLook (Look p) -> optGram (NegLook p)
+  NegLook (Look p) -> optComb (NegLook p)
 
   -- Left Identity Law
   Look (NegLook p) -> NegLook p
   -- Transparency Law
-  NegLook (Try p :<|> q) -> optGram (optGram (NegLook p) :*> optGram (NegLook q))
+  NegLook (Try p :<|> q) -> optComb (optComb (NegLook p) :*> optComb (NegLook q))
   -- Distributivity Law
-  Look p :<|> Look q -> optGram (Look (optGram (Try p :<|> q)))
+  Look p :<|> Look q -> optComb (Look (optComb (Try p :<|> q)))
   -- Interchange Law
-  Look (p :$> x) -> optGram (optGram (Look p) :$> x)
+  Look (p :$> x) -> optComb (optComb (Look p) :$> x)
   -- Interchange law
-  Look (f :<$> p) -> optGram (f :<$> optGram (Look p))
+  Look (f :<$> p) -> optComb (f :<$> optComb (Look p))
   -- Absorption Law
-  p :<*> NegLook q -> optGram (optGram (p :<*> Pure S.unit) :<* NegLook q)
+  p :<*> NegLook q -> optComb (optComb (p :<*> Pure Hask.unit) :<* NegLook q)
   -- Idempotence Law
-  NegLook (p :$> _) -> optGram (NegLook p)
+  NegLook (p :$> _) -> optComb (NegLook p)
   -- Idempotence Law
-  NegLook (_ :<$> p) -> optGram (NegLook p)
+  NegLook (_ :<$> p) -> optComb (NegLook p)
   -- Interchange Law
-  Try (p :$> x) -> optGram (optGram (Try p) :$> x)
+  Try (p :$> x) -> optComb (optComb (Try p) :$> x)
   -- Interchange law
-  Try (f :<$> p) -> optGram (f :<$> optGram (Try p))
+  Try (f :<$> p) -> optComb (f :<$> optComb (Try p))
 
   -- pure Left/Right laws
   Branch (Pure (unlift -> lr)) l r ->
     case getEval lr of
-     Left e -> optGram (l :<*> Pure (S.OptRuntime (Runtime (Eval e) c)))
+     Left e -> optComb (l :<*> Pure (Hask.Haskell (Runtime (Eval e) c)))
       where c = Code [|| case $$(getCode lr) of Left x -> x ||]
-     Right e -> optGram (r :<*> Pure (S.OptRuntime (Runtime (Eval e) c)))
+     Right e -> optComb (r :<*> Pure (Hask.Haskell (Runtime (Eval e) c)))
       where c = Code [|| case $$(getCode lr) of Right x -> x ||]
   -- Generalised Identity law
   Branch b (Pure (unlift -> l)) (Pure (unlift -> r)) ->
-    optGram (S.OptRuntime (Runtime e c) :<$> b)
+    optComb (Hask.Haskell (Runtime e c) :<$> b)
     where
     e = Eval (either (getEval l) (getEval r))
     c = Code [|| either $$(getCode l) $$(getCode r) ||]
   -- Interchange law
   Branch (x :*> y) p q ->
-    optGram (x :*> optGram (Branch y p q))
+    optComb (x :*> optComb (Branch y p q))
   -- Negated Branch law
   Branch b l Empty ->
-    Branch (Pure (S.OptRuntime (Runtime e c)) :<*> b) Empty l
+    Branch (Pure (Hask.Haskell (Runtime e c)) :<*> b) Empty l
     where
     e = Eval (either Right Left)
     c = Code [||either Right Left||]
   -- Branch Fusion law
   Branch (Branch b Empty (Pure (unlift -> lr))) Empty br ->
-    optGram (Branch (optGram (Pure (S.OptRuntime (Runtime (Eval e) c)) :<*> b)) Empty br)
+    optComb (Branch (optComb (Pure (Hask.Haskell (Runtime (Eval e) c)) :<*> b)) Empty br)
     where
     e Left{} = Left ()
     e (Right r) = case getEval lr r of
@@ -235,7 +237,7 @@ optGram = \case
                                    Left _ -> Left ()
                                    Right rr -> Right rr ||]
   -- Distributivity Law
-  f :<$> Branch b l r -> optGram (Branch b (optGram ((S..@) (S..) f :<$> l))
-                                           (optGram ((S..@) (S..) f :<$> r)))
+  f :<$> Branch b l r -> optComb (Branch b (optComb ((Hask..@) (Hask..) f :<$> l))
+                                           (optComb ((Hask..@) (Hask..) f :<$> r)))
 
   x -> x
index 9214400920e25099a4827e6d906aa2bbe50da1a8..b5c1834e5b7c5af4ad312c4a781dc081b20c0113 100644 (file)
@@ -4,7 +4,6 @@ module Symantic.Parser.Staging where
 import Data.Bool (Bool)
 import Data.Char (Char)
 import Data.Eq (Eq)
-import Data.Functor.Identity (Identity(..))
 import Language.Haskell.TH (TExpQ)
 import qualified Data.Eq as Eq
 import qualified Data.Function as Function
@@ -51,60 +50,60 @@ instance Unliftable Code where
   unlift = Function.id
   {-# INLINE unlift #-}
 
--- * Class 'Runtimeable'
--- | Final encoding of some Runtimeable functions
+-- * Class 'Haskellable'
+-- | Final encoding of some Haskellable functions
 -- useful for some optimizations in 'optGram'.
-class Runtimeable (app :: * -> *) where
+class Haskellable (app :: * -> *) where
   runtime :: Unlift app a -> app a
-  (.)   :: app ((b->c) -> (a->b) -> a -> c)
-  ($)   :: app ((a->b) -> a -> b)
-  (.@)  :: app (a->b) -> app a -> app b
-  bool  :: Bool -> app Bool
-  char  :: Char -> app Char
-  cons  :: app (a -> [a] -> [a])
+  (.) :: app ((b->c) -> (a->b) -> a -> c)
+  ($) :: app ((a->b) -> a -> b)
+  (.@) :: app (a->b) -> app a -> app b
+  bool :: Bool -> app Bool
+  char :: Char -> app Char
+  cons :: app (a -> [a] -> [a])
   const :: app (a -> b -> a)
-  eq    :: Eq a => app a -> app (a -> Bool)
-  flip  :: app ((a -> b -> c) -> b -> a -> c)
-  id    :: app (a->a)
-  nil   :: app [a]
-  unit  :: app ()
-instance Runtimeable Identity
+  eq :: Eq a => app a -> app (a -> Bool)
+  flip :: app ((a -> b -> c) -> b -> a -> c)
+  id :: app (a->a)
+  nil :: app [a]
+  unit :: app ()
+-- instance Haskellable Identity
 
--- ** Type 'Runtimeable'
--- | Initial encoding of 'Runtimeable'
-data OptRuntime (app:: * -> *) a where
-  OptRuntime :: app a -> OptRuntime app a
-  (:.)  :: OptRuntime app ((b->c) -> (a->b) -> a -> c)
-  (:$)  :: OptRuntime app ((a->b) -> a -> b)
-  (:@)  :: OptRuntime app (a->b) -> OptRuntime app a -> OptRuntime app b
-  Const :: OptRuntime app (a -> b -> a)
-  Flip  :: OptRuntime app ((a -> b -> c) -> b -> a -> c)
-  Id    :: OptRuntime app (a->a)
-type instance Unlift (OptRuntime app) = app
-instance (Liftable app, Unliftable app, Runtimeable app) => Liftable (OptRuntime app) where
-  lift = OptRuntime
-instance (Unliftable app, Runtimeable app) => Unliftable (OptRuntime app) where
+-- ** Type 'Haskellable'
+-- | Initial encoding of 'Haskellable'
+data Haskell (app:: * -> *) a where
+  Haskell :: app a -> Haskell app a
+  (:.) :: Haskell app ((b->c) -> (a->b) -> a -> c)
+  (:$) :: Haskell app ((a->b) -> a -> b)
+  (:@) :: Haskell app (a->b) -> Haskell app a -> Haskell app b
+  Const :: Haskell app (a -> b -> a)
+  Flip :: Haskell app ((a -> b -> c) -> b -> a -> c)
+  Id :: Haskell app (a->a)
+type instance Unlift (Haskell app) = app
+instance (Liftable app, Unliftable app, Haskellable app) => Liftable (Haskell app) where
+  lift = Haskell
+instance (Unliftable app, Haskellable app) => Unliftable (Haskell app) where
   unlift = \case
-   OptRuntime x -> runtime (unlift x)
-   (:.)     -> (.)
-   (:$)     -> ($)
+   Haskell x -> runtime (unlift x)
+   (:.) -> (.)
+   (:$) -> ($)
    (:@) f x -> (.@) (unlift f) (unlift x)
-   Const    -> const
-   Flip     -> flip
-   Id       -> id
+   Const -> const
+   Flip -> flip
+   Id -> id
 infixr 0 $, :$
 infixr 9 ., :.
 infixl 9 .@, :@
 
-instance Runtimeable (OptRuntime app) where
-  runtime = OptRuntime
+instance Haskellable (Haskell app) where
+  runtime = Haskell
   (.)   = (:.)
   ($)   = (:$)
   (.@)  = (:@)
   const = Const
   flip  = Flip
   id    = Id
-instance Runtimeable Runtime where
+instance Haskellable Runtime where
   runtime  = Function.id
   (.)      = Runtime (.) (.)
   ($)      = Runtime ($) ($)
@@ -118,11 +117,11 @@ instance Runtimeable Runtime where
   id       = Runtime id id
   nil      = Runtime nil nil
   unit     = Runtime unit unit
-instance Runtimeable Eval where
+instance Haskellable Eval where
   runtime  = lift
   (.)      = Eval (Function..)
   ($)      = Eval (Function.$)
-  (.@) f x = Eval ((unEval f) (unEval x))
+  (.@) f x = Eval (unEval f (unEval x))
   bool     = Eval
   char     = Eval
   cons     = Eval (:)
@@ -132,7 +131,7 @@ instance Runtimeable Eval where
   id       = Eval Function.id
   nil      = Eval []
   unit     = Eval ()
-instance Runtimeable Code where
+instance Haskellable Code where
   runtime  = lift
   (.)      = Code [|| \f g x -> f (g x) ||]
   ($)      = Code [|| \f x -> f x ||]
index 584594ed8e2c85ea50a8f721d2f5645f753f948c..a2d7af99ecc627c3517500cd9eeefa0df3fd40d6 100644 (file)
@@ -23,6 +23,8 @@ library
     Symantic.Parser.Grammar.Combinators
     Symantic.Parser.Grammar.Observations
     Symantic.Parser.Grammar.Optimizations
+    Symantic.Parser.Automaton
+    Symantic.Parser.Automaton.Instructions
     Symantic.Parser.Staging
     Symantic.Base.Univariant
   other-modules:
@@ -46,11 +48,14 @@ library
     array,
     bytestring,
     containers,
-    dependent-map >= 0.4.0.0,
-    dependent-sum >= 0.7.1.0,
+    -- dependent-map >= 0.4.0.0,
+    -- dependent-sum >= 0.7.1.0,
+    dependent-map,
+    dependent-sum,
     ghc-prim,
     hashable,
-    template-haskell >= 2.16,
+    template-haskell >= 2.15,
+    -- template-haskell >= 2.16,
     text,
     transformers,
     unordered-containers