/*
//
// Copyright (c) 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 generate_parser.sh,
WHICH GENERATES THE GLSL ES preprocessor expression parser.
*/

%{
//
// Copyright (c) 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 is auto-generated by generate_parser.sh. DO NOT EDIT!

#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
// Triggered by the auto-generated pplval variable.
#pragma GCC diagnostic ignored "-Wuninitialized"
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#pragma GCC diagnostic warning "-Wpragmas"
#pragma GCC diagnostic warning "-Wunknown-pragmas"
#elif defined(_MSC_VER)
#pragma warning(disable: 4065 4701)
#endif

#include "ExpressionParser.h"

#include <cassert>
#include <sstream>

#include "DiagnosticsBase.h"
#include "Lexer.h"
#include "Token.h"

#if defined(_MSC_VER)
typedef __int64 YYSTYPE;
#else
#include <stdint.h>
typedef intmax_t YYSTYPE;
#endif  // _MSC_VER
#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;
};
}  // 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
%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
    | expression TOK_OP_OR expression {
        $$ = $1 || $3;
    }
    | expression TOK_OP_AND expression {
        $$ = $1 && $3;
    }
    | 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 {
        $$ = $1 >> $3;
    }
    | expression TOK_OP_LEFT expression {
        $$ = $1 << $3;
    }
    | expression '-' expression {
        $$ = $1 - $3;
    }
    | expression '+' expression {
        $$ = $1 + $3;
    }
    | expression '%' expression {
        if ($3 == 0) {
            std::ostringstream stream;
            stream << $1 << " % " << $3;
            std::string text = stream.str();
            context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO,
                                         context->token->location,
                                         text.c_str());
            YYABORT;
        } else {
            $$ = $1 % $3;
        }
    }
    | expression '/' expression {
        if ($3 == 0) {
            std::ostringstream stream;
            stream << $1 << " / " << $3;
            std::string text = stream.str();
            context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO,
                                         context->token->location,
                                         text.c_str());
            YYABORT;
        } else {
            $$ = $1 / $3;
        }
    }
    | expression '*' expression {
        $$ = $1 * $3;
    }
    | '!' expression %prec TOK_UNARY {
        $$ = ! $2;
    }
    | '~' expression %prec TOK_UNARY {
        $$ = ~ $2;
    }
    | '-' expression %prec TOK_UNARY {
        $$ = - $2;
    }
    | '+' expression %prec TOK_UNARY {
        $$ = + $2;
    }
    | '(' expression ')' {
        $$ = $2;
    }
;

%%

int yylex(YYSTYPE* lvalp, Context* context)
{
    int type = 0;

    pp::Token* token = context->token;
    switch (token->type)
    {
      case pp::Token::CONST_INT:
      {
        unsigned int val = 0;
        if (!token->uValue(&val))
        {
            context->diagnostics->report(pp::Diagnostics::INTEGER_OVERFLOW,
                                         token->location, token->text);
        }
        *lvalp = static_cast<YYSTYPE>(val);
        type = TOK_CONST_INT;
        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 '|': type = '|'; break;
      case '^': type = '^'; break;
      case '&': type = '&'; break;
      case '>': type = '>'; break;
      case '<': type = '<'; break;
      case '-': type = '-'; break;
      case '+': type = '+'; break;
      case '%': type = '%'; break;
      case '/': type = '/'; break;
      case '*': type = '*'; break;
      case '!': type = '!'; break;
      case '~': type = '~'; break;
      case '(': type = '('; break;
      case ')': type = ')'; break;

      default: break;
    }

    // Advance to the next token if the current one is valid.
    if (type != 0) context->lexer->lex(token);

    return type;
}

void yyerror(Context* context, const char* reason)
{
    context->diagnostics->report(pp::Diagnostics::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)
{
    Context context;
    context.diagnostics = mDiagnostics;
    context.lexer = mLexer;
    context.token = token;
    context.result = result;
    int ret = yyparse(&context);
    switch (ret)
    {
      case 0:
      case 1:
        break;

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

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

    return ret == 0;
}

}  // namespace pp
