infix exprs
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
HAPPY = happy
|
HAPPY = happy
|
||||||
HAPPY_OPTS = -a -g -c
|
HAPPY_OPTS = -a -g -c -d -i/tmp/happy-info
|
||||||
ALEX = alex
|
ALEX = alex
|
||||||
ALEX_OPTS = -g
|
ALEX_OPTS = -g
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ category: Language
|
|||||||
build-type: Simple
|
build-type: Simple
|
||||||
extra-doc-files: README.md
|
extra-doc-files: README.md
|
||||||
-- extra-source-files:
|
-- extra-source-files:
|
||||||
|
tested-with: GHC==9.6.2
|
||||||
|
|
||||||
common warnings
|
common warnings
|
||||||
-- ghc-options: -Wall -Wno-incomplete-uni-patterns -Wno-unused-top-binds
|
-- ghc-options: -Wall -Wno-incomplete-uni-patterns -Wno-unused-top-binds
|
||||||
|
|||||||
@@ -90,6 +90,8 @@ $white_no_nl+ ;
|
|||||||
-- control characters
|
-- control characters
|
||||||
<0>
|
<0>
|
||||||
{
|
{
|
||||||
|
"(" { constToken TokenLParen }
|
||||||
|
")" { constToken TokenRParen }
|
||||||
"{" { explicitLBrace }
|
"{" { explicitLBrace }
|
||||||
"}" { explicitRBrace }
|
"}" { explicitRBrace }
|
||||||
";" { constToken TokenSemicolon }
|
";" { constToken TokenSemicolon }
|
||||||
|
|||||||
@@ -1,28 +1,33 @@
|
|||||||
{
|
{
|
||||||
|
{-# LANGUAGE LambdaCase #-}
|
||||||
module Rlp.Parse
|
module Rlp.Parse
|
||||||
( parseRlpProgram
|
( parseRlpProg
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
import Rlp.Lex
|
import Rlp.Lex
|
||||||
import Rlp.Syntax
|
import Rlp.Syntax
|
||||||
import Rlp.Parse.Types
|
import Rlp.Parse.Types
|
||||||
import Rlp.Parse.Associate
|
import Rlp.Parse.Associate
|
||||||
|
import Lens.Micro
|
||||||
import Lens.Micro.Mtl
|
import Lens.Micro.Mtl
|
||||||
|
import Lens.Micro.Platform ()
|
||||||
import Data.List.Extra
|
import Data.List.Extra
|
||||||
import Data.Fix
|
import Data.Fix
|
||||||
import Data.Functor.Const
|
import Data.Functor.Const
|
||||||
}
|
}
|
||||||
|
|
||||||
%name parseRlpProgram StandaloneProgram
|
%name parseRlpProg StandaloneProgram
|
||||||
|
|
||||||
%monad { P }
|
%monad { P }
|
||||||
%lexer { lexDebug } { Located _ TokenEOF }
|
%lexer { lexCont } { Located _ TokenEOF }
|
||||||
%error { parseError }
|
%error { parseError }
|
||||||
%tokentype { Located RlpToken }
|
%tokentype { Located RlpToken }
|
||||||
|
|
||||||
%token
|
%token
|
||||||
varname { Located _ (TokenVarName $$) }
|
varname { Located _ (TokenVarName $$) }
|
||||||
conname { Located _ (TokenConName $$) }
|
conname { Located _ (TokenConName $$) }
|
||||||
|
consym { Located _ (TokenConSym $$) }
|
||||||
|
varsym { Located _ (TokenVarSym $$) }
|
||||||
data { Located _ TokenData }
|
data { Located _ TokenData }
|
||||||
litint { Located _ (TokenLitInt $$) }
|
litint { Located _ (TokenLitInt $$) }
|
||||||
'=' { Located _ TokenEquals }
|
'=' { Located _ TokenEquals }
|
||||||
@@ -36,6 +41,9 @@ import Data.Functor.Const
|
|||||||
'}' { Located _ TokenRBrace }
|
'}' { Located _ TokenRBrace }
|
||||||
vlbrace { Located _ TokenLBraceV }
|
vlbrace { Located _ TokenLBraceV }
|
||||||
vrbrace { Located _ TokenRBraceV }
|
vrbrace { Located _ TokenRBraceV }
|
||||||
|
infixl { Located _ TokenInfixL }
|
||||||
|
infixr { Located _ TokenInfixR }
|
||||||
|
infix { Located _ TokenInfix }
|
||||||
|
|
||||||
%right '->'
|
%right '->'
|
||||||
|
|
||||||
@@ -67,8 +75,17 @@ VS : ';' { $1 }
|
|||||||
| vsemi { $1 }
|
| vsemi { $1 }
|
||||||
|
|
||||||
Decl :: { PartialDecl' }
|
Decl :: { PartialDecl' }
|
||||||
Decl : FunDecl { $1 }
|
: FunDecl { $1 }
|
||||||
| DataDecl { $1 }
|
| DataDecl { $1 }
|
||||||
|
| InfixDecl { $1 }
|
||||||
|
|
||||||
|
InfixDecl :: { PartialDecl' }
|
||||||
|
: InfixWord litint InfixOp {% mkInfixD $1 $2 $3 }
|
||||||
|
|
||||||
|
InfixWord :: { Assoc }
|
||||||
|
: infixl { InfixL }
|
||||||
|
| infixr { InfixR }
|
||||||
|
| infix { Infix }
|
||||||
|
|
||||||
DataDecl :: { PartialDecl' }
|
DataDecl :: { PartialDecl' }
|
||||||
: data Con TyParams '=' DataCons { DataD $2 $3 $5 }
|
: data Con TyParams '=' DataCons { DataD $2 $3 $5 }
|
||||||
@@ -109,9 +126,24 @@ Pat1 :: { Pat' }
|
|||||||
| Lit { LitP $1 }
|
| Lit { LitP $1 }
|
||||||
|
|
||||||
Expr :: { PartialExpr' }
|
Expr :: { PartialExpr' }
|
||||||
Expr : Lit { Fix . E $ LitEF $1 }
|
: Expr1 varsym Expr { Fix $ B $2 (unFix $1) (unFix $3) }
|
||||||
|
| Expr1 { $1 }
|
||||||
|
|
||||||
|
Expr1 :: { PartialExpr' }
|
||||||
|
: '(' Expr ')' { wrapFix . Par . unwrapFix $ $2 }
|
||||||
|
| Lit { Fix . E $ LitEF $1 }
|
||||||
| Var { Fix . E $ VarEF $1 }
|
| Var { Fix . E $ VarEF $1 }
|
||||||
|
|
||||||
|
-- TODO: happy prefers left-associativity. doing such would require adjusting
|
||||||
|
-- the code in Rlp.Parse.Associate to expect left-associative input rather than
|
||||||
|
-- right.
|
||||||
|
InfixExpr :: { PartialExpr' }
|
||||||
|
: Expr1 varsym Expr { Fix $ B $2 (unFix $1) (unFix $3) }
|
||||||
|
|
||||||
|
InfixOp :: { Name }
|
||||||
|
: consym { $1 }
|
||||||
|
| varsym { $1 }
|
||||||
|
|
||||||
Lit :: { Lit' }
|
Lit :: { Lit' }
|
||||||
Lit : litint { IntL $1 }
|
Lit : litint { IntL $1 }
|
||||||
|
|
||||||
@@ -131,4 +163,14 @@ mkProgram ds = do
|
|||||||
parseError :: Located RlpToken -> P a
|
parseError :: Located RlpToken -> P a
|
||||||
parseError = error . show
|
parseError = error . show
|
||||||
|
|
||||||
|
mkInfixD :: Assoc -> Int -> Name -> P PartialDecl'
|
||||||
|
mkInfixD a p n = do
|
||||||
|
let opl :: Lens' ParseState (Maybe OpInfo)
|
||||||
|
opl = psOpTable . at n
|
||||||
|
opl <~ (use opl >>= \case
|
||||||
|
-- TODO: non-fatal error
|
||||||
|
Just o -> pure (Just o)
|
||||||
|
Nothing -> pure (Just (a,p))
|
||||||
|
)
|
||||||
|
pure $ InfixD a p n
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ data RlpToken
|
|||||||
| TokenOf
|
| TokenOf
|
||||||
| TokenLet
|
| TokenLet
|
||||||
| TokenIn
|
| TokenIn
|
||||||
|
| TokenInfixL
|
||||||
|
| TokenInfixR
|
||||||
|
| TokenInfix
|
||||||
-- reserved ops
|
-- reserved ops
|
||||||
| TokenArrow
|
| TokenArrow
|
||||||
| TokenPipe
|
| TokenPipe
|
||||||
|
|||||||
Reference in New Issue
Block a user