/*
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

This file contains the Yacc grammar for GLSL ES preprocessor expression.

IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh,
WHICH GENERATES THE GLSL ES preprocessor expression parser.
*/

%{
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// This file is auto-generated by generate_parser.sh. DO NOT EDIT!

#if defined(__GNUC__)
// Triggered by the auto-generated pplval variable.
#if !defined(__clang__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#else
#pragma GCC diagnostic ignored "-Wuninitialized"
#endif
#elif defined(_MSC_VER)
#pragma warning(disable: 4065 4244 4701 4702)
#endif

#include "ExpressionParser.h"

#if defined(_MSC_VER)
#include <malloc.h>
#else
#include <stdlib.h>
#endif

#include <limits>
#include <cassert>
#include <sstream>
#include <stdint.h>

#include "DiagnosticsBase.h"
#include "Lexer.h"
#include "Token.h"
#include "../../common/debug.h"

typedef int32_t YYSTYPE;
typedef uint32_t UNSIGNED_TYPE;

#define YYENABLE_NLS 0
#define YYLTYPE_IS_TRIVIAL 1
#define YYSTYPE_IS_TRIVIAL 1
#define YYSTYPE_IS_DECLARED 1

namespace {
struct Context
{
    pp::Diagnostics* diagnostics;
    pp::Lexer* lexer;
    pp::Token* token;
    int* result;
    bool parsePresetToken;

    pp::ExpressionParser::ErrorSettings errorSettings;
    bool *valid;

    void startIgnoreErrors() { ++ignoreErrors; }
    void endIgnoreErrors() { --ignoreErrors; }

    bool isIgnoringErrors() { return ignoreErrors > 0; }

    int ignoreErrors;
};
}  // namespace
%}

%pure-parser
%name-prefix "pp"
%parse-param {Context *context}
%lex-param {Context *context}

%{
static int yylex(YYSTYPE* lvalp, Context* context);
static void yyerror(Context* context, const char* reason);
%}

%token TOK_CONST_INT
%token TOK_IDENTIFIER
%left TOK_OP_OR
%left TOK_OP_AND
%left '|'
%left '^'
%left '&'
%left TOK_OP_EQ TOK_OP_NE
%left '<' '>' TOK_OP_LE TOK_OP_GE
%left TOK_OP_LEFT TOK_OP_RIGHT
%left '+' '-'
%left '*' '/' '%'
%right TOK_UNARY

%%

input
    : expression {
        *(context->result) = static_cast<int>($1);
        YYACCEPT;
    }
;

expression
    : TOK_CONST_INT
    | TOK_IDENTIFIER {
        if (!context->isIgnoringErrors())
        {
            // This rule should be applied right after the token is lexed, so we can
            // refer to context->token in the error message.
            context->diagnostics->report(context->errorSettings.unexpectedIdentifier,
                                         context->token->location, context->token->text);
            *(context->valid) = false;
        }
        $$ = $1;
    }
    | expression TOK_OP_OR {
        if ($1 != 0)
        {
            // Ignore errors in the short-circuited part of the expression.
            // ESSL3.00 section 3.4:
            // If an operand is not evaluated, the presence of undefined identifiers
            // in the operand will not cause an error.
            // Unevaluated division by zero should not cause an error either.
            context->startIgnoreErrors();
        }
    } expression {
        if ($1 != 0)
        {
            context->endIgnoreErrors();
            $$ = static_cast<YYSTYPE>(1);
        }
        else
        {
            $$ = $1 || $4;
        }
    }
    | expression TOK_OP_AND {
        if ($1 == 0)
        {
            // Ignore errors in the short-circuited part of the expression.
            // ESSL3.00 section 3.4:
            // If an operand is not evaluated, the presence of undefined identifiers
            // in the operand will not cause an error.
            // Unevaluated division by zero should not cause an error either.
            context->startIgnoreErrors();
        }
    } expression {
        if ($1 == 0)
        {
            context->endIgnoreErrors();
            $$ = static_cast<YYSTYPE>(0);
        }
        else
        {
            $$ = $1 && $4;
        }
    }
    | expression '|' expression {
        $$ = $1 | $3;
    }
    | expression '^' expression {
        $$ = $1 ^ $3;
    }
    | expression '&' expression {
        $$ = $1 & $3;
    }
    | expression TOK_OP_NE expression {
        $$ = $1 != $3;
    }
    | expression TOK_OP_EQ expression {
        $$ = $1 == $3;
    }
    | expression TOK_OP_GE expression {
        $$ = $1 >= $3;
    }
    | expression TOK_OP_LE expression {
        $$ = $1 <= $3;
    }
    | expression '>' expression {
        $$ = $1 > $3;
    }
    | expression '<' expression {
        $$ = $1 < $3;
    }
    | expression TOK_OP_RIGHT expression {
        if ($3 < 0 || $3 > 31)
        {
            if (!context->isIgnoringErrors())
            {
                std::ostringstream stream;
                stream << $1 << " >> " << $3;
                std::string text = stream.str();
                context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT,
                                             context->token->location,
                                             text.c_str());
                *(context->valid) = false;
            }
            $$ = static_cast<YYSTYPE>(0);
        }
        else if ($1 < 0)
        {
            // Logical shift right.
            $$ = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>($1) >> $3);
        }
        else
        {
            $$ = $1 >> $3;
        }
    }
    | expression TOK_OP_LEFT expression {
        if ($3 < 0 || $3 > 31)
        {
            if (!context->isIgnoringErrors())
            {
                std::ostringstream stream;
                stream << $1 << " << " << $3;
                std::string text = stream.str();
                context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT,
                                             context->token->location,
                                             text.c_str());
                *(context->valid) = false;
            }
            $$ = static_cast<YYSTYPE>(0);
        }
        else
        {
            // Logical shift left. Casting to unsigned is needed to ensure there's no signed integer
            // overflow, which some tools treat as an error.
            $$ = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>($1) << $3);
        }
    }
    | expression '-' expression {
        $$ = $1 - $3;
    }
    | expression '+' expression {
        $$ = $1 + $3;
    }
    | expression '%' expression {
        if ($3 == 0)
        {
            if (!context->isIgnoringErrors())
            {
                std::ostringstream stream;
                stream << $1 << " % " << $3;
                std::string text = stream.str();
                context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
                                             context->token->location,
                                             text.c_str());
                *(context->valid) = false;
            }
            $$ = static_cast<YYSTYPE>(0);
        }
        else if (($1 == std::numeric_limits<YYSTYPE>::min()) && ($3 == -1))
        {
            // Check for the special case where the minimum representable number is
            // divided by -1. If left alone this has undefined results.
            $$ = 0;
        }
        else
        {
            $$ = $1 % $3;
        }
    }
    | expression '/' expression {
        if ($3 == 0)
        {
            if (!context->isIgnoringErrors())
            {
                std::ostringstream stream;
                stream << $1 << " / " << $3;
                std::string text = stream.str();
                context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
                                            context->token->location,
                                            text.c_str());
                *(context->valid) = false;
            }
            $$ = static_cast<YYSTYPE>(0);
        }
        else if (($1 == std::numeric_limits<YYSTYPE>::min()) && ($3 == -1))
        {
            // Check for the special case where the minimum representable number is
            // divided by -1. If left alone this leads to integer overflow in C++, which
            // has undefined results.
            $$ = std::numeric_limits<YYSTYPE>::max();
        }
        else
        {
            $$ = $1 / $3;
        }
    }
    | expression '*' expression {
        $$ = $1 * $3;
    }
    | '!' expression %prec TOK_UNARY {
        $$ = ! $2;
    }
    | '~' expression %prec TOK_UNARY {
        $$ = ~ $2;
    }
    | '-' expression %prec TOK_UNARY {
        // Check for negation of minimum representable integer to prevent undefined signed int
        // overflow.
        if ($2 == std::numeric_limits<YYSTYPE>::min())
        {
            $$ = std::numeric_limits<YYSTYPE>::min();
        }
        else
        {
            $$ = -$2;
        }
    }
    | '+' expression %prec TOK_UNARY {
        $$ = + $2;
    }
    | '(' expression ')' {
        $$ = $2;
    }
;

%%

int yylex(YYSTYPE *lvalp, Context *context)
{
    pp::Token *token = context->token;
    if (!context->parsePresetToken)
    {
        context->lexer->lex(token);
    }
    context->parsePresetToken = false;

    int type = 0;

    switch (token->type)
    {
      case pp::Token::CONST_INT: {
        unsigned int val = 0;
        int testVal = 0;
        if (!token->uValue(&val) || (!token->iValue(&testVal) &&
                                     context->errorSettings.integerLiteralsMustFit32BitSignedRange))
        {
            context->diagnostics->report(pp::Diagnostics::PP_INTEGER_OVERFLOW,
                                         token->location, token->text);
            *(context->valid) = false;
        }
        *lvalp = static_cast<YYSTYPE>(val);
        type = TOK_CONST_INT;
        break;
      }
      case pp::Token::IDENTIFIER:
        *lvalp = static_cast<YYSTYPE>(-1);
        type = TOK_IDENTIFIER;
        break;
      case pp::Token::OP_OR:
        type = TOK_OP_OR;
        break;
      case pp::Token::OP_AND:
        type = TOK_OP_AND;
        break;
      case pp::Token::OP_NE:
        type = TOK_OP_NE;
        break;
      case pp::Token::OP_EQ:
        type = TOK_OP_EQ;
        break;
      case pp::Token::OP_GE:
        type = TOK_OP_GE;
        break;
      case pp::Token::OP_LE:
        type = TOK_OP_LE;
        break;
      case pp::Token::OP_RIGHT:
        type = TOK_OP_RIGHT;
        break;
      case pp::Token::OP_LEFT:
        type = TOK_OP_LEFT;
        break;
      case '|':
      case '^':
      case '&':
      case '>':
      case '<':
      case '-':
      case '+':
      case '%':
      case '/':
      case '*':
      case '!':
      case '~':
      case '(':
      case ')':
        type = token->type;
        break;

      default:
        break;
    }

    return type;
}

void yyerror(Context *context, const char *reason)
{
    context->diagnostics->report(pp::Diagnostics::PP_INVALID_EXPRESSION,
                                 context->token->location,
                                 reason);
}

namespace pp {

ExpressionParser::ExpressionParser(Lexer *lexer, Diagnostics *diagnostics)
    : mLexer(lexer),
      mDiagnostics(diagnostics)
{
}

bool ExpressionParser::parse(Token *token,
                             int *result,
                             bool parsePresetToken,
                             const ErrorSettings &errorSettings,
                             bool *valid)
{
    Context context;
    context.diagnostics = mDiagnostics;
    context.lexer = mLexer;
    context.token = token;
    context.result = result;
    context.ignoreErrors = 0;
    context.parsePresetToken = parsePresetToken;
    context.errorSettings    = errorSettings;
    context.valid            = valid;
    int ret = yyparse(&context);
    switch (ret)
    {
      case 0:
      case 1:
        break;

      case 2:
        mDiagnostics->report(Diagnostics::PP_OUT_OF_MEMORY, token->location, "");
        break;

      default:
        assert(false);
        mDiagnostics->report(Diagnostics::PP_INTERNAL_ERROR, token->location, "");
        break;
    }

    return ret == 0;
}

}  // namespace pp
