This commit is contained in:
crumbtoo
2024-01-18 17:21:04 -07:00
parent f22d4238f5
commit a4c0c3a71a
6 changed files with 101 additions and 14 deletions

View File

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

View File

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

View File

@@ -2,6 +2,8 @@
{-# LANGUAGE LambdaCase #-} {-# LANGUAGE LambdaCase #-}
module Rlp.Parse module Rlp.Parse
( parseRlpProg ( parseRlpProg
, execP
, execP'
) )
where where
import Rlp.Lex import Rlp.Lex
@@ -30,6 +32,7 @@ import Data.Functor.Const
varsym { Located _ (TokenVarSym $$) } 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 }
@@ -76,9 +79,15 @@ VS : ';' { $1 }
Decl :: { PartialDecl' } Decl :: { PartialDecl' }
: FunDecl { $1 } : FunDecl { $1 }
| TySigDecl { $1 }
| DataDecl { $1 } | DataDecl { $1 }
| InfixDecl { $1 } | InfixDecl { $1 }
-- TODO: multiple vars
TySigDecl :: { PartialDecl' }
: Var '::' Type { TySigD [$1] $3 }
InfixDecl :: { PartialDecl' } InfixDecl :: { PartialDecl' }
: InfixWord litint InfixOp {% mkInfixD $1 $2 $3 } : InfixWord litint InfixOp {% mkInfixD $1 $2 $3 }
@@ -168,8 +177,7 @@ mkInfixD a p n = do
let opl :: Lens' ParseState (Maybe OpInfo) let opl :: Lens' ParseState (Maybe OpInfo)
opl = psOpTable . at n opl = psOpTable . at n
opl <~ (use opl >>= \case opl <~ (use opl >>= \case
-- TODO: non-fatal error Just o -> error "(TODO: non-fatal) duplicate inix decls"
Just o -> pure (Just o)
Nothing -> pure (Just (a,p)) Nothing -> pure (Just (a,p))
) )
pure $ InfixD a p n pure $ InfixD a p n

View File

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