You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

96 lines
4.5 KiB

{-|
Module: Simple.Convert
Description: Defines a conversion from the parsed language to a subset
Defines a conversion from the parsed language to a simpler subset of the language
which is used by the Simple modules.
-}
{-# LANGUAGE TupleSections #-}
module Simple.Convert where
import Types
import Error
import Misc
import qualified Parser.Types as P
import qualified Simple.AST as S
-- | Convert from the original parse tree to the simpler subset
convert :: FilePath -> String -> [P.TL] -> Either String [S.TopLevel]
convert fp tx = traverse convertTL
where
-- | Create an error message at a provided position
lerror :: PN -> String -> Either String a
lerror p = Left . errorMessage p fp tx
-- All the following are functions to convert different types from the P module to the S module
convertTL :: P.TL -> Either String S.TopLevel
convertTL (P.ExDef p t i pes) = S.Def p <$> convertTYSG t <*> pure i <*> convertPE2 <~> pes
convertTL (P.DtDef p i (_:_) _) = lerror p ("Type arguments in definition of type '" <> unId i <> "'")
convertTL (P.DtDef p i [] tis) = S.Dat p i <$> convertTI <~> tis
convertTL (P.RcDef p i (_:_) _) = lerror p ("Type arguments in definition of record '" <> unId i <> "'")
convertTL (P.RcDef p i [] tis) = S.Rec p i <$> convertTI <~> tis
convertPattern :: P.Pattern -> S.Pattern
convertPattern (P.PWild p) = S.Wild p
convertPattern (P.PVar p i) = S.PVar p i
convertPattern (P.PLit l) = S.PLit (convertLiteral l)
convertPattern (P.PApp p i ps) = S.PApp p i (convertPattern <$> ps)
convertTYSG :: P.TYSG -> Either String S.Type
convertTYSG (P.TyAll p _ _) = lerror p "Quanitification in type signature"
convertTYSG (P.TySG1 t) = convertTYSG1 t
convertTYSG1 :: P.TYSG1 -> Either String S.Type
convertTYSG1 (P.TyVar p i) = pure (S.UsrType p i)
convertTYSG1 (P.TyImp p _) = lerror p "Implicit type argument"
convertTYSG1 (P.TyArr p a b) = S.FuncType p <$> convertTYSG1 a <*> convertTYSG1 b
convertTYSG1 (P.TyApp p _ _) = lerror p "Application in type signature"
convertTYSG1 (P.TyType p) = lerror p "Type type"
convertTYSG1 (P.TyChar p) = pure (S.ChrType p)
convertTYSG1 (P.TyString p) = pure (S.StrType p)
convertTYSG1 (P.TyInt p) = pure (S.IntType p)
convertTYSG1 (P.TyNpl p _ _) = lerror p "Npl"
convertLiteral :: P.Literal -> S.Literal
convertLiteral (P.LInt p i) = S.LInt p i
convertLiteral (P.LChar p c) = S.LChr p c
convertLiteral (P.LString p s) = S.LStr p s
convertTerm :: P.Term -> Either String S.Term
convertTerm (P.TLit l) = pure (S.TLit (convertLiteral l))
convertTerm (P.TLambda p _ _) = lerror p "Ambigously typed lambda"
convertTerm (P.TLambdaCase p _) = lerror p "Ambigously typed lambda"
convertTerm (P.TyLambda p tis e) = S.TLambda p <$> convertTI <~> tis <*> convertExpr e
convertTerm (P.TyLambdaCase p t pes) = S.TLambdaCase p <$> convertTYSG1 t <*> convertPE <~> pes
convertTerm (P.TVar p i) = pure (S.TVar p i)
convertTerm (P.TNpl p _ _) = lerror p "Npl"
convertExpr :: P.Expr -> Either String S.Expr
convertExpr (P.TExp t e) = S.ExpExpr <$> convertTYSG t <*> convertExpr1 e
convertExpr (P.EExp e) = S.ImpExpr <$> convertExpr1 e
convertExpr1 :: P.Expr1 -> Either String S.Expr1
convertExpr1 (P.Apply p e as) = S.Apply p <$> convertExpr e <*> convertArg <~> as
convertExpr1 (P.ECase p e pes) = S.Case p <$> convertExpr e <*> convertPE <~> pes
convertExpr1 (P.ELet p ies e) = S.Let p <$> convertIE <~> ies <*> convertExpr e
convertExpr1 (P.Inst p i ies) = S.Inst p i <$> convertIE <~> ies
convertExpr1 (P.Term t) = S.Term <$> convertTerm t
convertIE :: (Identifier, P.Expr) -> Either String (Identifier, S.Expr)
convertIE (i,e) = (i,) <$> convertExpr e
convertPE :: (P.Pattern, P.Expr) -> Either String (S.Pattern, S.Expr)
convertPE (p,e) = (convertPattern p,) <$> convertExpr e
convertPE2 :: ([P.Pattern], P.Expr) -> Either String ([S.Pattern], S.Expr)
convertPE2 (ps,e) = (convertPattern <$> ps,) <$> convertExpr e
convertArg :: P.Arg -> Either String S.Expr
convertArg (P.Imp a) = lerror (pos a) "Implicit argument"
convertArg (P.Exp (P.Wild p)) = lerror p "Wildcard argument"
convertArg (P.Exp (P.EArg e)) = convertExpr e
convertTI :: (P.TYSG1, Identifier) -> Either String (S.Type, Identifier)
convertTI (t,i) = (,i) <$> convertTYSG1 t