static void Main(string[] args)
        {
            ExpTree tree = new ExpTree();

            while (true)
            {
                Console.WriteLine("Menu (current expression = \"" + tree.expression + "\")");
                Console.WriteLine("  1 = Enter a new expression");
                Console.WriteLine("  2 = Set a variable value");
                Console.WriteLine("  3 = Evaluate Tree");
                Console.WriteLine("  4 = Quit");
                string choice = Console.ReadLine();

                if (choice.Length != 1)
                    continue;

                switch(Convert.ToInt32(choice))
                {
                    case 1:
                        Console.WriteLine("Enter new expression: ");
                        string exp = Console.ReadLine();
                        tree = new ExpTree(exp);
                        continue;
                    case 2:
                        Console.WriteLine("Enter variable name: ");
                        string name = Console.ReadLine();
                        Console.WriteLine("Enter variable value: ");
                        string value = Console.ReadLine();
                        tree.SetVar(name, Convert.ToDouble(value));
                        continue;
                    case 3:
                        Console.WriteLine(tree.Eval());
                        continue;
                    case 4:
                        Console.WriteLine("Done");
                        goto exit;
                    default:
                        goto continueLoop;
                }

                exit:
                    break;

                continueLoop:
                    continue;
            }
        }
Ejemplo n.º 2
0
        //work on evaluation maybe
        //USE OF EXP TREE HERE
        private void evaluate(Cell c)
        {
            SpreadSheetCell myCell = (SpreadSheetCell)c;
            myCell.setValue("");
            string text = myCell.Text;

            //stores all cells that this cell is referencing
            List<Cell> cellsReferenced = new List<Cell>();

            //iterates through every key in references and if we find our cell in the list of cells
            //that is referencing one of the cells, we add that cell to list of items to remove
            //and remove our cell from them
            foreach (Cell key in _references.Keys)
            {
                if(_references[key].Contains((Cell)myCell))
                {
                    _references[key].Remove((Cell) myCell);
                }
            }

            //evaluates for if the cell is set equal to another cell
            //also collects the cells that are being referenced in our expression
            if (text != "")
            {
                //THIS REGION
                //evaluates the expression inside the cell
                //and creates a list of cells that have been referenced by our cell
                #region
                //if the text needs to be evaluated further, it will start with
                // and '=' sign. Else _value = _text of the cell (at least for
                //this assignment so far)
                if (text[0] == '=')
                {
                    //create a dictionary that stores all variables by cell name and value in the cell.
                    //ex. A1 is 12, adds <A1:12> to dictionary.
                    //ex. A1 is "Hello World". Adds <A1:0> to dictionary.
                    //zero by default.
                    ExpTree evaluator = new ExpTree(myCell.Text.Substring(1), createDict());

                    //if we only have a cell name, set the cell to the value
                    //of the cell name. (should only be in case where
                    //the referenced cell is a text string).
                    if (isCellName(myCell.Text.Substring(1)))
                    {
                        int myRow = 0;
                        int myColumn = 0;

                        if (myCell.Text[1] >= 'A' && myCell.Text[1] <= 'Z')
                        {
                            myColumn = (int)(myCell.Text[1] - 'A');
                        }

                        else if (myCell.Text[1] >= 'a' && myCell.Text[1] <= 'z')
                        {
                            myColumn = (int)(myCell.Text[1] - 'a');
                        }

                        myRow = (int)toDouble(myCell.Text.Substring(2)) - 1;

                        text = _cells[myColumn, myRow].Value;

                        //set reference to the specific cell
                        if (!cellsReferenced.Contains(_cells[myColumn, myRow]))
                        {
                            cellsReferenced.Add(_cells[myColumn, myRow]);
                        }
                    }

                    //if we are operating on the contents, we must
                    //evaluate the text
                    else if (evaluator.isValidExpression())
                    {
                        //get list of cells that we are referencing in the expression
                        //and add to references
                        text = evaluator.Eval().ToString();

                        //get each split in the expression
                        List<string> mySplit = evaluator.splitExpression();
                        
                        foreach(string s in mySplit)
                        {
                            //if we hit a cellname, store it into our referenced cells list
                            if(isCellName(s))
                            {
                                int myRow = 0;
                                int myColumn = 0;

                                if (s[0] >= 'A' && s[0] <= 'Z')
                                {
                                    myColumn = (int)(s[0] - 'A');
                                }

                                else if (s[0] >= 'a' && s[0] <= 'z')
                                {
                                    myColumn = (int)(s[0] - 'a');
                                }

                                myRow = (int)toDouble(s.Substring(1)) - 1;

                                if (!cellsReferenced.Contains(_cells[myColumn, myRow]))
                                {
                                    cellsReferenced.Add(_cells[myColumn, myRow]);
                                }
                            } 
                        }
                    }

                    else
                    {
                        myCell.setValue("!(bad reference)");
                    }
                }
                #endregion
            }

            //check to make sure we dont override if a we prviously wrote the statement of "bad reference"
            if (myCell.Value != "!(bad reference)")
            {
                //check for self reference
                if (!selfReferenceCheck(cellsReferenced, myCell))
                {
                    //sets the value to the evaluated
                    //string of the input text string
                    myCell.setValue(text);

                    //links our cell to every cell that it has referenced.
                    foreach (Cell cell in cellsReferenced)
                    {
                        _references[cell].Add(myCell);
                    }

                    
                    //update all cells that are referencing our cell
                    List<Cell> cellsReferencing = new List<Cell>();

                    //adds all the cells in the hashset of our cell
                    foreach (Cell referencing in _references[myCell])
                    {
                        cellsReferencing.Add(referencing);
                    }
                    
                    if(crefCheck(_references[myCell],myCell))
                    {
                        myCell.setValue("!(circular reference)");

                        //if we do have a circular reference, unlink this cell from referencing all cells
                        foreach (Cell key in _references.Keys)
                        {
                            if (_references[key].Contains((Cell)myCell))
                            {
                                _references[key].Remove((Cell)myCell);
                            }
                        }
                    }

                    else
                    {
                        //evey cell we referenced, fire their event so we will update our cell in the UI
                        foreach (Cell referencing in cellsReferencing)
                        {
                            referencing.OnChanged("Text");
                        }
                    }    
                }

                //if we do have a self reference
                else
                {
                    myCell.setValue("!(self reference)");
                }
            }
        }