module NplusK where
import Syntax
import TokenId
hasNplusK (DeclFun pos tid [Fun pats gdexps (DeclsParse w)]) =
any npkPat pats || any npkGdExp gdexps || any hasNplusK w
where
npkPat (ExpRecord exp _) = npkExp exp
npkPat (ExpApplication _ exps) = any npkExp exps
npkPat (ExpInfixList _ exps) = any npkExp exps
npkPat (ExpList _ exps) = any npkExp exps
npkPat (PatAs _ _ pat) = npkPat pat
npkPat (PatIrrefutable _ pat) = npkPat pat
npkPat (PatNplusK _ _ _ _ _) = True
npkPat _ = False
npkExp (ExpLambda _ pats exp) = any npkPat pats || npkExp exp
npkExp (ExpLet _ (DeclsParse decls) exp) = any hasNplusK decls || npkExp exp
npkExp (ExpDo _ stmts) = any npkStmt stmts
npkExp (ExpCase _ exp alts) = npkExp exp || any npkAlt alts
npkExp (ExpFatbar exp1 exp2) = npkExp exp1 || npkExp exp2
npkExp ExpFail = False
npkExp (ExpIf _ c t e) = any npkExp [c,t,e]
npkExp (ExpType _ exp _ _) = npkExp exp
npkExp (ExpRecord exp _) = npkExp exp
npkExp (ExpApplication _ exps) = any npkExp exps
npkExp (ExpInfixList _ exps) = any npkExp exps
npkExp (ExpList _ exps) = any npkExp exps
npkExp _ = False
npkGdExp (gd,exp) = npkExp exp
npkAlt (Alt pat gdexps (DeclsParse w)) = npkPat pat || any npkGdExp gdexps || any hasNplusK w
npkStmt _ = False -- WRONG!!
hasNplusK _ = False
{- This section removed.
transNplusK f@(DeclFun pos tid [Fun pats gdexps (DeclsParse w)]) =
let (pats',defs) = unzip (map (npkPat (`elem` w')) pats)
in
if pats'==pats then f
else DeclFun ps tid [Fun pats' gdexps (DeclsParse (concat defs++w))]
where
w' = concatMap stripLhs w
npkPat inUse
-}
-- Make the function (caf) definition n | n'>=k = n'-k
buildNplusK pos n n' k (DeclsParse decls) =
DeclsParse
((DeclFun pos n
[Fun []
[ (ExpApplication pos [ExpVar pos t_lessequal, k, ExpVar pos n']
,ExpApplication pos [ExpVar pos tminus, ExpVar pos n', k])
]
(DeclsParse [])])
: decls)
-- Translate f (n+k) = rhs(n)
-- to f n' = rhs(n)
-- where n | n'>=k = n'-k
-- Translate do (n+k) <- exp
-- stmts(n)
-- to do n'<- exp
-- n <- return (let n | n'>=k = n'-k in n)
-- stmts(n)
transNkStmt :: Pat a -> (ns,d,[Pat a]) -> (ns,d,[Pat a])
transNkStmt pat (ns,d,pat0) =
case pat of
(ExpApplication p pats) -> let (ns',d',pats') = foldr transNkStmt (ns,d,[]) pats
in (ns',d', (ExpApplication p pats': pat0))
(ExpInfixList p pats) -> let (ns',d',pats') = foldr transNkStmt (ns,d,[]) pats
in (ns',d', (ExpInfixList p pats': pat0))
(ExpList p pats) -> let (ns',d',pats') = foldr transNkStmt (ns,d,[]) pats
in (ns',d', (ExpList p pats': pat0))
(PatAs p tid pat) -> let (ns',d',[pat']) = transNkStmt pat (ns,d,undefined)
in (ns',d', (PatAs p tid pat': pat0))
(PatIrrefutable p pat) -> let (ns',d',[pat']) = transNkStmt pat (ns,d,undefined)
in (ns',d', (PatIrrefutable p pat': pat0))
-- (PatNplusK p tid int) -> let
_ -> (ns, d, (pat: pat0))
-- Translate \(n+k)-> exp(n)
-- to \n'-> let n | n'>=k = n'-k in exp(n)
-- Translate case exp0 of
-- (n+k) | gd(n) -> exp(n)
-- to case exp0 of
-- n' -> let n | n'>=k = n'-k in
-- case n of
-- n | gd(n) -> exp(n)
-- One-level test for (n+k) in pattern
npkPat (ExpApplication _ exps) = any npkPat exps
npkPat (ExpInfixList _ exps) = any npkPat exps
npkPat (ExpList _ exps) = any npkPat exps
npkPat (PatAs _ _ pat) = npkPat pat
npkPat (PatIrrefutable _ pat) = npkPat pat
npkPat (PatNplusK _ _ _ _ _) = True
npkPat _ = False
|