336 lines
7.7 KiB
C
336 lines
7.7 KiB
C
/***********************************************************************
|
|
* Microsoft (R) Windows (R) Resource Compiler
|
|
*
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
*
|
|
* File Comments:
|
|
*
|
|
*
|
|
***********************************************************************/
|
|
|
|
#include "rc.h"
|
|
|
|
/************************************************************************/
|
|
/* Local Function Prototypes */
|
|
/************************************************************************/
|
|
long and(void);
|
|
long andif(void);
|
|
long constant(void);
|
|
long constexpr(void);
|
|
long eqset(void);
|
|
long mult(void);
|
|
long or(void);
|
|
long orelse(void);
|
|
long plus(void);
|
|
long prim(void);
|
|
long relation(void);
|
|
long shift(void);
|
|
long xor(void);
|
|
|
|
|
|
/************************************************************************/
|
|
/* File Global Variables */
|
|
/************************************************************************/
|
|
long Currval = 0;
|
|
static int Parencnt = 0;
|
|
|
|
|
|
/************************************************************************/
|
|
/* do_constexpr() */
|
|
/************************************************************************/
|
|
long
|
|
do_constexpr(
|
|
void
|
|
)
|
|
{
|
|
REG long val;
|
|
|
|
Parencnt = 0;
|
|
Currtok = L_NOTOKEN;
|
|
val = constexpr();
|
|
if( Currtok == L_RPAREN ) {
|
|
if( Parencnt-- == 0 ) {
|
|
fatal(1012, L"("); /* missing left paren */
|
|
}
|
|
} else if( Currtok != L_NOTOKEN ) {
|
|
warning(4067, PPifel_str);
|
|
}
|
|
|
|
if( Parencnt > 0 ) {
|
|
fatal(4012, L")"); /* missing right paren */
|
|
}
|
|
return(val);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* constexpr ::= orelse [ '?' orelse ':' orelse ]; */
|
|
/************************************************************************/
|
|
long
|
|
constexpr(
|
|
void
|
|
)
|
|
{
|
|
REG long val;
|
|
REG long val1;
|
|
long val2;
|
|
|
|
val = orelse();
|
|
if( nextis(L_QUEST) ) {
|
|
val1 = orelse();
|
|
if( nextis(L_COLON) )
|
|
val2 = orelse();
|
|
return(val ? val1 : val2);
|
|
}
|
|
return(val);
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
/* orelse ::= andif [ '||' andif ]* ; */
|
|
/************************************************************************/
|
|
long
|
|
orelse(
|
|
void
|
|
)
|
|
{
|
|
REG long val;
|
|
|
|
val = andif();
|
|
while(nextis(L_OROR))
|
|
val = andif() || val;
|
|
return(val);
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
/* andif ::= or [ '&&' or ]* ; */
|
|
/************************************************************************/
|
|
long
|
|
andif(
|
|
void
|
|
)
|
|
{
|
|
REG long val;
|
|
|
|
val = or();
|
|
while(nextis(L_ANDAND))
|
|
val = or() && val;
|
|
return(val);
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
/* or ::= xor [ '|' xor]* ; */
|
|
/************************************************************************/
|
|
long
|
|
or(
|
|
void
|
|
)
|
|
{
|
|
REG long val;
|
|
|
|
val = xor();
|
|
while( nextis(L_OR) )
|
|
val |= xor();
|
|
return(val);
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
/* xor ::= and [ '^' and]* ; */
|
|
/************************************************************************/
|
|
long
|
|
xor(
|
|
void
|
|
)
|
|
{
|
|
REG long val;
|
|
|
|
val = and();
|
|
while( nextis(L_XOR) )
|
|
val ^= and();
|
|
return(val);
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
/* and ::= eqset [ '&' eqset]* ; */
|
|
/************************************************************************/
|
|
long
|
|
and(
|
|
void
|
|
)
|
|
{
|
|
REG long val;
|
|
|
|
val = eqset();
|
|
while( nextis(L_AND) )
|
|
val &= eqset();
|
|
return(val);
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
/* eqset ::= relation [ ('==' | '!=') eqset] ; */
|
|
/************************************************************************/
|
|
long
|
|
eqset(
|
|
void
|
|
)
|
|
{
|
|
REG long val;
|
|
|
|
val = relation();
|
|
if( nextis(L_EQUALS) )
|
|
return(val == relation());
|
|
if( nextis(L_NOTEQ) )
|
|
return(val != relation());
|
|
return(val);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* relation ::= shift [ ('<' | '>' | '<=' | '>=' ) shift] ; */
|
|
/************************************************************************/
|
|
long
|
|
relation(
|
|
void
|
|
)
|
|
{
|
|
REG long val;
|
|
|
|
val = shift();
|
|
if( nextis(L_LT) )
|
|
return(val < shift());
|
|
if( nextis(L_GT) )
|
|
return(val > shift());
|
|
if( nextis(L_LTEQ) )
|
|
return(val <= shift());
|
|
if( nextis(L_GTEQ) )
|
|
return(val >= shift());
|
|
return(val);
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
/* shift ::= plus [ ('<< | '>>') plus] ; */
|
|
/************************************************************************/
|
|
long
|
|
shift(
|
|
void
|
|
)
|
|
{
|
|
REG long val;
|
|
|
|
val = plus();
|
|
if( nextis(L_RSHIFT) )
|
|
return(val >> plus());
|
|
if( nextis(L_LSHIFT) )
|
|
return(val << plus());
|
|
return(val);
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
/* plus ::= mult [ ('+' | '-') mult ]* ; */
|
|
/************************************************************************/
|
|
long
|
|
plus(
|
|
void
|
|
)
|
|
{
|
|
REG long val;
|
|
|
|
val = mult();
|
|
for(;;) {
|
|
if( nextis(L_PLUS) )
|
|
val += mult();
|
|
else if( nextis(L_MINUS) )
|
|
val -= mult();
|
|
else
|
|
break;
|
|
}
|
|
return(val);
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
/* mult ::= prim [ ('*' | '/' | '%' ) prim ]* ; */
|
|
/************************************************************************/
|
|
long
|
|
mult(
|
|
void
|
|
)
|
|
{
|
|
REG long val;
|
|
long PrimVal;
|
|
|
|
val = prim();
|
|
for(;;) {
|
|
if( nextis(L_MULT) )
|
|
val *= prim();
|
|
else if( nextis(L_DIV) ) {
|
|
PrimVal = prim();
|
|
if (PrimVal)
|
|
val /= PrimVal;
|
|
else
|
|
val = PrimVal;
|
|
}
|
|
else if( nextis(L_MOD) ) {
|
|
PrimVal = prim();
|
|
if (PrimVal)
|
|
val %= PrimVal;
|
|
else
|
|
val = 0;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
return(val);
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
/* prim ::= constant | ( '!' | '~' | '-' ) constant */
|
|
/************************************************************************/
|
|
long
|
|
prim(
|
|
void
|
|
)
|
|
{
|
|
if( nextis(L_EXCLAIM) )
|
|
return( ! constant());
|
|
else if( nextis(L_TILDE) )
|
|
return( ~ constant() );
|
|
else if( nextis(L_MINUS) )
|
|
return(-constant());
|
|
else
|
|
return(constant());
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
/* constant - at last, a terminal symbol | '(' constexpr ')' */
|
|
/************************************************************************/
|
|
long
|
|
constant(
|
|
void
|
|
)
|
|
{
|
|
REG long val;
|
|
|
|
if( nextis(L_LPAREN) ) {
|
|
Parencnt++;
|
|
val = constexpr();
|
|
if( nextis(L_RPAREN) ) {
|
|
Parencnt--;
|
|
return(val);
|
|
} else {
|
|
fatal(1012, L")");
|
|
}
|
|
} else if( ! nextis(L_CINTEGER) ) {
|
|
fatal(1017); /* invalid integer constant expression */
|
|
}
|
|
|
|
return(Currval);
|
|
}
|