content: module CLI where
  { import Control.Exception ( catch, SomeException );
    import System.IO;
    import Text.ParserCombinators.Parsec;
    import Text.ParserCombinators.Parsec.Expr;
    import Text.ParserCombinators.Parsec.Language;
    import qualified Text.ParserCombinators.Parsec.Token as PT;
    import Arith;
    
    lexer :: PT.TokenParser ();
    lexer
      = PT.makeTokenParser
          (haskellDef{reservedNames = ["let", "in", "ite", "true", "false"],
          						-- TODO MRO: - bei BinOps ODER UnOps
                      reservedOpNames = ["+", "-", "*", "/", "&&", "||", "#", "!", "\\", "=", "->"]});
    reserved = PT.reserved lexer;
    reservedOp = PT.reservedOp lexer;
    parens = PT.parens lexer;
    semi = PT.semi lexer;
    identifier = PT.identifier lexer;
    naturalOrFloat = PT.naturalOrFloat lexer;
    stringLiteral = PT.stringLiteral lexer;
     
    expr :: Parser (Exp TypedVal);
    expr = buildExpressionParser table factor <?> "expression";
    
    -- TODO MRO: f�rben
    factor :: Parser (Exp TypedVal);
    factor
      =   do { reservedOp "-";
             e <- expr;
             return (Unary Neg e)}
          <|>
          do { reservedOp "#";
               e <- expr;
               return (Unary Recip e)}
          <|>
          do { reservedOp "!";
               e <- expr;
               return (Unary Not e)}
          <|> letExpr
          <|> lamExpr
          <|> iteExpr
          <|> appExpr
          <?> "simple expression";
     
    number :: Parser (Exp TypedVal);
    number
      = do { nof <- naturalOrFloat;
             case nof of
                 { Right d -> return (Const (TVDouble d));
                   Left n -> return (Const (TVDouble (fromIntegral n)))}}
          <?> "number";
     
    stringConst :: Parser (Exp TypedVal);
    stringConst
      = do { s <- stringLiteral;
             return (Const (TVString s))}
          <?> "string literal"
  }
  