Get rid of experimental code for handling "deriving"

This commit is contained in:
Evan Czaplicki 2014-01-20 01:09:50 +01:00
parent 3640376be8
commit 6ba394c9cb
12 changed files with 54 additions and 114 deletions

View file

@ -35,8 +35,8 @@ build noPrelude interfaces source =
| null exs =
let get = Set.toList . Pattern.boundVars in
concat [ get pattern | Definition (Expr.Definition pattern _ _) <- decls ] ++
concat [ map fst ctors | Datatype _ _ ctors _ <- decls ] ++
[ name | TypeAlias name _ (Type.Record _ _) _ <- decls ]
concat [ map fst ctors | Datatype _ _ ctors <- decls ] ++
[ name | TypeAlias name _ (Type.Record _ _) <- decls ]
| otherwise = exs
metaModule <- Canonical.metadataModule interfaces $
@ -48,9 +48,9 @@ build noPrelude interfaces source =
-- reorder AST into strongly connected components
, program = SD.sortDefs . Expr.dummyLet $ TcDecl.toExpr decls
, types = Map.empty
, datatypes = [ (name,vars,ctors,ds) | Datatype name vars ctors ds <- decls ]
, datatypes = [ (name,vars,ctors) | Datatype name vars ctors <- decls ]
, fixities = [ (assoc,level,op) | Fixity assoc level op <- decls ]
, aliases = [ (name,tvs,tipe,ds) | TypeAlias name tvs tipe ds <- decls ]
, aliases = [ (name,tvs,tipe) | TypeAlias name tvs tipe <- decls ]
}
types <- TI.infer interfaces metaModule

View file

@ -134,14 +134,13 @@ collect infixes types aliases adts things =
collect (Map.insert name (assoc,prec) infixes) types aliases adts rest
D.Definition (E.TypeAnnotation name tipe) ->
collect infixes (insert name [ "type" .= tipe ] types) aliases adts rest
D.TypeAlias name vars tipe derivations ->
let fields = ["typeVariables" .= vars, "type" .= tipe, "deriving" .= derivations ]
D.TypeAlias name vars tipe ->
let fields = ["typeVariables" .= vars, "type" .= tipe ]
in collect infixes types (insert name fields aliases) adts rest
D.Datatype name vars ctors derivations ->
D.Datatype name vars ctors ->
let tipe = Data name (map Var vars)
fields = ["typeVariables" .= vars
, "constructors" .= map (ctorToJson tipe) ctors
, "deriving" .= derivations ]
, "constructors" .= map (ctorToJson tipe) ctors ]
in collect infixes types aliases (insert name fields adts) rest
where
insert name fields dict = Map.insert name (obj name fields) dict
@ -162,6 +161,3 @@ instance ToJSON Type where
ctorToJson tipe (ctor, tipes) =
object [ "name" .= ctor
, "type" .= foldr Lambda tipe tipes ]
instance ToJSON D.Derivation where
toJSON = toJSON . show

View file

