Exemple #1
0
void doAssign(ListIterator &i, ExprNode *&node)
{
  ExprNode *left, *right;
  string eq;
  ListIterator temp = i;

  node = new Variable(i.token().tokenChar());
  if(!i.ended())
    i.advance();
  if(!i.ended())
    eq = i.token().tokenChar();
    
  if(eq == "=" && !i.ended())
    {
      while(eq == "=" && !i.ended())
	{
	  if(!i.ended())
	    i.advance();
	  if(!i.ended())
	    doSum(i, right);
	  node = new Operation(node, eq, right);
	  if(!i.ended())
	    eq = i.token().tokenChar();
	  else
	    eq = "Done";
	}
    }
  else if(!i.ended() && (i.token().tokenChar() != "("))
    i = temp;
  else if(!i.ended() && (i.token().tokenChar() == "("))
    {
      i = temp;
      doCall(i, node);
    }
}
// getValue
// Gets the value of the number/expression at the current position
// If the current value is an integer, return it
// If it's a parenthetical expression, evaluate, and return
// evalMultiplication is a flag used to ensure multiplication happens before addition
// If true, it will handle any multiplication that is applied to the current value
// That way, what is returned to the addition function is what we actually want to add
// Parameters:
//     iter  - the iterator for the list of tokens
//     postExpr - the postfix expression we are converting to
//     evalMultiplication (input boolean) whether to evaluate multiplication, see above
// Pre-condition:  expr[pos] is an int or parenthesis
// Post-condition: expr[pos] is the end of the value
//                     If it was an int, it's on the int
//                     If it was a parenthesis, it's on the end parenthesis
//                     If handling multiplication, it's on the last multiplied int
//                 postExpr has the values handled here pushed to it
void getValue(ListIterator& iter, TokenList& postExpr, bool evalMultiplication)
{
    bool negative = false;

    if (!iter.currentIsInteger() && iter.tokenChar() == '-')
    {
        negative = true;
        iter.advance();
    }

    if (iter.currentIsInteger())
    {
        postExpr.push_back(iter.integerValue());

        if (negative)
        {
            postExpr.push_back(Token('~'));
        }

        while (evalMultiplication && isNextOperatorMultiplication(iter))
        {
            iter.advance();
            handleMultiplyLevelOperation(iter, postExpr);
        }
    }
    else
    {
        handleParenthesis(iter, postExpr);

        if (negative)
        {
            postExpr.push_back(Token('~'));
        }
    }
}
//This function takes in the iterator, and rewrite both sides of the sum expression in postFix
//Pre- The position is at a symbol +,-,*,/,%
//Post- It will change postFix and the iterator
void addOp(ListIterator &iter, TokenList &postFix)
{
	int pos;
	Token saveToken;
	bool solved = false;

	while(solved == false)
	{
		if (iter.tokenChar() == '*' || iter.tokenChar() == '/' || iter.tokenChar() == '%')
		{
			//This means that a product operation was encountered immediately so the prgoram can finish the expression and return without
			multOp(iter, postFix);
		}
		else if (iter.tokenChar() == '+' || iter.tokenChar() == '-')
		{
			//We advance to save the next number and then again to check the next character
			saveToken = iter.token();
			iter.advance();
			getValue(iter, postFix);
			iter.advance();
			if (iter.tokenChar() == '*' || iter.tokenChar() == '/' || iter.tokenChar() == '%')
			{
				//If a product expression is found it will calculate the entirety of that
				multOp(iter, postFix);
			}
			postFix.push_back(saveToken);
		}
		else
		{
			solved = true;
		}
	}
}
Exemple #4
0
void doCompare(ListIterator &i, ExprNode *&test)
{
  ExprNode *trueCase, *falseCase, *right;
  string comp;

  doSum(i, test);
  if(!i.ended())
    {
      if(i.token().tokenChar() == ")")
	i.advance();
    }
  if(!i.ended() && i.token().isOperator())
    {
      comp = i.token().tokenChar(); 
      i.advance();
      doSum(i, right);
      test = new Operation(test, comp, right);
    }
  if(!i.ended() && (i.token().tokenChar() == "?" || i.token().isOperator()))
    {
      i.advance();
      doSum(i, trueCase);
    }
  if(!i.ended() && (i.token().isOperator() || i.token().tokenChar() == ":"))
    {
      i.advance();
      doSum(i, falseCase);
      test = new Conditional(test, trueCase, falseCase);
    }

}
Exemple #5
0
const List<Object>& List<Object>::operator =( const List<Object>& rhs ) {
	if (this != &rhs) {
		makeEmpty();

		ListIterator<Object> rightiter = rhs.first( );
		ListIterator<Object> myiterator = zeroth();
		while( rightiter.isValid() ) {
			insert( rightiter.retrieve(), myiterator );
			rightiter.advance();
			myiterator.advance();
		}
	}
	return( *this );
}
Exemple #6
0
void doSum(ListIterator &i, TokenList *pf)
{
  char oper;       // For holding the operator


  doProduct(i, pf); // Sum = product + product


  if(!i.ended())
    oper = i.token().tokenChar(); // Grab an operator, only if current != NULL
    
  while(((oper == '+') || (oper == '-')) && !i.ended() ) 
    {
      i.advance(); // Move to next token, an int or a '('
      doProduct(i, pf); 
    
      Token t(oper);
      pf->push_back(t); // Add the operator the the expression
      
      if(!i.ended())
	oper = i.token().tokenChar(); // Grab the next operator
	
    }

}
//The function takes in an iterator and TokenList and will rewrite numbers at the iterator's
//Pre- The position is located at a number or a parethesis
//Post- It will write to the postFix TokenList and update the iterator
void getValue(ListIterator &iter, TokenList &postFix)
{
	//If parethesis are found this else if will rewrite the parenthesis in postFix
	if (iter.tokenChar() == '(')
	{
		iter.advance();
		getValue(iter, postFix);
		iter.advance();
		assignOp(iter, postFix);
	}
	//If the current position is an integer
	else
	{
		postFix.push_back(iter.token());
	}
}
Exemple #8
0
void doCall(ListIterator &i, ExprNode *&node)
{
  string name;
  ExprNode *parameters[10];
  int p = 0;

  if(!i.ended())
    name = i.token().tokenChar();
  i.advance();
    if(!i.ended())
    doCompare(i, node);
  parameters[p] = node;
  p++;
  if(!i.ended()){
    while(!i.ended() && i.token().tokenChar() != ")")
      {
	if(!i.ended())
	  doCompare(i, node);
	parameters[p] = node;
	p++;
      }
  }

  for(; p < 10; p++)
    parameters[p] = NULL;
  node = new Function(name, parameters);
}
//This function takes in the iterator, and the TokeList, and will rewrite any product expressions
//Pre- The position will be on a operation symbol that is either *, /, %
//Post- It will rewrite the infix to postFix product expression
void multOp(ListIterator &iter, TokenList &postFix)
{
	Token saveToken;

	//This loop will run indefinately and rewrite to postFix until the product expression ends
	while (iter.tokenChar() == '*' || iter.tokenChar() == '/' || iter.tokenChar() == '%')
	{
		saveToken = iter.token();
		iter.advance();

		getValue(iter, postFix);
		iter.advance();

		postFix.push_back(saveToken);
	}
}
Exemple #10
0
//  output operation
//  Display all of the tokens in the list
ostream& operator<<( ostream &stream, TokenList &t )
{
    for (ListIterator iter = t.begin(); iter != t.end(); iter.advance())
    {
	stream << iter.token() << " ";
    }
    return stream;
}
void makeFunction(ListIterator& infix, TokenList& list, FunctionDef& funs)
{
    infix.advance(); //advance past deffn

    string name = tokenText(infix, list);
    funs[name] = FunDef();

    FunDef* function = &funs[name]; //to avoid multiple lookups in this function body

    function->name = name;
    infix.advance(); //advance past function name
    infix.advance(); //advance past '('

    function->locals = new VarTree();

    int paramcount = 0;
    while (tokenText(infix, list) != ")")
    {
        string paramname = tokenText(infix, list);
        function->parameter[paramcount] = paramname;
        function->locals->assign(paramname, 0);
        ++paramcount;
        infix.advance();

        if (tokenText(infix, list) == ",")
            infix.advance();

    } //we are now on a ")"
    infix.advance(); //so advance past ")"

    for (int i = paramcount; i < 10; ++i)
        function->parameter[i] = "";

    function->functionBody = assignmentToTree(infix,list,funs);

#ifdef DEBUG
    cout << "Function:" << endl;
    cout << "    Name: " << function->name << endl;
    for (int i = 0; i < 10 && function->parameter[i] != ""; ++i)
        cout << "    Parameter " << i << ": " << function->parameter[i] << endl;
    cout << "    VarTree: " << function->locals << endl;
    cout << "    VarTree: " << *function->locals << endl;
    cout << "    ExprNode: " << function->functionBody << endl;
    cout << "    ExprNode: " << *function->functionBody << endl;
#endif
}
// handleMultiplyLevelOperation
// Handles *, /, and %
// Parameters:
//     iter  - the iterator for the list of tokens
//     postExpr - the postfix expression we are converting to
// Pre-condition:  iter.tokenChar() == '*' or '/' or '%'
// Post-condition: iter.tokenChar() == end of what was multiplied (last int/parenthesis)
//                 postExpr has both operands and the operator pushed to it
void handleMultiplyLevelOperation(ListIterator& iter, TokenList& postExpr)
{
    Token operation(iter.token());
    iter.advance();

    getValue(iter, postExpr, false); //Do not handle multiplication (see getValue())

    postExpr.push_back(operation);
}
// handleMultiplyLevelOperation
// Handles + and -
// Parameters:
//     iter  - the iterator for the list of tokens
//     postExpr - the postfix expression we are converting to
// Pre-condition:  iter.tokenChar() == '+' or '-'
// Post-condition: iter.tokenChar() == end of what was added (last int/parenthesis)
//                 postExpr has both operands and the operator pushed to it
void handleAdditionLevelOperation(ListIterator& iter, TokenList& postExpr)
{
    Token operation(iter.token());
    iter.advance();

    getValue(iter, postExpr, true); //Do evaluate multiplication (see getValue())

    postExpr.push_back(operation);
}
Exemple #14
0
void doFactor(ListIterator &i, TokenList *pf) // Grabs a factor; evaluates if needed; return
{
  int left;
  // factor = int || factor = (int + int)

  if(i.token().tokenChar() == '(')
    {
      i.advance();     
      doSum(i, pf); 
    }
  else
    {
      left = i.token().integerValue(); // grab the factor
      Token t(left);
      pf->push_back(t);    // add it to the list
    }
  if(!i.ended())
    i.advance();

}
// handleParenthesis
// Helper function to handle evaluating parenthesis
// Parameters:
//     iter  - the iterator for the list of tokens
//     postExpr - the postfix expression we are converting to
// Pre-condition:  iter.tokenChar() == '('
// Post-condition: iter.tokenChar() == ')'
//                 postExpr has everything inside the parenthesis pushed to it
void handleParenthesis(ListIterator& iter, TokenList& postExpr)
{
    iter.advance();

    getValue(iter, postExpr, false);

    while (iter.tokenChar() != ')')
    {
        evalStep(iter, postExpr);
    }
}
Exemple #16
0
void printList( const List<int>& l ) {
	if (l.isEmpty())
		cout << "Empty list" << endl;
	else {
		ListIterator<int> iter = l.first();
		while (iter.isValid()) {
			cout << iter.retrieve() << " -> ";
			iter.advance();
		}
		cout << "NULL";
		cout << endl;
	}
}
Exemple #17
0
void doFactor(ListIterator &i, ExprNode *&node)
{
  ExprNode *left;

  if(i.token().tokenChar() == "(")
    {
      i.advance();
      doSum(i, node);
    }

  else
    {
      if(i.token().isInteger())
	{
	  node = new Value(i.token().integerValue());
	}
      else if(!i.token().isOperator())
	doAssign(i, node);
      else
	doCompare(i, node);
    }
  if(!i.ended())
    i.advance();
}
// evalStep
// Evaluates the current operator
// Parameters:
//     iter  - the iterator for the list of tokens
//     postExpr - the postfix expression we are converting to
// Pre-condition: Next token is an operator (although, it will just advance if it isn't)
// Post-condition: All values related to this operation pushed to postExpr in the order dictated by postfix
//                 Iter is on the last token evaluated in this step (so iter.advance() next time will
//                     bring it to the next thing to be evaluated)
void evalStep(ListIterator& iter, TokenList& postExpr)
{
    iter.advance();
    switch (iter.tokenChar())
    {
    case '*':
    case '/':
    case '%':
        handleMultiplyLevelOperation(iter, postExpr);
        break;
    case '+':
    case '-':
        handleAdditionLevelOperation(iter, postExpr);
        break;
    }
}
// isNextOperatorMultiplication
// Checks if the next operation in the expression has multiplication precedence
// This is used to ensure multiplication is handled before addition
// Parameters:
//     iter - the iterator for the list of tokens - not sent by reference, as in the other
//            functions, so that we can look ahead without having to go back again.
// Pre-condition: Next token is an operator (although, if it's not, I suppose the next operation isn't
//                technically multiplication)
// Return: whether the next operation is multiplication
bool isNextOperatorMultiplication(ListIterator iter)
{
    bool isMultiplication;
    iter.advance();

    switch (iter.tokenChar())
    {
    case '*':
    case '/':
    case '%':
        isMultiplication = true;
        break;
    default:
        isMultiplication = false;
        break;
    }

    return isMultiplication;
}
Exemple #20
0
void doProduct(ListIterator & i, ExprNode *&node)
{
  ExprNode *left, *right;
  string oper;

  doFactor(i, node);

  if(!i.ended())
    oper = i.token().tokenChar(); 
  while(oper == "*" || oper == "/" || oper == "%")
    {
      i.advance();
      doFactor(i, right);
      node = new Operation(node, oper, right);
      if(!i.ended())
	oper = i.token().tokenChar();
      else
	oper = "Done";
    }
}
Exemple #21
0
void doDefine(ListIterator &i, FunctionDef &fmap)
{
  string n;
  string parameters[10];
  ExprNode *body;
  int p = 0;

  i.advance(); // i is now on the function name

  if(!i.ended())
    n = i.token().tokenChar(); 


  i.advance(); // i is now on open paren of parameters
  i.advance(); // i is now on the first parameter
  if(!i.ended())
    parameters[p] = i.token().tokenChar();
  p++;
  i.advance(); // i is now on comma separating parameters or close paren
  while(i.token().tokenChar() == "," && !i.ended())
    {
      i.advance(); // i is now on next parameter
      if(!i.ended())
	parameters[p] = i.token().tokenChar();
      p++;
      i.advance(); // i is on new comma or close paren
    }
  i.advance(); // i is now on "="
  i.advance();
  
  if(!i.ended())
    doCompare(i, body);

  fmap[n].name = n;
  for(int i = 0; i < p; i++)
    {
      fmap[n].parameter[i] = parameters[i];
    }
  fmap[n].functionBody = body;
  fmap[n].locals = new VarTree();

  cout << *fmap[n].functionBody << endl;
  
}
Exemple #22
0
void doProduct(ListIterator &i, TokenList *pf) // Works exactly the same way as doSum(), except
{                           // here, left and right are factors
  int left, right;
  char oper;

  
  doFactor(i, pf); // product = factor * factor

  if(!i.ended())
    oper = i.token().tokenChar();
  while(((oper == '*') || (oper == '/') || (oper =='%')) && !i.ended())
    {
      i.advance();
      doFactor(i, pf);

      Token t(oper);
      pf->push_back(t);

      if(!i.ended())
	oper = i.token().tokenChar();
	
    }

}
//This function will solve a postFix notation TokenList.
//Pre- This function takes in an iterator for a postFix TokenList and a TokenList in postFix notation.
//Post- It will return the result of the entire postFix notation.
int evalPost(ListIterator &iter, TokenList &postFix, VarTree &vt)
{
	Token v1, v2;
	int value = 0, n1, n2;
	bool solved = false, solvedI = false;
	char saveChar;
	//Making the stack
	TokenList toSolve;

	//Runs until the equation is determined to be solved.
	while (solved == false)
	{
		//Will add all the consecutive integers onto the stack
		while (iter.tokenChar() != '=' && iter.tokenChar() != '+' && iter.tokenChar() != '-' && iter.tokenChar() != '*' && iter.tokenChar() != '/' && iter.tokenChar() != '%')
		{
			//Actually pushing onto the stack
			toSolve.push_front(iter.token());
			iter.advance();
		}

		//Getting 2 numbers from the stack
		v2 = toSolve.pop_front();
		v1 = toSolve.pop_front();

		//If it a normal integer
		if(v2.isInteger()) 
		{
			n2 = v2.integerValue();
		}
		//If it is a variable find it
		else
		{
			n2 = vt.lookup(v2.tokenText());
		}

		//If it a normal integer
		if(v1.isInteger())
		{
			n1 = v1.integerValue();
		}
		//If it is a variable find it
		else
		{
			n1 = vt.lookup(v1.tokenText());
		}

		//Grabbing the character operation from the originol TokenList
		saveChar = iter.tokenChar();
		iter.advance();

		if(saveChar == '+')
		{
			value = n1 + n2;
		}
		else if(saveChar == '-')
		{
			value = n1 - n2;
		}
		else if(saveChar == '*')
		{
			value = n1 * n2;
		}
		else if(saveChar == '/')
		{
			value = n1 / n2;
		}
		else if(saveChar == '%')
		{
			value = n1 % n2;
		}
		else if(saveChar == '=')
		{
			vt.assign(v1.tokenText(), n2);
			value = n2;
		}

		//Checks if the equation is done
		if(toSolve.empty() && !(iter != postFix.end()))
		{
			solved = true;
		}
		//If the equation is not done you push the current result and loop
		else
		{
			toSolve.push_front(Token(value));
		}
	}
	return value;
}
Exemple #24
0
int evaluate(const char str[])
{
  TokenList l(str); // Declare and construct our linked list
  TokenList *pf = new TokenList;    // List for postfix expression
  static int ans = 0;   // For handling previous answers
  
  ListIterator i = l.begin();

  if((!i.token().isInteger()) && (i.token().tokenChar() != '(')) 
    { // Complicated condition: evaluates as true if l.head is an operator
      // but not a parenthesis. 
      // In this case, we want to push the previous answer to the front
      Token newHead(ans);
      l.push_front(newHead);
      i = l.begin();
    }

  
  doSum(i, pf);          // Here begins the Conversion

  cout << l << endl;
  cout << *pf << endl;

  TokenList *stack = new TokenList; // Stack for holding operators
  ListIterator eval = pf->begin();  // Iterator to parse postfix expression
  Token left, right;                // Containers

  while(!eval.ended())
    {
      if(eval.token().isInteger()) // While there are integers, push them onto the stack
	stack->push_front(eval.token());
      else
	{
	  right = stack->pop(); // grab the operands in order
	  left = stack->pop();
	  switch(eval.token().tokenChar()) // Evaluate each piece of postfix
	    {
	    case '+':
	      left = (left.integerValue() + right.integerValue());
	      break;
	    case '-':
	      left = (left.integerValue() - right.integerValue());
	      break;
	    case '*':
	      left = (left.integerValue() * right.integerValue());
	      break;
	    case '/':
	      left = (left.integerValue() / right.integerValue());
	      break;
	    case '%':
	      left = (left.integerValue() % right.integerValue());
	      break;
	    }
	  stack->push_front(left);
	}
      eval.advance();
      
    }
  
  ans = left.integerValue();

  return ans;
}
// evaluate
// Evaluates the entire expression
// Parameters:
//     expression (input string) the expression to evaluate
// Pre-condition: The expression is correctly formatted
// Return: Value of the expression
int evaluate(const char expression[])
{
    TokenList expr(expression), //Original expression
              postExpr,         //Expression converted to postfix
              numberStack;      //Stack of numbers to facilitate evaluation

    //Converts expr into postfix and store it into postExpr
    convertToPostfix(expr, postExpr);

    std::cout << "Original expression:          " << expr << std::endl;
    std::cout << "Converted postfix expression: " << postExpr << std::endl;

    
    for (ListIterator iter = postExpr.begin(); iter != postExpr.end(); iter.advance())
    {
        Token t = iter.token();

        if (t.isInteger())
        {
            numberStack.push_front(t);
        }
        else
        {
            //This is the huge bit that handles operators
            //val2 is created but uninitialized to handle binary operators and
            //unary operators ('~') easily in the same switch
            int value = numberStack.pop_front().integerValue();
            int val2 = 0;
            switch (t.tokenChar())
            {
            case '*':
                val2 = numberStack.pop_front().integerValue();
                val2 *= value;
                numberStack.push_front(Token(val2));
                break;
            case '/':
                val2 = numberStack.pop_front().integerValue();
                val2 /= value;
                numberStack.push_front(Token(val2));
                break;
            case '%':
                val2 = numberStack.pop_front().integerValue();
                val2 %= value;
                numberStack.push_front(Token(val2));
                break;
            case '+':
                val2 = numberStack.pop_front().integerValue();
                val2 += value;
                numberStack.push_front(Token(val2));
                break;
            case '-':
                val2 = numberStack.pop_front().integerValue();
                val2 -= value;
                numberStack.push_front(Token(val2));
                break;
            case '~':
                value = -value;
                numberStack.push_front(Token(value));
                break;
            }
        }
    }

    //Value left on the top of the number stack is the final value of the expression
    return numberStack.pop_front().integerValue();
}