/*
//
// 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__)
// Triggered by the auto-generated pplval variable.
#pragma GCC diagnostic ignored "-Wuninitialized"
#elif defined(_MSC_VER)
#pragma warning(disable: 4065 4701)
#endif

#include "ExpressionParser.h"

#include <cassert>
#include <cstdlib>
#include <sstream>

#include "Diagnostics.h"
#include "Lexer.h"
#include "Token.h"

#if defined(_MSC_VER)
typedef __int64 YYSTYPE;
#define strtoll _strtoi64
#else
#include <stdint.h>
typedef intmax_t YYSTYPE;
#endif  // _MSC_VER
#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
%}

%define api.pure
%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 CONST_INT
%left OP_OR
%left OP_AND
%left '|'
%left '^'
%left '&'
%left OP_EQ OP_NE
%left '<' '>' OP_LE OP_GE
%left OP_LEFT OP_RIGHT
%left '+' '-'
%left '*' '/' '%'
%right UNARY

%%

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

expression
    : CONST_INT
    | expression OP_OR expression {
        $$ = $1 || $3;
    }
    | expression OP_AND expression {
        $$ = $1 && $3;
    }
    | expression '|' expression {
        $$ = $1 | $3;
    }
    | expression '^' expression {
        $$ = $1 ^ $3;
    }
    | expression '&' expression {
        $$ = $1 & $3;
    }
    | expression OP_NE expression {
        $$ = $1 != $3;
    }
    | expression OP_EQ expression {
        $$ = $1 == $3;
    }
    | expression OP_GE expression {
        $$ = $1 >= $3;
    }
    | expression OP_LE expression {
        $$ = $1 <= $3;
    }
    | expression '>' expression {
        $$ = $1 > $3;
    }
    | expression '<' expression {
        $$ = $1 < $3;
    }
    | expression OP_RIGHT expression {
        $$ = $1 >> $3;
    }
    | expression OP_LEFT expression {
        $$ = $1 << $3;
    }
    | expression '-' expression {
        $$ = $1 - $3;
    }
    | expression '+' expression {
        $$ = $1 + $3;
    }
    | expression '%' expression {
        if ($3 == 0) {
            std::stringstream 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::stringstream 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 UNARY {
        $$ = ! $2;
    }
    | '~' expression %prec UNARY {
        $$ = ~ $2;
    }
    | '-' expression %prec UNARY {
        $$ = - $2;
    }
    | '+' expression %prec 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:
        *lvalp = strtoll(token->text.c_str(), NULL, 0);
        type = CONST_INT;
        break;

      case pp::Token::OP_OR: type = OP_OR; break;
      case pp::Token::OP_AND: type = OP_AND; break;
      case pp::Token::OP_NE: type = OP_NE; break;
      case pp::Token::OP_EQ: type = OP_EQ; break;
      case pp::Token::OP_GE: type = OP_GE; break;
      case pp::Token::OP_LE: type = OP_LE; break;
      case pp::Token::OP_RIGHT: type = OP_RIGHT; break;
      case pp::Token::OP_LEFT: type = 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
