module Derive.Enum(deriveEnum) where import Syntax import IntState import IdKind import NT import State import Derive.Lib import TokenId(tEnum,tfromEnum,ttoEnum,tenumFrom,tenumFromThen,t_fromEnum,t_toEnum,t_enumFromTo,t_enumFromThenTo) import Util.Extra(strPos) deriveEnum :: ((TokenId,IdKind) -> Id) -> Id -> Id -> [Id] -> [(Id,Id)] -> Pos -> a -> IntState -> (Decl Id,IntState) deriveEnum tidFun cls typ tvs ctxs pos = getInfo typ >>>= \ typInfo -> mapS getInfo (constrsI typInfo) >>>= \ constrInfos -> if not (all noArgs constrInfos) then deriveError ("Nhc can only derive Enum for enumeration types (" ++ strPos pos ++ ")") else let expLast = ExpLit pos (LitInt Boxed (length constrInfos -1)) nt = NewType tvs [] ctxs [mkNTcons typ (map mkNTvar tvs)] tidTyp = tidI typInfo in addInstMethod tEnum tidTyp tfromEnum nt (tidFun (tfromEnum,Method)) >>>= \ funFromEnum -> addInstMethod tEnum tidTyp ttoEnum nt (tidFun (ttoEnum,Method)) >>>= \ funToEnum -> addInstMethod tEnum tidTyp tenumFrom nt (tidFun (tenumFrom,Method)) >>>= \ funFrom -> addInstMethod tEnum tidTyp tenumFromThen nt (tidFun (tenumFromThen,Method)) >>>= \ funFromThen -> (unitS (ExpVar pos) =>>> getUnique) >>>= \expA -> (unitS (ExpVar pos) =>>> getUnique) >>>= \expB -> (unitS (ExpVar pos) =>>> getUnique) >>>= \expC -> (unitS (ExpVar pos) =>>> getUnique) >>>= \expD -> (unitS (ExpVar pos) =>>> getUnique) >>>= \expE -> (unitS (ExpVar pos) =>>> getUnique) >>>= \expF -> (unitS (ExpVar pos) =>>> getUnique) >>>= \expG -> (unitS (ExpVar pos) =>>> getUnique) >>>= \expH -> unitS $ DeclInstance pos (syntaxCtxs pos ctxs) cls [syntaxType pos typ tvs] $ DeclsParse [DeclFun pos funFromEnum [Fun [expA] (Unguarded (ExpApplication pos [ExpVar pos (tidFun (t_fromEnum,Var)),expA])) (DeclsParse [])] ,DeclFun pos funToEnum [Fun [expB] (Unguarded ( let cons = zip (constrsI typInfo) [0..] alts = map mkAlt cons mkAlt (c,n) = Alt pat (Unguarded rhs) decls where pat = ExpLit pos (LitInt Boxed n) rhs = ExpCon pos c decls = DeclsParse [] in (ExpCase pos expB alts) )) {- no such luck! (ExpApplication pos [ExpVar pos (tidFun (t_toEnum,Var)),expB])) -} (DeclsParse [])] ,DeclFun pos funFrom [Fun [expC] (Unguarded (ExpApplication pos [ExpVar pos (tidFun (t_enumFromTo,Var)),expC,expLast])) (DeclsParse [])] ,DeclFun pos funFromThen [Fun [expD,expE] (Unguarded (ExpApplication pos [ExpVar pos (tidFun (t_enumFromThenTo,Var)) ,expD,expE,expLast])) (DeclsParse []) ] ]