📄 engine.cpp
字号:
state = sStart;}#endif#ifdef NEW_STYLE_STACKvoid Engine::pushInstruction(QString name) { if (state == sError) return; InstructionDescription *id = resolveDescription(name); if (!id) return; previousInstructionsPrecedence = id->precedence; secondaryReset = FALSE; if (!id->precedence) { executeInstructionOnStack(name,dStack); updateDisplay(); delete id; if (state != sError) state = sStart; return; } if (!iStack.isEmpty() && state == sStart && id->precedence && previousInstructionsPrecedence) { iStack.pop(); } if (!iStack.isEmpty()) { InstructionDescription *top = resolveDescription(*(iStack.top())); if (id->precedence <= top->precedence) { Data *accPtr = acc; acc = evalStack(accPtr,FALSE,top->precedence); if (accPtr != acc) delete accPtr; updateDisplay(); } } Instruction *copy = resolveInstruction("Copy"); // No tr if (!copy) return; id->num = copy->eval(acc); delete copy; if ( state == sError ) return; stack.push(id); state = sStart;}#elsevoid Engine::pushInstruction(InstructionDescription *i) { if (state != sError) { secondaryReset = FALSE; if (!i->precedence) { executeInstructionOnStack(i->instructionName,stack); updateDisplay(); if (state != sError) state = sStart; } else { if (!stack.isEmpty() && state == sStart && i->precedence && previousInstructionsPrecedence) { delete stack.pop(); } if (!stack.isEmpty()) { if (i->precedence <= stack.top()->precedence) { Data *accPtr = acc; acc = evalStack(accPtr,FALSE,stack.top()->precedence); if (accPtr != acc) delete accPtr; updateDisplay(); } } InstructionDescription *id = resolveDescription(i->instructionName); if (id) { Instruction *copy = resolveInstruction("Copy"); // No tr if (copy) { i->num = copy->eval(acc); delete copy; if ( state != sError ) { stack.push(i); state = sStart; previousInstructionsPrecedence = i->precedence; return; } else if (i->num != acc) delete i->num; } } } previousInstructionsPrecedence = i->precedence; } delete i;}#endif#ifdef NEW_STYLE_STACKvoid Engine::pushChar(char c) { if (state == sError) return; if (dStack.isEmpty()) executeInstructionOnStack("Factory",dStack); // No tr if (dStack.isEmpty()) { setError(eNoDataFactory); return; } if (!dStack.top()->push(c, FALSE)) return; if (state == sStart) { softReset(FALSE); state = sAppend; } dStack.top()->push(c); secondaryReset = FALSE; updateDisplay();}#elsevoid Engine::pushChar(char c) { if (!checkState()) return; if (state == sStart) { Instruction *copy = resolveInstruction("Copy"); // No tr if (copy) { Data *num = copy->eval(acc); delete copy; if (num == acc) { state = sError; return; } if ( state != sError ) { num->clear(); if (!num->push(c, FALSE)) { delete num; return; } } delete num; } } else { if (!acc->push(c, FALSE)) return; } if (state == sStart) { softReset(FALSE); state = sAppend; } acc->push(c); secondaryReset = FALSE; updateDisplay();}#endifvoid Engine::push(QString s) { softReset(); for (uint i=0;i < s.length();i++) pushChar(s[(int)i].latin1());}void Engine::delChar() { if (!checkState()) return; acc->del(); updateDisplay();}void Engine::updateDisplay() { if (state == sError || !lcd) return;#ifdef NEW_STYLE_STACK if (dStack.isEmpty()) executeInstructionOnStack("Factory",dStack); // No tr if (dStack.isEmpty()) qDebug("still empty, type = %s, state = %d,stack size = %d",currentType.latin1(),state,dStack.count()); Data *d = dStack.top();#else if (!acc) executeInstructionOnStack("Factory",stack); // No tr Data *d = acc;#endif#ifdef NEW_STYLE_DISPLAY if (!lcdPainter) { lcdPainter = new QPainter(); } QPixmap lcdPixmap(300,100); lcdPixmap.fill(); lcdPainter->begin(&lcdPixmap); lcdPainter->setPen(Qt::black); d->draw(lcdPainter); lcdPainter->end(); lcd->setPixmap(lcdPixmap);#else lcd->setText(d->getFormattedOutput());#endif}bool Engine::checkState() { if (state == sError) return FALSE; if (!acc) //stack.isEmpty()) executeInstructionOnStack("Factory",stack); // No tr if (!acc) //stack.isEmpty()) return FALSE; if (currentType == "NONE") return FALSE; return TRUE;}// Memory#ifdef NEW_STYLE_STACKvoid Engine::memorySave() { if (state == sError) return; if (dStack.isEmpty()) return; QStack<Data> tmp; if (!mem) { executeInstructionOnStack("Factory",tmp); // No tr mem = tmp.pop(); } tmp.push(dStack.pop()); tmp.push(mem); executeInstructionOnStack("Add",tmp); // No tr if (state != sError) state = sStart;}#elsevoid Engine::memorySave() { if (!checkState()) return; if (!mem) { Instruction *factory = resolveInstruction("Factory"); // No tr if (!factory) { setError(eNoDataFactory); return; } mem = factory->eval(new Data()); delete factory; memMark->show();#ifdef QTESTqDebug("creating the new memory data at %p, value = %s" ,mem,mem->getFormattedOutput().latin1());#endif } Instruction *add = resolveInstruction("Add"); // No tr if (!add) return; add->num = acc; mem = add->eval(mem); delete add;#ifdef QTESTqDebug("adding the new memory data to the old at %p, value = %s" ,mem,mem->getFormattedOutput().latin1());#endif Instruction *factory = resolveInstruction("Factory"); // No tr if (factory) { Data *memCmp = factory->eval(acc); if (memCmp) { if (mem->getFormattedOutput() == memCmp->getFormattedOutput()) memoryReset(); delete memCmp; } delete factory; } if (state != sError) state = sStart; qApp->processEvents();}#endifvoid Engine::memoryRecall() { softReset(); if (!mem) return;#ifdef QTESTqDebug("contents of memory at memoryRecall() = %s", mem->getFormattedOutput().latin1());#endif Instruction *copy = resolveInstruction("Copy"); // No tr if (!copy) return; if (acc) delete acc; acc = copy->eval(mem); delete copy; updateDisplay(); if (state != sError) state = sStart;}void Engine::memoryReset() { if (mem) { delete mem; mem = 0; } memMark->hide();}// Uninteresting functionsvoid Engine::setError(Error e){ QString s; switch (e) { case eNotANumber: s = qApp->translate("Engine", "Not a number"); break; case eNegInf: // For the translations sake s = qApp->translate("Engine", "Negative infinity"); break; case eInf: s = qApp->translate("Engine", "Infinity"); break; case eNonPositive: s = qApp->translate("Engine", "Input not a positive number"); break; case eNonInteger: s = qApp->translate("Engine", "Not an integer"); break; case eOutOfRange: s = qApp->translate("Engine", "Out of range"); break; case eDivZero: s = qApp->translate("Engine", "Divide by zero error"); break; case eNotSolvable: s = qApp->translate("Engine", "Not solvable"); break; case eNoDataFactory: s = qApp->translate("Engine", "No data factory found"); case eError: default: // let setError(QString) pick it up break; } setError(s);}void Engine::setError(QString s) { if (s.isEmpty()) s = qApp->translate("Engine","Error"); state = sError; lcd->setText(s);}#ifdef NEW_STYLE_DISPLAYvoid Engine::setDisplay(QLabel *l) {#elsevoid Engine::setDisplay(QLineEdit *l) {#endif lcd = l; memMark = new QLabel( "m", lcd ); memMark->setBackgroundMode( QWidget::PaletteBase ); memMark->setFont( QFont( "helvetica", 12, QFont::Bold, TRUE ) ); memMark->resize( 12, 12 ); memMark->move( 4, 2 ); memMark->hide(); kMark = new QLabel( "k", lcd ); kMark->setBackgroundMode( QWidget::PaletteBase ); kMark->setFont( QFont( "helvetica", 12, QFont::Bold, TRUE ) ); kMark->resize( 12, 12 ); kMark->move( 4, 14 ); kMark->hide();}#ifdef NEW_STYLE_STACKvoid Engine::executeInstructionOnStack(QString name,QStack<Data> ds) { InstructionDescription *id = resolveDescription(name); if (!id) {#ifdef QTESTqDebug("desc not found for %s",name.latin1());#endif return; } Instruction *i = resolveInstruction(id); if (name == "Factory") { // No tr if (!i) {#ifdef QTESTqDebug("Instruction not found for %s",name.latin1());#endif setError(eNoDataFactory); } else {#ifdef QTESTqDebug("before eval stack size is %d",ds.count());#endif ds.push(i->eval(0));#ifdef QTESTqDebug("after eval stack size is %d",ds.count());#endif delete id; delete i; } return; } if (!i) {#ifdef QTESTqDebug("Instruction not found for %s",name.latin1());#endif return; } while (iStack.count() < uint(id->argCount)) // might be better to just bail out executeInstructionOnStack("Factory",ds); // No tr if (state == sError) {#ifdef QTESTqDebug("trouble in recursive call");#endif return; } Data *ret = i->eval(ds.pop()); if (!ret) {#ifdef QTESTqDebug("error in evaluating instruction");#endif return; } if (state == sError) {#ifdef QTESTqDebug("Error in evaluating %s",name.latin1());#endif delete ret; return; } ds.push(ret); delete i; delete id;#ifdef QTESTqDebug("end");#endif}#else// this function is convoluted because acc is not (yet) the top of the stackvoid Engine::executeInstructionOnStack(QString name,QStack<InstructionDescription> ds) { Instruction *i = resolveInstruction(name); if (name == "Factory") { // No tr if (!i) { setError(eNoDataFactory); } else { if (acc) { InstructionDescription *id = new InstructionDescription(); id->num = acc; stack.push(id); } Data *tmpData = new Data(); acc = i->eval(tmpData); delete i; if (tmpData != acc) delete tmpData; } return; } if (!acc) // i->argCount) executeInstructionOnStack("Factory",ds); // No tr if (state == sError) return; Data *accPtr = acc; acc = i->eval(accPtr); delete i; if ( accPtr != acc ) delete accPtr;}#endif#ifdef NEW_STYLE_STACKvoid Engine::setAccType(QString type) { if (currentType == type) return; currentType = type; if (dStack.isEmpty()) { executeInstructionOnStack("Factory",dStack); // No tr if (state != sError) state = sStart; } else { executeInstructionOnStack("Convert",dStack); // No tr } updateDisplay();}#elsevoid Engine::setAccType(QString type) { if (currentType == type) return; currentType = type; if (!acc) { executeInstructionOnStack("Factory",stack); // No tr if (state != sError) state = sStart; } else { executeInstructionOnStack("Convert",stack); // No tr } updateDisplay();}#endifQString Engine::getDisplay() { return acc->getFormattedOutput();}void Engine::openBrace () { if (state == sError) return; stack.push(new BraceOpen()); state = sStart;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -