module STGArity(stgArity) where import State import IntState import Id import PosCode import Building stgArity :: IntState -> [(Id,PosLambda)] -> ([(Id,PosLambda)],IntState) stgArity state code = case mapS arityBinding code () (state,[],()) of (bs,(state,_,_)) -> (bs,state) arityBinding (fun,PosLambda pos int env args exp) = pushEnv (map snd args) >>> arityExp exp >>>= \ exp -> popEnv >>> unitS (fun,PosLambda pos int env args exp) arityBinding b@(fun,PosPrimitive pos f) = unitS b arityBinding b@(fun,PosForeign pos f ar t c ie) = unitS b arityExp (PosExpLambda pos int envs args exp) = pushEnv (map snd args) >>> arityExp exp >>>= \ exp -> popEnv >>> unitS (PosExpLambda pos int envs args exp) arityExp (PosExpLet rec pos bindings exp) = pushEnv (map fst bindings) >>> mapS arityBinding bindings >>>= \ bindings -> arityExp exp >>>= \ exp -> popEnv >>> unitS (PosExpLet rec pos bindings exp) arityExp (PosExpCase pos exp alts) = mapS arityAlt alts >>>= \ alts -> arityExp exp >>>= \ exp -> unitS (PosExpCase pos exp alts) arityExp (PosExpFatBar b exp1 exp2) = arityExp exp2 >>>= \ exp2 -> arityExp exp1 >>>= \ exp1 -> unitS (PosExpFatBar b exp1 exp2) arityExp (PosExpFail) = unitS (PosExpFail) arityExp (PosExpIf pos g exp1 exp2 exp3) = arityExp exp2 >>>= \ exp2 -> arityExp exp3 >>>= \ exp3 -> arityExp exp1 >>>= \ exp1 -> unitS (PosExpIf pos g exp1 exp2 exp3) arityExp (PosExpApp pos (PosExpApp _ es1:es2)) = -- Can be be created in lift arityExp (PosExpApp pos (es1++es2)) arityExp (PosExpApp epos (atom@(PosVar pos i):atoms)) = mapS arityExp atoms >>>= \ atoms -> arityArity i >>>= \ qarity -> case qarity of Nothing -> -- assume it alway is strict (we lift _everything_ :-) unitS (PosExpApp epos (atom:atoms)) Just arity -> if length atoms <= arity then unitS (PosExpThunk epos False (atom:atoms)) else case splitAt arity atoms of (args,eargs) -> unitS (PosExpApp epos (PosExpThunk pos False (atom:args):eargs)) arityExp (PosExpApp pos es) = -- complicated function mapS arityExp es >>>= \ es -> unitS (PosExpApp pos es) arityExp (PosExpThunk pos False es) = -- prim/con mapS arityExp es >>>= \ es -> unitS (PosExpThunk pos False es) arityExp (PosExpThunk pos True es) | compiler==Nhc98 = mapS arityExp es >>>= \ es -> unitS (PosExpThunk pos True es) arityExp e = unitS e arityAlt (PosAltCon pos con args exp) = pushEnv (map snd args) >>> arityExp exp >>>= \ (exp) -> popEnv >>> unitS (PosAltCon pos con args exp) arityAlt (PosAltInt pos int b exp) = arityExp exp >>>= \ (exp) -> unitS (PosAltInt pos int b exp) ------ pushEnv args down up@(state,env,bs) = (state,args:env,bs) popEnv down up@(state,(_:env),bs) = (state,env,bs) arityArity i down up@(state,env,bs) = if any (i `elem`) env then (Nothing,up) else (Just (arityIS state i),up)