import Control. Arrow
newtype StateT s m a = StateT { runStateT :: s -> m ( a, s) }
m >>= k = StateT $ \s -> do
~ ( a, s') <- runStateT m s
runStateT (k a) s'
instance ( MonadPlus m) => MonadPlus ( StateT s m) where
mzero = StateT $ \_ -> mzero
m `mplus` n = StateT $ \s -> runStateT m s `mplus` runStateT n s
evalStateT m s = do
~ ( a, _ ) <- runStateT m s
--------------------------------------------------------------------------------------------------------------------
type DD = D -> D
type DDD = D -> D -> D
data Oper = Prinfix ( DD, Order) | Prefix DD | Postfix DD | Infix ( DDD, Order)
data Expr = Operand D | Operator Oper | Statement [ Expr]
( leftass, rightass) = ( True, False)
makeGuard d g = Operator $ d ( g, ( 1 , True) )
toOp' d xs l = lookup l xs >>= Just . Operator . d
toOp 0 = toOp' Prinfix
[ ( "-" , ( negate , ( 5 , leftass
) ) ) ] toOp 1 = toOp' Prefix [("sqr", (^2))]
toOp 3 = toOp' Postfix
[ ( "!" , \x
-> product [ 1 .. x
] ) ] toOp 4 = toOp' Infix [("+", ((+), (5, leftass))), ("-", ((-), (5, leftass))),
("*", ((*), (6, leftass))), ("/", ((/), (6, leftass))), ("^", ((**), (7, rightass)))]
modifyVal g s = s >>= return . g
parse = modifyVal (Statement . (makeGuard Prinfix id :)) $ parse' 0 where
add i t = modifyVal ( t :) $ parse' i
parse' i
= StateT
( listToMaybe
. lex ) >>= parse
'' i
parse'' pos l
| l
== "" || l
== ")" = guard
( pos
>= 3 ) >> return [ makeGuard Infix
undefined ] | isDigit
$ head l
= guard
( pos
<= 2 ) >> add
3 ( Operand
$ read l
) | l == "(" = guard ( pos <= 2 ) >> parse >>= add 3
| pos <= 1 = choose 1
| pos <= 4 = choose 4
where choose i
= uncurry add
=<< case ( toOp i l
, guard
( pos
< i
) >> toOp
( i
- 1 ) l
) of ( Just t
, Nothing
) -> return ( i `
rem `
2 + 1 , t
) ( Nothing
, Just t
) -> return ( i
, t
) _ -> mzero
eval ( Operand t) = t
eval
( Statement t
) = fst . snd $ eval
' (0, True) (undefined, t) where cond (pr1, as1) (pr2, as2) = pr1 > pr2 || pr1 == pr2 && if as1 == as2 then as1
else error "cannot mix two operators"
eval' op ( n, ots@ ( Operator o : ts) ) = case o of
Postfix g -> eval' op ( g n, ts)
Prinfix
( g
, opt
) -> h g
$ until ( cond opt
. fst ) ( eval
' opt . snd) Infix (g, opt) -> (,) opt . (,) n $ if cond op opt then ots else Operator (Prinfix (g n, opt)) : ts
where h g f = second (first g) $ f ((10, undefined), (undefined, ts))
eval' op ( n, t : ts) = eval' op (eval t, ts)
calc = fmap eval . evalStateT parse
main = mapM_ (print . calc)
[ "2 + 3"
, "4 - 3"
, "2 + (-3)"
, "4 * 5"
, "6/4"
, "1.2 + 1/2"
, "1/(-3)"
, "0.5 + 0.2"
, "3 ^ 2 ^ 2"
, "17654/342"
, "2/3 ^ 2"
, "(2/3) ^ 2"
, "(2 + 3) / (2 - 2)"
, "2 + 345 + + + + 6"
, " - sqr 5! +(-sqr(1 - 2^ 3) ^sqr 2 *9 !) "
, "5 + 9 3"
, "sqr sqr 3"
]
aW1wb3J0IERhdGEuQ2hhcgppbXBvcnQgRGF0YS5NYXliZQppbXBvcnQgQ29udHJvbC5Nb25hZAppbXBvcnQgQ29udHJvbC5BcnJvdwoKbmV3dHlwZSBTdGF0ZVQgcyBtIGEgPSBTdGF0ZVQgeyBydW5TdGF0ZVQgOjogcyAtPiBtIChhLHMpIH0KCmluc3RhbmNlIChNb25hZCBtKSA9PiBNb25hZCAoU3RhdGVUIHMgbSkgd2hlcmUKICAgIHJldHVybiBhID0gU3RhdGVUICQgXHMgLT4gcmV0dXJuIChhLCBzKQogICAgbSA+Pj0gayAgPSBTdGF0ZVQgJCBccyAtPiBkbwogICAgICAgIH4oYSwgcycpIDwtIHJ1blN0YXRlVCBtIHMKICAgICAgICBydW5TdGF0ZVQgKGsgYSkgcycKCmluc3RhbmNlIChNb25hZFBsdXMgbSkgPT4gTW9uYWRQbHVzIChTdGF0ZVQgcyBtKSB3aGVyZQogICAgbXplcm8gPSBTdGF0ZVQgJCBcXyAtPiBtemVybwogICAgbSBgbXBsdXNgIG4gPSBTdGF0ZVQgJCBccyAtPiBydW5TdGF0ZVQgbSBzIGBtcGx1c2AgcnVuU3RhdGVUIG4gcwoKZXZhbFN0YXRlVCBtIHMgPSBkbwogICAgfihhLCBfKSA8LSBydW5TdGF0ZVQgbSBzCiAgICByZXR1cm4gYQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp0eXBlIE9yZGVyID0gKEludCwgQm9vbCkKdHlwZSBEID0gRG91YmxlCnR5cGUgREQgPSBEIC0+IEQKdHlwZSBEREQgPSBEIC0+IEQgLT4gRAoKZGF0YSBPcGVyID0gUHJpbmZpeCAoREQsIE9yZGVyKSB8IFByZWZpeCBERCB8IFBvc3RmaXggREQgfCBJbmZpeCAoRERELCBPcmRlcikKZGF0YSBFeHByID0gT3BlcmFuZCBEIHwgT3BlcmF0b3IgT3BlciB8IFN0YXRlbWVudCBbRXhwcl0KCihsZWZ0YXNzLCByaWdodGFzcykgPSAoVHJ1ZSwgRmFsc2UpCm1ha2VHdWFyZCBkIGcgPSBPcGVyYXRvciAkIGQgKGcsICgxLCBUcnVlKSkKCnRvT3AnIGQgeHMgbCA9IGxvb2t1cCBsIHhzID4+PSBKdXN0IC4gT3BlcmF0b3IgLiBkCgp0b09wIDAgPSB0b09wJyBQcmluZml4IFsoIi0iLCAobmVnYXRlLCAoNSwgbGVmdGFzcykpKV0KdG9PcCAxID0gdG9PcCcgUHJlZml4IFsoInNxciIsICheMikpXQp0b09wIDMgPSB0b09wJyBQb3N0Zml4IFsoIiEiLCBceCAtPiBwcm9kdWN0IFsxLi54XSldCnRvT3AgNCA9IHRvT3AnIEluZml4IFsoIisiLCAoKCspLCAoNSwgbGVmdGFzcykpKSwgKCItIiwgKCgtKSwgKDUsIGxlZnRhc3MpKSksIAoJKCIqIiwgKCgqKSwgKDYsIGxlZnRhc3MpKSksICgiLyIsICgoLyksICg2LCBsZWZ0YXNzKSkpLCAoIl4iLCAoKCoqKSwgKDcsIHJpZ2h0YXNzKSkpXQoKbW9kaWZ5VmFsIGcgcyA9IHMgPj49IHJldHVybiAuIGcKCnBhcnNlID0gbW9kaWZ5VmFsIChTdGF0ZW1lbnQgLiAobWFrZUd1YXJkIFByaW5maXggaWQgOikpICQgcGFyc2UnIDAgd2hlcmUKCWFkZCBpIHQgPSBtb2RpZnlWYWwgKHQgOikgJCBwYXJzZScgaQoJcGFyc2UnIGkgPSBTdGF0ZVQgKGxpc3RUb01heWJlIC4gbGV4KSA+Pj0gcGFyc2UnJyBpCglwYXJzZScnIHBvcyBsCgkJfCBsID09ICIiIHx8IGwgPT0gIikiID0gZ3VhcmQgKHBvcyA+PSAzKSA+PiByZXR1cm4gW21ha2VHdWFyZCBJbmZpeCB1bmRlZmluZWRdCgkJfCBpc0RpZ2l0ICQgaGVhZCBsID0gZ3VhcmQgKHBvcyA8PSAyKSA+PiBhZGQgMyAoT3BlcmFuZCAkIHJlYWQgbCkKCQl8IGwgPT0gIigiID0gZ3VhcmQgKHBvcyA8PSAyKSA+PiBwYXJzZSA+Pj0gYWRkIDMKCQl8IHBvcyA8PSAxID0gY2hvb3NlIDEKCQl8IHBvcyA8PSA0ID0gY2hvb3NlIDQKCQl3aGVyZSBjaG9vc2UgaSA9IHVuY3VycnkgYWRkID08PCBjYXNlICh0b09wIGkgbCwgZ3VhcmQgKHBvcyA8IGkpID4+IHRvT3AgKGkgLSAxKSBsKSBvZgoJCQkJKEp1c3QgdCwgTm90aGluZykgLT4gcmV0dXJuIChpIGByZW1gIDIgKyAxLCB0KQoJCQkJKE5vdGhpbmcsIEp1c3QgdCkgLT4gcmV0dXJuIChpLCB0KQoJCQkJXyAtPiBtemVybwoKZXZhbCAoT3BlcmFuZCB0KSA9IHQKZXZhbCAoU3RhdGVtZW50IHQpID0gZnN0IC4gc25kICQgZXZhbCcgKDAsIFRydWUpICh1bmRlZmluZWQsIHQpIHdoZXJlCgljb25kIChwcjEsIGFzMSkgKHByMiwgYXMyKSA9IHByMSA+IHByMiB8fCBwcjEgPT0gcHIyICYmIGlmIGFzMSA9PSBhczIgdGhlbiBhczEKCQllbHNlIGVycm9yICJjYW5ub3QgbWl4IHR3byBvcGVyYXRvcnMiCglldmFsJyBvcCAobiwgb3RzQChPcGVyYXRvciBvIDogdHMpKSA9IGNhc2UgbyBvZgoJCVByZWZpeCBnIC0+IGggZyAkIHVuY3VycnkgZXZhbCcKCQlQb3N0Zml4IGcgLT4gZXZhbCcgb3AgKGcgbiwgdHMpCgkJUHJpbmZpeCAoZywgb3B0KSAtPiBoIGcgJCB1bnRpbCAoY29uZCBvcHQgLiBmc3QpIChldmFsJyBvcHQgLiBzbmQpCgkJSW5maXggKGcsIG9wdCkgLT4gKCwpIG9wdCAuICgsKSBuICQgaWYgY29uZCBvcCBvcHQgdGhlbiBvdHMgZWxzZSBPcGVyYXRvciAoUHJpbmZpeCAoZyBuLCBvcHQpKSA6IHRzCgkJd2hlcmUgaCBnIGYgPSBzZWNvbmQgKGZpcnN0IGcpICQgZiAoKDEwLCB1bmRlZmluZWQpLCAodW5kZWZpbmVkLCB0cykpCglldmFsJyBvcCAobiwgdCA6IHRzKSA9IGV2YWwnIG9wIChldmFsIHQsIHRzKQoKY2FsYyA9IGZtYXAgZXZhbCAuIGV2YWxTdGF0ZVQgcGFyc2UKCm1haW4gPSBtYXBNXyAocHJpbnQgLiBjYWxjKQoJWyAiMiArIDMiCgksICI0IC0gMyIKCSwgIjIgKyAoLTMpIgoJLCAiNCAqIDUiCgksICI2LzQiCgksICIxLjIgKyAxLzIiCgksICIxLygtMykiCgksICIwLjUgKyAwLjIiCgksICIzIF4gMiBeIDIiCgksICIxNzY1NC8zNDIiCgksICIyLzMgXiAyIgoJLCAiKDIvMykgXiAyIgoJLCAiKDIgKyAzKSAvICgyIC0gMikiCgksICIyICsgMzQ1ICsgKyArICsgNiIKCSwgIiAtIHNxciA1ISArKC1zcXIoMSAtIDJeIDMpIF5zcXIgMiAqOSAhKSAiCgksICI1ICsgOSAzIgoJLCAic3FyIHNxciAzIgoJXQ==