Example #1
0
        /// <summary>
        /// Pop the given "op_stack" as long as the stack operator's precedence
        /// >= the given "precedence". These popped operators are moved
        /// onto the "terms_list". The popping always stops at '('.
        /// If "cancel_left_paren" is true, then the '(' will be
        /// removed from the stack.
        /// </summary>
        /// <param name="cancel_left_paren">The caller sees a ')' and sets this
        /// parameter to true to cancel out the '(' on the stack.</param>
        void pop_op_stack(Stack <Operator> op_stack, int precedence,
                          List <ExpressionTerm> terms_list, bool cancel_left_paren = false)
        {
            while (op_stack.Count > 0)
            {
                var op = op_stack.Peek();

                if (op.type == OperatorType.Left_Paren)
                {
                    // Handle '(' case.
                    // Always stop at '(', but sometimes cancel it out.
                    if (cancel_left_paren)
                    {
                        op_stack.Pop();
                    }
                    return;
                }

                // Standard, non '(' case:
                if (op.precedence() >= precedence)
                {
                    op_stack.Pop();
                    terms_list.Add(ExpressionTerm.create_operator(op));
                }
                else
                {
                    return;
                }
            }
        }
Example #2
0
        /// <summary>
        /// An expression that is just a single value.
        /// </summary>
        public Expression(Value value, int line_number)
        {
            this.line_number = line_number;

            terms    = new ExpressionTerm[1];
            terms[0] = ExpressionTerm.create_value(value);
        }
Example #3
0
        /// <summary>
        /// Add the token at "token_list[index]" to "source_expression_terms", and
        /// advance the index.
        /// </summary>
        /// <param name="start_index">the very first index of the expression within token_list</param>
        /// <param name="end_index">how far can the expression continue</param>
        void process_expression_term(TokenList token_list, ref int index,
                                     List <ExpressionTerm> source_expression_terms, int start_index,
                                     int end_index)
        {
            var token = token_list[index];

            if (token.type == TokenType.Identifier)
            {
                // check for "identifier [ x ]" case
                if (index + 3 <= end_index &&
                    token_list[index + 1].type == TokenType.Left_Bracket)
                {
                    // slice expression
                    // find the end ']' character
                    int end_bracket = token_list.find_ending_token(index + 1);

                    if (end_bracket < 0 || end_bracket > end_index)
                    {
                        throw new Exception("Unable to find the ending ']' while processing the "
                                            + "bracket notation for \"" + token.ToString() + "\".");
                    }

                    // continue looking for more '[' - to handle cases like x[1][2]
                    while (end_bracket + 1 < token_list.Count &&
                           token_list[end_bracket + 1].type == TokenType.Left_Bracket)
                    {
                        end_bracket = token_list.find_ending_token(end_bracket + 1);

                        if (end_bracket < 0 || end_bracket > end_index)
                        {
                            throw new Exception("Unable to find the ending ']' while processing the "
                                                + "bracket notation for \"" + token.ToString() + "\".");
                        }
                    }

                    var slice_expr = new SliceExpression(token_list, index, end_bracket);
                    source_expression_terms.Add(ExpressionTerm.create_slice_expression(slice_expr));
                    index = end_bracket + 1;
                }
                else
                {
                    // stand alone identifier
                    source_expression_terms.Add(ExpressionTerm.create_identifier((string)token.value));
                    index++;
                }
            }
            else if (token.type == TokenType.Integer)
            {
                source_expression_terms.Add(ExpressionTerm.create_value(new DynamicValue((int)token.value)));
                index++;
            }
            else if (token.type == TokenType.Double)
            {
                source_expression_terms.Add(ExpressionTerm.create_value(new DynamicValue((double)token.value)));
                index++;
            }
            else if (token.type == TokenType.String)
            {
                // check for "string [ x ]" case
                if (index + 3 <= end_index &&
                    token_list[index + 1].type == TokenType.Left_Bracket)
                {
                    // slice expression
                    // find the end ']' character
                    int end_bracket = token_list.find_ending_token(index + 1);
                    if (end_bracket < index || end_bracket > end_index)
                    {
                        throw new Exception("Unable to find the ending ']' while processing the "
                                            + "bracket notation for \"" + token.ToString() + "\".");
                    }

                    var slice_expr = new SliceExpression(token_list, index, end_bracket);
                    source_expression_terms.Add(ExpressionTerm.create_slice_expression(slice_expr));
                    index = end_bracket + 1;
                }
                else
                {
                    // stand alone string
                    source_expression_terms.Add(ExpressionTerm.create_value(new StringValue((string)token.value)));
                    index++;
                }
            }
            else if (token.type == TokenType.None)
            {
                source_expression_terms.Add(ExpressionTerm.create_value(NoneValue.NONE));
                index++;
            }
            else if (token.type == TokenType.True)
            {
                source_expression_terms.Add(ExpressionTerm.create_value(new DynamicValue(true)));
                index++;
            }
            else if (token.type == TokenType.False)
            {
                source_expression_terms.Add(ExpressionTerm.create_value(new DynamicValue(false)));
                index++;
            }
            else if (token.type == TokenType.Left_Bracket)
            {
                // find the end bracket, but it has to be "end_index" or earlier
                int end_bracket_index = token_list.find_token_outside_of_paren(
                    TokenType.Right_Bracket, index + 1, end_index);

                if (end_bracket_index == -1)
                {
                    throw new Exception("Unable to find the ending ']' in the phrase \""
                                        + token_list.ToString(index, end_index) + "\".");
                }

                var list_expression = new ListExpression(token_list, index, end_bracket_index);

                source_expression_terms.Add(ExpressionTerm.create_list_expression(list_expression));
                index = end_bracket_index + 1;
            }
            else if (token.type == TokenType.Left_Brace)
            {
                // find the end '}'
                int end_brace_index = token_list.find_token_outside_of_paren(
                    TokenType.Right_Brace, index + 1, end_index);

                if (end_brace_index == -1)
                {
                    throw new Exception("Unable to find the ending '}' in the phrase \""
                                        + token_list.ToString(index, end_index) + "\".");
                }

                var dict_expression = new DictionaryExpression(token_list, index, end_brace_index);

                source_expression_terms.Add(ExpressionTerm.create_dict_expression(dict_expression));
                index = end_brace_index + 1;
            }
            else
            {
                // token must be a supported operator
                var op = Operator.parse_token(token);
                if (op != null)
                {
                    // detect redundant +, as in 2 + + 3
                    if (op.type == OperatorType.Add)
                    {
                        if (index == start_index || is_active_operator(token_list[index - 1]))
                        {
                            // skip over the redundant '+'
                            index++;
                            return;
                        }
                    }

                    // detect negation -, as in 2 + - 3
                    if (op.type == OperatorType.Subtract)
                    {
                        if ((index == start_index) || is_active_operator(token_list[index - 1]))
                        {
                            op = Operator.Constants.Negate;
                        }
                    }

                    source_expression_terms.Add(ExpressionTerm.create_operator(op));
                    index++;
                }
                else
                {
                    // op == null case, unable to convert "token" to "op"
                    throw new Exception("Source code error on line # "
                                        + (line_number + 1) + ". Unsupported operator \""
                                        + token.ToString() + "\".");
                }
            }
        }