infix decl

This commit is contained in:
crumbtoo
2024-01-09 11:39:26 -07:00
parent cb7cdf7ed7
commit 37d9e6f219
4 changed files with 74 additions and 3 deletions

View File

@@ -63,7 +63,7 @@ library
-- TODO: either learn recursion-schemes, or stop depending -- TODO: either learn recursion-schemes, or stop depending
-- on it. -- on it.
, recursion-schemes , recursion-schemes
, megaparsec , megaparsec ^>=9.6.0
, text , text
, data-fix , data-fix

View File

@@ -24,6 +24,7 @@ import Data.Functor
import Data.Functor.Const import Data.Functor.Const
import Data.Fix hiding (cata) import Data.Fix hiding (cata)
import Lens.Micro import Lens.Micro
import Lens.Micro.Platform
import Rlp.Parse.Types import Rlp.Parse.Types
import Rlp.Syntax import Rlp.Syntax
---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------
@@ -128,7 +129,40 @@ isVarSym = (`T.elem` "\\!#$%&*+./<=>?@^|-~")
isSym :: Char -> Bool isSym :: Char -> Bool
isSym c = c == ':' || isVarSym c isSym c = c == ':' || isVarSym c
infixD = undefined infixD :: Parser (Decl' e)
infixD = do
o <- getOffset
a <- infixWord
p <- prec
op <- infixOp
region (setErrorOffset o) $ updateOpTable a p op
pure $ InfixD a p op
where
infixWord :: Parser Assoc
infixWord = choice $ lexeme <$>
[ "infixr" $> InfixR
, "infixl" $> InfixL
, "infix" $> Infix
]
prec :: Parser Int
prec = do
o <- getOffset
n <- lexeme L.decimal
if 0 <= n && n <= 9 then
pure n
else
region (setErrorOffset o) $
registerCustomFailure (RlpParErrOutOfBoundsPrecedence n)
$> 9
updateOpTable :: Assoc -> Int -> Name -> Parser ()
updateOpTable a p op = do
t <- use psOpTable
psOpTable <~ H.alterF f op t
where
f Nothing = pure (Just (a,p))
f (Just _) = customFailure RlpParErrDuplicateInfixD
tySigD = undefined tySigD = undefined
dataD = undefined dataD = undefined

View File

@@ -1,3 +1,5 @@
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE ImplicitParams, ViewPatterns, PatternSynonyms #-} {-# LANGUAGE ImplicitParams, ViewPatterns, PatternSynonyms #-}
{- {-
Description : Supporting types for the parser Description : Supporting types for the parser
@@ -16,8 +18,13 @@ module Rlp.Parse.Types
-- * Parser types -- * Parser types
, Parser , Parser
, ParserState(..) , ParserState(..)
, psOpTable
, RlpParseError(..)
, OpTable , OpTable
, OpInfo , OpInfo
-- * Extras
, registerCustomFailure
) )
where where
---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------
@@ -29,14 +36,17 @@ import Data.Functor.Const
import Data.Functor.Classes import Data.Functor.Classes
import Data.Void import Data.Void
import Data.Maybe import Data.Maybe
import Data.Set qualified as S
import Text.Megaparsec hiding (State) import Text.Megaparsec hiding (State)
import Text.Printf
import Lens.Micro import Lens.Micro
import Lens.Micro.TH
import Rlp.Syntax import Rlp.Syntax
---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------
-- parser types -- parser types
type Parser = ParsecT Void Text (State ParserState) type Parser = ParsecT RlpParseError Text (State ParserState)
data ParserState = ParserState data ParserState = ParserState
{ _psOpTable :: OpTable { _psOpTable :: OpTable
@@ -46,6 +56,23 @@ data ParserState = ParserState
type OpTable = H.HashMap Name OpInfo type OpTable = H.HashMap Name OpInfo
type OpInfo = (Assoc, Int) type OpInfo = (Assoc, Int)
-- data WithLocation a = WithLocation [String] a
data RlpParseError = RlpParErrOutOfBoundsPrecedence Int
| RlpParErrDuplicateInfixD
deriving (Eq, Ord, Show)
instance ShowErrorComponent RlpParseError where
showErrorComponent = \case
-- TODO: wrap text to 80 characters
RlpParErrOutOfBoundsPrecedence n ->
printf "%d is an invalid precedence level! rl' currently only\
\allows custom precedences between 0 and 9 (inclusive).\
\ This is an arbitrary limit put in place for legibility\
\ concerns, and may change in the future." n
RlpParErrDuplicateInfixD ->
"duplicate infix decl"
---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------
-- absolute psycho shit (partial ASTs) -- absolute psycho shit (partial ASTs)
@@ -90,3 +117,10 @@ instance Show1 Partial where
type PartialExpr' = Fix Partial type PartialExpr' = Fix Partial
----------------------------------------------------------------------------------
makeLenses ''ParserState
registerCustomFailure :: MonadParsec e s m => e -> m ()
registerCustomFailure = registerFancyFailure . S.singleton . ErrorCustom

View File

@@ -9,6 +9,7 @@ module Rlp.Syntax
, RlpExprF(..) , RlpExprF(..)
, RlpExprF' , RlpExprF'
, Decl(..) , Decl(..)
, Decl'
, Assoc(..) , Assoc(..)
, VarId(..) , VarId(..)
, Pat(..) , Pat(..)
@@ -50,6 +51,8 @@ data Decl e b = FunD VarId [Pat b] (e b)
| InfixD Assoc Int Name | InfixD Assoc Int Name
deriving Show deriving Show
type Decl' e = Decl e Name
data Assoc = InfixL data Assoc = InfixL
| InfixR | InfixR
| Infix | Infix