Example #1
0
        // Secondary expression:
        // - Depends on (alters the value of) *one* expression.
        public IExpression ReadSecondaryExpression()
        {
            var unary_op = OperatorInfo.FromToken(CurToken);

            if (unary_op != null && unary_op.Value.IsUnary)
            {
                Move();
            }

            IExpression expr;

            if (CurToken.IsPunctuation("("))
            {
                Move();
                var complex = ReadComplexExpression(ReadSecondaryExpression(), 0, true);
                if (!CurToken.IsPunctuation(")"))
                {
                    ThrowExpect("closing parenthesis", CurToken);
                }
                Move();
                expr = complex;
                if (expr is FunctionCall)
                {
                    ((FunctionCall)expr).ForceTruncateReturnValues = true;
                }
            }
            else
            {
                expr = ReadPrimaryExpression();
            }

            while (CurToken.IsPunctuation(".") || CurToken.IsPunctuation("["))
            {
                if (expr is FunctionCall)
                {
                    ((FunctionCall)expr).ForceTruncateReturnValues = false;
                }

                if (expr is StringLiteral && ParserSettings.MaintainSyntaxErrorCompatibility)
                {
                    Throw($"syntax error compat: can't directly index strings, use parentheses", CurToken);
                }
                expr = ReadTableAccess(expr);
            }

            while (CurToken.IsPunctuation(":"))
            {
                if (expr is FunctionCall)
                {
                    ((FunctionCall)expr).ForceTruncateReturnValues = false;
                }

                if (expr is StringLiteral && ParserSettings.MaintainSyntaxErrorCompatibility)
                {
                    Throw($"syntax error compat: can't directly index strings, use parentheses", CurToken);
                }
                var self_expr = expr;
                expr = ReadTableAccess(expr, allow_colon: true);
                expr = ReadFunctionCall(expr, self_expr);
            }

            if (CurToken.IsPunctuation("("))
            {
                if (expr is FunctionCall)
                {
                    ((FunctionCall)expr).ForceTruncateReturnValues = false;
                }

                if (expr is StringLiteral && ParserSettings.MaintainSyntaxErrorCompatibility)
                {
                    Throw($"syntax error compat: can't directly call strings, use parentheses", CurToken);
                }
                expr = ReadFunctionCall(expr);
            }
            else if (CurToken.IsPunctuation("{"))
            {
                if (expr is FunctionCall)
                {
                    ((FunctionCall)expr).ForceTruncateReturnValues = false;
                }

                if (expr is StringLiteral && ParserSettings.MaintainSyntaxErrorCompatibility)
                {
                    Throw($"syntax error compat: can't directly call strings, use parentheses", CurToken);
                }
                expr = new FunctionCall {
                    Function  = expr,
                    Arguments = new List <IExpression> {
                        ReadTableConstructor()
                    }
                };
            }
            else if (CurToken.Type == TokenType.QuotedString)
            {
                if (expr is FunctionCall)
                {
                    ((FunctionCall)expr).ForceTruncateReturnValues = false;
                }

                if (expr is StringLiteral && ParserSettings.MaintainSyntaxErrorCompatibility)
                {
                    Throw($"syntax error compat: can't directly call strings, use parentheses", CurToken);
                }
                expr = new FunctionCall {
                    Function  = expr,
                    Arguments = new List <IExpression> {
                        ReadStringLiteral()
                    }
                };
            }

            if (unary_op != null && unary_op.Value.IsUnary)
            {
                if (expr is FunctionCall)
                {
                    ((FunctionCall)expr).ForceTruncateReturnValues = false;
                }

                expr = new UnaryOp(unary_op.Value.UnaryOpType.Value, expr);
            }

            return(expr);
        }