@ -24,11 +24,7 @@ alias = do
args <- spacePrefix lowVar
padded equals
tipe <- Type.expr
json <- option [] $ do
try $ padded (reserved "deriving")
string "Json"
return [D.Json]
return (D.TypeAlias name args tipe json)
return (D.TypeAlias name args tipe)
datatype :: IParser D.ParseDeclaration
datatype = do
@ -38,7 +34,7 @@ datatype = do
args <- spacePrefix lowVar
padded equals
tcs <- pipeSep1 Type.constructor
return $ D.Datatype name args tcs []
return $ D.Datatype name args tcs
infixDecl :: IParser D.ParseDeclaration
@ -60,4 +56,4 @@ port =
whitespace
let port' op ctor expr = do { try op ; whitespace ; ctor name <$> expr }
D.Port <$> choice [ port' hasType D.PPAnnotation Type.expr
, port' equals D.PPDef Expr.expr ]
, port' equals D.PPDef Expr.expr ]

View file

@ -9,8 +9,8 @@ import Text.PrettyPrint as P
data Declaration' port def
= Definition def
| Datatype String [String] [(String,[T.Type])] [Derivation]
| TypeAlias String [String] T.Type [Derivation]
| Datatype String [String] [(String,[T.Type])]
| TypeAlias String [String] T.Type
| Port port
| Fixity Assoc Int String
deriving (Show)
@ -18,9 +18,6 @@ data Declaration' port def
data Assoc = L | N | R
deriving (Eq)
data Derivation = Json | JS | Binary | New
deriving (Eq, Show)
data ParsePort
= PPAnnotation String T.Type
| PPDef String Expr.LParseExpr
@ -34,23 +31,6 @@ data Port
type ParseDeclaration = Declaration' ParsePort Expr.ParseDef
type Declaration = Declaration' Port Expr.Def
instance Binary Derivation where
get = do n <- getWord8
return $ case n of
0 -> Json
1 -> JS
2 -> Binary
3 -> New
_ -> error "Unable to decode Derivation. You may have corrupted binary files,\n\
\so please report an issue at <https://github.com/evancz/Elm/issues>"
put derivation =
putWord8 $ case derivation of
Json -> 0
JS -> 1
Binary -> 2
New -> 3
instance Show Assoc where
show assoc =
case assoc of
@ -73,19 +53,18 @@ instance (Pretty port, Pretty def) => Pretty (Declaration' port def) where
case decl of
Definition def -> pretty def
Datatype tipe tvars ctors deriveables ->
Datatype tipe tvars ctors ->
P.hang (P.text "data" <+> P.text tipe <+> P.hsep (map P.text tvars)) 4
(P.sep $ zipWith join ("=" : repeat "|") ctors) <+> prettyDeriving deriveables
(P.sep $ zipWith join ("=" : repeat "|") ctors)
where
join c ctor = P.text c <+> prettyCtor ctor
prettyCtor (name, tipes) =
P.hang (P.text name) 2 (P.sep (map T.prettyParens tipes))
TypeAlias name tvars tipe deriveables ->
alias <+> prettyDeriving deriveables
TypeAlias name tvars tipe ->
P.hang (P.text "type" <+> name' <+> P.equals) 4 (pretty tipe)
where
name' = P.text name <+> P.hsep (map P.text tvars)
alias = P.hang (P.text "type" <+> name' <+> P.equals) 4 (pretty tipe)
Port port -> pretty port
@ -112,11 +91,3 @@ instance Pretty Port where
prettyPort :: (Pretty a) => String -> String -> a -> Doc
prettyPort name op e = P.text "port" <+> P.text name <+> P.text op <+> pretty e
prettyDeriving :: [Derivation] -> Doc
prettyDeriving deriveables =
case deriveables of
[] -> P.empty
[d] -> P.text "deriving" <+> P.text (show d)
ds -> P.text "deriving" <+>
P.parens (P.hsep $ P.punctuate P.comma $ map (P.text . show) ds)

View file

@ -50,8 +50,8 @@ data MetadataModule =
} deriving Show
type Interfaces = Map.Map String ModuleInterface
type ADT = (String, [String], [(String,[Type])], [Derivation])
type Alias = (String, [String], Type, [Derivation])
type ADT = (String, [String], [(String,[Type])])
type Alias = (String, [String], Type)
data ModuleInterface = ModuleInterface {
iVersion :: Version.Version,

View file

@ -27,11 +27,11 @@ interface moduleName iface =
, iFixities = iFixities iface -- cannot have canonicalized operators while parsing
}
where
both f g (a,b,c,d) = (f a, b, g c, d)
both f g (a,b,c) = (f a, b, g c)
prefix name = moduleName ++ "." ++ name
pair name = (name, moduleName ++ "." ++ name)
canon (name,_,_,_) = pair name
canon (name,_,_) = pair name
canons = Map.fromList $ concat
[ map canon (iAdts iface), map canon (iAliases iface) ]
@ -56,24 +56,24 @@ metadataModule ifaces modul =
[] -> Right ()
missings -> Left [ P.text $ "The following imports were not found: " ++ List.intercalate ", " missings ]
program' <- rename initialEnv (program modul)
aliases' <- mapM (three4 renameType') (aliases modul)
datatypes' <- mapM (three4 (mapM (two2 (mapM renameType')))) (datatypes modul)
aliases' <- mapM (three3 renameType') (aliases modul)
datatypes' <- mapM (three3 (mapM (two2 (mapM renameType')))) (datatypes modul)
return $ modul { program = program'
, aliases = aliases'
, datatypes = datatypes' }
where
two2 f (a,b) = (,) a <$> f b
three4 f (a,b,c,d) = (,,,) a b <$> f c <*> return d
three3 f (a,b,c) = (,,) a b <$> f c
renameType' =
Either.either (\err -> Left [P.text err]) return . renameType (replace "type" initialEnv)
get1 (a,_,_,_) = a
get1 (a,_,_) = a
canon (name, importMethod) =
let pair pre var = (pre ++ drop (length name + 1) var, var)
iface = ifaces Map.! name
allNames = concat [ Map.keys (iTypes iface)
, map get1 (iAliases iface)
, concat [ n : map fst ctors | (n,_,ctors,_) <- iAdts iface ] ]
, concat [ n : map fst ctors | (n,_,ctors) <- iAdts iface ] ]
in case importMethod of
As alias -> map (pair (alias ++ ".")) allNames
Hiding vars -> map (pair "") $ filter (flip Set.notMember vs) allNames

