some
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE PatternSynonyms, ViewPatterns, ImplicitParams #-}
|
||||
module Rlp.Parse.Associate
|
||||
{-# WARNING "temporarily unimplemented" #-}
|
||||
( associate
|
||||
)
|
||||
where
|
||||
@@ -13,88 +14,6 @@ import Rlp.Parse.Types
|
||||
import Rlp.Syntax
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
associate :: OpTable -> PartialDecl' -> Decl' RlpExpr
|
||||
associate pt (FunD n as b w) = FunD n as b' w
|
||||
where b' = let ?pt = pt in completeExpr (getConst b)
|
||||
associate pt (TySigD ns t) = TySigD ns t
|
||||
associate pt (DataD n as cs) = DataD n as cs
|
||||
associate pt (InfixD a p n) = InfixD a p n
|
||||
|
||||
completeExpr :: (?pt :: OpTable) => PartialExpr' -> RlpExpr'
|
||||
completeExpr = cata completePartial
|
||||
|
||||
completePartial :: (?pt :: OpTable) => PartialE -> RlpExpr'
|
||||
completePartial (E e) = completeRlpExpr e
|
||||
completePartial p@(B o l r) = completeB (build p)
|
||||
completePartial (Par e) = completePartial e
|
||||
|
||||
completeRlpExpr :: (?pt :: OpTable) => RlpExprF' RlpExpr' -> RlpExpr'
|
||||
completeRlpExpr = embed
|
||||
|
||||
completeB :: (?pt :: OpTable) => PartialE -> RlpExpr'
|
||||
completeB p = case build p of
|
||||
B o l r -> (o' `AppE` l') `AppE` r'
|
||||
where
|
||||
-- TODO: how do we know it's symbolic?
|
||||
o' = VarE (SymVar o)
|
||||
l' = completeB l
|
||||
r' = completeB r
|
||||
Par e -> completeB e
|
||||
E e -> completeRlpExpr e
|
||||
|
||||
build :: (?pt :: OpTable) => PartialE -> PartialE
|
||||
build e = go id e (rightmost e) where
|
||||
rightmost :: PartialE -> PartialE
|
||||
rightmost (B _ _ r) = rightmost r
|
||||
rightmost p@(E _) = p
|
||||
rightmost p@(Par _) = p
|
||||
|
||||
go :: (?pt :: OpTable)
|
||||
=> (PartialE -> PartialE)
|
||||
-> PartialE -> PartialE -> PartialE
|
||||
go f p@(WithInfo o _ r) = case r of
|
||||
E _ -> mkHole o (f . f')
|
||||
Par _ -> mkHole o (f . f')
|
||||
B _ _ _ -> go (mkHole o (f . f')) r
|
||||
where f' r' = p & pR .~ r'
|
||||
go f _ = id
|
||||
|
||||
mkHole :: (?pt :: OpTable)
|
||||
=> OpInfo
|
||||
-> (PartialE -> PartialE)
|
||||
-> PartialE
|
||||
-> PartialE
|
||||
mkHole _ hole p@(Par _) = hole p
|
||||
mkHole _ hole p@(E _) = hole p
|
||||
mkHole (a,d) hole p@(WithInfo (a',d') _ _)
|
||||
| d' < d = above
|
||||
| d' > d = below
|
||||
| d == d' = case (a,a') of
|
||||
-- left-associative operators of equal precedence are
|
||||
-- associated left
|
||||
(InfixL,InfixL) -> above
|
||||
-- right-associative operators are handled similarly
|
||||
(InfixR,InfixR) -> below
|
||||
-- non-associative operators of equal precedence, or equal
|
||||
-- precedence operators of different associativities are
|
||||
-- invalid
|
||||
(_, _) -> error "invalid expression"
|
||||
where
|
||||
above = p & pL %~ hole
|
||||
below = hole p
|
||||
|
||||
examplePrecTable :: OpTable
|
||||
examplePrecTable = H.fromList
|
||||
[ ("+", (InfixL,6))
|
||||
, ("*", (InfixL,7))
|
||||
, ("^", (InfixR,8))
|
||||
, (".", (InfixR,7))
|
||||
, ("~", (Infix, 9))
|
||||
, ("=", (Infix, 4))
|
||||
, ("&&", (Infix, 3))
|
||||
, ("||", (Infix, 2))
|
||||
, ("$", (InfixR,0))
|
||||
, ("&", (InfixL,0))
|
||||
]
|
||||
|
||||
associate = undefined
|
||||
{-# WARNING associate "temporarily undefined" #-}
|
||||
|
||||
|
||||
@@ -2,38 +2,24 @@
|
||||
{-# LANGUAGE ImplicitParams, ViewPatterns, PatternSynonyms #-}
|
||||
{-# LANGUAGE LambdaCase #-}
|
||||
module Rlp.Parse.Types
|
||||
( LexerAction
|
||||
, MsgEnvelope(..)
|
||||
, RlpcError(..)
|
||||
, AlexInput(..)
|
||||
, Position(..)
|
||||
, RlpToken(..)
|
||||
, P(..)
|
||||
, ParseState(..)
|
||||
, psLayoutStack
|
||||
, psLexState
|
||||
, psInput
|
||||
, psOpTable
|
||||
, Layout(..)
|
||||
, Located(..)
|
||||
, OpTable
|
||||
, OpInfo
|
||||
, RlpParseError(..)
|
||||
, PartialDecl'
|
||||
, Partial(..)
|
||||
, pL, pR
|
||||
, PartialE
|
||||
, pattern WithInfo
|
||||
, opInfoOrDef
|
||||
, PartialExpr'
|
||||
, aiPrevChar
|
||||
, aiSource
|
||||
, aiBytes
|
||||
, aiPos
|
||||
, addFatal
|
||||
, addWound
|
||||
, addFatalHere
|
||||
, addWoundHere
|
||||
(
|
||||
-- * Trees That Grow
|
||||
RlpcPs
|
||||
|
||||
-- * Parser monad and state
|
||||
, P(..), ParseState(..), Layout(..), OpTable, OpInfo
|
||||
-- ** Lenses
|
||||
, psLayoutStack, psLexState, psInput, psOpTable
|
||||
|
||||
-- * Other parser types
|
||||
, RlpToken(..), AlexInput(..), Position(..), spanFromPos, LexerAction
|
||||
, Located(..), PsName
|
||||
-- ** Lenses
|
||||
, aiPrevChar, aiSource, aiBytes, aiPos, posLine, posColumn
|
||||
|
||||
-- * Error handling
|
||||
, MsgEnvelope(..), RlpcError(..), RlpParseError(..)
|
||||
, addFatal, addWound, addFatalHere, addWoundHere
|
||||
)
|
||||
where
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -49,12 +35,26 @@ import Data.Functor.Foldable
|
||||
import Data.Functor.Const
|
||||
import Data.Functor.Classes
|
||||
import Data.HashMap.Strict qualified as H
|
||||
import Data.Void
|
||||
import Data.Word (Word8)
|
||||
import Lens.Micro.TH
|
||||
import Lens.Micro
|
||||
import Rlp.Syntax
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
-- | Phantom type identifying rlpc's parser phase
|
||||
|
||||
data RlpcPs
|
||||
|
||||
type instance XRec RlpcPs f = Located (f RlpcPs)
|
||||
type instance IdP RlpcPs = PsName
|
||||
|
||||
type instance XInfixD RlpcPs = ()
|
||||
|
||||
type PsName = Text
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
type LexerAction a = AlexInput -> Int -> P a
|
||||
|
||||
data AlexInput = AlexInput
|
||||
@@ -106,7 +106,7 @@ data RlpToken
|
||||
| TokenLParen
|
||||
| TokenRParen
|
||||
-- 'virtual' control symbols, inserted by the lexer without any correlation
|
||||
-- to a specific symbol
|
||||
-- to a specific part of the input
|
||||
| TokenSemicolonV
|
||||
| TokenLBraceV
|
||||
| TokenRBraceV
|
||||
@@ -154,8 +154,14 @@ data Layout = Explicit
|
||||
| Implicit Int
|
||||
deriving (Show, Eq)
|
||||
|
||||
data Located a = Located (Position, Int) a
|
||||
deriving (Show)
|
||||
-- | Token wrapped with a span (line, column, length)
|
||||
data Located a = Located !(Int, Int, Int) a
|
||||
deriving (Show, Functor)
|
||||
|
||||
spanFromPos :: Position -> Int -> (Int, Int, Int)
|
||||
spanFromPos (l,c) s = (l,c,s)
|
||||
|
||||
{-# INLINE spanFromPos #-}
|
||||
|
||||
type OpTable = H.HashMap Name OpInfo
|
||||
type OpInfo = (Assoc, Int)
|
||||
@@ -171,47 +177,6 @@ data RlpParseError = RlpParErrOutOfBoundsPrecedence Int
|
||||
instance IsRlpcError RlpParseError where
|
||||
|
||||
----------------------------------------------------------------------------------
|
||||
-- absolute psycho shit (partial ASTs)
|
||||
|
||||
type PartialDecl' = Decl (Const PartialExpr') Name
|
||||
|
||||
data Partial a = E (RlpExprF Name a)
|
||||
| B Name (Partial a) (Partial a)
|
||||
| Par (Partial a)
|
||||
deriving (Show, Functor)
|
||||
|
||||
pL :: Traversal' (Partial a) (Partial a)
|
||||
pL k (B o l r) = (\l' -> B o l' r) <$> k l
|
||||
pL _ x = pure x
|
||||
|
||||
pR :: Traversal' (Partial a) (Partial a)
|
||||
pR k (B o l r) = (\r' -> B o l r') <$> k r
|
||||
pR _ x = pure x
|
||||
|
||||
type PartialE = Partial RlpExpr'
|
||||
|
||||
-- i love you haskell
|
||||
pattern WithInfo :: (?pt :: OpTable) => OpInfo -> PartialE -> PartialE -> PartialE
|
||||
pattern WithInfo p l r <- B (opInfoOrDef -> p) l r
|
||||
|
||||
opInfoOrDef :: (?pt :: OpTable) => Name -> OpInfo
|
||||
opInfoOrDef c = fromMaybe (InfixL,9) $ H.lookup c ?pt
|
||||
|
||||
-- required to satisfy constraint on Fix's show instance
|
||||
instance Show1 Partial where
|
||||
liftShowsPrec :: forall a. (Int -> a -> ShowS)
|
||||
-> ([a] -> ShowS)
|
||||
-> Int -> Partial a -> ShowS
|
||||
|
||||
liftShowsPrec sp sl p m = case m of
|
||||
(E e) -> showsUnaryWith lshow "E" p e
|
||||
(B f a b) -> showsTernaryWith showsPrec lshow lshow "B" p f a b
|
||||
(Par e) -> showsUnaryWith lshow "Par" p e
|
||||
where
|
||||
lshow :: forall f. (Show1 f) => Int -> f a -> ShowS
|
||||
lshow = liftShowsPrec sp sl
|
||||
|
||||
type PartialExpr' = Fix Partial
|
||||
|
||||
makeLenses ''AlexInput
|
||||
makeLenses ''ParseState
|
||||
|
||||
Reference in New Issue
Block a user