Beispiel #1
0
        private RpnItem getToken()
        {
            if (!moveToNextNonWhiteSpace())
            {
                return(null);
            }

            var opInxex = RpnItemOperator.OpIndex(Expression, _i);

            if (opInxex >= 0)
            {
                _i += RpnItemOperator.Operators[opInxex].Length;
                return(new RpnItemOperator((Operator)opInxex));
            }

            var m = _legalOperand.Matches(Expression.Substring(_i));

            if (m.Count == 1)
            {
                var x = m[0].Value;
                _i += x.Length;
                double num;
                if (double.TryParse(x, out num))
                {
                    return(new RpnItemOperandNumeric(num));
                }
                if (!moveToNextNonWhiteSpace() || Expression[_i] != '(')
                {
                    return(x != "null"
                        ? (RpnItem) new RpnItemOperandVariable(x)
                        : new RpnItemOperandString(null));
                }
                _i++;
                return(new RpnItemFunction(x));
            }

            switch (Expression[_i++])
            {
            case '\"':
            case '\'':
                return(getString(Expression[_i - 1]));
            }

            return(null);
        }
Beispiel #2
0
        private void handleItemOperator(RpnItemOperator op)
        {
            switch (op.Operator)
            {
            case Operator.Comma:
                while (!(_stack.Peek() is RpnItemFunction))
                {
                    Result.Add(_stack.Pop());
                }
                ((RpnItemFunction)_stack.Peek()).ArgumentCount++;
                return;

            case Operator.LeftP:
                _stack.Push(op);
                return;

            case Operator.RightP:
                while (true)
                {
                    var pop = _stack.Pop();
                    if (pop is RpnItemFunction)
                    {
                        Result.Add(pop);
                        return;
                    }
                    if ((pop as RpnItemOperator)?.Operator == Operator.LeftP)
                    {
                        return;
                    }
                    Result.Add(pop);
                }
            }

            while (_stack.Any() && op.ShuntIt(_stack.Peek() as RpnItemOperator))
            {
                Result.Add(_stack.Pop());
            }
            _stack.Push(op);
        }
Beispiel #3
0
        public Rpn(string expression)
        {
            Expression = expression;
            var expectedOperand = true;

            while (_i < Expression.Length)
            {
                var token = getToken();
                if (token == null)
                {
                    if (_i >= Expression.Length)
                    {
                        break;
                    }
                    else
                    {
                        throw new Exception();
                    }
                }
                if (token is RpnItemOperand && expectedOperand)
                {
                    Result.Add(token);
                    expectedOperand = false;
                }
                else if (token is RpnItemFunction && expectedOperand)
                {
                    _stack.Push(token);
                }
                else if (token is RpnItemOperator)
                {
                    var op = (RpnItemOperator)token;
                    if (expectedOperand)
                    {
                        switch (op.Operator)
                        {
                        case Operator.LeftP:
                        case Operator.Not:
                            break;

                        case Operator.Minus:
                            op = new RpnItemOperator(Operator.Negation);
                            break;

                        case Operator.Addition:
                            continue;

                        default:
                            throw new Exception($"Expected operand but found operator {op.Operator}");
                        }
                    }
                    expectedOperand = op.Operator != Operator.RightP;
                    handleItemOperator(op);
                }
            }

            while (_stack.Any())
            {
                var item = _stack.Pop();
                if ((item as RpnItemOperator)?.Operator == Operator.LeftP)
                {
                    throw new Exception("Open parenthisis");
                }
                Result.Add(item);
            }

            for (var i = 1; i < Result.Count; i++)
            {
                if (Result[i - 1] is RpnItemOperandNumeric && (Result[i] as RpnItemOperator)?.Operator == Operator.Negation)
                {
                    Result[i - 1] = new RpnItemOperandNumeric(-((RpnItemOperandNumeric)Result[i - 1]).Value);
                    Result.RemoveAt(i--);
                }
            }
        }
Beispiel #4
0
        private void typeEval()
        {
            var stack = new Stack <RpnItemOperand>();

            for (var i = 0; i < _original.Count; i++)
            {
                var item    = _original[i];
                var operand = item as RpnItemOperand;
                if (operand != null)
                {
                    stack.Push(operand);
                    continue;
                }

                var variable = item as RpnIndexedVariable;
                if (variable != null)
                {
                    stack.Push(variable.IsNumeric ? (RpnItemOperand) new RpnItemOperandNumeric(0) : new RpnItemOperandString(""));
                    continue;
                }

                var itemOperator = item as RpnItemOperator;
                if (itemOperator != null)
                {
                    switch (itemOperator.Operator)
                    {
                    case Operator.Addition:
                    {
                        var op2 = stack.Pop();
                        var op1 = stack.Pop();
                        if (op1 is RpnItemOperandString || op2 is RpnItemOperandString)
                        {
                            _original[i] = new RpnItemOperator(Operator.Concat);
                            push(stack, "");
                        }
                        else
                        {
                            push(stack, 0);
                        }
                        break;
                    }

                    case Operator.Negation:
                    case Operator.Not:
                        stack.Pop();
                        stack.Push(new RpnItemOperandNumeric(0));
                        break;

                    case Operator.NullCoalescing:
                    case Operator.Question:
                    {
                        var op2 = stack.Pop();
                        stack.Pop();
                        stack.Push(op2);
                        break;
                    }

                    default:
                        stack.Pop();
                        stack.Pop();
                        push(stack, 0);
                        break;
                    }
                    continue;
                }

                var itemFunction = item as RpnItemFunction;
                if (itemFunction != null)
                {
                    for (var j = 0; j < itemFunction.ArgumentCount; j++)
                    {
                        stack.Pop();
                    }
                    if (_functions[itemFunction.Name].Type == typeof(string))
                    {
                        push(stack, "");
                    }
                    else
                    {
                        push(stack, 0);
                    }
                    continue;
                }

                throw new Exception("What the hell happened here?");
            }

            ResultingType = stack.Single();
        }