Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

engine.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2000 Trolltech AS.  All rights reserved.
00003 **
00004 ** This file is part of Qtopia Environment.
00005 **
00006 ** This file may be distributed and/or modified under the terms of the
00007 ** GNU General Public License version 2 as published by the Free Software
00008 ** Foundation and appearing in the file LICENSE.GPL included in the
00009 ** packaging of this file.
00010 **
00011 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 **
00014 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00015 **
00016 ** Contact info@trolltech.com if any conditions of this licensing are
00017 ** not clear to you.
00018 **
00019 **********************************************************************/
00020 
00021 #include "engine.h"
00022 
00023 /* OPIE */
00024 #include <opie2/odebug.h>
00025 
00026 /* QT */
00027 #include <qstring.h>
00028 #include <qlcdnumber.h>
00029 
00030 /* STD */
00031 #include <math.h>
00032 
00033 Data Engine::evalStack (Data num, bool inbrace = FALSE)
00034 {
00035   if (state != sError) {
00036     Instruction *i;
00037 
00038 // Pop the next op from the stack
00039     while (!stack.isEmpty () && (braces || !inbrace)) {
00040       i = stack.pop ();
00041 
00042 // Check this ops prec vs next ops prec
00043       if (!stack.isEmpty ())
00044     if (i->precedence <= stack.top()->precedence)
00045       i->acc = evalStack (i->acc, inbrace);
00046 
00047 // Evaluate this instruction
00048       num = i->eval (num);
00049 
00050 // Error-check ( change this to work for all types )
00051       if (isnan (num.dbl) || isinf (num.dbl)) {
00052     odebug << "bad result from operation" << oendl;
00053     state = sError;
00054     clearData(&num);
00055     return num;
00056       }
00057     }
00058   }
00059   return num;
00060 }
00061 
00062 // Plugins call this to request the stack be evaluated
00063 void Engine::eval ()
00064 {
00065   num = evalStack (num);
00066   if (state != sError) {
00067     displayData(num);
00068     state = sStart;
00069   }
00070 // if the user didnt close all their braces, its no big deal
00071   braces = 0;
00072 }
00073 
00074 void Engine::immediateInstruction (Instruction * i)
00075 {
00076   if (state != sError) {
00077     i->setRep(currentRep);
00078     num = i->eval (num);
00079     displayData(num);
00080     state = sStart;
00081   }
00082 }
00083 
00084 void Engine::pushInstruction (Instruction * i)
00085 {
00086   if (state != sError) {
00087     i->setRep(currentRep);
00088     i->acc = num;
00089     stack.push (i);
00090     state = sStart;
00091     }
00092 }
00093 
00094 void Engine::pushValue (char v)
00095 {
00096   if (state == sAppend) {
00097     bool ok = FALSE;
00098     switch (currentRep) {
00099     case rDouble:
00100         displayString.append(v);
00101         num.dbl=displayString.toDouble(&ok);
00102         break;
00103     case rFraction:
00104         break;
00105     default:
00106         displayString.append(v);
00107         num.i=displayString.toInt(&ok, calcBase());
00108     };
00109     if (!ok) {
00110     state = sError;
00111     odebug << "pushValue() - num->string conversion" << oendl;
00112     } else {
00113     const QString constString = displayString;
00114     emit(display(constString));
00115     };
00116 
00117   } else if (state == sStart) {
00118     softReset();
00119     displayString.truncate(0);
00120     state = sAppend;
00121     pushValue (v);
00122   } else if (state == sError) {
00123     odebug << "in error state" << oendl;
00124     return;
00125   }
00126 }
00127 
00128 void Engine::del ()
00129 {
00130     bool ok;
00131     switch (currentRep) {
00132     case rDouble:
00133         displayString.truncate(displayString.length());
00134         num.dbl=displayString.toDouble(&ok);
00135         break;
00136     case rFraction:
00137         odebug << "not available" << oendl;
00138         break;
00139     default:
00140         displayString.truncate(displayString.length());
00141         num.i = displayString.toInt(&ok, calcBase());
00142     };
00143 
00144     if (!ok) {
00145     state = sError;
00146     odebug << "del() - num->string conversion" << oendl;
00147     } else {
00148     const QString constString = displayString;
00149     emit(display(constString));
00150     };
00151 }
00152 
00153 void Engine::displayData(Data d) {
00154     switch (currentRep) {
00155     case rDouble:
00156         displayString.setNum(d.dbl);
00157         break;
00158     case rFraction:
00159         odebug << "fractional display not yet impl" << oendl;
00160         break;
00161     default:
00162         displayString.setNum(d.i, calcBase());
00163         break;
00164     };
00165     const QString constString= displayString;
00166     emit(display(constString));
00167 }
00168 
00169 // Returns the base when Rep is an integer type
00170 int Engine::calcBase () {
00171     switch (currentRep) {
00172     case rBin:
00173         return 2;
00174     case rOct:
00175         return 8;
00176     case rDec:
00177         return 10;
00178     case rHex:
00179         return 16;
00180     default:
00181         state = sError;
00182         odebug << "Error - attempt to calc base for non-integer" << oendl;
00183         return 10;
00184     };
00185 }
00186 
00187 // Special instruction for internal use only
00188 class iOpenBrace:public Instruction {
00189     public:
00190     iOpenBrace (Engine *e):Instruction (100) {engine = e;};
00191     ~iOpenBrace () {};
00192 
00193     Data eval (Data num) {
00194         engine->decBraces();
00195         return num;
00196     };
00197     private:
00198     Engine *engine;
00199 };
00200 
00201 void Engine::openBrace() {
00202     pushInstruction(new iOpenBrace(this));
00203 }
00204 
00205 void Engine::closeBrace() {
00206     braces++;evalStack(num,TRUE);
00207 }
00208 
00209 // will need to show and hide display widgets
00210 void Engine::setRepresentation(Representation r) {
00211     currentRep = r;
00212     clearData(&num);
00213     clearData(&mem);
00214     state = sStart;
00215 }
00216 
00217 void Engine::clearData(Data *d) {
00218     d->i = d->fraction.numerator = d->fraction.denominator = 0;
00219     d->dbl = 0;
00220 }
00221 

Generated on Sat Nov 5 16:18:01 2005 for OPIE by  doxygen 1.4.2