Permalink
Cannot retrieve contributors at this time
Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign up
Fetching contributors…
| -- | | |
| -- Read the core functional representation from JSON format | |
| -- | |
| module Language.PureScript.CoreFn.FromJSON | |
| ( moduleFromJSON | |
| ) where | |
| import Prelude.Compat | |
| import Data.Aeson | |
| import Data.Aeson.Types (Parser, Value, listParser) | |
| import Data.Text (Text) | |
| import qualified Data.Text as T | |
| import Text.ParserCombinators.ReadP (readP_to_S) | |
| import qualified Data.Vector as V | |
| import Data.Version (Version, parseVersion) | |
| import Language.PureScript.AST.SourcePos (SourceSpan(SourceSpan)) | |
| import Language.PureScript.AST.Literals | |
| import Language.PureScript.CoreFn.Ann | |
| import Language.PureScript.CoreFn | |
| import Language.PureScript.Names | |
| import Language.PureScript.PSString (PSString) | |
| constructorTypeFromJSON :: Value -> Parser ConstructorType | |
| constructorTypeFromJSON v = do | |
| t <- parseJSON v | |
| case t of | |
| "ProductType" -> return ProductType | |
| "SumType" -> return SumType | |
| _ -> fail ("not recognized ConstructorType: " ++ T.unpack t) | |
| metaFromJSON :: Value -> Parser (Maybe Meta) | |
| metaFromJSON Null = return Nothing | |
| metaFromJSON v = withObject "Meta" metaFromObj v | |
| where | |
| metaFromObj o = do | |
| type_ <- o .: "metaType" | |
| case type_ of | |
| "IsConstructor" -> isConstructorFromJSON o | |
| "IsNewtype" -> return $ Just IsNewtype | |
| "IsTypeClassConstructor" | |
| -> return $ Just IsTypeClassConstructor | |
| "IsForeign" -> return $ Just IsForeign | |
| "IsWhere" -> return $ Just IsWhere | |
| _ -> fail ("not recognized Meta: " ++ T.unpack type_) | |
| isConstructorFromJSON o = do | |
| ct <- o .: "constructorType" >>= constructorTypeFromJSON | |
| is <- o .: "identifiers" >>= listParser identFromJSON | |
| return $ Just (IsConstructor ct is) | |
| annFromJSON :: FilePath -> Value -> Parser Ann | |
| annFromJSON modulePath = withObject "Ann" annFromObj | |
| where | |
| annFromObj o = do | |
| ss <- o .: "sourceSpan" >>= sourceSpanFromJSON modulePath | |
| mm <- o .: "meta" >>= metaFromJSON | |
| return (ss, [], Nothing, mm) | |
| sourceSpanFromJSON :: FilePath -> Value -> Parser SourceSpan | |
| sourceSpanFromJSON modulePath = withObject "SourceSpan" $ \o -> | |
| SourceSpan modulePath <$> | |
| o .: "start" <*> | |
| o .: "end" | |
| literalFromJSON :: (Value -> Parser a) -> Value -> Parser (Literal a) | |
| literalFromJSON t = withObject "Literal" literalFromObj | |
| where | |
| literalFromObj o = do | |
| type_ <- o .: "literalType" :: Parser Text | |
| case type_ of | |
| "IntLiteral" -> NumericLiteral . Left <$> o .: "value" | |
| "NumberLiteral" -> NumericLiteral . Right <$> o .: "value" | |
| "StringLiteral" -> StringLiteral <$> o .: "value" | |
| "CharLiteral" -> CharLiteral <$> o .: "value" | |
| "BooleanLiteral" -> BooleanLiteral <$> o .: "value" | |
| "ArrayLiteral" -> parseArrayLiteral o | |
| "ObjectLiteral" -> parseObjectLiteral o | |
| _ -> fail ("error parsing Literal: " ++ show o) | |
| parseArrayLiteral o = do | |
| val <- o .: "value" | |
| as <- mapM t (V.toList val) | |
| return $ ArrayLiteral as | |
| parseObjectLiteral o = do | |
| val <- o .: "value" | |
| ObjectLiteral <$> recordFromJSON t val | |
| identFromJSON :: Value -> Parser Ident | |
| identFromJSON = withText "Ident" (return . Ident) | |
| properNameFromJSON :: Value -> Parser (ProperName a) | |
| properNameFromJSON = fmap ProperName . parseJSON | |
| qualifiedFromJSON :: (Text -> a) -> Value -> Parser (Qualified a) | |
| qualifiedFromJSON f = withObject "Qualified" qualifiedFromObj | |
| where | |
| qualifiedFromObj o = do | |
| mn <- o .:? "moduleName" >>= traverse moduleNameFromJSON | |
| i <- o .: "identifier" >>= withText "Ident" (return . f) | |
| return $ Qualified mn i | |
| moduleNameFromJSON :: Value -> Parser ModuleName | |
| moduleNameFromJSON v = ModuleName <$> listParser properNameFromJSON v | |
| moduleFromJSON :: Value -> Parser (Version, Module Ann) | |
| moduleFromJSON = withObject "Module" moduleFromObj | |
| where | |
| moduleFromObj o = do | |
| version <- o .: "builtWith" >>= versionFromJSON | |
| moduleName <- o .: "moduleName" >>= moduleNameFromJSON | |
| modulePath <- o .: "modulePath" | |
| moduleSourceSpan <- o .: "sourceSpan" >>= sourceSpanFromJSON modulePath | |
| moduleImports <- o .: "imports" >>= listParser (importFromJSON modulePath) | |
| moduleExports <- o .: "exports" >>= listParser identFromJSON | |
| moduleDecls <- o .: "decls" >>= listParser (bindFromJSON modulePath) | |
| moduleForeign <- o .: "foreign" >>= listParser identFromJSON | |
| moduleComments <- o .: "comments" >>= listParser parseJSON | |
| return (version, Module {..}) | |
| versionFromJSON :: String -> Parser Version | |
| versionFromJSON v = | |
| case readP_to_S parseVersion v of | |
| (r, _) : _ -> return r | |
| _ -> fail "failed parsing purs version" | |
| importFromJSON :: FilePath -> Value -> Parser (Ann, ModuleName) | |
| importFromJSON modulePath = withObject "Import" | |
| (\o -> do | |
| ann <- o .: "annotation" >>= annFromJSON modulePath | |
| mn <- o .: "moduleName" >>= moduleNameFromJSON | |
| return (ann, mn)) | |
| bindFromJSON :: FilePath -> Value -> Parser (Bind Ann) | |
| bindFromJSON modulePath = withObject "Bind" bindFromObj | |
| where | |
| bindFromObj :: Object -> Parser (Bind Ann) | |
| bindFromObj o = do | |
| type_ <- o .: "bindType" :: Parser Text | |
| case type_ of | |
| "NonRec" -> (uncurry . uncurry) NonRec <$> bindFromObj' o | |
| "Rec" -> Rec <$> (o .: "binds" >>= listParser (withObject "Bind" bindFromObj')) | |
| _ -> fail ("not recognized bind type \"" ++ T.unpack type_ ++ "\"") | |
| bindFromObj' :: Object -> Parser ((Ann, Ident), Expr Ann) | |
| bindFromObj' o = do | |
| a <- o .: "annotation" >>= annFromJSON modulePath | |
| i <- o .: "identifier" >>= identFromJSON | |
| e <- o .: "expression" >>= exprFromJSON modulePath | |
| return ((a, i), e) | |
| recordFromJSON :: (Value -> Parser a) -> Value -> Parser [(PSString, a)] | |
| recordFromJSON p = listParser parsePair | |
| where | |
| parsePair v = do | |
| (l, v') <- parseJSON v :: Parser (PSString, Value) | |
| a <- p v' | |
| return (l, a) | |
| exprFromJSON :: FilePath -> Value -> Parser (Expr Ann) | |
| exprFromJSON modulePath = withObject "Expr" exprFromObj | |
| where | |
| exprFromObj o = do | |
| type_ <- o .: "type" | |
| case type_ of | |
| "Var" -> varFromObj o | |
| "Literal" -> literalExprFromObj o | |
| "Constructor" -> constructorFromObj o | |
| "Accessor" -> accessorFromObj o | |
| "ObjectUpdate" -> objectUpdateFromObj o | |
| "Abs" -> absFromObj o | |
| "App" -> appFromObj o | |
| "Case" -> caseFromObj o | |
| "Let" -> letFromObj o | |
| _ -> fail ("not recognized expression type: \"" ++ T.unpack type_ ++ "\"") | |
| varFromObj o = do | |
| ann <- o .: "annotation" >>= annFromJSON modulePath | |
| qi <- o .: "value" >>= qualifiedFromJSON Ident | |
| return $ Var ann qi | |
| literalExprFromObj o = do | |
| ann <- o .: "annotation" >>= annFromJSON modulePath | |
| lit <- o .: "value" >>= literalFromJSON (exprFromJSON modulePath) | |
| return $ Literal ann lit | |
| constructorFromObj o = do | |
| ann <- o .: "annotation" >>= annFromJSON modulePath | |
| tyn <- o .: "typeName" >>= properNameFromJSON | |
| con <- o .: "constructorName" >>= properNameFromJSON | |
| is <- o .: "fieldNames" >>= listParser identFromJSON | |
| return $ Constructor ann tyn con is | |
| accessorFromObj o = do | |
| ann <- o .: "annotation" >>= annFromJSON modulePath | |
| f <- o .: "fieldName" | |
| e <- o .: "expression" >>= exprFromJSON modulePath | |
| return $ Accessor ann f e | |
| objectUpdateFromObj o = do | |
| ann <- o .: "annotation" >>= annFromJSON modulePath | |
| e <- o .: "expression" >>= exprFromJSON modulePath | |
| us <- o .: "updates" >>= recordFromJSON (exprFromJSON modulePath) | |
| return $ ObjectUpdate ann e us | |
| absFromObj o = do | |
| ann <- o .: "annotation" >>= annFromJSON modulePath | |
| idn <- o .: "argument" >>= identFromJSON | |
| e <- o .: "body" >>= exprFromJSON modulePath | |
| return $ Abs ann idn e | |
| appFromObj o = do | |
| ann <- o .: "annotation" >>= annFromJSON modulePath | |
| e <- o .: "abstraction" >>= exprFromJSON modulePath | |
| e' <- o .: "argument" >>= exprFromJSON modulePath | |
| return $ App ann e e' | |
| caseFromObj o = do | |
| ann <- o .: "annotation" >>= annFromJSON modulePath | |
| cs <- o .: "caseExpressions" >>= listParser (exprFromJSON modulePath) | |
| cas <- o .: "caseAlternatives" >>= listParser (caseAlternativeFromJSON modulePath) | |
| return $ Case ann cs cas | |
| letFromObj o = do | |
| ann <- o .: "annotation" >>= annFromJSON modulePath | |
| bs <- o .: "binds" >>= listParser (bindFromJSON modulePath) | |
| e <- o .: "expression" >>= exprFromJSON modulePath | |
| return $ Let ann bs e | |
| caseAlternativeFromJSON :: FilePath -> Value -> Parser (CaseAlternative Ann) | |
| caseAlternativeFromJSON modulePath = withObject "CaseAlternative" caseAlternativeFromObj | |
| where | |
| caseAlternativeFromObj o = do | |
| bs <- o .: "binders" >>= listParser (binderFromJSON modulePath) | |
| isGuarded <- o .: "isGuarded" | |
| if isGuarded | |
| then do | |
| es <- o .: "expressions" >>= listParser parseResultWithGuard | |
| return $ CaseAlternative bs (Left es) | |
| else do | |
| e <- o .: "expression" >>= exprFromJSON modulePath | |
| return $ CaseAlternative bs (Right e) | |
| parseResultWithGuard :: Value -> Parser (Guard Ann, Expr Ann) | |
| parseResultWithGuard = withObject "parseCaseWithGuards" $ | |
| \o -> do | |
| g <- o .: "guard" >>= exprFromJSON modulePath | |
| e <- o .: "expression" >>= exprFromJSON modulePath | |
| return (g, e) | |
| binderFromJSON :: FilePath -> Value -> Parser (Binder Ann) | |
| binderFromJSON modulePath = withObject "Binder" binderFromObj | |
| where | |
| binderFromObj o = do | |
| type_ <- o .: "binderType" | |
| case type_ of | |
| "NullBinder" -> nullBinderFromObj o | |
| "VarBinder" -> varBinderFromObj o | |
| "LiteralBinder" -> literalBinderFromObj o | |
| "ConstructorBinder" -> constructorBinderFromObj o | |
| "NamedBinder" -> namedBinderFromObj o | |
| _ -> fail ("not recognized binder: \"" ++ T.unpack type_ ++ "\"") | |
| nullBinderFromObj o = do | |
| ann <- o .: "annotation" >>= annFromJSON modulePath | |
| return $ NullBinder ann | |
| varBinderFromObj o = do | |
| ann <- o .: "annotation" >>= annFromJSON modulePath | |
| idn <- o .: "identifier" >>= identFromJSON | |
| return $ VarBinder ann idn | |
| literalBinderFromObj o = do | |
| ann <- o .: "annotation" >>= annFromJSON modulePath | |
| lit <- o .: "literal" >>= literalFromJSON (binderFromJSON modulePath) | |
| return $ LiteralBinder ann lit | |
| constructorBinderFromObj o = do | |
| ann <- o .: "annotation" >>= annFromJSON modulePath | |
| tyn <- o .: "typeName" >>= qualifiedFromJSON ProperName | |
| con <- o .: "constructorName" >>= qualifiedFromJSON ProperName | |
| bs <- o .: "binders" >>= listParser (binderFromJSON modulePath) | |
| return $ ConstructorBinder ann tyn con bs | |
| namedBinderFromObj o = do | |
| ann <- o .: "annotation" >>= annFromJSON modulePath | |
| n <- o .: "identifier" >>= identFromJSON | |
| b <- o .: "binder" >>= binderFromJSON modulePath | |
| return $ NamedBinder ann n b |