View file

@ -21,8 +21,7 @@ mistakes decls =
concat [ infiniteTypeAliases decls
, illFormedTypes decls
, map P.text (duplicateConstructors decls)
, map P.text (duplicates decls)
, badDerivations decls ]
, map P.text (duplicates decls) ]
dups :: Ord a => [a] -> [a]
dups = map head . filter ((>1) . length) . List.group . List.sort
@ -67,35 +66,14 @@ duplicateConstructors decls =
map (dupErr "definition of type constructor") (dups typeCtors) ++
map (dupErr "definition of data constructor") (dups dataCtors)
where
typeCtors = [ name | D.Datatype name _ _ _ <- decls ]
dataCtors = concat [ map fst patterns | D.Datatype _ _ patterns _ <- decls ]
badDerivations :: [D.Declaration] -> [Doc]
badDerivations decls = concatMap badDerivation derivations
where
derivations =
[ (decl, tvars, derives) | decl@(D.TypeAlias _ tvars _ derives) <- decls ] ++
[ (decl, tvars, derives) | decl@(D.Datatype _ tvars _ derives) <- decls ]
badDerivation (decl, tvars, derives) =
case (tvars, derives) of
(_:_, _)
| D.Json `elem` derives -> [report decl D.Json]
| D.Binary `elem` derives -> [report decl D.Binary]
_ -> []
report decl derive =
P.vcat [ P.text $ "Error: cannot derive '" ++ show derive ++ "' from this type alias."
, P.text "Make sure all type variables are replaced with concrete types:"
, P.text "\n"
, nest 4 (pretty decl)
]
typeCtors = [ name | D.Datatype name _ _ <- decls ]
dataCtors = concat [ map fst patterns | D.Datatype _ _ patterns <- decls ]
illFormedTypes :: [D.Declaration] -> [Doc]
illFormedTypes decls = map report (Maybe.mapMaybe isIllFormed (aliases ++ adts))
where
aliases = [ (decl, tvars, [tipe]) | decl@(D.TypeAlias _ tvars tipe _) <- decls ]
adts = [ (decl, tvars, concatMap snd ctors) | decl@(D.Datatype _ tvars ctors _) <- decls ]
aliases = [ (decl, tvars, [tipe]) | decl@(D.TypeAlias _ tvars tipe) <- decls ]
adts = [ (decl, tvars, concatMap snd ctors) | decl@(D.Datatype _ tvars ctors) <- decls ]
freeVars tipe =
case tipe of
@ -138,8 +116,8 @@ illFormedTypes decls = map report (Maybe.mapMaybe isIllFormed (aliases ++ adts))
infiniteTypeAliases :: [D.Declaration] -> [Doc]
infiniteTypeAliases decls =
[ report name tvars tipe ds | D.TypeAlias name tvars tipe ds <- decls
, infiniteType name tipe ]
[ report name tvars tipe | D.TypeAlias name tvars tipe <- decls
, infiniteType name tipe ]
where
infiniteType name tipe =
let infinite = infiniteType name in
@ -152,11 +130,11 @@ infiniteTypeAliases decls =
indented :: D.Declaration -> Doc
indented decl = P.text "\n " <> pretty decl <> P.text "\n"
report name args tipe derivations =
report name args tipe =
P.vcat [ P.text $ eightyCharLines 0 msg1
, indented $ D.TypeAlias name args tipe derivations
, indented $ D.TypeAlias name args tipe
, P.text $ eightyCharLines 0 msg2
, indented $ D.Datatype name args [(name,[tipe])] derivations
, indented $ D.Datatype name args [(name,[tipe])]
, P.text $ eightyCharLines 0 msg3 ++ "\n"
]
where

View file

@ -23,11 +23,11 @@ combineAnnotations = go
-- simple cases, pass them through with no changes
[] -> return []
Datatype name tvars ctors ds : rest ->
(:) (Datatype name tvars ctors ds) <$> go rest
Datatype name tvars ctors : rest ->
(:) (Datatype name tvars ctors) <$> go rest
TypeAlias name tvars alias ds : rest ->
(:) (TypeAlias name tvars alias ds) <$> go rest
TypeAlias name tvars alias : rest ->
(:) (TypeAlias name tvars alias) <$> go rest
Fixity assoc prec op : rest ->
(:) (Fixity assoc prec op) <$> go rest

View file

