+1 (315) 557-6473 

C++ Program to Manipulate Stacks Assignment Solution.


Instructions

Objective
Write a C++ assignment program to manipulate stacks.

Requirements and Specifications

program to implement stacks in C++

Source Code

// Your implementation of the Stack class goes here!!!!

#include "Stack.hpp"

#include

using namespace std;

ActivationRecord* Stack::pop() {

 ActivationRecord* ar = back();

 pop_back();

 return ar;

}

void Stack::push(ActivationRecord *newAR) {

 push_back(newAR);

}

ActivationRecord* Stack::top() const {

 return back();

}

ActivationRecord* Stack::peek() const {

 return top();

}

bool Stack::isEmpty() const {

 return empty();

}

ostream& operator<<(ostream &os, const Stack &s) {

 for (auto it = s.rbegin(); it != s.rend(); ++it) {

  os << *(*it) << endl;

 }

 return os;

}

STATEMENT

// !!!!!! You will have to add code inside of this class. Some of

// the code provided here is designed to help you, but you

// do not need to use it if you do not want to.

#include "Statement.hpp"

#include

#include

#include

using namespace std;

int __nextSnum=0; // keeps track of the next statement number to use.

int __paramValue; // this is a global to help with passing a parameter.

/****

 **** If you are following project specifications, then you will likley

 **** find this function quite useful. When given an ActivationRecord

 **** (pointer) and a string containing an operand, this function returns

 **** the operand's value (as found in the ActivationRecord.)

 ****/

int getValue(ActivationRecord *ar, const std::string &operand)

{

  if (operand == "$$") // looking for the parameter

    return ar->parameterValue();

  else if (isdigit(operand[0]) || operand[0]=='-') // constant value (int)

    {

      return atoi(operand.c_str());

    }

  else // ID

    {

      // find the variable in the activation record

      Variable *var = (Variable *) ar->getVariable(operand);

      // if the variable was not found, let the user know.

      if (var==NULL)

 {

   cerr << "Attempt to use an uninitialized variable: "

        << operand << endl;

   return 0;

 }

      else

 return var->value(); //return value of the associated variable

    }

}

/****

 **** If you are following project specifications, then you will likley

 **** find this function quite useful. When given an ActivationRecord

 **** (pointer), a string containing an variable name, and a new value,

 **** this function sets that variable to the new value (in the associated

 **** ActivationRecord.) If the variable isn't found in the Activation

 *** Record, it is added to the ActivationRecord.

 ****/

void setValue(ActivationRecord *ar, const std::string &varName, int toVal)

{

  if (varName == "$$") // parameter

    ar->parameterValue() = toVal;

  else // anything else must be a variable

    {

      // get the Variable from the ActivationRecord

      Variable *var = (Variable *) ar->getVariable(varName);

      // no such variable? Means we need to add it to the ActivationRecord

      if (var==NULL)

 {

   ar->addVariable(varName);

   var = (Variable *) ar->getVariable(varName);

 }

      // now that we know we have a variable, set its value ...

      var->value()=toVal;

    }

}

//

// ******** YOU MUST CODE LARGE PARTS OF THIS !!!! **********

//

// Executes a statement. See the project handout for details. Some

// initial statements are given as examples.

//

// withStack - The ActivationRecord (i.e. execution) stack to use

// ft - the table of function names & starting points

//

// *should return the statement number (ddress) of the next statement to run

int

Statement::execute(Stack &withStack, const FunctionTable &ft) const

