📄 qcalc.cpp
字号:
//////////////////////////////////////////////////////////////////////////////// Product: Quantum Calculator Example// Last Updated for Version: 3.3.00// Date of the Last Update: Jan 22, 2007//// Q u a n t u m L e a P s// ---------------------------// innovating embedded systems//// Copyright (C) 2002-2007 Quantum Leaps, LLC. All rights reserved.//// This software may be distributed and modified under the terms of the GNU// General Public License version 2 (GPL) as published by the Free Software// Foundation and appearing in the file GPL.TXT included in the packaging of// this file. Please note that GPL Section 2[b] requires that all works based// on this software must also be made publicly available under the terms of// the GPL ("Copyleft").//// Alternatively, this software may be distributed and modified under the// terms of Quantum Leaps commercial licenses, which expressly supersede// the GPL and are specifically designed for licensees interested in// retaining the proprietary status of their code.//// Contact information:// Quantum Leaps Web site: http://www.quantum-leaps.com// e-mail: sales@quantum-leaps.com//////////////////////////////////////////////////////////////////////////////#include "qep_port.h"#include "qcalc.h"#include "qassert.h"#include <string.h>#include <stdlib.h>#include <stdio.h>Q_DEFINE_THIS_FILE#define KEY_UNKNOWN '?'#define KEY_PLUS '+'#define KEY_MINUS '-'#define KEY_MULT '*'#define KEY_DIVIDE '/'//............................................................................void QCalc::clear(void) { memset(display_, ' ', DISP_WIDTH - 1); display_[DISP_WIDTH - 1] = '0'; display_[DISP_WIDTH] = '\0'; len_ = 0;}//............................................................................void QCalc::insert(int keyId) { if (len_ == 0) { display_[DISP_WIDTH - 1] = (char)keyId; ++len_; } else if (len_ < (DISP_WIDTH - 1)) { memmove(&display_[0], &display_[1], DISP_WIDTH - 1); display_[DISP_WIDTH - 1] = (char)keyId; ++len_; } else { }}//............................................................................void QCalc::negate(void) { clear(); display_[DISP_WIDTH - 2] = '-';}//............................................................................uint8_t QCalc::eval(void) { uint8_t ok = (uint8_t)1; double result = 0.0; switch (opKey_) { case KEY_PLUS: { result = operand1_ + operand2_; break; } case KEY_MINUS: { result = operand1_ - operand2_; break; } case KEY_MULT: { result = operand1_ * operand2_; break; } case KEY_DIVIDE: { if ((operand2_ < -1e-10) || (1e-10 < operand2_)) { result = operand1_ / operand2_; } else { strcpy(display_, "Error 0"); // divide by zero ok = 0; } break; } default: { Q_ERROR(); break; } } if (ok) { if ((-1.0e10 < result) && (result < 1.0e10)) { sprintf(display_, "%14.11g", result); } else { strcpy(display_, "Error 1"); // result out of range ok = 0; } } return ok;}// HSM definition ------------------------------------------------------------void QCalc::initial(QCalc *me, QEvent const *) { me->operand1_ = 0.0; me->operand2_ = 0.0; me->opKey_ = KEY_UNKNOWN; me->clear(); Q_INIT(&QCalc::on);}//............................................................................QSTATE QCalc::on(QCalc *me, QEvent const *e) { switch (e->sig) { case Q_ENTRY_SIG: { me->updateState("on-ENTRY"); return (QSTATE)0; } case Q_EXIT_SIG: { me->updateState("on-EXIT"); return (QSTATE)0; } case Q_INIT_SIG: { me->updateState("on-INIT"); Q_INIT(&QCalc::ready); return (QSTATE)0; } case C_SIG: { me->clear(); Q_TRAN(&QCalc::on); // transition to self return (QSTATE)0; } case TERMINATE_SIG: { me->exit(); return (QSTATE)0; } } return (QSTATE)&QHsm::top;}//............................................................................QSTATE QCalc::error(QCalc *me, QEvent const *e) { switch (e->sig) { case Q_ENTRY_SIG: { me->updateState("error-ENTRY"); return (QSTATE)0; } case Q_EXIT_SIG: { me->updateState("error-EXIT"); return (QSTATE)0; } } return (QSTATE)&QCalc::on;}//............................................................................QSTATE QCalc::ready(QCalc *me, QEvent const *e) { switch (e->sig) { case Q_ENTRY_SIG: { me->updateState("ready-ENTRY"); return (QSTATE)0; } case Q_EXIT_SIG: { me->updateState("ready-EXIT"); return (QSTATE)0; } case Q_INIT_SIG: { me->updateState("ready-INIT"); Q_INIT(&QCalc::begin); return (QSTATE)0; } case DIGIT_0_SIG: { me->clear(); Q_TRAN(&QCalc::zero1); return (QSTATE)0; } case DIGIT_1_9_SIG: { me->clear(); me->insert(((QCalcEvt *)e)->keyId); Q_TRAN(&QCalc::int1); return (QSTATE)0; } case POINT_SIG: { me->clear(); me->insert((int)'0'); me->insert((int)'.'); Q_TRAN(&QCalc::frac1); return (QSTATE)0; } case OPER_SIG: { me->operand1_ = strtod(me->display_, (char **)0); me->opKey_ = ((QCalcEvt *)e)->keyId; Q_TRAN(&QCalc::opEntered); return (QSTATE)0; } } return (QSTATE)&QCalc::on;}//............................................................................QSTATE QCalc::result(QCalc *me, QEvent const *e) { switch (e->sig) { case Q_ENTRY_SIG: { me->updateState("result-ENTRY"); return (QSTATE)0; } case Q_EXIT_SIG: { me->updateState("result-EXIT"); return (QSTATE)0; } } return (QSTATE)&QCalc::ready;}//............................................................................QSTATE QCalc::begin(QCalc *me, QEvent const *e) { switch (e->sig) { case Q_ENTRY_SIG: { me->updateState("begin-ENTRY"); return (QSTATE)0; } case Q_EXIT_SIG: { me->updateState("begin-EXIT"); return (QSTATE)0; } case OPER_SIG: { if (((QCalcEvt *)e)->keyId == KEY_MINUS) { Q_TRAN(&QCalc::negated1); return (QSTATE)0; // event handled } break; } } return (QSTATE)&QCalc::ready;}//............................................................................QSTATE QCalc::negated1(QCalc *me, QEvent const *e) { switch (e->sig) { case Q_ENTRY_SIG: { me->updateState("negated1-ENTRY"); me->negate(); return (QSTATE)0; } case Q_EXIT_SIG: { me->updateState("negated1-EXIT"); return (QSTATE)0; } case OPER_SIG: { if (((QCalcEvt *)e)->keyId == KEY_MINUS) { ; // explicitly ignore return (QSTATE)0; // event handled } break; } case CE_SIG: { me->clear(); Q_TRAN(&QCalc::begin); return (QSTATE)0; } case DIGIT_0_SIG: { me->insert(((QCalcEvt *)e)->keyId); Q_TRAN(&QCalc::zero1); return (QSTATE)0; } case DIGIT_1_9_SIG: { me->insert(((QCalcEvt *)e)->keyId); Q_TRAN(&QCalc::int1); return (QSTATE)0; } case POINT_SIG: { me->insert(((QCalcEvt *)e)->keyId); Q_TRAN(&QCalc::frac1); return (QSTATE)0; } } return (QSTATE)&QCalc::on;}//............................................................................QSTATE QCalc::negated2(QCalc *me, QEvent const *e) { switch (e->sig) { case Q_ENTRY_SIG: { me->updateState("negated2-ENTRY"); me->negate(); return (QSTATE)0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -