build: ghcid: run even with warnings
[haskell/symantic-parser.git] / src / Symantic / Parser / Machine / Program.hs
index 7ca32e7aa1081932173a34ebbeac2c560eaabc57..fcee19a3648740427b9bfbd611cf7f22839ed333 100644 (file)
@@ -9,24 +9,24 @@
 -- those generated (see for instance 'joinNext').
 module Symantic.Parser.Machine.Program where
 
-import Control.Monad (Monad(..), (<=<), (=<<), liftM, liftM2, sequence)
-import Data.Function (($))
-import System.IO (IO)
-import Type.Reflection (Typeable)
 import Control.DeepSeq (NFData)
+import Control.Monad (Monad(..), (<=<), (=<<), liftM, liftM2, sequence)
 import Data.Bool (Bool(..))
 import Data.Eq (Eq)
-import Data.Function ((.))
+import Data.Function (($), (.))
 import Data.Ord (Ord)
+import Data.Semigroup (Semigroup(..))
+import System.IO (IO)
 import Text.Show (Show(..))
+import Type.Reflection (Typeable)
 import qualified Data.Functor as Functor
 import qualified Data.Set as Set
 import qualified Data.Traversable as Traversable
 import qualified Language.Haskell.TH as TH
 import qualified Language.Haskell.TH.Syntax as TH
-import qualified Symantic.Lang as Prod
+import qualified Symantic.Syntaxes.Classes as Prod
 
-import Symantic.Derive
+import Symantic.Syntaxes.Derive
 import Symantic.Parser.Grammar
 import Symantic.Parser.Machine.Input
 import Symantic.Parser.Machine.Instructions
@@ -37,7 +37,7 @@ import Symantic.Parser.Machine.Optimize
 -- where each 'Instr'uction is built by a continuation
 -- to be able to introspect, duplicate and/or change
 -- the next 'Instr'uction.
-data Program repr inp a = Program { unProgram ::
+newtype Program repr inp a = Program { unProgram ::
   forall vs ret.
   -- This is the next instruction.
   SomeInstr repr inp (a ': vs) ret ->
@@ -76,24 +76,27 @@ type Machinable tok repr =
   )
 
 instance
-  ( Cursorable (Cursor inp)
+  ( Positionable (InputPosition inp)
   , InstrBranchable repr
+  , InstrComment repr
   , InstrExceptionable repr
   , InstrInputable repr
   , InstrJoinable repr
   , InstrValuable repr
   ) => CombAlternable (Program repr inp) where
   alt exn (Program l) (Program r) = joinNext $ Program $ \next ->
-    liftM2 (catch exn)
-      (l (commit exn next))
+    liftM2
+      (catch exn)
+      (l $ commit exn next)
       (raiseAgainIfConsumed exn Functor.<$> r next)
   throw exn = Program $ \_next -> return $ raise exn
   failure flr = Program $ \_next -> return $ fail (Set.singleton flr)
   empty = Program $ \_next -> return $ fail (Set.singleton (SomeFailure FailureEmpty))
   try (Program x) = Program $ \next ->
-    liftM2 (catch ExceptionFailure)
-      (x (commit ExceptionFailure next))
-      -- On exception, reset the input, and propagate the failure.
+    liftM2
+      (catch ExceptionFailure)
+      (x $ commit ExceptionFailure next)
+      -- On 'ExceptionFailure', reset the input, and propagate the failure.
       (return $ loadInput $ fail Set.empty)
 
 -- | @(raiseAgainIfConsumed exn ok)@
@@ -103,17 +106,19 @@ instance
 -- without updating the farthest error
 -- (which is usually done when 'fail'ing).
 raiseAgainIfConsumed ::
-  Cursorable (Cursor inp) =>
+  Positionable (InputPosition inp) =>
   InstrBranchable repr =>
+  InstrComment repr =>
   InstrExceptionable repr =>
   InstrInputable repr =>
   InstrValuable repr =>
   Exception ->
   SomeInstr repr inp vs ret ->
-  SomeInstr repr inp (Cursor inp ': vs) ret
+  SomeInstr repr inp (InputPosition inp ': vs) ret
 raiseAgainIfConsumed exn ok =
-  pushInput $
-  lift2Value (splice sameOffset) $
+  comment "raiseAgainIfConsumed" $
+  saveInput $
+  lift2Value (splice samePosition) $
   ifBranch ok $
     case exn of
       ExceptionLabel lbl -> raise lbl
@@ -162,9 +167,10 @@ instance
   Program x *> Program y = Program (x <=< return . popValue <=< y)
   Program x <* Program y = Program (x <=< y <=< return . popValue)
 instance
-  ( Cursorable (Cursor inp)
+  ( Positionable (InputPosition inp)
   , InstrBranchable repr
   , InstrCallable repr
+  , InstrComment repr
   , InstrExceptionable repr
   , InstrInputable repr
   , InstrIterable repr
@@ -221,7 +227,7 @@ instance
     liftM (defLet defs') (body next)
 instance
   ( Eq (InputToken inp)
-  , Cursorable (Cursor inp)
+  , Positionable (InputPosition inp)
   , InstrBranchable repr
   , InstrExceptionable repr
   , InstrInputable repr
@@ -233,17 +239,23 @@ instance
   ) => CombLookable (Program repr inp) where
   look (Program x) = Program $ \next ->
     liftM (comment "look") $
-    liftM pushInput (x (swapValue (loadInput next)))
+    liftM saveInput $
+    x $
+    swapValue $
+    loadInput next
   eof =
-    negLook (satisfy (Prod.const Prod..@ Prod.bool True))
+    negLook (satisfy (Prod.const Prod..@ Prod.constant True))
       -- This sets a better failure message
       <|> (Program $ \_next ->
-        return $ comment "eof.fail" $ fail (Set.singleton (SomeFailure FailureEnd)))
+        return $
+          comment "eof.fail" $
+          fail (Set.singleton (SomeFailure FailureEnd)))
   negLook (Program x) = Program $ \next ->
     liftM (comment "negLook") $
     liftM2 (catch ExceptionFailure)
       -- On x success, discard the result,
-      -- and replace this 'Catcher' by a failure whose 'farthestExpecting' is negated,
+      -- and replace this 'OnException' by a failure
+      -- whose 'farthestExpecting' is negated,
       -- then a failure is raised from the input
       -- when entering 'negLook', to avoid odd cases:
       -- - where the failure that made (negLook x)
@@ -255,15 +267,20 @@ instance
       --   and (negLook x) fail.
       (
         liftM (comment "negLook.ahead") $
-        liftM pushInput $ x $
-        popValue $ commit ExceptionFailure $
-          loadInput $ fail Set.empty
+        liftM saveInput $
+        x $
+        popValue $
+        commit ExceptionFailure $
+        loadInput $
+        fail Set.empty
       )
-      -- On x failure, reset the input,
+      -- On the failure of x: reset the input,
       -- and go on with the next 'Instr'uctions.
       (
         liftM (comment "negLook.reset") $
-        return $ loadInput $ pushValue Prod.unit next
+        return $
+          loadInput $
+          pushValue Prod.unit next
       )
 instance
   ( InstrBranchable repr
@@ -280,7 +297,7 @@ instance
   ) => CombSatisfiable tok (Program repr inp) where
   satisfyOrFail fs p = Program $ \next ->
     return $
-      comment "satisfy" $
+      comment ("satisfy "<>showsPrec 11 (prodCode p) "") $
       read fs (prodCode p) next
 instance
   ( InstrBranchable repr