Compare commits
29 Commits
happy-fron
...
rlp2core
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a4c0c3a71a | ||
|
|
f22d4238f5 | ||
|
|
4e1c9dd750 | ||
|
|
d6ac991105 | ||
|
|
d5663c1aad | ||
|
|
7e6bee3d4a | ||
|
|
5ec625e0fd | ||
|
|
9196e20e08 | ||
|
|
cb9ec43c14 | ||
|
|
8ad967fac0 | ||
|
|
55dbc9de70 | ||
|
|
05226373ee | ||
|
|
981c5d8a83 | ||
|
|
86cd1075ca | ||
|
|
1d43c1d304 | ||
|
|
4b44f57066 | ||
|
|
90a9594e8f | ||
|
|
074350768c | ||
|
|
37d9e6f219 | ||
|
|
cb7cdf7ed7 | ||
|
|
2f783d96e8 | ||
|
|
a71c099fe0 | ||
|
|
d1e64eb12d | ||
|
|
f31726b43d | ||
|
|
8aa9bb843f | ||
|
|
9a357a99b7 | ||
|
|
060d48f9e1 | ||
|
|
bf4abeb8b4 | ||
|
|
7ed565fc24 |
@@ -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
|
||||||
@@ -36,12 +37,14 @@ library
|
|||||||
, Rlp.Parse.Associate
|
, Rlp.Parse.Associate
|
||||||
, Rlp.Lex
|
, Rlp.Lex
|
||||||
, Rlp.Parse.Types
|
, Rlp.Parse.Types
|
||||||
|
, Rlp.TH
|
||||||
|
|
||||||
other-modules: Data.Heap
|
other-modules: Data.Heap
|
||||||
, Data.Pretty
|
, Data.Pretty
|
||||||
, Core.Parse
|
, Core.Parse
|
||||||
, Core.Lex
|
, Core.Lex
|
||||||
, Core2Core
|
, Core2Core
|
||||||
|
, Rlp2Core
|
||||||
, Control.Monad.Utils
|
, Control.Monad.Utils
|
||||||
|
|
||||||
build-tool-depends: happy:happy, alex:alex
|
build-tool-depends: happy:happy, alex:alex
|
||||||
|
|||||||
BIN
src/.DS_Store
vendored
BIN
src/.DS_Store
vendored
Binary file not shown.
@@ -9,6 +9,8 @@ module Rlp.Lex
|
|||||||
, lexToken
|
, lexToken
|
||||||
, lexDebug
|
, lexDebug
|
||||||
, lexCont
|
, lexCont
|
||||||
|
, execP
|
||||||
|
, execP'
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
import Codec.Binary.UTF8.String (encodeChar)
|
import Codec.Binary.UTF8.String (encodeChar)
|
||||||
@@ -54,7 +56,7 @@ $asciisym = [\!\#\$\%\&\*\+\.\/\<\=\>\?\@\\\^\|\-\~\:]
|
|||||||
case|data|do|import|in|let|letrec|module|of|where
|
case|data|do|import|in|let|letrec|module|of|where
|
||||||
|
|
||||||
@reservedop =
|
@reservedop =
|
||||||
"=" | \\ | "->" | "|"
|
"=" | \\ | "->" | "|" | "::"
|
||||||
|
|
||||||
rlp :-
|
rlp :-
|
||||||
|
|
||||||
@@ -90,6 +92,8 @@ $white_no_nl+ ;
|
|||||||
-- control characters
|
-- control characters
|
||||||
<0>
|
<0>
|
||||||
{
|
{
|
||||||
|
"(" { constToken TokenLParen }
|
||||||
|
")" { constToken TokenRParen }
|
||||||
"{" { explicitLBrace }
|
"{" { explicitLBrace }
|
||||||
"}" { explicitRBrace }
|
"}" { explicitRBrace }
|
||||||
";" { constToken TokenSemicolon }
|
";" { constToken TokenSemicolon }
|
||||||
|
|||||||
@@ -1,30 +1,38 @@
|
|||||||
{
|
{
|
||||||
|
{-# LANGUAGE LambdaCase #-}
|
||||||
module Rlp.Parse
|
module Rlp.Parse
|
||||||
( parseRlpProgram
|
( parseRlpProg
|
||||||
|
, execP
|
||||||
|
, execP'
|
||||||
)
|
)
|
||||||
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 _ TokenHasType }
|
||||||
'=' { Located _ TokenEquals }
|
'=' { Located _ TokenEquals }
|
||||||
'|' { Located _ TokenPipe }
|
'|' { Located _ TokenPipe }
|
||||||
';' { Located _ TokenSemicolon }
|
';' { Located _ TokenSemicolon }
|
||||||
@@ -36,6 +44,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 +78,23 @@ VS : ';' { $1 }
|
|||||||
| vsemi { $1 }
|
| vsemi { $1 }
|
||||||
|
|
||||||
Decl :: { PartialDecl' }
|
Decl :: { PartialDecl' }
|
||||||
Decl : FunDecl { $1 }
|
: FunDecl { $1 }
|
||||||
|
| TySigDecl { $1 }
|
||||||
| DataDecl { $1 }
|
| DataDecl { $1 }
|
||||||
|
| InfixDecl { $1 }
|
||||||
|
|
||||||
|
-- TODO: multiple vars
|
||||||
|
|
||||||
|
TySigDecl :: { PartialDecl' }
|
||||||
|
: Var '::' Type { TySigD [$1] $3 }
|
||||||
|
|
||||||
|
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 +135,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 +172,13 @@ 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
|
||||||
|
Just o -> error "(TODO: non-fatal) duplicate inix decls"
|
||||||
|
Nothing -> pure (Just (a,p))
|
||||||
|
)
|
||||||
|
pure $ InfixD a p n
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE PatternSynonyms, ViewPatterns, ImplicitParams #-}
|
{-# LANGUAGE PatternSynonyms, ViewPatterns, ImplicitParams #-}
|
||||||
module Rlp.Parse.Associate
|
module Rlp.Parse.Associate
|
||||||
( associate
|
( associate
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ data RlpToken
|
|||||||
| TokenOf
|
| TokenOf
|
||||||
| TokenLet
|
| TokenLet
|
||||||
| TokenIn
|
| TokenIn
|
||||||
|
| TokenInfixL
|
||||||
|
| TokenInfixR
|
||||||
|
| TokenInfix
|
||||||
-- reserved ops
|
-- reserved ops
|
||||||
| TokenArrow
|
| TokenArrow
|
||||||
| TokenPipe
|
| TokenPipe
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import Data.Functor.Foldable.TH (makeBaseFunctor)
|
|||||||
import Data.Functor.Classes
|
import Data.Functor.Classes
|
||||||
import Lens.Micro
|
import Lens.Micro
|
||||||
import Lens.Micro.TH
|
import Lens.Micro.TH
|
||||||
|
import Language.Haskell.TH.Syntax (Lift)
|
||||||
import Core.Syntax hiding (Lit)
|
import Core.Syntax hiding (Lit)
|
||||||
import Core (HasRHS(..), HasLHS(..))
|
import Core (HasRHS(..), HasLHS(..))
|
||||||
----------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------
|
||||||
@@ -55,7 +56,7 @@ data RlpModule b = RlpModule
|
|||||||
}
|
}
|
||||||
|
|
||||||
newtype RlpProgram b = RlpProgram [Decl RlpExpr b]
|
newtype RlpProgram b = RlpProgram [Decl RlpExpr b]
|
||||||
deriving Show
|
deriving (Show, Lift)
|
||||||
|
|
||||||
type RlpProgram' = RlpProgram Name
|
type RlpProgram' = RlpProgram Name
|
||||||
|
|
||||||
@@ -70,17 +71,17 @@ data Decl e b = FunD VarId [Pat b] (e b) (Maybe (Where b))
|
|||||||
| TySigD [VarId] Type
|
| TySigD [VarId] Type
|
||||||
| DataD ConId [Name] [ConAlt]
|
| DataD ConId [Name] [ConAlt]
|
||||||
| InfixD Assoc Int Name
|
| InfixD Assoc Int Name
|
||||||
deriving Show
|
deriving (Show, Lift)
|
||||||
|
|
||||||
type Decl' e = Decl e Name
|
type Decl' e = Decl e Name
|
||||||
|
|
||||||
data Assoc = InfixL
|
data Assoc = InfixL
|
||||||
| InfixR
|
| InfixR
|
||||||
| Infix
|
| Infix
|
||||||
deriving Show
|
deriving (Show, Lift)
|
||||||
|
|
||||||
data ConAlt = ConAlt ConId [Type]
|
data ConAlt = ConAlt ConId [Type]
|
||||||
deriving Show
|
deriving (Show, Lift)
|
||||||
|
|
||||||
data RlpExpr b = LetE [Bind b] (RlpExpr b)
|
data RlpExpr b = LetE [Bind b] (RlpExpr b)
|
||||||
| VarE VarId
|
| VarE VarId
|
||||||
@@ -90,7 +91,7 @@ data RlpExpr b = LetE [Bind b] (RlpExpr b)
|
|||||||
| IfE (RlpExpr b) (RlpExpr b) (RlpExpr b)
|
| IfE (RlpExpr b) (RlpExpr b) (RlpExpr b)
|
||||||
| AppE (RlpExpr b) (RlpExpr b)
|
| AppE (RlpExpr b) (RlpExpr b)
|
||||||
| LitE (Lit b)
|
| LitE (Lit b)
|
||||||
deriving Show
|
deriving (Show, Lift)
|
||||||
|
|
||||||
type RlpExpr' = RlpExpr Name
|
type RlpExpr' = RlpExpr Name
|
||||||
|
|
||||||
@@ -99,15 +100,15 @@ type Where' = [Bind Name]
|
|||||||
|
|
||||||
-- do we want guards?
|
-- do we want guards?
|
||||||
data Alt b = AltA (Pat b) (RlpExpr b)
|
data Alt b = AltA (Pat b) (RlpExpr b)
|
||||||
deriving Show
|
deriving (Show, Lift)
|
||||||
|
|
||||||
data Bind b = PatB (Pat b) (RlpExpr b)
|
data Bind b = PatB (Pat b) (RlpExpr b)
|
||||||
| FunB VarId [Pat b] (RlpExpr b)
|
| FunB VarId [Pat b] (RlpExpr b)
|
||||||
deriving Show
|
deriving (Show, Lift)
|
||||||
|
|
||||||
data VarId = NameVar Text
|
data VarId = NameVar Text
|
||||||
| SymVar Text
|
| SymVar Text
|
||||||
deriving Show
|
deriving (Show, Lift)
|
||||||
|
|
||||||
instance IsString VarId where
|
instance IsString VarId where
|
||||||
-- TODO: use symvar if it's an operator
|
-- TODO: use symvar if it's an operator
|
||||||
@@ -115,19 +116,19 @@ instance IsString VarId where
|
|||||||
|
|
||||||
data ConId = NameCon Text
|
data ConId = NameCon Text
|
||||||
| SymCon Text
|
| SymCon Text
|
||||||
deriving Show
|
deriving (Show, Lift)
|
||||||
|
|
||||||
data Pat b = VarP VarId
|
data Pat b = VarP VarId
|
||||||
| LitP (Lit b)
|
| LitP (Lit b)
|
||||||
| ConP ConId [Pat b]
|
| ConP ConId [Pat b]
|
||||||
deriving Show
|
deriving (Show, Lift)
|
||||||
|
|
||||||
type Pat' = Pat Name
|
type Pat' = Pat Name
|
||||||
|
|
||||||
data Lit b = IntL Int
|
data Lit b = IntL Int
|
||||||
| CharL Char
|
| CharL Char
|
||||||
| ListL [RlpExpr b]
|
| ListL [RlpExpr b]
|
||||||
deriving Show
|
deriving (Show, Lift)
|
||||||
|
|
||||||
type Lit' = Lit Name
|
type Lit' = Lit Name
|
||||||
|
|
||||||
|
|||||||
30
src/Rlp/TH.hs
Normal file
30
src/Rlp/TH.hs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
module Rlp.TH
|
||||||
|
( rlpProg
|
||||||
|
)
|
||||||
|
where
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
import Language.Haskell.TH
|
||||||
|
import Language.Haskell.TH.Syntax hiding (Module)
|
||||||
|
import Language.Haskell.TH.Quote
|
||||||
|
import Control.Monad ((>=>))
|
||||||
|
import Compiler.RLPC
|
||||||
|
import Data.Default.Class (def)
|
||||||
|
import Data.Text qualified as T
|
||||||
|
import Rlp.Parse
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
rlpProg :: QuasiQuoter
|
||||||
|
rlpProg = QuasiQuoter
|
||||||
|
{ quoteExp = qRlpProg
|
||||||
|
, quotePat = error "rlp quasiquotes may only be used in expressions"
|
||||||
|
, quoteType = error "rlp quasiquotes may only be used in expressions"
|
||||||
|
, quoteDec = error "rlp quasiquotes may only be used in expressions"
|
||||||
|
}
|
||||||
|
|
||||||
|
qRlpProg :: String -> Q Exp
|
||||||
|
qRlpProg s = case parse (T.pack s) of
|
||||||
|
Nothing -> error "error lol iddfk"
|
||||||
|
Just a -> lift a
|
||||||
|
where
|
||||||
|
parse = execP' parseRlpProg
|
||||||
|
|
||||||
44
src/Rlp2Core.hs
Normal file
44
src/Rlp2Core.hs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
{-# LANGUAGE LambdaCase #-}
|
||||||
|
module Rlp2Core
|
||||||
|
( rlp2core
|
||||||
|
)
|
||||||
|
where
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
import Core.Syntax as Core
|
||||||
|
import Rlp.Syntax as Rlp
|
||||||
|
import Data.Foldable
|
||||||
|
import Data.HashMap.Strict qualified as H
|
||||||
|
import Control.Monad.State
|
||||||
|
import Lens.Micro.Platform
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
rlp2core :: RlpProgram' -> Program'
|
||||||
|
rlp2core (RlpProgram ds) = execState (decl2core `traverse_` ds) init
|
||||||
|
where
|
||||||
|
init = Program
|
||||||
|
{ _programScDefs = mempty
|
||||||
|
, _programTypeSigs = mempty
|
||||||
|
}
|
||||||
|
|
||||||
|
type GenCoreProg b = State (Program b)
|
||||||
|
|
||||||
|
type GenCoreProg' = GenCoreProg Name
|
||||||
|
|
||||||
|
emitTypeSig :: Name -> Type -> GenCoreProg' ()
|
||||||
|
emitTypeSig b t = do
|
||||||
|
let tl :: Lens' Program' (Maybe Type)
|
||||||
|
tl = programTypeSigs . at b
|
||||||
|
tl <~ (use tl >>= \case
|
||||||
|
-- TODO: non-fatal error
|
||||||
|
Just o -> error "(TODO: non-fatal) duplicate type sigs"
|
||||||
|
Nothing -> pure (Just t)
|
||||||
|
)
|
||||||
|
|
||||||
|
decl2core :: Decl' RlpExpr -> GenCoreProg' ()
|
||||||
|
|
||||||
|
decl2core (DataD n as cs) = undefined
|
||||||
|
|
||||||
|
decl2core (TySigD vs t) = mkSig `traverse_` vs where
|
||||||
|
mkSig :: VarId -> GenCoreProg' ()
|
||||||
|
mkSig (NameVar n) = emitTypeSig n t
|
||||||
|
|
||||||
Reference in New Issue
Block a user