{ module Presyntax.Parser where import qualified Data.Text as T import Data.Text (Text) import Presyntax.Presyntax import Presyntax.Tokens import Presyntax.Lexer import Prelude hiding (span) } %name parseExp Exp %name parseStmt Statement %name parseProg Program %tokentype { Token } %monad { Alex } %lexer { lexer } { Token TokEof _ _ } %errorhandlertype explist %error { parseError } %token var { $$@(Token (TokVar _) _ _) } '(' { Token TokOParen _ _ } ')' { Token TokCParen _ _ } '{' { Token TokOBrace _ _ } '}' { Token TokCBrace _ _ } '\\' { Token TokLambda _ _ } '->' { Token TokArrow _ _ } ':' { Token TokColon _ _ } ';' { Token TokSemi _ _ } '=' { Token TokEqual _ _ } ',' { Token TokComma _ _ } '*' { Token TokStar _ _ } '.1' { Token TokPi1 _ _ } '.2' { Token TokPi2 _ _ } %% Exp :: { Expr } Exp : Exp ExpProj { span $1 $2 $ App Ex $1 $2 } | Exp '{' Exp '}' { span $1 $4 $ App Im $1 $3 } | '\\' LambdaList '->' Exp { span $1 $4 $ makeLams $2 $4 } | '(' VarList ':' Exp ')' ProdTail { span $1 $6 $ makePis Ex $2 $4 $6 } | '{' VarList ':' Exp '}' ProdTail { span $1 $6 $ makePis Im $2 $4 $6 } | ExpProj '->' Exp { span $1 $3 $ Pi Ex (T.singleton '_') $1 $3 } | '(' VarList ':' Exp ')' '*' Exp { span $1 $7 $ makeSigmas $2 $4 $7 } | ExpProj '*' Exp { span $1 $3 $ Sigma (T.singleton '_') $1 $3 } | ExpProj { $1 } ProdTail :: { Expr } : '(' VarList ':' Exp ')' ProdTail { span $1 $6 $ makePis Ex $2 $4 $6 } | '{' VarList ':' Exp '}' ProdTail { span $1 $6 $ makePis Im $2 $4 $6 } | '->' Exp { span $2 $2 $ $2 } LambdaList :: { [(Plicity, Text)] } : var { [(Ex, getVar $1)] } | var LambdaList { (Ex, getVar $1):$2 } | '{'var'}' { [(Im, getVar $2)] } | '{'var'}' LambdaList { (Im, getVar $2):$4 } LhsList :: { [(Plicity, Text)] } : { [] } | LambdaList { $1 } VarList :: { [Text] } : var { [getVar $1] } | var VarList { getVar $1:$2 } ExpProj :: { Expr } : ExpProj '.1' { span $1 $2 $ Proj1 $1 } | ExpProj '.2' { span $1 $2 $ Proj2 $1 } | Atom { $1 } Atom :: { Expr } : var { span $1 $1 $ Var (getVar $1) } | '(' Tuple ')' { span $1 $3 $ $2 } Tuple :: { Expr } : Exp { $1 } | Exp ',' Tuple { span $1 $3 $ Pair $1 $3 } Statement :: { Statement } : var ':' Exp { Decl (getVar $1) $3 } | var LhsList '=' Exp { Defn (getVar $1) (makeLams $2 $4) } Program :: { [Statement] } : Statement { [$1] } | Statement ';' Program { $1:$3 } { lexer cont = alexMonadScan >>= cont parseError x = alexError (show x) makeLams xs b = foldr (uncurry Lam) b xs makePis p xs t b = foldr (flip (Pi p) t) b xs makeSigmas xs t b = foldr (flip Sigma t) b xs class HasPosn a where startPosn :: a -> Posn endPosn :: a -> Posn instance HasPosn Token where startPosn (Token _ l c) = Posn l c endPosn (Token t l c) = Posn l (c + tokSize t) instance HasPosn Expr where startPosn (Span _ s _) = s startPosn _ = error "no start posn in parsed expression?" endPosn (Span _ _ e) = e endPosn _ = error "no end posn in parsed expression?" span s e ex = Span ex (startPosn s) (endPosn e) getVar (Token (TokVar s) _ _) = s getVar _ = error "getVar non-var" }