{

  // the next statement will be 1 after this one ... with the exception

  // of calls, rets, and skips (see project handout.)

  int nextAddr = _snum+1;

  if (_operation=="printS") // print string.

    {

      cout << _operands.front();

    }

  else if (_operation=="printN") // print number

    {

      // get the value to print from the current activation record.

      int valueOfN = getValue(withStack.top(), _operands.front());

      // print that value

      cout << valueOfN;

    }

  else if (_operation=="printNL") // drop down a line in output

    {

      cout << endl; // yep, it's that simple!

    }

 else if (_operation=="call")

    {

   // getting function name

   string fName = _operands.front();

   // creating new activation record for this function call

   ActivationRecord* ar = new ActivationRecord(fName, nextAddr, __paramValue);

   // pushing record into the stack

   withStack.push(ar);

   // updating next address

   nextAddr = ft.lookup(fName).firstInstruction();

    }

 else if (_operation=="ret")

    {

   // removing top record

   ActivationRecord* ar = withStack.pop();

   // changing next address according to record address

   nextAddr = ar->returnAddress();

    }

 else if (_operation=="retv")

    {

   // removing top record

      ActivationRecord* ar = withStack.pop();

   // updating incoming return value in the next top record

      ActivationRecord* ar2 = withStack.top();

   ar2->incomingReturnValue() = getValue(ar, _operands.front());

   // updating address

      nextAddr = ar->returnAddress();

    }

 else if (_operation=="storet")

    {

   // getting current record

   ActivationRecord* ar = withStack.top();

   // setting value to variable with incoming return value

   setValue(ar, _operands.front(), ar->incomingReturnValue());

    }

 else if (_operation=="param")

    {

   // getting current record

      ActivationRecord* ar = withStack.top();

      __paramValue = getValue(ar, _operands.front());

    }

 else if (_operation=="sub")

    {

   // getting each operand string value

   auto it = _operands.begin();

   string a = *it;

   it++;

   string b = *it;

   it++;

   string c = *it;

   // getting current record

      ActivationRecord* ar = withStack.top();

   // updating value of operand c

   setValue(ar, c, getValue(ar, a) - getValue(ar, b));

    }

 else if (_operation=="add")

    {

      // getting each operand string value

   auto it = _operands.begin();

   string a = *it;

   it++;

   string b = *it;

   it++;

   string c = *it;

      // getting current record

      ActivationRecord* ar = withStack.top();

   // updating value of operand c

   setValue(ar, c, getValue(ar, a) + getValue(ar, b));

    }

 else if (_operation=="mul")

    {

   // getting each operand string value

      auto it = _operands.begin();

   string a = *it;

   it++;

   string b = *it;

   it++;

   string c = *it;

      // getting current record

      ActivationRecord* ar = withStack.top();

   // updating value of operand c

   setValue(ar, c, getValue(ar, a) * getValue(ar, b));

    }

 else if (_operation=="div")

    {

   // getting each operand string value

      auto it = _operands.begin();

   string a = *it;

   it++;

   string b = *it;

   it++;

   string c = *it;

      // getting current record

      ActivationRecord* ar = withStack.top();

   // updating value of operand c

   setValue(ar, c, getValue(ar, a) / getValue(ar, b));

    }

 else if (_operation=="skipz")

    {

   // getting string values of both operands

   auto it = _operands.begin();

   string a = *it;

   it++;

   string b = *it;

      // getting current record

      ActivationRecord* ar = withStack.top();

   // evaluating first operand

   int firstVal = getValue(ar, a);

   // evaluating second operand

   int secondVal = getValue(ar, b);

   // moving next address if first operand is 0

   if (firstVal == 0) {

    nextAddr += secondVal;

   }

    }

 else if (_operation=="skipnz")

    {

   // getting string values of both operands

      auto it = _operands.begin();

   string a = *it;

   it++;

   string b = *it;

      // getting current record

      ActivationRecord* ar = withStack.top();

   // evaluating first operand

   int firstVal = getValue(ar, a);

   // evaluating second operand

   int secondVal = getValue(ar, b);

   // moving next address if first operand is NOT 0

   if (firstVal != 0) {

    nextAddr += secondVal;

   }

    }

 else if (_operation=="read")

    {

   // getting current record

   ActivationRecord* ar = withStack.top();

   // reading value from console

   int val;

   cin >> val;

   // setting variable to this value

   setValue(ar, _operands.front(), val);

    }

 else if (_operation=="dump")

    {

   // outputting current stack state

      cout << withStack << endl;

    }

  else

    {

      cout << _operation << ": not implememnted" << endl;

    }

  return nextAddr;

}

// prints out this statement to the specified stream (overloads <<)

ostream& operator<<(ostream &os, const Statement &s)

{

  // print the statement number in the specified width.

  os.width(5);

  os << s._snum << " ";

  // print the operation

  os << s._operation << '\t';

  // print each operand ..

  list::const_iterator lsci = s._operands.begin();

  for (int i=0; i< s._operandCount; i++)

    {

      os << *lsci << " ";

      lsci++;

    }

  return os;

}