infix exprs

This commit is contained in:
crumbtoo
2024-01-17 10:08:57 -07:00
parent 5ec625e0fd
commit 7e6bee3d4a
5 changed files with 54 additions and 6 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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 }

View File

@@ -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
} }

View File

@@ -48,6 +48,9 @@ data RlpToken
| TokenOf | TokenOf
| TokenLet | TokenLet
| TokenIn | TokenIn
| TokenInfixL
| TokenInfixR
| TokenInfix
-- reserved ops -- reserved ops
| TokenArrow | TokenArrow
| TokenPipe | TokenPipe