module LambdaPrinter where

import Lambda

paren exp = case exp of
	(App (App x y) z)	-> (paren x)++(paren' y)++(paren' z)
	(App x y)			-> (paren x)++(paren' y)
	(Lambda id x)		-> if exp == xComb
		then "x"
		else inParens $ "\\"++(show id)++" -> "++(paren x)
	(Var id)			-> paren' exp
	where
		inParens s = "(" ++ s ++ ")"
		paren' exp = case exp of
			(Var id)			-> (show id)
			_					->
				if exp == xComb then paren exp else inParens $ paren exp

idFreeIn id (Var x)
	| x == id = True
idFreeIn id (Lambda x exp)
	| x /= id = idFreeIn id exp
idFreeIn id (App x y) = idFreeIn id x || idFreeIn id y
idFreeIn _ _ = False

getVarName exp id = if idFreeIn id exp then "v"++(show id) else "_"

l2h (Var id) = getVarName (Var id) id
l2h (App x y) = l2h x ++ " (" ++ l2h y ++ ")"
l2h exp@(Lambda id x) = "(\\" ++ (unwords $ map (getVarName exp') $ reverse ids) ++ " -> " ++ l2h exp' ++")"
	where
		(ids,exp') = getIds exp []
		getIds x prevs = case x of
			(Lambda id y) -> if (elem id prevs)
				then (prevs,x)
				else getIds y (id:prevs)
			x -> (prevs,x)

prettyPrint = l2h

