📄 qcalc.c
字号:
/****************************************************************************** Product: Quantum Calculator Example* Version: Compatible with QEP/C 3.x.yy* Updated: Oct 21, 2005** Copyright (C) 2002-2005 Quantum Leaps, LLC. All rights reserved.** This example is part of the Quantum Leaps QP/C software, and 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 in conjunction* with a valid QP/C Quantum Leaps commercial license. Quantum Leaps* commercial licenses are designed for users who want to retain proprietary* status of their code. The users who license this software under one of* Quantum Leaps commercial licenses do not use this software under the GPL* and therefore are not subject to any of its terms.** Contact information:* Quantum Leaps Web site: http://www.quantum-leaps.com* Quantum Leaps licensing: http://www.quantum-leaps.com/licensing* Quantum Leaps products: http://www.quantum-leaps.com/products* 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_ctor(QCalc *me) { QHsm_ctor_(&me->super_, (QState)&QCalc_initial);}/*..........................................................................*/char const *QCalc_getDisplay(QCalc const *me) { return me->display_;}/*..........................................................................*/void QCalc_clear_(QCalc *me) { memset(me->display_, ' ', DISP_WIDTH - 1); me->display_[DISP_WIDTH - 1] = '0'; me->display_[DISP_WIDTH] = '\0'; me->len_ = 0;}/*..........................................................................*/void QCalc_insert_(QCalc *me, int keyId) { if (me->len_ == 0) { me->display_[DISP_WIDTH - 1] = (char)keyId; ++me->len_; } else if (me->len_ < (DISP_WIDTH - 1)) { memmove(&me->display_[0], &me->display_[1], DISP_WIDTH - 1); me->display_[DISP_WIDTH - 1] = (char)keyId; ++me->len_; } else { }}/*..........................................................................*/void QCalc_negate_(QCalc *me) { QCalc_clear_(me); me->display_[DISP_WIDTH - 2] = '-';}/*..........................................................................*/int QCalc_eval_(QCalc *me) { int ok = 1; double result = 0.0; switch (me->opKey_) { case KEY_PLUS: { result = me->operand1_ + me->operand2_; break; } case KEY_MINUS: { result = me->operand1_ - me->operand2_; break; } case KEY_MULT: { result = me->operand1_ * me->operand2_; break; } case KEY_DIVIDE: { if ((me->operand2_ < -1e-10) || (1e-10 < me->operand2_)) { result = me->operand1_ / me->operand2_; } else { strcpy(me->display_, "Error 0"); /* divide by zero */ ok = 0; } break; } default: { Q_ERROR(); break; } } if (ok) { if ((-1.0e10 < result) && (result < 1.0e10)) { sprintf(me->display_, "%14.11g", result); } else { strcpy(me->display_, "Error 1"); /* Result out of range */ ok = 0; } } return ok;}/* HSM definition ----------------------------------------------------------*/void QCalc_initial(QCalc *me, QEvent const *e) { (void)e; /* suppress the "unreferenced parameter" warning */ me->operand1_ = 0.0; me->operand2_ = 0.0; me->opKey_ = KEY_UNKNOWN; QCalc_clear_(me); Q_INIT(&QCalc_on);}/*..........................................................................*/QSTATE QCalc_on(QCalc *me, QEvent const *e) { switch (e->sig) { case Q_ENTRY_SIG: { QCalc_updateState(me, "on-ENTRY"); return (QSTATE)0; } case Q_EXIT_SIG: { QCalc_updateState(me, "on-EXIT"); return (QSTATE)0; } case Q_INIT_SIG: { QCalc_updateState(me, "on-INIT"); Q_INIT(&QCalc_ready); return (QSTATE)0; } case C_SIG: { QCalc_clear_(me); Q_TRAN_STA(&QCalc_on); /* self-transition */ return (QSTATE)0; } case TERMINATE_SIG: { QCalc_exit(me); return (QSTATE)0; } } return (QSTATE)&QHsm_top;}/*..........................................................................*/QSTATE QCalc_error(QCalc *me, QEvent const *e) { switch (e->sig) { case Q_ENTRY_SIG: { QCalc_updateState(me, "error-ENTRY"); return (QSTATE)0; } case Q_EXIT_SIG: { QCalc_updateState(me, "error-EXIT"); return (QSTATE)0; } } return (QSTATE)&QCalc_on;}/*..........................................................................*/QSTATE QCalc_ready(QCalc *me, QEvent const *e) { switch (e->sig) { case Q_ENTRY_SIG: { QCalc_updateState(me, "ready-ENTRY"); return (QSTATE)0; } case Q_EXIT_SIG: { QCalc_updateState(me, "ready-EXIT"); return (QSTATE)0; } case Q_INIT_SIG: { QCalc_updateState(me, "ready-INIT"); Q_INIT(&QCalc_begin); return (QSTATE)0; } case DIGIT_0_SIG: { QCalc_clear_(me); Q_TRAN(&QCalc_zero1); return (QSTATE)0; } case DIGIT_1_9_SIG: { QCalc_clear_(me); QCalc_insert_(me, ((QCalcEvt *)e)->keyId); Q_TRAN(&QCalc_int1); return (QSTATE)0; } case POINT_SIG: { QCalc_clear_(me); QCalc_insert_(me, (int)'0'); QCalc_insert_(me, (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: { QCalc_updateState(me, "result-ENTRY"); return (QSTATE)0; } case Q_EXIT_SIG: { QCalc_updateState(me, "result-EXIT"); return (QSTATE)0; } } return (QSTATE)&QCalc_ready;}/*..........................................................................*/QSTATE QCalc_begin(QCalc *me, QEvent const *e) { switch (e->sig) { case Q_ENTRY_SIG: { QCalc_updateState(me, "begin-ENTRY"); return (QSTATE)0; } case Q_EXIT_SIG: { QCalc_updateState(me, "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: { QCalc_updateState(me, "negated1-ENTRY"); QCalc_negate_(me); return (QSTATE)0; } case Q_EXIT_SIG: { QCalc_updateState(me, "negated1-EXIT"); return (QSTATE)0; } case CE_SIG: { QCalc_clear_(me); Q_TRAN(&QCalc_begin); return (QSTATE)0; } case DIGIT_0_SIG: { QCalc_insert_(me, ((QCalcEvt *)e)->keyId); Q_TRAN(&QCalc_zero1); return (QSTATE)0; } case DIGIT_1_9_SIG: { QCalc_insert_(me, ((QCalcEvt *)e)->keyId); Q_TRAN(&QCalc_int1); return (QSTATE)0; } case POINT_SIG: { QCalc_insert_(me, ((QCalcEvt *)e)->keyId); Q_TRAN(&QCalc_frac1); return (QSTATE)0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -