?? stackmachine.cpp
字號:
//////////////////////////////////////////////////////////////////////
//
// Graphite For WinCE(Pocket PC)
// Initially Written By Hyouck "Hawk" Kim, peakhunt@yahoo.com
// 2002, All Rights Reserved
//
// This is GPLed, open source based, software development project.
// For more question about GPL,
// visit http://www.gnu.org/licenses/gpl.txt
//
//
// Revision History
// Nov/30/2002, Initial Release hkim
//
//
//
//
//
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//
// This is implementation of a simple calculator based on POSTFIX
// stack machine.
//
// Several Classes are here.
// First of all, a simple stack and linked list are here.
// The reason those classes are written is STL is not available
// on WinCE as of Nov/2002.
//
// The implementation is awkward and not so serious.
//
// Second of all,
// POSTFIX calculator implementation is provided here.
// The idea is really simple.
// First, by parser, which is implemented as CMathParser,
// all the infix tokens are converted to postfix linked list.
// The Stack Machine calculates some arithmetic with the postfix
// linked list and a stack, which is quite traditional and not
// so much interesting.
//
// Right now, only a limited set of operators and mathematical functions
// are provided. But to extend the set should be a trivila task.
// H.Kim
//////////////////////////////////////////////////////////////////////
// StackMachine.cpp: implementation of the CStackMachine class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "graphite.h"
#include "StackMachine.h"
#include "mathlex.h"
#include <math.h>
#include <stdlib.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSimpleStack::CSimpleStack()
{
m_top = NULL;
}
CSimpleStack::~CSimpleStack()
{
while(!isEmpty())
{
pop();
}
}
void CSimpleStack::push(double val)
{
struct CStackElement* elem = NULL;
elem = new struct CStackElement;
elem->val = val;
elem->next = m_top;
m_top = elem;
}
double CSimpleStack::pop(void)
{
struct CStackElement* elem;
double val;
elem = m_top;
if(elem == NULL)
return 0;
m_top = m_top->next;
val = elem->val;
delete elem;
return val;
}
bool CSimpleStack::isEmpty(void)
{
return m_top == NULL ? true : false;
}
CStackMachine::CStackMachine()
{
m_list = NULL;
m_valid = false;
}
CStackMachine::~CStackMachine()
{
if(m_list != NULL)
delete m_list;
}
//
// this is postfix calculator without stack
//
double CStackMachine::execute(double x)
{
CListElement* elem;
CSimpleStack stack;
double v[2], result, numb;
elem = m_list->m_head;
while(elem != NULL)
{
switch(elem->token->m_type)
{
case MATH_TOKEN_TYPE_OP:
if(stack.isEmpty())
{
TRACE(L"BUG op, stack is empty\n");
return 0;
}
v[1] = stack.pop();
if(stack.isEmpty())
{
TRACE(L"BUG op 2, stack is empty\n");
return 0;
}
v[0] = stack.pop();
result = mathOP(v, 2, elem->token->m_str);
stack.push(result);
break;
case MATH_TOKEN_TYPE_VAR:
// FIXME : variable substitution is not yet implemened
stack.push(x);
break;
case MATH_TOKEN_TYPE_NUM:
{
char buffer[512];
WideCharToMultiByte(CP_ACP, NULL, elem->token->m_str, -1,
buffer,512, NULL, NULL);
numb = atof(buffer);
stack.push(numb);
}
break;
case MATH_TOKEN_TYPE_FUNC:
if(stack.isEmpty())
{
TRACE(L"(BUG func, stack is empty\n");
return 0;
}
v[0] = stack.pop();
result = mathFunc(v, 1, elem->token->m_str);
stack.push(result);
break;
}
elem = elem->next;
}
if(stack.isEmpty())
{
TRACE(L"BUG: returning stack is empty\n");
return 0;
}
return stack.pop();
}
void CStackMachine::changeFormula(CTokenList* list)
{
if(m_list != NULL)
delete m_list;
m_list = list;
m_valid = true;
}
double CStackMachine::mathOP(double variable[], int len, CString &op)
{
double result;
if(len != 2)
{
TRACE(L"PANIC : BUG\n");
return 0;
}
if(op.Compare(L"+") == 0)
{
result = variable[0] + variable[1];
}
else if(op.Compare(L"-") == 0)
{
result = variable[0] - variable[1];
}
else if(op.Compare(L"*") == 0)
{
result = variable[0] * variable[1];
}
else if(op.Compare(L"/") == 0)
{
result = variable[0] / variable[1];
}
else if(op.Compare(L"^") == 0)
{
result = pow(variable[0], variable[1]);
}
else
{
TRACE(L"PANIC : BUG unrecognized op\n");
return 0;
}
return result;
}
double CStackMachine::mathFunc(double variable[], int len, CString func)
{
if(len != 1)
{
TRACE(L"PANIC : BUG VAR!= 1\n");
return 0;
}
double result;
if(func.Compare(L"sin") == 0)
{
result = sin(variable[0]);
}
else if(func.Compare(L"cos") == 0)
{
result = cos(variable[0]);
}
else if(func.Compare(L"tan") == 0)
{
result = tan(variable[0]);
}
else if(func.Compare(L"sqrt") == 0)
{
result = sqrt(variable[0]);
}
else if(func.Compare(L"abs") == 0)
{
result = variable[0];
if(result < 0)
result = -1*result;
}
else if(func.Compare(L"neg") == 0)
{
result = -1*variable[0];
}
else
{
TRACE(L"PANIC : BUG unrecognized function\n");
}
return result;
}
CTokenList::CTokenList()
{
m_head = m_tail = NULL;
}
CTokenList::~CTokenList()
{
CListElement* elem, *tmp;
elem = m_head;
while(elem != NULL)
{
tmp = elem;
delete tmp->token;
delete tmp;
elem = elem->next;
}
}
void CTokenList::addTail(CMathToken* elem)
{
CListElement* newElem = new CListElement;
newElem->token = elem;
newElem->next = NULL;
if(m_head == NULL)
{
m_head = m_tail = newElem;
}
else
{
m_tail->next = newElem;
m_tail = newElem;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -