/*
//
// Copyright 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

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

IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN scripts/run_code_generation.py
WHICH GENERATES THE GLSL ES preprocessor expression parser.
*/

%{
// GENERATED FILE - DO NOT EDIT.
// Generated by generate_parser.py from preprocessor.y
//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// preprocessor.y:
//   Parser for the OpenGL shading language preprocessor.

#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
#if defined(__clang__)
#pragma clang diagnostic ignored "-Wunreachable-code"
#pragma clang diagnostic ignored "-Wunused-but-set-variable"
#endif

#include "ExpressionParser.h"

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

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

#include "DiagnosticsBase.h"
#include "Lexer.h"
#include "Token.h"
#include "common/mathutil.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
{
    angle::pp::Diagnostics *diagnostics;
    angle::pp::Lexer *lexer;
    angle::pp::Token *token;
    int* result;
    bool parsePresetToken;

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

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

    bool isIgnoringErrors() { return ignoreErrors > 0; }

    int ignoreErrors;
};
}  // namespace
%}

%define api.pure
%define api.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(angle::pp::Diagnostics::PP_UNDEFINED_SHIFT,
                                             context->token->location, text);
                *(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(angle::pp::Diagnostics::PP_UNDEFINED_SHIFT,
                                             context->token->location, text);
                *(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 {
        $$ = gl::WrappingDiff<YYSTYPE>($1, $3);
    }
    | expression '+' expression {
        $$ = gl::WrappingSum<YYSTYPE>($1, $3);
    }
    | expression '%' expression {
        if ($3 == 0)
        {
            if (!context->isIgnoringErrors())
            {
                std::ostringstream stream;
                stream << $1 << " % " << $3;
                std::string text = stream.str();
                context->diagnostics->report(angle::pp::Diagnostics::PP_DIVISION_BY_ZERO,
                                             context->token->location, text);
                *(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(angle::pp::Diagnostics::PP_DIVISION_BY_ZERO,
                                            context->token->location, text);
                *(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 {
        $$ = gl::WrappingMul($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)
{
    angle::pp::Token *token = context->token;
    if (!context->parsePresetToken)
    {
        context->lexer->lex(token);
    }
    context->parsePresetToken = false;

    int type = 0;

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

namespace angle {

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

}  // namespace angle
