widl: Add support for comparison, exclusive or, logical not and positive operators in expressions.
This commit is contained in:
parent
6f9020290b
commit
cc3682cf12
|
@ -495,14 +495,26 @@ void write_expr(FILE *h, const expr_t *e, int brackets)
|
|||
case EXPR_IDENTIFIER:
|
||||
fprintf(h, "%s", e->u.sval);
|
||||
break;
|
||||
case EXPR_NEG:
|
||||
fprintf(h, "-");
|
||||
case EXPR_LOGNOT:
|
||||
fprintf(h, "!");
|
||||
write_expr(h, e->ref, 1);
|
||||
break;
|
||||
case EXPR_NOT:
|
||||
fprintf(h, "~");
|
||||
write_expr(h, e->ref, 1);
|
||||
break;
|
||||
case EXPR_POS:
|
||||
fprintf(h, "+");
|
||||
write_expr(h, e->ref, 1);
|
||||
break;
|
||||
case EXPR_NEG:
|
||||
fprintf(h, "-");
|
||||
write_expr(h, e->ref, 1);
|
||||
break;
|
||||
case EXPR_ADDRESSOF:
|
||||
fprintf(h, "&");
|
||||
write_expr(h, e->ref, 1);
|
||||
break;
|
||||
case EXPR_PPTR:
|
||||
fprintf(h, "*");
|
||||
write_expr(h, e->ref, 1);
|
||||
|
@ -529,20 +541,38 @@ void write_expr(FILE *h, const expr_t *e, int brackets)
|
|||
case EXPR_OR:
|
||||
case EXPR_MEMBERPTR:
|
||||
case EXPR_MEMBER:
|
||||
if (brackets) fprintf(h, "(");
|
||||
case EXPR_LOGOR:
|
||||
case EXPR_LOGAND:
|
||||
case EXPR_XOR:
|
||||
case EXPR_EQUALITY:
|
||||
case EXPR_INEQUALITY:
|
||||
case EXPR_GTR:
|
||||
case EXPR_LESS:
|
||||
case EXPR_GTREQL:
|
||||
case EXPR_LESSEQL:
|
||||
if (brackets) fprintf(h, "(");
|
||||
write_expr(h, e->ref, 1);
|
||||
switch (e->type) {
|
||||
case EXPR_SHL: fprintf(h, " << "); break;
|
||||
case EXPR_SHR: fprintf(h, " >> "); break;
|
||||
case EXPR_MOD: fprintf(h, " %% "); break;
|
||||
case EXPR_MUL: fprintf(h, " * "); break;
|
||||
case EXPR_DIV: fprintf(h, " / "); break;
|
||||
case EXPR_ADD: fprintf(h, " + "); break;
|
||||
case EXPR_SUB: fprintf(h, " - "); break;
|
||||
case EXPR_AND: fprintf(h, " & "); break;
|
||||
case EXPR_OR: fprintf(h, " | "); break;
|
||||
case EXPR_MEMBERPTR: fprintf(h, "->"); break;
|
||||
case EXPR_MEMBER: fprintf(h, "."); break;
|
||||
case EXPR_SHL: fprintf(h, " << "); break;
|
||||
case EXPR_SHR: fprintf(h, " >> "); break;
|
||||
case EXPR_MOD: fprintf(h, " %% "); break;
|
||||
case EXPR_MUL: fprintf(h, " * "); break;
|
||||
case EXPR_DIV: fprintf(h, " / "); break;
|
||||
case EXPR_ADD: fprintf(h, " + "); break;
|
||||
case EXPR_SUB: fprintf(h, " - "); break;
|
||||
case EXPR_AND: fprintf(h, " & "); break;
|
||||
case EXPR_OR: fprintf(h, " | "); break;
|
||||
case EXPR_MEMBERPTR: fprintf(h, "->"); break;
|
||||
case EXPR_MEMBER: fprintf(h, "."); break;
|
||||
case EXPR_LOGOR: fprintf(h, " || "); break;
|
||||
case EXPR_LOGAND: fprintf(h, " && "); break;
|
||||
case EXPR_XOR: fprintf(h, " ^ "); break;
|
||||
case EXPR_EQUALITY: fprintf(h, " == "); break;
|
||||
case EXPR_INEQUALITY: fprintf(h, " != "); break;
|
||||
case EXPR_GTR: fprintf(h, " > "); break;
|
||||
case EXPR_LESS: fprintf(h, " < "); break;
|
||||
case EXPR_GTREQL: fprintf(h, " >= "); break;
|
||||
case EXPR_LESSEQL: fprintf(h, " <= "); break;
|
||||
default: break;
|
||||
}
|
||||
write_expr(h, e->u.ext, 1);
|
||||
|
@ -557,10 +587,6 @@ void write_expr(FILE *h, const expr_t *e, int brackets)
|
|||
write_expr(h, e->ext2, 1);
|
||||
if (brackets) fprintf(h, ")");
|
||||
break;
|
||||
case EXPR_ADDRESSOF:
|
||||
fprintf(h, "&");
|
||||
write_expr(h, e->ref, 1);
|
||||
break;
|
||||
case EXPR_ARRAY:
|
||||
if (brackets) fprintf(h, "(");
|
||||
write_expr(h, e->ref, 1);
|
||||
|
|
|
@ -163,6 +163,12 @@ SAFEARRAY{ws}*/\( return tSAFEARRAY;
|
|||
<INITIAL,ATTR>\<\< return SHL;
|
||||
<INITIAL,ATTR>\>\> return SHR;
|
||||
<INITIAL,ATTR>\-\> return MEMBERPTR;
|
||||
<INITIAL,ATTR>== return EQUALITY;
|
||||
<INITIAL,ATTR>!= return INEQUALITY;
|
||||
<INITIAL,ATTR>\>= return GREATEREQUAL;
|
||||
<INITIAL,ATTR>\<= return LESSEQUAL;
|
||||
<INITIAL,ATTR>\|\| return LOGICALOR;
|
||||
<INITIAL,ATTR>&& return LOGICALAND;
|
||||
<INITIAL,ATTR>. return yytext[0];
|
||||
<<EOF>> {
|
||||
if (import_stack_ptr)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* IDL Compiler
|
||||
*
|
||||
* Copyright 2002 Ove Kaaven
|
||||
* Copyright 2006-2008 Robert Shearman
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -181,6 +182,9 @@ static void add_explicit_handle_if_necessary(func_t *func);
|
|||
%token aEOF
|
||||
%token SHL SHR
|
||||
%token MEMBERPTR
|
||||
%token EQUALITY INEQUALITY
|
||||
%token GREATEREQUAL LESSEQUAL
|
||||
%token LOGICALOR LOGICALAND
|
||||
%token tAGGREGATABLE tALLOCATE tAPPOBJECT tASYNC tASYNCUUID
|
||||
%token tAUTOHANDLE tBINDABLE tBOOLEAN tBROADCAST tBYTE tBYTECOUNT
|
||||
%token tCALLAS tCALLBACK tCASE tCDECL tCHAR tCOCLASS tCODE tCOMMSTATUS
|
||||
|
@ -290,12 +294,17 @@ static void add_explicit_handle_if_necessary(func_t *func);
|
|||
|
||||
%left ','
|
||||
%right '?' ':'
|
||||
%left LOGICALOR
|
||||
%left LOGICALAND
|
||||
%left '|'
|
||||
%left '^'
|
||||
%left '&'
|
||||
%left EQUALITY INEQUALITY
|
||||
%left '<' '>' LESSEQUAL GREATEREQUAL
|
||||
%left SHL SHR
|
||||
%left '-' '+'
|
||||
%left '*' '/' '%'
|
||||
%right '~' CAST PPTR NEG ADDRESSOF tSIZEOF
|
||||
%right '!' '~' CAST PPTR POS NEG ADDRESSOF tSIZEOF
|
||||
%left '.' MEMBERPTR '[' ']'
|
||||
|
||||
%%
|
||||
|
@ -624,16 +633,27 @@ expr: aNUM { $$ = make_exprl(EXPR_NUM, $1); }
|
|||
| tTRUE { $$ = make_exprl(EXPR_TRUEFALSE, 1); }
|
||||
| aIDENTIFIER { $$ = make_exprs(EXPR_IDENTIFIER, $1); }
|
||||
| expr '?' expr ':' expr { $$ = make_expr3(EXPR_COND, $1, $3, $5); }
|
||||
| expr LOGICALOR expr { $$ = make_expr2(EXPR_LOGOR, $1, $3); }
|
||||
| expr LOGICALAND expr { $$ = make_expr2(EXPR_LOGAND, $1, $3); }
|
||||
| expr '|' expr { $$ = make_expr2(EXPR_OR , $1, $3); }
|
||||
| expr '^' expr { $$ = make_expr2(EXPR_XOR, $1, $3); }
|
||||
| expr '&' expr { $$ = make_expr2(EXPR_AND, $1, $3); }
|
||||
| expr EQUALITY expr { $$ = make_expr2(EXPR_EQUALITY, $1, $3); }
|
||||
| expr INEQUALITY expr { $$ = make_expr2(EXPR_INEQUALITY, $1, $3); }
|
||||
| expr '>' expr { $$ = make_expr2(EXPR_GTR, $1, $3); }
|
||||
| expr '<' expr { $$ = make_expr2(EXPR_LESS, $1, $3); }
|
||||
| expr GREATEREQUAL expr { $$ = make_expr2(EXPR_GTREQL, $1, $3); }
|
||||
| expr LESSEQUAL expr { $$ = make_expr2(EXPR_LESSEQL, $1, $3); }
|
||||
| expr SHL expr { $$ = make_expr2(EXPR_SHL, $1, $3); }
|
||||
| expr SHR expr { $$ = make_expr2(EXPR_SHR, $1, $3); }
|
||||
| expr '+' expr { $$ = make_expr2(EXPR_ADD, $1, $3); }
|
||||
| expr '-' expr { $$ = make_expr2(EXPR_SUB, $1, $3); }
|
||||
| expr '%' expr { $$ = make_expr2(EXPR_MOD, $1, $3); }
|
||||
| expr '*' expr { $$ = make_expr2(EXPR_MUL, $1, $3); }
|
||||
| expr '/' expr { $$ = make_expr2(EXPR_DIV, $1, $3); }
|
||||
| expr SHL expr { $$ = make_expr2(EXPR_SHL, $1, $3); }
|
||||
| expr SHR expr { $$ = make_expr2(EXPR_SHR, $1, $3); }
|
||||
| '!' expr { $$ = make_expr1(EXPR_LOGNOT, $2); }
|
||||
| '~' expr { $$ = make_expr1(EXPR_NOT, $2); }
|
||||
| '+' expr %prec POS { $$ = make_expr1(EXPR_POS, $2); }
|
||||
| '-' expr %prec NEG { $$ = make_expr1(EXPR_NEG, $2); }
|
||||
| '&' expr %prec ADDRESSOF { $$ = make_expr1(EXPR_ADDRESSOF, $2); }
|
||||
| '*' expr %prec PPTR { $$ = make_expr1(EXPR_PPTR, $2); }
|
||||
|
@ -1203,6 +1223,12 @@ static expr_t *make_expr1(enum expr_type type, expr_t *expr)
|
|||
if (expr->is_const) {
|
||||
e->is_const = TRUE;
|
||||
switch (type) {
|
||||
case EXPR_LOGNOT:
|
||||
e->cval = !expr->cval;
|
||||
break;
|
||||
case EXPR_POS:
|
||||
e->cval = +expr->cval;
|
||||
break;
|
||||
case EXPR_NEG:
|
||||
e->cval = -expr->cval;
|
||||
break;
|
||||
|
@ -1264,6 +1290,33 @@ static expr_t *make_expr2(enum expr_type type, expr_t *expr1, expr_t *expr2)
|
|||
case EXPR_SHR:
|
||||
e->cval = expr1->cval >> expr2->cval;
|
||||
break;
|
||||
case EXPR_LOGOR:
|
||||
e->cval = expr1->cval || expr2->cval;
|
||||
break;
|
||||
case EXPR_LOGAND:
|
||||
e->cval = expr1->cval && expr2->cval;
|
||||
break;
|
||||
case EXPR_XOR:
|
||||
e->cval = expr1->cval ^ expr2->cval;
|
||||
break;
|
||||
case EXPR_EQUALITY:
|
||||
e->cval = expr1->cval == expr2->cval;
|
||||
break;
|
||||
case EXPR_INEQUALITY:
|
||||
e->cval = expr1->cval != expr2->cval;
|
||||
break;
|
||||
case EXPR_GTR:
|
||||
e->cval = expr1->cval > expr2->cval;
|
||||
break;
|
||||
case EXPR_LESS:
|
||||
e->cval = expr1->cval < expr2->cval;
|
||||
break;
|
||||
case EXPR_GTREQL:
|
||||
e->cval = expr1->cval >= expr2->cval;
|
||||
break;
|
||||
case EXPR_LESSEQL:
|
||||
e->cval = expr1->cval <= expr2->cval;
|
||||
break;
|
||||
default:
|
||||
e->is_const = FALSE;
|
||||
break;
|
||||
|
|
|
@ -360,6 +360,15 @@ static int compare_expr(const expr_t *a, const expr_t *b)
|
|||
case EXPR_MEMBERPTR:
|
||||
case EXPR_MEMBER:
|
||||
case EXPR_ARRAY:
|
||||
case EXPR_LOGOR:
|
||||
case EXPR_LOGAND:
|
||||
case EXPR_XOR:
|
||||
case EXPR_EQUALITY:
|
||||
case EXPR_INEQUALITY:
|
||||
case EXPR_GTR:
|
||||
case EXPR_LESS:
|
||||
case EXPR_GTREQL:
|
||||
case EXPR_LESSEQL:
|
||||
ret = compare_expr(a->ref, b->ref);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
@ -373,6 +382,8 @@ static int compare_expr(const expr_t *a, const expr_t *b)
|
|||
case EXPR_NEG:
|
||||
case EXPR_PPTR:
|
||||
case EXPR_ADDRESSOF:
|
||||
case EXPR_LOGNOT:
|
||||
case EXPR_POS:
|
||||
return compare_expr(a->ref, b->ref);
|
||||
case EXPR_SIZEOF:
|
||||
return compare_type(a->u.tref, b->u.tref);
|
||||
|
@ -3124,14 +3135,26 @@ static void write_struct_expr(FILE *h, const expr_t *e, int brackets,
|
|||
if (&field->entry == fields) error("no field found for identifier %s\n", e->u.sval);
|
||||
break;
|
||||
}
|
||||
case EXPR_NEG:
|
||||
fprintf(h, "-");
|
||||
case EXPR_LOGNOT:
|
||||
fprintf(h, "!");
|
||||
write_struct_expr(h, e->ref, 1, fields, structvar);
|
||||
break;
|
||||
case EXPR_NOT:
|
||||
fprintf(h, "~");
|
||||
write_struct_expr(h, e->ref, 1, fields, structvar);
|
||||
break;
|
||||
case EXPR_POS:
|
||||
fprintf(h, "+");
|
||||
write_struct_expr(h, e->ref, 1, fields, structvar);
|
||||
break;
|
||||
case EXPR_NEG:
|
||||
fprintf(h, "-");
|
||||
write_struct_expr(h, e->ref, 1, fields, structvar);
|
||||
break;
|
||||
case EXPR_ADDRESSOF:
|
||||
fprintf(h, "&");
|
||||
write_struct_expr(h, e->ref, 1, fields, structvar);
|
||||
break;
|
||||
case EXPR_PPTR:
|
||||
fprintf(h, "*");
|
||||
write_struct_expr(h, e->ref, 1, fields, structvar);
|
||||
|
@ -3158,20 +3181,38 @@ static void write_struct_expr(FILE *h, const expr_t *e, int brackets,
|
|||
case EXPR_OR:
|
||||
case EXPR_MEMBERPTR:
|
||||
case EXPR_MEMBER:
|
||||
case EXPR_LOGOR:
|
||||
case EXPR_LOGAND:
|
||||
case EXPR_XOR:
|
||||
case EXPR_EQUALITY:
|
||||
case EXPR_INEQUALITY:
|
||||
case EXPR_GTR:
|
||||
case EXPR_LESS:
|
||||
case EXPR_GTREQL:
|
||||
case EXPR_LESSEQL:
|
||||
if (brackets) fprintf(h, "(");
|
||||
write_struct_expr(h, e->ref, 1, fields, structvar);
|
||||
switch (e->type) {
|
||||
case EXPR_SHL: fprintf(h, " << "); break;
|
||||
case EXPR_SHR: fprintf(h, " >> "); break;
|
||||
case EXPR_MOD: fprintf(h, " %% "); break;
|
||||
case EXPR_MUL: fprintf(h, " * "); break;
|
||||
case EXPR_DIV: fprintf(h, " / "); break;
|
||||
case EXPR_ADD: fprintf(h, " + "); break;
|
||||
case EXPR_SUB: fprintf(h, " - "); break;
|
||||
case EXPR_AND: fprintf(h, " & "); break;
|
||||
case EXPR_OR: fprintf(h, " | "); break;
|
||||
case EXPR_MEMBERPTR: fprintf(h, "->"); break;
|
||||
case EXPR_MEMBER: fprintf(h, "."); break;
|
||||
case EXPR_SHL: fprintf(h, " << "); break;
|
||||
case EXPR_SHR: fprintf(h, " >> "); break;
|
||||
case EXPR_MOD: fprintf(h, " %% "); break;
|
||||
case EXPR_MUL: fprintf(h, " * "); break;
|
||||
case EXPR_DIV: fprintf(h, " / "); break;
|
||||
case EXPR_ADD: fprintf(h, " + "); break;
|
||||
case EXPR_SUB: fprintf(h, " - "); break;
|
||||
case EXPR_AND: fprintf(h, " & "); break;
|
||||
case EXPR_OR: fprintf(h, " | "); break;
|
||||
case EXPR_MEMBERPTR: fprintf(h, "->"); break;
|
||||
case EXPR_MEMBER: fprintf(h, "."); break;
|
||||
case EXPR_LOGOR: fprintf(h, " || "); break;
|
||||
case EXPR_LOGAND: fprintf(h, " && "); break;
|
||||
case EXPR_XOR: fprintf(h, " ^ "); break;
|
||||
case EXPR_EQUALITY: fprintf(h, " == "); break;
|
||||
case EXPR_INEQUALITY: fprintf(h, " != "); break;
|
||||
case EXPR_GTR: fprintf(h, " > "); break;
|
||||
case EXPR_LESS: fprintf(h, " < "); break;
|
||||
case EXPR_GTREQL: fprintf(h, " >= "); break;
|
||||
case EXPR_LESSEQL: fprintf(h, " <= "); break;
|
||||
default: break;
|
||||
}
|
||||
write_struct_expr(h, e->u.ext, 1, fields, structvar);
|
||||
|
@ -3186,10 +3227,6 @@ static void write_struct_expr(FILE *h, const expr_t *e, int brackets,
|
|||
write_struct_expr(h, e->ext2, 1, fields, structvar);
|
||||
if (brackets) fprintf(h, ")");
|
||||
break;
|
||||
case EXPR_ADDRESSOF:
|
||||
fprintf(h, "&");
|
||||
write_struct_expr(h, e->ref, 1, fields, structvar);
|
||||
break;
|
||||
case EXPR_ARRAY:
|
||||
if (brackets) fprintf(h, "(");
|
||||
write_struct_expr(h, e->ref, 1, fields, structvar);
|
||||
|
|
|
@ -165,6 +165,17 @@ enum expr_type
|
|||
EXPR_MEMBER,
|
||||
EXPR_ARRAY,
|
||||
EXPR_MOD,
|
||||
EXPR_LOGOR,
|
||||
EXPR_LOGAND,
|
||||
EXPR_XOR,
|
||||
EXPR_EQUALITY,
|
||||
EXPR_INEQUALITY,
|
||||
EXPR_GTR,
|
||||
EXPR_LESS,
|
||||
EXPR_GTREQL,
|
||||
EXPR_LESSEQL,
|
||||
EXPR_LOGNOT,
|
||||
EXPR_POS,
|
||||
};
|
||||
|
||||
enum type_kind
|
||||
|
|
Loading…
Reference in New Issue