author | mickeyl <mickeyl> | 2005-08-23 10:06:07 (UTC) |
---|---|---|
committer | mickeyl <mickeyl> | 2005-08-23 10:06:07 (UTC) |
commit | d6e8e6bf49bb176ec54efed5eb0d012098f056d7 (patch) (side-by-side diff) | |
tree | 7fc70f3d3b41ee05ddb2ea559c7339a18ef0464b /noncore/tools/calc2/main/engine.cpp | |
parent | ce5b18efcb27c853ed4af2b603a82d3f89097764 (diff) | |
download | opie-d6e8e6bf49bb176ec54efed5eb0d012098f056d7.zip opie-d6e8e6bf49bb176ec54efed5eb0d012098f056d7.tar.gz opie-d6e8e6bf49bb176ec54efed5eb0d012098f056d7.tar.bz2 |
make calc2 a subdir project
Diffstat (limited to 'noncore/tools/calc2/main/engine.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/tools/calc2/main/engine.cpp | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/noncore/tools/calc2/main/engine.cpp b/noncore/tools/calc2/main/engine.cpp new file mode 100644 index 0000000..74cd701 --- a/dev/null +++ b/noncore/tools/calc2/main/engine.cpp @@ -0,0 +1,221 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "engine.h" + +/* OPIE */ +#include <opie2/odebug.h> + +/* QT */ +#include <qstring.h> +#include <qlcdnumber.h> + +/* STD */ +#include <math.h> + +Data Engine::evalStack (Data num, bool inbrace = FALSE) +{ + if (state != sError) { + Instruction *i; + +// Pop the next op from the stack + while (!stack.isEmpty () && (braces || !inbrace)) { + i = stack.pop (); + +// Check this ops prec vs next ops prec + if (!stack.isEmpty ()) + if (i->precedence <= stack.top()->precedence) + i->acc = evalStack (i->acc, inbrace); + +// Evaluate this instruction + num = i->eval (num); + +// Error-check ( change this to work for all types ) + if (isnan (num.dbl) || isinf (num.dbl)) { + odebug << "bad result from operation" << oendl; + state = sError; + clearData(&num); + return num; + } + } + } + return num; +} + +// Plugins call this to request the stack be evaluated +void Engine::eval () +{ + num = evalStack (num); + if (state != sError) { + displayData(num); + state = sStart; + } +// if the user didnt close all their braces, its no big deal + braces = 0; +} + +void Engine::immediateInstruction (Instruction * i) +{ + if (state != sError) { + i->setRep(currentRep); + num = i->eval (num); + displayData(num); + state = sStart; + } +} + +void Engine::pushInstruction (Instruction * i) +{ + if (state != sError) { + i->setRep(currentRep); + i->acc = num; + stack.push (i); + state = sStart; + } +} + +void Engine::pushValue (char v) +{ + if (state == sAppend) { + bool ok = FALSE; + switch (currentRep) { + case rDouble: + displayString.append(v); + num.dbl=displayString.toDouble(&ok); + break; + case rFraction: + break; + default: + displayString.append(v); + num.i=displayString.toInt(&ok, calcBase()); + }; + if (!ok) { + state = sError; + odebug << "pushValue() - num->string conversion" << oendl; + } else { + const QString constString = displayString; + emit(display(constString)); + }; + + } else if (state == sStart) { + softReset(); + displayString.truncate(0); + state = sAppend; + pushValue (v); + } else if (state == sError) { + odebug << "in error state" << oendl; + return; + } +} + +void Engine::del () +{ + bool ok; + switch (currentRep) { + case rDouble: + displayString.truncate(displayString.length()); + num.dbl=displayString.toDouble(&ok); + break; + case rFraction: + odebug << "not available" << oendl; + break; + default: + displayString.truncate(displayString.length()); + num.i = displayString.toInt(&ok, calcBase()); + }; + + if (!ok) { + state = sError; + odebug << "del() - num->string conversion" << oendl; + } else { + const QString constString = displayString; + emit(display(constString)); + }; +} + +void Engine::displayData(Data d) { + switch (currentRep) { + case rDouble: + displayString.setNum(d.dbl); + break; + case rFraction: + odebug << "fractional display not yet impl" << oendl; + break; + default: + displayString.setNum(d.i, calcBase()); + break; + }; + const QString constString= displayString; + emit(display(constString)); +} + +// Returns the base when Rep is an integer type +int Engine::calcBase () { + switch (currentRep) { + case rBin: + return 2; + case rOct: + return 8; + case rDec: + return 10; + case rHex: + return 16; + default: + state = sError; + odebug << "Error - attempt to calc base for non-integer" << oendl; + return 10; + }; +} + +// Special instruction for internal use only +class iOpenBrace:public Instruction { + public: + iOpenBrace (Engine *e):Instruction (100) {engine = e;}; + ~iOpenBrace () {}; + + Data eval (Data num) { + engine->decBraces(); + return num; + }; + private: + Engine *engine; +}; + +void Engine::openBrace() { + pushInstruction(new iOpenBrace(this)); +} + +void Engine::closeBrace() { + braces++;evalStack(num,TRUE); +} + +// will need to show and hide display widgets +void Engine::setRepresentation(Representation r) { + currentRep = r; + clearData(&num); + clearData(&mem); + state = sStart; +} + +void Engine::clearData(Data *d) { + d->i = d->fraction.numerator = d->fraction.denominator = 0; + d->dbl = 0; +} + |