Blame src/constexp.y

Packit 1c1d7e
/******************************************************************************
Packit 1c1d7e
 *
Packit 1c1d7e
 * 
Packit 1c1d7e
 *
Packit 1c1d7e
 *
Packit 1c1d7e
 * Copyright (C) 1997-2015 by Dimitri van Heesch.
Packit 1c1d7e
 *
Packit 1c1d7e
 * Permission to use, copy, modify, and distribute this software and its
Packit 1c1d7e
 * documentation under the terms of the GNU General Public License is hereby 
Packit 1c1d7e
 * granted. No representations are made about the suitability of this software 
Packit 1c1d7e
 * for any purpose. It is provided "as is" without express or implied warranty.
Packit 1c1d7e
 * See the GNU General Public License for more details.
Packit 1c1d7e
 *
Packit 1c1d7e
 * Documents produced by Doxygen are derivative works derived from the
Packit 1c1d7e
 * input used in their production; they are not affected by this license.
Packit 1c1d7e
 *
Packit 1c1d7e
 */
Packit 1c1d7e
Packit 1c1d7e
%{
Packit 1c1d7e
Packit 1c1d7e
#include "cppvalue.h"
Packit 1c1d7e
#include "constexp.h"
Packit 1c1d7e
#include "message.h"
Packit 1c1d7e
Packit 1c1d7e
#if defined(_MSC_VER)
Packit 1c1d7e
#define MSDOS
Packit 1c1d7e
#endif
Packit 1c1d7e
Packit 1c1d7e
#define YYSTYPE CPPValue
Packit 1c1d7e
Packit 1c1d7e
#include <stdio.h>
Packit 1c1d7e
#include <stdlib.h>
Packit 1c1d7e
Packit 1c1d7e
int constexpYYerror(const char *s)
Packit 1c1d7e
{
Packit 1c1d7e
  warn(g_constExpFileName,g_constExpLineNr,
Packit 1c1d7e
       "preprocessing issue while doing constant expression evaluation: %s",s);
Packit 1c1d7e
  return 0;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
int constexpYYlex();
Packit 1c1d7e
Packit 1c1d7e
%}
Packit 1c1d7e
Packit 1c1d7e
%no-lines
Packit 1c1d7e
%name-prefix="constexpYY"
Packit 1c1d7e
Packit 1c1d7e
%token TOK_QUESTIONMARK
Packit 1c1d7e
%token TOK_COLON
Packit 1c1d7e
%token TOK_OR
Packit 1c1d7e
%token TOK_AND
Packit 1c1d7e
%token TOK_BITWISEOR
Packit 1c1d7e
%token TOK_BITWISEXOR
Packit 1c1d7e
%token TOK_AMPERSAND
Packit 1c1d7e
%token TOK_NOTEQUAL
Packit 1c1d7e
%token TOK_EQUAL
Packit 1c1d7e
%token TOK_LESSTHAN
Packit 1c1d7e
%token TOK_GREATERTHAN
Packit 1c1d7e
%token TOK_LESSTHANOREQUALTO
Packit 1c1d7e
%token TOK_GREATERTHANOREQUALTO
Packit 1c1d7e
%token TOK_SHIFTLEFT
Packit 1c1d7e
%token TOK_SHIFTRIGHT
Packit 1c1d7e
%token TOK_PLUS
Packit 1c1d7e
%token TOK_MINUS
Packit 1c1d7e
%token TOK_STAR
Packit 1c1d7e
%token TOK_DIVIDE
Packit 1c1d7e
%token TOK_MOD
Packit 1c1d7e
%token TOK_TILDE
Packit 1c1d7e
%token TOK_NOT
Packit 1c1d7e
%token TOK_LPAREN
Packit 1c1d7e
%token TOK_RPAREN
Packit 1c1d7e
%token TOK_OCTALINT
Packit 1c1d7e
%token TOK_DECIMALINT
Packit 1c1d7e
%token TOK_HEXADECIMALINT
Packit 1c1d7e
%token TOK_CHARACTER
Packit 1c1d7e
%token TOK_FLOAT
Packit 1c1d7e
Packit 1c1d7e
%%
Packit 1c1d7e
Packit 1c1d7e
start: constant_expression
Packit 1c1d7e
       { g_resultValue = $1; return 0; }
Packit 1c1d7e
;
Packit 1c1d7e
Packit 1c1d7e
constant_expression: logical_or_expression
Packit 1c1d7e
                     { $$ = $1; }
Packit 1c1d7e
	           | logical_or_expression 
Packit 1c1d7e
                     TOK_QUESTIONMARK logical_or_expression 
Packit 1c1d7e
                     TOK_COLON logical_or_expression
Packit 1c1d7e
		     {
Packit 1c1d7e
		       bool c = ($1.isInt() ? ((long)$1 != 0) : ((double)$1 != 0.0));
Packit 1c1d7e
		       $$ = c ? $3 : $5;
Packit 1c1d7e
	             }
Packit 1c1d7e
;
Packit 1c1d7e
Packit 1c1d7e
logical_or_expression: logical_and_expression
Packit 1c1d7e
		       { $$ = $1; }
Packit 1c1d7e
                     | logical_or_expression TOK_OR logical_and_expression
Packit 1c1d7e
		       {
Packit 1c1d7e
			 $$ = CPPValue( (long)((long)$1 || (long)$3) );
Packit 1c1d7e
		       }
Packit 1c1d7e
;
Packit 1c1d7e
Packit 1c1d7e
logical_and_expression: inclusive_or_expression
Packit 1c1d7e
			{ $$ = $1; }
Packit 1c1d7e
		      | logical_and_expression TOK_AND inclusive_or_expression
Packit 1c1d7e
			{
Packit 1c1d7e
			  $$ = CPPValue( (long)((long)$1 && (long)$3) );
Packit 1c1d7e
			}
Packit 1c1d7e
;
Packit 1c1d7e
Packit 1c1d7e
inclusive_or_expression: exclusive_or_expression
Packit 1c1d7e
			 { $$ = $1; }
Packit 1c1d7e
		       | inclusive_or_expression TOK_BITWISEOR 
Packit 1c1d7e
                         exclusive_or_expression
Packit 1c1d7e
			 { 
Packit 1c1d7e
			   $$ = CPPValue( (long)$1 | (long)$3 );
Packit 1c1d7e
			 }
Packit 1c1d7e
;
Packit 1c1d7e
Packit 1c1d7e
exclusive_or_expression: and_expression
Packit 1c1d7e
			 { $$ = $1; }
Packit 1c1d7e
		       | exclusive_or_expression TOK_BITWISEXOR and_expression
Packit 1c1d7e
			 {
Packit 1c1d7e
			   $$ = CPPValue( (long)$1 ^ (long)$3 );
Packit 1c1d7e
			 }
Packit 1c1d7e
;
Packit 1c1d7e
Packit 1c1d7e
and_expression:	equality_expression
Packit 1c1d7e
		{ $$ = $1; }
Packit 1c1d7e
	      | and_expression TOK_AMPERSAND equality_expression
Packit 1c1d7e
		{ 
Packit 1c1d7e
		  $$ = CPPValue( (long)$1 & (long)$3 );
Packit 1c1d7e
		}
Packit 1c1d7e
;
Packit 1c1d7e
Packit 1c1d7e
equality_expression: relational_expression
Packit 1c1d7e
		     { $$ = $1; }
Packit 1c1d7e
		   | equality_expression TOK_EQUAL relational_expression
Packit 1c1d7e
		     { 
Packit 1c1d7e
		       $$ = CPPValue( (long)((double)$1 == (double)$3) );
Packit 1c1d7e
	             }
Packit 1c1d7e
		   | equality_expression TOK_NOTEQUAL relational_expression
Packit 1c1d7e
		     {
Packit 1c1d7e
                       $$ = CPPValue( (long)((double)$1 != (double)$3) );
Packit 1c1d7e
		     }
Packit 1c1d7e
;
Packit 1c1d7e
Packit 1c1d7e
relational_expression: shift_expression
Packit 1c1d7e
		       { $$ = $1; }
Packit 1c1d7e
		     | relational_expression TOK_LESSTHAN shift_expression
Packit 1c1d7e
		       { 
Packit 1c1d7e
			 $$ = CPPValue( (long)((double)$1 < (double)$3) );
Packit 1c1d7e
		       }
Packit 1c1d7e
		     | relational_expression TOK_GREATERTHAN shift_expression
Packit 1c1d7e
		       {
Packit 1c1d7e
                         $$ = CPPValue( (long)((double)$1 > (double)$3) );
Packit 1c1d7e
		       }
Packit 1c1d7e
		     | relational_expression TOK_LESSTHANOREQUALTO
Packit 1c1d7e
		       shift_expression
Packit 1c1d7e
		       {
Packit 1c1d7e
		         $$ = CPPValue( (long)((double)$1 <= (double)$3) );
Packit 1c1d7e
		       }
Packit 1c1d7e
		     | relational_expression TOK_GREATERTHANOREQUALTO
Packit 1c1d7e
		       shift_expression
Packit 1c1d7e
		       {
Packit 1c1d7e
			 $$ = CPPValue( (long)((double)$1 >= (double)$3) );
Packit 1c1d7e
		       }
Packit 1c1d7e
;
Packit 1c1d7e
Packit 1c1d7e
shift_expression: additive_expression
Packit 1c1d7e
		  { $$ = $1; }
Packit 1c1d7e
		| shift_expression TOK_SHIFTLEFT additive_expression
Packit 1c1d7e
		  {
Packit 1c1d7e
		    $$ = CPPValue( (long)$1 << (long)$3 );	
Packit 1c1d7e
		  }
Packit 1c1d7e
		| shift_expression TOK_SHIFTRIGHT additive_expression
Packit 1c1d7e
		  {
Packit 1c1d7e
		    $$ = CPPValue( (long)$1 >> (long)$3 );
Packit 1c1d7e
		  }
Packit 1c1d7e
;
Packit 1c1d7e
Packit 1c1d7e
additive_expression: multiplicative_expression
Packit 1c1d7e
		     { $$ = $1; }
Packit 1c1d7e
		   | additive_expression TOK_PLUS multiplicative_expression
Packit 1c1d7e
		     {
Packit 1c1d7e
		       if (!$1.isInt() || !$3.isInt())
Packit 1c1d7e
		       {
Packit 1c1d7e
		         $$ = CPPValue( (double)$1 + (double)$3 );
Packit 1c1d7e
		       }
Packit 1c1d7e
		       else	
Packit 1c1d7e
		       {
Packit 1c1d7e
		         $$ = CPPValue( (long)$1 + (long)$3 );
Packit 1c1d7e
		       }
Packit 1c1d7e
		     }
Packit 1c1d7e
		   | additive_expression TOK_MINUS multiplicative_expression
Packit 1c1d7e
		     {
Packit 1c1d7e
		       if (!$1.isInt() || !$3.isInt())
Packit 1c1d7e
		       {
Packit 1c1d7e
		         $$ = CPPValue( (double)$1 - (double)$3 );
Packit 1c1d7e
		       }
Packit 1c1d7e
		       else	
Packit 1c1d7e
		       {
Packit 1c1d7e
		         $$ = CPPValue( (long)$1 - (long)$3 );
Packit 1c1d7e
		       }
Packit 1c1d7e
		     }
Packit 1c1d7e
;
Packit 1c1d7e
Packit 1c1d7e
multiplicative_expression: unary_expression
Packit 1c1d7e
			   { $$ = $1; }
Packit 1c1d7e
			 | multiplicative_expression TOK_STAR unary_expression
Packit 1c1d7e
			   { 
Packit 1c1d7e
			     if (!$1.isInt() || !$3.isInt())
Packit 1c1d7e
			     {
Packit 1c1d7e
			       $$ = CPPValue( (double)$1 * (double)$3 );
Packit 1c1d7e
			     }
Packit 1c1d7e
			     else
Packit 1c1d7e
			     {
Packit 1c1d7e
			       $$ = CPPValue( (long)$1 * (long)$3 );
Packit 1c1d7e
			     }
Packit 1c1d7e
			   }
Packit 1c1d7e
			 | multiplicative_expression TOK_DIVIDE unary_expression
Packit 1c1d7e
			   { 
Packit 1c1d7e
			     if (!$1.isInt() || !$3.isInt())
Packit 1c1d7e
			     {
Packit 1c1d7e
			       $$ = CPPValue( (double)$1 / (double)$3 );
Packit 1c1d7e
			     }
Packit 1c1d7e
			     else
Packit 1c1d7e
			     {
Packit 1c1d7e
			       long value = $3;
Packit 1c1d7e
			       if (value==0) value=1;
Packit 1c1d7e
			       $$ = CPPValue( (long)$1 / value );
Packit 1c1d7e
			     }
Packit 1c1d7e
			   }
Packit 1c1d7e
			 | multiplicative_expression TOK_MOD unary_expression
Packit 1c1d7e
			   { 
Packit 1c1d7e
			     long value = $3;
Packit 1c1d7e
			     if (value==0) value=1;
Packit 1c1d7e
			     $$ = CPPValue( (long)$1 % value );
Packit 1c1d7e
			   }
Packit 1c1d7e
;
Packit 1c1d7e
Packit 1c1d7e
unary_expression: primary_expression
Packit 1c1d7e
		  { $$ = $1; }
Packit 1c1d7e
	        | TOK_PLUS unary_expression
Packit 1c1d7e
		  { $$ = $1; }
Packit 1c1d7e
		| TOK_MINUS unary_expression
Packit 1c1d7e
		  { 
Packit 1c1d7e
		    if ($2.isInt()) 
Packit 1c1d7e
                      $$ = CPPValue(-(long)$2);
Packit 1c1d7e
                    else
Packit 1c1d7e
		      $$ = CPPValue(-(double)$2);
Packit 1c1d7e
		  }
Packit 1c1d7e
		| TOK_TILDE unary_expression
Packit 1c1d7e
		  {
Packit 1c1d7e
		    $$ = CPPValue(~(long)$2);
Packit 1c1d7e
		  }
Packit 1c1d7e
		| TOK_NOT unary_expression
Packit 1c1d7e
		  {
Packit 1c1d7e
		    $$ = CPPValue((long)!(long)$2);
Packit 1c1d7e
		  }
Packit 1c1d7e
;
Packit 1c1d7e
Packit 1c1d7e
primary_expression: constant
Packit 1c1d7e
		    { $$ = $1; }
Packit 1c1d7e
		  | TOK_LPAREN constant_expression TOK_RPAREN
Packit 1c1d7e
		    { $$ = $2; }
Packit 1c1d7e
;
Packit 1c1d7e
Packit 1c1d7e
constant: TOK_OCTALINT
Packit 1c1d7e
	  { $$ = parseOctal(); }
Packit 1c1d7e
	| TOK_DECIMALINT
Packit 1c1d7e
	  { $$ = parseDecimal(); }
Packit 1c1d7e
	| TOK_HEXADECIMALINT
Packit 1c1d7e
	  { $$ = parseHexadecimal(); }
Packit 1c1d7e
	| TOK_CHARACTER
Packit 1c1d7e
	  { $$ = parseCharacter(); }
Packit 1c1d7e
	| TOK_FLOAT
Packit 1c1d7e
	  { $$ = parseFloat(); }
Packit 1c1d7e
;
Packit 1c1d7e
Packit 1c1d7e
%%