Esempio n. 1
0
        //------------------------------------------------------------------------------------------------------------
        private int evaluatePostfix(string postfix, int lineNumber)
        {
            Stack <string> expression = new Stack <string>(postfix.Split(' ').Reverse());
            Stack <int>    operands   = new Stack <int>();
            Stack <int>    temps      = new Stack <int>();
            int            firstTemp  = _symbolTable.TempLocation;

            while (expression.Count > 0)
            {
                string working = expression.Pop();
                if (Int32.TryParse(working, out int intWorking))
                {
                    // working string is an integer value
                    operands.Push(_symbolTable.FindConstant(intWorking).Location());
                }
                else if (Toolbelt.IsValidVariable(working))
                {
                    char workingChar = Convert.ToChar(working);
                    operands.Push(_symbolTable.FindVariable(Convert.ToInt32(workingChar)).Location());
                }
                else if (Toolbelt.IsOperator(working))
                {
                    int  left, right;
                    char op = Convert.ToChar(working);
                    if (operands.Count() >= 2)
                    {
                        right = operands.Pop();
                        left  = operands.Pop();
                    }
                    else if (operands.Count() == 1 && temps.Count >= 1)
                    {
                        right = temps.Pop();
                        left  = operands.Pop();
                    }
                    else if (temps.Count >= 2)
                    {
                        right = temps.Pop();
                        left  = temps.Pop();
                    }
                    else
                    {
                        return(-1);
                    }
                    // load 'left' from memory
                    _compiledCode.Add(Word.Build((int)EPC.Code.LOAD, left), _workingLineNumber++);
                    // perform calculation on 'left'
                    switch (op)
                    {
                    case '+':
                        _compiledCode.Add(Word.Build((int)EPC.Code.ADD, right), _workingLineNumber++);
                        break;

                    case '-':
                        _compiledCode.Add(Word.Build((int)EPC.Code.SUBTRACT, right), _workingLineNumber++);
                        break;

                    case '*':
                        _compiledCode.Add(Word.Build((int)EPC.Code.MULTIPLY, right), _workingLineNumber++);
                        break;

                    case '/':
                        _compiledCode.Add(Word.Build((int)EPC.Code.DIVIDE, right), _workingLineNumber++);
                        break;
                    }
                    // store result in 'temp'
                    temps.Push(firstTemp - temps.Count());
                    if (_symbolTable.HasLocation(temps.Peek()) && _symbolTable.AtLocation(temps.Peek()).IsConst())
                    {
                        throw new SystemException($"Cannot override constant value at memory[{temps.Peek()}] -on code line {lineNumber}");
                    }
                    _compiledCode.Add(Word.Build((int)EPC.Code.STORE, temps.Peek()), _workingLineNumber++);
                }
                else
                {
                    return(-1);
                }
            }
            return(temps.Pop());
        }