more parser goodness
This commit is contained in:
parent
b236bb1753
commit
6ab03dd6c6
4 changed files with 43 additions and 31 deletions
|
|
@ -33,7 +33,6 @@ findType g (Var x n) = do
|
||||||
validateType g t
|
validateType g t
|
||||||
pure t
|
pure t
|
||||||
findType _ (Free n) = envLookupTy n
|
findType _ (Free n) = envLookupTy n
|
||||||
findType _ (Axiom n) = envLookupTy n
|
|
||||||
findType g e@(App m n) = do
|
findType g e@(App m n) = do
|
||||||
(a, b) <- findType g m >>= matchPi m
|
(a, b) <- findType g m >>= matchPi m
|
||||||
a' <- findType g n
|
a' <- findType g n
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ module Expr where
|
||||||
data Expr where
|
data Expr where
|
||||||
Var :: Text -> Integer -> Expr
|
Var :: Text -> Integer -> Expr
|
||||||
Free :: Text -> Expr
|
Free :: Text -> Expr
|
||||||
Axiom :: Text -> Expr
|
|
||||||
Level :: Integer -> Expr
|
Level :: Integer -> Expr
|
||||||
App :: Expr -> Expr -> Expr
|
App :: Expr -> Expr -> Expr
|
||||||
Abs :: Text -> Expr -> Expr -> Expr
|
Abs :: Text -> Expr -> Expr -> Expr
|
||||||
|
|
@ -14,7 +13,6 @@ data Expr where
|
||||||
instance Eq Expr where
|
instance Eq Expr where
|
||||||
(Var _ n) == (Var _ m) = n == m
|
(Var _ n) == (Var _ m) = n == m
|
||||||
(Free s) == (Free t) = s == t
|
(Free s) == (Free t) = s == t
|
||||||
(Axiom a) == (Axiom b) = a == b
|
|
||||||
(Level i) == (Level j) = i == j
|
(Level i) == (Level j) = i == j
|
||||||
(App e1 e2) == (App f1 f2) = e1 == f1 && e2 == f2
|
(App e1 e2) == (App f1 f2) = e1 == f1 && e2 == f2
|
||||||
(Abs _ t1 b1) == (Abs _ t2 b2) = t1 == t2 && b1 == b2
|
(Abs _ t1 b1) == (Abs _ t2 b2) = t1 == t2 && b1 == b2
|
||||||
|
|
@ -25,7 +23,6 @@ instance Eq Expr where
|
||||||
occursFree :: Integer -> Expr -> Bool
|
occursFree :: Integer -> Expr -> Bool
|
||||||
occursFree n (Var _ k) = n == k
|
occursFree n (Var _ k) = n == k
|
||||||
occursFree _ (Free _) = False
|
occursFree _ (Free _) = False
|
||||||
occursFree _ (Axiom _) = False
|
|
||||||
occursFree _ (Level _) = False
|
occursFree _ (Level _) = False
|
||||||
occursFree n (App a b) = on (||) (occursFree n) a b
|
occursFree n (App a b) = on (||) (occursFree n) a b
|
||||||
occursFree n (Abs _ a b) = occursFree n a || occursFree (n + 1) b
|
occursFree n (Abs _ a b) = occursFree n a || occursFree (n + 1) b
|
||||||
|
|
@ -37,7 +34,6 @@ shiftIndices d c (Var x k)
|
||||||
| k >= c = Var x (k + d)
|
| k >= c = Var x (k + d)
|
||||||
| otherwise = Var x k
|
| otherwise = Var x k
|
||||||
shiftIndices _ _ (Free s) = Free s
|
shiftIndices _ _ (Free s) = Free s
|
||||||
shiftIndices _ _ (Axiom s) = Axiom s
|
|
||||||
shiftIndices _ _ (Level i) = Level i
|
shiftIndices _ _ (Level i) = Level i
|
||||||
shiftIndices d c (App m n) = App (shiftIndices d c m) (shiftIndices d c n)
|
shiftIndices d c (App m n) = App (shiftIndices d c m) (shiftIndices d c n)
|
||||||
shiftIndices d c (Abs x m n) = Abs x (shiftIndices d c m) (shiftIndices d (c + 1) n)
|
shiftIndices d c (Abs x m n) = Abs x (shiftIndices d c m) (shiftIndices d (c + 1) n)
|
||||||
|
|
@ -109,7 +105,6 @@ showBinding (ident, params, val) =
|
||||||
helper :: Integer -> Expr -> Text
|
helper :: Integer -> Expr -> Text
|
||||||
helper _ (Var s _) = s
|
helper _ (Var s _) = s
|
||||||
helper _ (Free s) = s
|
helper _ (Free s) = s
|
||||||
helper _ (Axiom s) = s
|
|
||||||
helper _ (Level i)
|
helper _ (Level i)
|
||||||
| i == 0 = "*"
|
| i == 0 = "*"
|
||||||
| otherwise = "*" <> show i
|
| otherwise = "*" <> show i
|
||||||
|
|
|
||||||
19
lib/IR.hs
19
lib/IR.hs
|
|
@ -8,7 +8,6 @@ type Param = (Text, IRExpr)
|
||||||
|
|
||||||
data IRExpr
|
data IRExpr
|
||||||
= Var {_varName :: Text}
|
= Var {_varName :: Text}
|
||||||
| Axiom
|
|
||||||
| Level {_level :: Integer}
|
| Level {_level :: Integer}
|
||||||
| App
|
| App
|
||||||
{ _appFunc :: IRExpr
|
{ _appFunc :: IRExpr
|
||||||
|
|
@ -34,11 +33,17 @@ data IRExpr
|
||||||
|
|
||||||
makeLenses ''IRExpr
|
makeLenses ''IRExpr
|
||||||
|
|
||||||
data IRDef = Def
|
data IRDef
|
||||||
{ _defName :: Text
|
= Def
|
||||||
, _defParams :: [Param]
|
{ _defName :: Text
|
||||||
, _defAscription :: Maybe IRExpr
|
, _defParams :: [Param]
|
||||||
, _defBody :: IRExpr
|
, _defAscription :: Maybe IRExpr
|
||||||
}
|
, _defBody :: IRExpr
|
||||||
|
}
|
||||||
|
| Axiom
|
||||||
|
{ _axiomName :: Text
|
||||||
|
, _axiomParams :: [Param]
|
||||||
|
, _axiomAscription :: IRExpr
|
||||||
|
}
|
||||||
|
|
||||||
type IRProgram = [IRDef]
|
type IRProgram = [IRDef]
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,13 @@
|
||||||
module Parser where
|
module Parser where
|
||||||
|
|
||||||
import Control.Monad.Except
|
import Control.Monad.Except
|
||||||
|
import Data.Char
|
||||||
import Data.List (foldl1)
|
import Data.List (foldl1)
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import Errors (Error (..))
|
import Errors (Error (..))
|
||||||
import IR
|
import IR
|
||||||
import Preprocessor
|
import Preprocessor
|
||||||
import Text.Megaparsec (Parsec, ShowErrorComponent (..), between, choice, chunk, errorBundlePretty, label, runParser, try)
|
import Text.Megaparsec (Parsec, ShowErrorComponent (..), between, choice, chunk, errorBundlePretty, label, runParser, satisfy, try)
|
||||||
import Text.Megaparsec.Char
|
import Text.Megaparsec.Char
|
||||||
import qualified Text.Megaparsec.Char.Lexer as L
|
import qualified Text.Megaparsec.Char.Lexer as L
|
||||||
|
|
||||||
|
|
@ -34,17 +35,19 @@ eat :: Text -> Parser ()
|
||||||
eat = void . lexeme . chunk
|
eat = void . lexeme . chunk
|
||||||
|
|
||||||
keywords :: [Text]
|
keywords :: [Text]
|
||||||
keywords = ["forall", "let", "in", "end", "fun"]
|
keywords = ["forall", "let", "in", "end", "fun", "def", "axiom"]
|
||||||
|
|
||||||
|
reservedChars :: [Char]
|
||||||
|
reservedChars = "();:"
|
||||||
|
|
||||||
pIdentifier :: Parser Text
|
pIdentifier :: Parser Text
|
||||||
pIdentifier = try $ label "identifier" $ lexeme $ do
|
pIdentifier = try $ label "identifier" $ lexeme $ do
|
||||||
firstChar <- letterChar <|> char '_'
|
chars <- many $ satisfy isAllowed
|
||||||
rest <- many $ alphaNumChar <|> char '_'
|
let ident = T.pack chars
|
||||||
let ident = T.pack (firstChar : rest)
|
when (ident `elem` keywords) $ fail $ "Reserved word: " ++ T.unpack ident
|
||||||
when (ident `elem` keywords) $
|
|
||||||
fail $
|
|
||||||
"Reserved word: " ++ T.unpack ident
|
|
||||||
pure ident
|
pure ident
|
||||||
|
where
|
||||||
|
isAllowed c = isLetter c || isNumber c || c == '_' || isSymbol c && c `notElem` reservedChars
|
||||||
|
|
||||||
pVar :: Parser IRExpr
|
pVar :: Parser IRExpr
|
||||||
pVar = label "variable" $ lexeme $ Var <$> pIdentifier
|
pVar = label "variable" $ lexeme $ Var <$> pIdentifier
|
||||||
|
|
@ -86,7 +89,7 @@ pBinding = lexeme $ label "binding" $ do
|
||||||
eat "("
|
eat "("
|
||||||
ident <- pIdentifier
|
ident <- pIdentifier
|
||||||
params <- pManyParams
|
params <- pManyParams
|
||||||
ascription <- pAscription
|
ascription <- optional pAscription
|
||||||
eat ":="
|
eat ":="
|
||||||
value <- pIRExpr
|
value <- pIRExpr
|
||||||
eat ")"
|
eat ")"
|
||||||
|
|
@ -126,20 +129,31 @@ pNumSort = lexeme $ label "sort" $ eat "*" >> Level <$> L.decimal
|
||||||
pSort :: Parser IRExpr
|
pSort :: Parser IRExpr
|
||||||
pSort = try pNumSort <|> pStar
|
pSort = try pNumSort <|> pStar
|
||||||
|
|
||||||
pAxiom :: Parser IRExpr
|
pAxiom :: Parser IRDef
|
||||||
pAxiom = Axiom <$ eat "axiom"
|
pAxiom = lexeme $ label "axiom" $ do
|
||||||
|
|
||||||
pIRDef :: Parser IRDef
|
|
||||||
pIRDef = lexeme $ label "definition" $ do
|
|
||||||
skipSpace
|
skipSpace
|
||||||
|
eat "def"
|
||||||
ident <- pIdentifier
|
ident <- pIdentifier
|
||||||
params <- pManyParams
|
params <- pManyParams
|
||||||
ascription <- fmap (flip (foldr (uncurry Pi)) params) <$> pAscription
|
ascription <- fmap (flip (foldr (uncurry Pi)) params) pAscription
|
||||||
|
eat ";"
|
||||||
|
pure $ Axiom ident params ascription
|
||||||
|
|
||||||
|
pDef :: Parser IRDef
|
||||||
|
pDef = lexeme $ label "definition" $ do
|
||||||
|
skipSpace
|
||||||
|
eat "def"
|
||||||
|
ident <- pIdentifier
|
||||||
|
params <- pManyParams
|
||||||
|
ascription <- fmap (flip (foldr (uncurry Pi)) params) <$> optional pAscription
|
||||||
eat ":="
|
eat ":="
|
||||||
body <- pIRExpr
|
body <- pIRExpr
|
||||||
eat ";"
|
eat ";"
|
||||||
pure $ Def ident params ascription body
|
pure $ Def ident params ascription body
|
||||||
|
|
||||||
|
pIRDef :: Parser IRDef
|
||||||
|
pIRDef = pDef <|> pAxiom
|
||||||
|
|
||||||
pTerm :: Parser IRExpr
|
pTerm :: Parser IRExpr
|
||||||
pTerm =
|
pTerm =
|
||||||
lexeme $
|
lexeme $
|
||||||
|
|
@ -147,7 +161,6 @@ pTerm =
|
||||||
choice
|
choice
|
||||||
[ between (char '(') (char ')') pIRExpr
|
[ between (char '(') (char ')') pIRExpr
|
||||||
, pSort
|
, pSort
|
||||||
, pAxiom
|
|
||||||
, pVar
|
, pVar
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -164,8 +177,8 @@ pAppTerm =
|
||||||
pIRExpr :: Parser IRExpr
|
pIRExpr :: Parser IRExpr
|
||||||
pIRExpr = lexeme $ try pArrow <|> pAppTerm
|
pIRExpr = lexeme $ try pArrow <|> pAppTerm
|
||||||
|
|
||||||
pAscription :: Parser (Maybe IRExpr)
|
pAscription :: Parser IRExpr
|
||||||
pAscription = lexeme $ optional $ try $ eat ":" >> label "type" pIRExpr
|
pAscription = lexeme $ try $ eat ":" >> label "type" pIRExpr
|
||||||
|
|
||||||
pIRProgram :: Parser IRProgram
|
pIRProgram :: Parser IRProgram
|
||||||
pIRProgram = many pIRDef
|
pIRProgram = many pIRDef
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue