Пример #1
0
        /// <summary>
        /// parse math expressions
        /// </summary>
        public static Exp ParseExp(Expression expr)
        {
            if (expr.operators != null)
            {
                expr.operands.Add(expr.tokens);
                // parse each operand
                List <Exp> operands  = expr.operands.Select(x => ParseExp(x)).ToList();
                List <Op>  operators = expr.operators;
                List <int> priority  = expr.priority;
                // create nodes
                while (operators.Count > 0)
                {
                    int i     = expr.IndexOfMin();
                    Op  op    = operators[i];
                    Exp left  = operands[i];
                    Exp right = operands[i + 1];
                    switch (op)
                    {
                    case Op.Increment:
                        if (right == Exp.Null)     // i++
                        {
                            operands[i] = new Operation.PostIncrement {
                                left = left
                            };
                        }
                        else     // ++i
                        {
                            operands[i] = new Operation.PreIncrement {
                                left = right
                            };
                        }
                        break;

                    case Op.Decrement:
                        if (right == Exp.Null)     // i--
                        {
                            operands[i] = new Operation.PostDecrement {
                                left = left
                            };
                        }
                        else     // --i
                        {
                            operands[i] = new Operation.PreDecrement {
                                left = right
                            };
                        }
                        break;

                    case Op.Power:
                        operands[i] = new Operation.Power {
                            left = left, right = right
                        };
                        break;

                    case Op.Multiply:
                        operands[i] = new Operation.Multiply {
                            left = left, right = right
                        };
                        break;

                    case Op.Divide:
                        operands[i] = new Operation.Divide {
                            left = left, right = right
                        };
                        break;

                    case Op.Modulo:
                        operands[i] = new Operation.Modulo {
                            left = left, right = right
                        };
                        break;

                    case Op.LeftShift:
                        operands[i] = new Operation.LeftShift {
                            left = left, right = right
                        };
                        break;

                    case Op.RightShift:
                        operands[i] = new Operation.RightShift {
                            left = left, right = right
                        };
                        break;

                    case Op.Add:
                        operands[i] = new Operation.Add {
                            left = left, right = right
                        };
                        break;

                    case Op.Subtract:
                        if (left == Exp.Null)
                        {
                            operands[i] = new Operation.Negate {
                                left = right
                            };
                        }
                        else
                        {
                            operands[i] = new Operation.Subtract {
                                left = left, right = right
                            };
                        }
                        break;

                    case Op.Less:
                        operands[i] = new Operation.Less {
                            left = left, right = right
                        };
                        break;

                    case Op.Greater:
                        operands[i] = new Operation.Greater {
                            left = left, right = right
                        };
                        break;

                    case Op.LessOrEqual:
                        operands[i] = new Operation.LessOrEqual {
                            left = left, right = right
                        };
                        break;

                    case Op.GreaterOrEqual:
                        operands[i] = new Operation.GreaterOrEqual {
                            left = left, right = right
                        };
                        break;

                    case Op.Is:
                        operands[i] = new Operation.Is {
                            left = left, right = right
                        };
                        break;

                    case Op.As:
                        operands[i] = new Operation.As {
                            left = left, right = right
                        };
                        break;

                    case Op.In:
                        operands[i] = new Operation.In {
                            left = left, right = right
                        };
                        break;

                    case Op.Like:
                        operands[i] = new Operation.Like {
                            left = left, right = right
                        };
                        break;

                    case Op.Equal:
                        operands[i] = new Operation.Equal {
                            left = left, right = right
                        };
                        break;

                    case Op.NotEqual:
                        operands[i] = new Operation.NotEqual {
                            left = left, right = right
                        };
                        break;

                    case Op.Not:
                        operands[i] = new Operation.Not {
                            left = right
                        };
                        break;

                    case Op.And:
                        if (left == Exp.Null)
                        {
                            operands[i] = new Operation.Ref {
                                left = right
                            };
                        }
                        else
                        {
                            operands[i] = new Operation.And {
                                left = left, right = right
                            };
                        }
                        break;

                    case Op.Xor:
                        operands[i] = new Operation.Xor {
                            left = left, right = right
                        };
                        break;

                    case Op.Or:
                        operands[i] = new Operation.Or {
                            left = left, right = right
                        };
                        break;

                    case Op.AndAlso:
                        operands[i] = new Operation.AndAlso {
                            left = left, right = right
                        };
                        break;

                    case Op.OrElse:
                        operands[i] = new Operation.OrElse {
                            left = left, right = right
                        };
                        break;

                    case Op.Coalesce:
                        operands[i] = new Operation.Coalesce {
                            left = left, right = right
                        };
                        break;

                    case Op.Condition:
                        operands[i] = new Operation.Condition {
                            left = left, right = right
                        };
                        break;

                    case Op.Colon:
                        if (left is Operation.Condition iif)
                        {
                            iif.ifFalse = right;
                        }
                        else
                        {
                            operands[i] = new Operation.Colon {
                                left = left, right = right
                            };
                        }
                        break;

                    case Op.Assign:
                        operands[i] = new Operation.Assign {
                            left = left, right = right
                        };
                        break;

                    case Op.Lambda:
                        throw new Exception("Lambda operator '=>' is not implemented yet in jsc1.0");
                        break;
                    }
                    operands.RemoveAt(i + 1);
                    operators.RemoveAt(i);
                    priority.RemoveAt(i);
                }
                return(operands[0]);
            }
            else
            {
                return(ParseExp(expr.tokens));
            }
        }
 return(BinOp(Operation.Multiply, ps, rounding));