@ -64,9 +64,9 @@ metadataModule modul =
, imports = map (first var) (imports modul)
, program = expression (program modul)
, aliases =
let makeSafe (name,tvars,tipe,ds) = (var name, tvars, tipe, ds)
let makeSafe (name,tvars,tipe) = (var name, tvars, tipe)
in map makeSafe (aliases modul)
, datatypes =
let makeSafe (name,tvars,ctors,ds) = (var name, tvars, map (first var) ctors, ds)
let makeSafe (name,tvars,ctors) = (var name, tvars, map (first var) ctors)
in map makeSafe (datatypes modul)
}
}

View file

@ -21,7 +21,7 @@ collect interfaces moduleAliases =
rawAliases =
moduleAliases ++ concatMap iAliases (Map.elems interfaces)
isPrimitive (_,_,tipe,_) =
isPrimitive (_,_,tipe) =
case tipe of
Data _ [] -> True
_ -> False
@ -68,7 +68,7 @@ canonicalRealias aliases tipe =
[] -> if tipe == tipe' then tipe else f tipe'
tipes -> f (bestType tipes)
where
tryRealias (name, args, aliasTipe, _) =
tryRealias (name, args, aliasTipe) =
case diff aliasTipe tipe of
Nothing -> []
Just kvs ->
@ -136,4 +136,4 @@ collectFields fields =
foldr (\(f,t) fs -> Map.insertWith (++) f [t] fs) Map.empty fields
flattenFields fields =
concatMap (\(f,ts) -> map ((,) f) ts) (Map.toList fields)
concatMap (\(f,ts) -> map ((,) f) ts) (Map.toList fields)

View file

@ -15,7 +15,7 @@ toDefs decl =
case decl of
Definition def -> [def]
Datatype name tvars constructors _ -> concatMap toDefs' constructors
Datatype name tvars constructors -> concatMap toDefs' constructors
where
toDefs' (ctor, tipes) =
let vars = take (length tipes) arguments
@ -23,7 +23,7 @@ toDefs decl =
body = L.none . E.Data ctor $ map (L.none . E.Var) vars
in [ definition ctor (buildFunction body vars) (foldr T.Lambda tbody tipes) ]
TypeAlias name _ tipe@(T.Record fields ext) _ ->
TypeAlias name _ tipe@(T.Record fields ext) ->
[ definition name (buildFunction record vars) (foldr T.Lambda tipe args) ]
where
args = map snd fields ++ maybe [] (\x -> [T.Var x]) ext
@ -38,8 +38,7 @@ toDefs decl =
-- Type aliases must be added to an extended equality dictionary,
-- but they do not require any basic constraints.
-- TODO: with the ability to derive code, you may need to generate stuff!
TypeAlias _ _ _ _ -> []
TypeAlias _ _ _ -> []
Port port ->
case port of
@ -60,4 +59,4 @@ buildFunction body@(L.L s _) vars =
foldr (\p e -> L.L s (E.Lambda p e)) body (map P.PVar vars)
definition :: String -> E.LExpr -> T.Type -> E.Def
definition name expr tipe = E.Definition (P.PVar name) expr (Just tipe)
definition name expr tipe = E.Definition (P.PVar name) expr (Just tipe)

View file

@ -29,7 +29,7 @@ data Environment = Environment {
initialEnvironment :: [ADT] -> [Alias] -> IO Environment
initialEnvironment datatypes aliases = do
types <- makeTypes datatypes
let aliases' = Map.fromList $ map (\(a,b,c,_) -> (a,(b,c))) aliases
let aliases' = Map.fromList $ map (\(a,b,c) -> (a,(b,c))) aliases
env = Environment {
constructor = Map.empty,
value = Map.empty,
@ -42,7 +42,7 @@ makeTypes :: [ADT] -> IO TypeDict
makeTypes datatypes =
Map.fromList <$> mapM makeCtor (builtins ++ map nameAndKind datatypes)
where
nameAndKind (name, tvars, _, _) = (name, length tvars)
nameAndKind (name, tvars, _) = (name, length tvars)
makeCtor (name, _) = do
ctor <- VarN <$> namedVar Constant name
@ -84,7 +84,7 @@ makeConstructors env datatypes = Map.fromList builtins
ctorToType :: Environment -> ADT -> [ (String, IO (Int, [Variable], [Type], Type)) ]
ctorToType env (name, tvars, ctors, _) =
ctorToType env (name, tvars, ctors) =
zip (map fst ctors) (map inst ctors)
where
inst :: (String, [Src.Type]) -> IO (Int, [Variable], [Type], Type)
@ -167,4 +167,4 @@ instantiator env sourceType = go sourceType
ext' <- case ext of
Nothing -> return $ TermN EmptyRecord1
Just x -> go (Src.Var x)
return $ TermN (Record1 fields' ext')
return $ TermN (Record1 fields' ext')