/*

Markus Raab
Anfang: 09 Oktober 2001

rechner

Dos Rechner zum Ausrechnen von beliebig langen Rechneoperationen
Die Rechnezeile kann als Argument übergeben werden, oder bei einen
Dialog eingegeben werden

Folgende Operatoren dürfen verwendet werden: (kann bei incl.h verändert werden
+   addition
-   subtraktion
*   multiplikation
/   division
^   potenz

Es werden Vorrangregeln und Klammern berücksichtigt.
Wurzeln können durch Potenzen verwendet werden (wurzel(5) = 5^(1/2))
Der Recher arbeitet nur mit Gleitkommazahlen, es muss ein '.' oder ',' in jeder
Zahl vorhanden sein!

Nicht erkannte Zeichen (Zeichen welche keine Operatoren sind) werden einfach
ignoriert. Syntaxfehler werden gemeldet. Wird die Raute verwendet ist das
Ergebnis nicht gesichert, da diese als Tokenkennzeichnung steht.

*/

/*

(c) 2001
Sie dürfen dieses Programm beliebig verändern. Das darf aber nur dann erfolgen
wenn sie es eindeutig kennzeichnen, dass es sich nicht um den Original rechner
handelt. (z.B: Versionsnummer o.ä. vergeben, Namen verändern)

Das Programm und seine Derivate dürfen kopiert, verschenkt, weitergeben und
veröffentlicht werden. Verboten ist jedoch jedliche Verkäufe gegen Geld oder
andere Leistungen.

*/

#include "incl.h" /*alles was fuer Rechner gebraucht wird*/

// * * * STRINGS * * *
std::string s_NoNum = "Eine Zahl ist fehlerhaft.";
std::string s_NoDEZ = "Es muss eine Dezimalzahl sein! (. oder , fehlt)";
std::string s_UnFeh = "Unbekannter Fehler!";
std::string s_DivZ  = "Division durch 0. Ergebnis undefiniert";

std::string s_Ein   = "Eingabe : ";
std::string s_Erg   = "Ergebnis: ";

std::string s_Klamm = "Eine Klammer wurde falsch gesetzt";
std::string s_Synt  = "Der String wurde aufgrund von Syntaxfehler abgeaendert";
std::string s_Chg   = "Neuer String: ";

   //will man das Programm in eine andere Sprache übersetzen, können hier, alle
   //Strings abgeändert werden

// * * * MAIN * * *

//verschiede mains zum Testen des Programmes

int main(int argc, char ** argv)
{
   if (argc <1 || argc >2)
      return 1;      //unerlaubte Menge an Parametern
   std::string Str;
   double Dbl;
   if (argc == 2)
   {
      if (argv[1][0] == '?')
      {
         cout << "Hilfe" << endl;
         cout << "Parameteruebergaben" << endl;
         cout << "String\t\tWird berechnet" << endl;
         cout << "?     \t\tRuft Hilfe auf" << endl;
         cout << "c     \t\tWartet auf keine Tastatureingabe am ende" << endl;
         cout << endl << endl;
         cout << "Der Rechner kann die Grundrechnungsarten:" << endl;
         cout << "+\t\t\tAddition" << endl;
         cout << "-\t\t\tSubraktion" << endl;
         cout << "*\t\t\tMultiplikation" << endl;
         cout << "/\t\t\tDivision" << endl;
         cout << "^\t\t\tPotenz" << endl;
         cout << endl << endl;
         cout << "Es werden Vorangsregel beachtet." << endl;
         cout << "Die Interne Darstellung erfolgt immer in double." << endl;
         cout << "Klammern koennen verwendet werden." << endl;
         cout << "Es werden alle Zeichen ausser folgende Ignoriert:" << endl;
         cout << "Operatoren (+,-,*,/,^), Dezimal(.,,), Zahlen und #" << endl;
         return 0;
      }
      else if (argv[1][0] == 'c')
      {
         cout << s_Ein;
         std::getline (cin,Str,'\n');
      }
      else
         Str = argv[1];
   }
   if (argc == 1)
   {
      cout << s_Ein;
      std::getline (cin,Str,'\n');
   }
   try
   {
      if (Check (Str))
      {
         cout << s_Synt << endl;
         cout << s_Chg;
         cout << Str << endl;
      }
   }
   catch (Klamm)
   {
      cout << s_Klamm << endl;
   }

   try
   {
      Dbl = klammerparser(Str);
   }
   catch (NoNum)
   {
   	cout << s_NoNum << endl;
   }
   catch (NoDEZ)
   {
   	cout << s_NoDEZ << endl;
   }
   catch (DivThrZero)
   {
      cout << s_DivZ << endl;
   }
   catch (...)
   {
      cout << s_UnFeh << endl;
   }

   cout << s_Erg;
   cout.precision(10);
   cout.width    (20);
   cout << Dbl << endl;
   cin.sync();
   cin.clear();
   if (argc == 1)
      cin.get();
   return 0;
}

