238 lines
8.2 KiB
Plaintext
238 lines
8.2 KiB
Plaintext
{
|
||
module Rlp.AltParse
|
||
( parseRlpProg
|
||
, parseRlpProgR
|
||
, parseRlpExprR
|
||
, runP'
|
||
)
|
||
where
|
||
import Data.List.Extra
|
||
import Data.Text (Text)
|
||
|
||
import Control.Comonad
|
||
import Control.Comonad.Cofree
|
||
import Control.Lens hiding (snoc)
|
||
|
||
import Compiler.RlpcError
|
||
import Compiler.RLPC
|
||
import Control.Monad.Errorful
|
||
|
||
import Rlp.Lex
|
||
import Rlp.AltSyntax
|
||
import Rlp.Parse.Types hiding (PsName)
|
||
import Core.Syntax qualified as Core
|
||
}
|
||
|
||
%name parseRlpProg StandaloneProgram
|
||
%name parseRlpExpr StandaloneExpr
|
||
|
||
%monad { P }
|
||
%lexer { lexCont } { Located _ TokenEOF }
|
||
%error { parseError }
|
||
%errorhandlertype explist
|
||
%tokentype { Located RlpToken }
|
||
|
||
%token
|
||
varname { Located _ (TokenVarName _) }
|
||
conname { Located _ (TokenConName _) }
|
||
consym { Located _ (TokenConSym _) }
|
||
varsym { Located _ (TokenVarSym _) }
|
||
data { Located _ TokenData }
|
||
case { Located _ TokenCase }
|
||
of { Located _ TokenOf }
|
||
litint { Located _ (TokenLitInt _) }
|
||
'=' { Located _ TokenEquals }
|
||
'|' { Located _ TokenPipe }
|
||
'::' { Located _ TokenHasType }
|
||
';' { Located _ TokenSemicolon }
|
||
'λ' { Located _ TokenLambda }
|
||
'(' { Located _ TokenLParen }
|
||
')' { Located _ TokenRParen }
|
||
'->' { Located _ TokenArrow }
|
||
vsemi { Located _ TokenSemicolonV }
|
||
'{' { Located _ TokenLBrace }
|
||
'}' { Located _ TokenRBrace }
|
||
vlbrace { Located _ TokenLBraceV }
|
||
vrbrace { Located _ TokenRBraceV }
|
||
infixl { Located _ TokenInfixL }
|
||
infixr { Located _ TokenInfixR }
|
||
infix { Located _ TokenInfix }
|
||
let { Located _ TokenLet }
|
||
letrec { Located _ TokenLetrec }
|
||
in { Located _ TokenIn }
|
||
forall { Located _ TokenForall }
|
||
|
||
%nonassoc '='
|
||
%right '->'
|
||
%right in
|
||
|
||
%%
|
||
|
||
StandaloneProgram :: { Program Name (RlpExpr PsName) }
|
||
: layout0(Decl) { Program $1 }
|
||
|
||
|
||
StandaloneExpr :: { RlpExpr PsName }
|
||
: VL Expr VR { $2 }
|
||
|
||
VL :: { () }
|
||
VL : vlbrace { () }
|
||
|
||
VR :: { () }
|
||
VR : vrbrace { () }
|
||
| error { () }
|
||
|
||
VS :: { () }
|
||
VS : ';' { () }
|
||
| vsemi { () }
|
||
|
||
Decl :: { Decl PsName (RlpExpr PsName) }
|
||
: FunD { $1 }
|
||
| DataD { $1 }
|
||
| TySigD { $1 }
|
||
|
||
TySigD :: { Decl PsName (RlpExpr PsName) }
|
||
: Var '::' Type { TySigD $1 $3 }
|
||
|
||
DataD :: { Decl PsName (RlpExpr PsName) }
|
||
: data Con TyVars { DataD $2 $3 [] }
|
||
| data Con TyVars '=' DataCons { DataD $2 $3 $5 }
|
||
|
||
DataCons :: { [DataCon PsName] }
|
||
: DataCon '|' DataCons { $1 : $3 }
|
||
| DataCon { [$1] }
|
||
|
||
DataCon :: { DataCon PsName }
|
||
: Con list0(Type1) { DataCon $1 $2 }
|
||
|
||
Type1 :: { Type PsName }
|
||
: varname { VarT $ extractVarName $1 }
|
||
| Con { ConT $1 }
|
||
| '(' Type ')' { $2 }
|
||
|
||
Type :: { Type PsName }
|
||
: Type '->' Type { $1 :-> $3 }
|
||
| AppT { $1 }
|
||
|
||
AppT :: { Type PsName }
|
||
: Type1 { $1 }
|
||
| AppT Type1 { AppT $1 $2 }
|
||
|
||
TyVars :: { [PsName] }
|
||
: list0(varname) { $1 <&> view ( to extract
|
||
. singular _TokenVarName ) }
|
||
|
||
FunD :: { Decl PsName (RlpExpr PsName) }
|
||
: Var Pat1s '=' Expr { FunD $1 $2 $4 }
|
||
|
||
Expr :: { RlpExpr PsName }
|
||
: AppE { $1 }
|
||
| LetE { $1 }
|
||
| CaseE { $1 }
|
||
| LamE { $1 }
|
||
|
||
LamE :: { RlpExpr PsName }
|
||
: 'λ' list0(varname) '->' Expr { Finl $ Core.LamF (fmap extractName $2) $4 }
|
||
|
||
CaseE :: { RlpExpr PsName }
|
||
: case Expr of CaseAlts { Finr $ CaseEF $2 $4 }
|
||
|
||
CaseAlts :: { [Alter PsName (RlpExpr PsName)] }
|
||
: layout1(CaseAlt) { $1 }
|
||
|
||
CaseAlt :: { Alter PsName (RlpExpr PsName) }
|
||
: Pat '->' Expr { Alter $1 $3 }
|
||
|
||
LetE :: { RlpExpr PsName }
|
||
: let layout1(Binding) in Expr
|
||
{ Finr $ LetEF Core.NonRec $2 $4 }
|
||
|
||
Binding :: { Binding PsName (RlpExpr PsName) }
|
||
: Pat '=' Expr { VarB $1 $3 }
|
||
|
||
Expr1 :: { RlpExpr PsName }
|
||
: VarE { $1 }
|
||
| litint { $1 ^. to extract
|
||
. singular _TokenLitInt
|
||
. to (Finl . Core.LitF . Core.IntL) }
|
||
| '(' Expr ')' { $2 }
|
||
|
||
AppE :: { RlpExpr PsName }
|
||
: AppE Expr1 { Finl $ Core.AppF $1 $2 }
|
||
| Expr1 { $1 }
|
||
|
||
VarE :: { RlpExpr PsName }
|
||
: Var { Finl $ Core.VarF $1 }
|
||
|
||
Pat1s :: { [Pat PsName] }
|
||
: list0(Pat1) { $1 }
|
||
|
||
Pat1 :: { Pat PsName }
|
||
: Var { VarP $1 }
|
||
| Con { ConP $1 }
|
||
| '(' Pat ')' { $2 }
|
||
|
||
Pat :: { Pat PsName }
|
||
: AppP { $1 }
|
||
|
||
AppP :: { Pat PsName }
|
||
: Pat1 { $1 }
|
||
| AppP Pat1 { $1 `AppP` $2 }
|
||
|
||
Con :: { PsName }
|
||
: conname { $1 ^. to extract
|
||
. singular _TokenConName }
|
||
| '(' consym ')' { $1 ^. to extract
|
||
. singular _TokenConSym }
|
||
|
||
Var :: { PsName }
|
||
: varname { $1 ^. to extract
|
||
. singular _TokenVarName }
|
||
| '(' varsym ')' { $2 ^. to extract
|
||
. singular _TokenVarSym }
|
||
|
||
-- list0(p : α) : [α]
|
||
list0(p) : {- epsilon -} { [] }
|
||
| list0(p) p { $1 `snoc` $2 }
|
||
|
||
-- layout0(p : β) :: [β]
|
||
layout0(p) : '{' '}' { [] }
|
||
| VL VR { [] }
|
||
| layout1(p) { $1 }
|
||
|
||
-- layout_list0(sep : α, p : β) :: [β]
|
||
layout_list0(sep,p) : p { [$1] }
|
||
| layout_list1(sep,p) sep p { $1 `snoc` $3 }
|
||
| {- epsilon -} { [] }
|
||
|
||
-- layout1(p : β) :: [β]
|
||
layout1(p) : '{' layout_list1(';',p) '}' { $2 }
|
||
| VL layout_list1(VS,p) VS VR { $2 }
|
||
| VL layout_list1(VS,p) VR { $2 }
|
||
|
||
-- layout_list1(sep : α, p : β) :: [β]
|
||
layout_list1(sep,p) : p { [$1] }
|
||
| layout_list1(sep,p) sep p { $1 `snoc` $3 }
|
||
|
||
{
|
||
|
||
extractVarName = view $ to extract . singular _TokenVarName
|
||
|
||
parseRlpProgR :: (Monad m) => Text -> RLPCT m (Program Name (RlpExpr PsName))
|
||
parseRlpProgR s = liftErrorful $ errorful (ma,es)
|
||
where
|
||
(_,es,ma) = runP' parseRlpProg s
|
||
|
||
parseRlpExprR :: (Monad m) => Text -> RLPCT m (RlpExpr PsName)
|
||
parseRlpExprR s = liftErrorful $ errorful (ma,es)
|
||
where
|
||
(_,es,ma) = runP' parseRlpExpr s
|
||
|
||
parseError :: (Located RlpToken, [String]) -> P a
|
||
parseError (Located ss t,ts) = addFatalHere (ss ^. srcSpanLen) $
|
||
RlpParErrUnexpectedToken t ts
|
||
|
||
extractName = view $ to extract . singular _TokenVarName
|
||
|
||
}
|