Eq-1.0: EqManips/Renderer/EqCode.hs
module EqManips.Renderer.EqCode( unparse, unparseS ) where
import Data.List( foldl' )
import Data.Ratio
import EqManips.Types
import EqManips.Propreties
import EqManips.Polynome( convertToFormula )
-- | Public function to translate a formula back to it's
-- original notation. NOTE : it's not used as a Show instance...
unparse :: FormulaPrim -> String
unparse f = unparseS f ""
unparseS :: FormulaPrim -> ShowS
unparseS = deparse maxPrio False
-- | used to render functions' arguments
argListToString :: [FormulaPrim] -> ShowS
argListToString [] = id
argListToString [f] = deparse maxPrio False f
argListToString lst = foldl' accum (unprint lastElem) reved
where unprint = deparse maxPrio False
accum acc f = unprint f . (',':) . acc
(lastElem:reved) = reverse lst
-- | only to avoid a weird constant somewhere
maxPrio :: Int
maxPrio = 15
-- | Real conversion function, pass down priority
-- and tree direction
deparse :: Int -> Bool -> FormulaPrim -> ShowS
-- INVISIBLE META NINJA !!
deparse i r (Meta _ op f) = (++) (show op) . ('(' :) . deparse i r f . (')':)
deparse i r (Poly _ p) = deparse i r . unTagFormula $ convertToFormula p
deparse i r (Complex _ (real, imag)) = ('(':)
. deparse maxPrio r real
. (++) ") + i * ("
. deparse i r imag . (')':)
deparse _ _ (Truth True) = ("true" ++)
deparse _ _ (Truth False) = ("false" ++)
deparse _ _ (BinOp _ _ []) =
error "The formula is denormalized : a binary operator without any operands"
deparse _ _ (Variable s) = (s ++)
deparse _ _ (Lambda _ _) = id -- NINJA HIDDEN!
deparse _ _ (NumEntity e) = (en e ++)
where en Pi = "pi"
en Nabla = "nabla"
en Infinite = "infinite"
en Ellipsis = "..."
deparse _ _ (CInteger i) = shows i
deparse _ _ (CFloat d) = shows d
deparse _ _ (List _ l) = ('[':) . argListToString l . (']':)
deparse prio left (Indexes _ a b) = deparse prio left a . ("_("++) . argListToString b . (')':)
deparse _ _ (Block i i1 i2) =
("block(" ++) . shows i . (',':) . shows i1 . (',' :) . shows i2 . (')' :)
deparse _ _ (App _ (Variable v) fl) =
(v ++) . ('(' :) . argListToString fl . (')' :)
deparse _ _ (App _ f1 fl) =
('(' :) . deparse maxPrio False f1 . (")(" ++) . argListToString fl . (')' :)
deparse _ _ (Sum _ i i1 i2) =
("sum(" ++) . argListToString [i, i1, i2] . (')':)
deparse _ _ (Product _ i i1 i2) =
("product(" ++) . argListToString [i, i1, i2] . (')':)
deparse _ _ (Derivate _ i i1) =
("derivate(" ++) . argListToString [i, i1] . (')':)
deparse _ _ (Integrate _ i i1 i2 i3) =
("integrate(" ++) . argListToString [i, i1, i2, i3] . (')':)
deparse _ _ (UnOp _ OpFactorial f) = ('(':) . deparse maxPrio False f . (")!" ++)
deparse _ _ (UnOp _ op f) =
(++) (unopString op) .
('(':) . deparse maxPrio False f . (')':)
deparse _ _ (Fraction f) =
('(':) . shows (numerator f)
. ('/':)
. shows (denominator f)
. (')':)
-- Special case... as OpEq is right associative...
-- we must reverse shit for serialisation
deparse oldPrio right (BinOp _ OpEq [f1,f2]) =
let (prio, txt) = (OpEq `obtainProp` Priority, binopString OpEq)
in
if prio > oldPrio || (not right && prio == oldPrio)
then ('(':)
. deparse prio False f1
. (' ' :) . (txt ++) . (' ':)
. deparse prio True f2 . (')':)
else deparse prio False f1
. (' ' :) . (txt ++) . (' ':)
. deparse prio True f2
deparse oldPrio right (BinOp _ op [f1,f2]) =
let (prio, txt) = (op `obtainProp` Priority, binopString op)
in
if prio > oldPrio || (right && prio == oldPrio)
then ('(':) . deparse prio False f1
. (' ' :) . (txt ++) . (' ':)
. deparse prio True f2 . (')':)
else deparse prio False f1
. (' ' :) . (txt ++) . (' ':)
. deparse prio True f2
deparse oldPrio right (BinOp _ op (f1:xs)) =
let (prio, txt) = (op `obtainProp` Priority, binopString op)
in
if prio > oldPrio || (right && prio == oldPrio)
then ('(':) . deparse prio False f1
. (' ':) . (txt ++) . (' ':)
. deparse prio False (binOp op xs) . (')':)
else deparse prio False f1
. (' ' :) . (txt ++) . (' ':)
. deparse prio False (binOp op xs)
deparse _ _ (Matrix _ n m fl) =
("matrix("++) . shows n
. (',':)
. shows m
. (',':) . argListToString (concat fl) . (')':)