#!/usr/bin/env runhaskell

import Text.ParserCombinators.Parsec
import Text.ParserCombinators.Parsec.Expr
 -- requires the haskeline-package (tested with 0.6.4.6) for line-editing /history
import System.Console.Haskeline

constExp = try $ spaces >> many1 digit >>= return . read

parenExp = between (sym "(" ) (sym ")") term

negExp   = sym "-" >> baseExp >>= return . negate

baseExp  = constExp <|> parenExp <|> negExp

opTable =
  [
   [ Infix (sym "^" >> return (**)) AssocRight]
  ,[
     Infix (sym "*" >> return (*)) AssocLeft
    ,Infix (sym "/" >> return (/)) AssocLeft
   ]
  ,[
     Infix (sym "+" >> return (+)) AssocLeft
    ,Infix (sym "-" >> return (-)) AssocLeft
   ]
  ]

sym x = try $ spaces >> string x

term  = buildExpressionParser opTable baseExp

tterm = do
  x<- term
  eof
  return x

main :: IO ()
main = runInputT defaultSettings loop
  where 
    loop :: InputT IO ()
    loop = do
      minput <- getInputLine "Term eingeben : "
      case minput of
        Nothing -> outputStrLn "\nEnde"
        Just "" -> outputStrLn "\nEnde"
        Just str -> do
          case (parse tterm "userInput" str) of
            Right x -> outputStrLn $ "Ergebnis : " ++ show x
            Left e -> outputStrLn $ "Parsefehler :" ++ show e
          loop

test = parse tterm "testInput" "(5-2)^3"

