LStack.h (Interface
File)
/*-- LStack.h ---------------------------------------------------
This header file defines a Stack
data type.
Basic operations:
constructor: Constructs an empty stack
empty: Checks if a stack is empty
push: Modifies a stack by adding a value at
the top
top: Accesses the top stack value; leaves
stack
unchanged
pop: Modifies stack by removing the value
at the
top
display: Displays all the stack elements
Class Invariant:
1. The stack elements (if any)
are stored in linked nodes and
have the myTop pointer that
points to the first node
---------------------------------------------------------------*/
#include <iostream>
using namespace std;
#ifndef LSTACK
#define LSTACK
typedef int StackElement;
class Stack
{
public:
/***** Function
Members *****/
/***** Constructors
*****/
Stack();
/*----------------------------------------------------------
Construct a Stack object.
Precondition: None.
Postcondition: An empty Stack
object has been constructed
-----------------------------------------------------------*/
Stack(const
Stack & original);
/*----------------------------------------------------------
Copy Constructor
Precondition: original is the stack to be copied and
is received as a const
reference parameter.
Postcondition: A copy of
original has been constructed.
-----------------------------------------------------------*/
/***** Destructor
*****/
~Stack();
/*----------------------------------------------------------
Class destructor
Precondition: None
Postcondition: The dynamic array
in the stack has been
deallocated.
-----------------------------------------------------------*/
/***** Assignment
*****/
Stack & operator=
(const Stack & original);
/*----------------------------------------------------------
Assignment Operator
Precondition: original is the stack to be assigned and
is received as a const
reference parameter.
Postcondition: The current stack
becomes a copy of
original and a reference to
it is returned.
-----------------------------------------------------------*/
bool empty() const;
/*-----------------------------------------------------------
Check if stack is empty.
Precondition: None
Postcondition: Returns true if
stack is empty and
false otherwise.
-----------------------------------------------------------*/
void push(const StackElement & value);
/*-----------------------------------------------------------
Add a value to a stack.
Precondition: value is to be added to this stack
Postcondition: value is added at
top of stack provided
there is space; otherwise, a
stack-full message is
displayed and execution is
terminated.
-----------------------------------------------------------*/
void
display(ostream & out) const;
/*-----------------------------------------------------------
Display values stored in the
stack.
Precondition: ostream out is open.
Postcondition: Stack's contents,
from top down, have
been output to out.
-----------------------------------------------------------*/
StackElement top() const;
/*-----------------------------------------------------------
Retrieve value at top of stack
(if any).
Precondition: Stack is nonempty
Postcondition: Value at top of
stack is returned, unless
the stack is empty; in that
case, an error message is
displayed and a
"garbage value" is returned.
----------------------------------------------------------*/
void pop();
/*-----------------------------------------------------------
Remove value at top of stack (if
any).
Precondition: Stack is nonempty.
Postcondition: Value at top of
stack has been removed,
unless the stack is empty;
in that case, an error
message is displayed and
execution allowed to proceed.
----------------------------------------------------------*/
private:
/*** Node class
***/
class Node
{
public:
StackElement data;
Node * next;
//--- Node
constructor
Node(StackElement value, Node * link = 0)
/*------------------------------------------------------
Precondition: value is received
Postcondition: A Node has
been constructed with value
in its data part and itb
next part set to link
(default 0).
------------------------------------------------------*/
{
data = value;
next = link;
}
};
private:
/***** Data Members
*****/
Node * myTop; // pointer to
top of stack
};
#endif //LSTACK_H
LStack.cpp
(Implementation File)
#include "LStack.h"
#include <cassert>
using namespace std;
//--- Definition of Stack constructor
Stack::Stack()
{
myTop = 0;
}
//************************************************************************
//--- Definition of Stack copy constructor
Stack::Stack(const Stack & original)
{
myTop = 0;
Node*ptr = original.myTop;
Node* LastNode;
if(!original.empty())
{
myTop = new(nothrow)Node(ptr->data);
assert(myTop!=0);
LastNode = myTop;
ptr = ptr->next;
while (ptr!=0)
{
LastNode->next = new(nothrow)Node(ptr->data);
ptr = ptr->next;
LastNode = LastNode->next;
}
}
}
//***********************************************************************
//--- Definition of Stack destructor
Stack::~Stack()
{
// Set pointers to
run through the stack
while(!empty())
pop();
}
//***********************************************************************
//--- Definition of assignment operator
Stack &
Stack::operator=(const
Stack & original)
{
myTop = 0;
if
(original.empty()) return *this;
if (this != &original) // check that
not st = st
{
this->~Stack(); // destroy
current linked list
Stack temp = original ;
myTop = temp.myTop;
temp.myTop = NULL;
}
return *this ;
}
//***********************************************************************
//--- Definition of empty()
bool
Stack::empty() const
{
return
(myTop == 0);
}
//***********************************************************************
//--- Definition of push()
void
Stack::push(const StackElement & value)
{
myTop
= new (nothrow) Node(value, myTop);
assert(myTop!=0);
}
//***********************************************************************
//--- Definition of display()
void Stack::display(ostream
& out) const
{
Node* ptr;
ptr = myTop;
while
(ptr!=0)
{
out << ptr->data << endl;
ptr = ptr->next;
}
}
//***********************************************************************
//--- Definition of top()
StackElement
Stack::top() const
{
if
(!empty())
return
(myTop->data);
else
{
cerr << "***
Stack is empty "
<< "
-- returning garbage ***\n";
StackElement garbage;
return
garbage; //
"Garbage" value
}
}
//***********************************************************************
//--- Definition of pop()
void
Stack::pop()
{
if
(!empty())
{
Node* ptr = myTop;
myTop = myTop->next;
delete
ptr;
}
else
cerr << "***
Stack is empty -- can't remove a value ***\n";
}
//***********************************************************************
Functions.h (Interface
File)
/*-- Functions.h ---------------------------------------------------
This header file contains some
function that we use in the program.
welcome_screen: Displays welcome
screen to the user
clear_screen: Cleans the screen
and makes it blank.
wait: Stops the excution of the
program for the number of the seconds that has been sent as an argument
convert: Converts the postfix
expression to Assmbly code and evaluts it.
Thank_You: Displays thanks screen
for the user.
---------------------------------------------------------------*/
#include <windows.h>
#include <iostream>
#include <stdio.h>
#include <time.h>
using namespace std;
void
welcome_screen();
/*************************************************************************
- A function that displays the
welcome screen with our initials.
- Precondition: None.
- Postcondition: The Welcome
Screen appears.
*************************************************************************/
void
clear_screen();
/*************************************************************************
- Prototype of the clear screen
function.
- Precondition: None.
- Postcondition: The screen
becomes clean.
*************************************************************************/
void wait ( int seconds );
/*************************************************************************
- Prototype of the wait
function.
- Precondition: the number of
seconds should be valid.
- Postcondition: The program
will stop for "seconds" seconds.
/*************************************************************************/
void
convert(string& str, int& acc);
/*************************************************************************
Converting the postfix
expression to Assembly Instructions
- Precondition: A str should be
sent by refrence.
an
accumulator register should be sent be refrence.
- Postcondition: The string
converts to Assembly code
and the postfix expression is evaluated
/*************************************************************************/
void
Thank_You();
/*************************************************************************
- A function that displays
"thank you" for the user.
- Precondition: None.
- Postcondition: The Thank You
screen appears.
*************************************************************************/
Functions.cpp
(Implementation File)
#include "Functions.h"
#include "LStack.h"
void
welcome_screen()
{
//Welcome Screen
cout << endl << endl;
cout << "
* * *" << "
********" << " *
" << " ******* " << " *** ***
" << " *****
*****" << "
********\n"
<< "
* * *" << "
* " << "
* " << "* " << "
* **
* " << "* * *" << "
*\n";
cout << "
* * *" << "
* " << "
* "
<< "* " << "
* * " << "* *
*" << " *\n"
<< "
* *
*" << " ********" << "
* "
<< "* " << " *
* " << "* *
*" << " ********\n";
cout << "
* * *" << "
* " << "
* "
<< "* " << " *
* " << "* *
*" << " *\n"
<< "
* * *" << "
* " << "
* "
<< "* " << " *
* " << "* *
*" << " *\n" << " ***** *****" << "
********" << " ******* " << " ******* " << " *
" << " * * *" << "
********\n";
/*Smiling Faces*/
cout << "\n\n";
cout << " ****" << " ****" << " ****\n"
<< " * *" << " * *" << " * *\n"
<< " *
* * *" <<
"
* * *
*" << "
* * *
*\n"
<< " * *" << " * *" << " * *\n"
<< " * * * *" <<
"
* * * *" << " * * * *\n"
<< " *
* * *" <<
"
* * *
*" << "
* * *
*\n"
<< " *
** *" << " *
** *" << " *
** *\n"
<< " *
*" << "
* *" << " * *\n"
<< " ****" << " ****" << " ****\n\n";
/*OUR INITIALS*/
cout << " ****** ** ** ******\n"
<< " **
** ** **\n"
<< " **
** ** **\n"
<< " ****** ********* \t
******\n"
<< " ** ** **
**\n"
<< " ** ** ** **\n"
<< " ****** ** ** ******\n\n";
}
//**********************************************************************
void
clear_screen () /* Definition of clear_screen function */
{
COORD coordScreen = { 0, 0 };
DWORD cCharsWritten;
CONSOLE_SCREEN_BUFFER_INFO csbi;
DWORD dwConSize;
HANDLE hConsole =
GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hConsole,
&csbi);
dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
FillConsoleOutputCharacter(hConsole, TEXT(' '), dwConSize, coordScreen, &cCharsWritten);
GetConsoleScreenBufferInfo(hConsole,
&csbi);
FillConsoleOutputAttribute(hConsole,
csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten);
SetConsoleCursorPosition(hConsole,
coordScreen);
}
//*********************************************************************************************
void wait ( int seconds )
{
clock_t endwait;
endwait = clock () + seconds * CLOCKS_PER_SEC
;
while
(clock() < endwait) {}
}
//*********************************************************************************************
void
convert(string& str, int& acc)
{
Stack s;
signed int_value;
//Temporary value to convert the string into
an int.
int
digit_count=0, char_count=0; //counters
for (unsigned i = 0 ; i< str.length(); i++)
{
if
(isdigit(str[i]))
digit_count ++;
else
if (str[i]=='+'
||str[i]=='-' ||str[i]=='*' ||str[i]=='/'
)
char_count++;
else
if (str[i]== ' '
|| str[i] == '~');
//just to
ignore the space and the unary operator
else
//if a character that is not one of the following
(digit, operator, space, tilda '~')
{
cout << "\n\a\a Invalid Postfix expression.\n\n";
return;
}
if(digit_count
<= char_count && char_count !=0) //To
check if it's a valid expression.
{
cout << "\n\a\a Invalid Postfix expression.\n\n"
<< " You
will get a wrong result.\n\n";
return;
}
}
if
(char_count < (digit_count - 1))
{
cout << "\n\a\a Invalid Postfix expression.\n\n"
<< " You
will get a wrong result.\n\n";
return;
}
for (unsigned i = 0 ; i< str.length(); i++)
if
(isdigit(str[i]))
{
int_value = str[i] - 48 ;
//When
a char is a digit it represents as the value of that digit + 48
s.push( int_value );
}
else if (str [i] == '~'
)
{
if
(isdigit(str[i+1]))
{
int_value = (str[i+1] - 48) *
(-1);
s.push(int_value);
i++;
}
else
{
cout << "\a\a Invalid.
A digit should follow the ~ immediatly.\n\n"
<< " You
will get a wrong result.\n\n";
return
;
}
}
else if (str [i] == ' ');
//Ignoring the
space
else
{
wait(1);
acc = s.top();
s.pop();
cout << "\n LOAD "<< s.top() << endl
<< endl;
wait(1);
if
(str[i] == '+')
{
cout << " ADD " << acc << endl << endl;
acc += s.top();
}
else
if (str[i] == '-')
{
cout << " SUB " << acc << endl << endl;
acc = s.top() - acc;
}
else
if (str[i] == '*')
{
cout << " MULT " << acc << endl << endl;
acc *= s.top();
}
else
if (str[i] == '/')
{
cout << " DIV " << acc << endl
<< endl ;
if
(acc == 0)
{
cout << "\a\a\a\a Logical error. You can not divide by 0.\n\n"
<< " You
will get a wrong result.\n\n";
return;
}
else
acc = s.top() / acc;
}
s.pop();
s.push(acc);
wait(1);
cout << " STORE " << s.top() << endl;
}
}
//*********************************************************************************************
void
Thank_You()
{
cout << "\n\n\n
\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1"
<< "\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\n\n\n"
<< " \x2 \x2 \x2
\x2 \x2 \x2
\x2 \x2 \x2
\x2 \t\x2 \x2
\x2\x2\x2 \x2 \x2\n"
<< " \x2
\x2 \x2 \x2 \x2 \x2\x2
\x2 \x2 \x2 \t \x2 \x2 \x2
\x2 \x2 \x2\n"
<< " \x2
\x2\x2\x2\x2\x2 \x2 \x2
\x2 \x2 \x2 \x2\x2 \t
\x2 \x2 \x2
\x2 \x2\n"
<< " \x2
\x2 \x2 \x2 \x2 \x2 \x2 \x2
\x2\x2 \x2 \x2 \t \x2
\x2 \x2 \x2
\x2\n"
<< " \x2
\x2 \x2 \x2
\x2 \x2 \x2
\x2 \x2 \t\x2
\x2\x2\x2 \x2\x2\x2"
<< "\n\n\n
\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1"
<< "\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\n\n\n";
}
//*********************************************************************************************
Client Code
#include "LStack.h"
#include "Functions.h"
#include <cctype>
#include <cstdlib>
#include <string>
void main()
{
welcome_screen();
wait(3);
clear_screen();
string postfix;
int
result;
char
answer;
cout << "\n\n\t
**********************************************************\n\n"
<< "\t\t \x4 The Puropose of This Program \x4"
<< "\n\n\t
**********************************************************\n\n"
<< "\t\t
To convert Post Fix expressions into its\n\n"
<< "\t\tequivelent
assembly language instructions\n\n"
<< "\t\tand
to evaluate the expressions\n\n\n\n";
do
{
result = 0;
cout << "\n Enter a postfix expression:\n\n ";
getline (cin ,postfix);
cout << "\n\n\n**************************************************************\n\n";
cout << "\n\n ASSEMBLY INSTRUCTIONS:\n\n";
wait(1);
convert(postfix, result);
cout << "\n\n\n The result = " << result
<< endl;
cout << "\n\n**************************************************************\n\n";
cout << " Would you like to convert another postfix
expression(Yes/No): ";
cin >> answer;
cin.ignore(100, '\n');
clear_screen();
}while(toupper(answer)
!= 'N');
clear_screen();
Thank_You();
}