Rob Shearman : widl: Add support for character constants in expressions.

Alexandre Julliard julliard at winehq.org
Tue Jan 19 11:53:42 CST 2010


Module: wine
Branch: master
Commit: d9b83e8bb214d0ca79f035a476877b5630a3dece
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d9b83e8bb214d0ca79f035a476877b5630a3dece

Author: Rob Shearman <robertshearman at gmail.com>
Date:   Mon Jan 18 22:15:46 2010 +0000

widl: Add support for character constants in expressions.

---

 tools/widl/expr.c      |   28 +++++++++++++++++++++++++++-
 tools/widl/parser.l    |   14 +++++++++++---
 tools/widl/parser.y    |    3 ++-
 tools/widl/widltypes.h |    1 +
 4 files changed, 41 insertions(+), 5 deletions(-)

diff --git a/tools/widl/expr.c b/tools/widl/expr.c
index b528376..bca7c5a 100644
--- a/tools/widl/expr.c
+++ b/tools/widl/expr.c
@@ -87,7 +87,9 @@ expr_t *make_exprs(enum expr_type type, char *val)
     e->u.sval = val;
     e->is_const = FALSE;
     /* check for predefined constants */
-    if (type == EXPR_IDENTIFIER)
+    switch (type)
+    {
+    case EXPR_IDENTIFIER:
     {
         var_t *c = find_const(val, 0);
         if (c)
@@ -97,6 +99,21 @@ expr_t *make_exprs(enum expr_type type, char *val)
             e->is_const = TRUE;
             e->cval = c->eval->cval;
         }
+        break;
+    }
+    case EXPR_CHARCONST:
+        if (!val[0])
+            error_loc("empty character constant\n");
+        else if (val[1])
+            error_loc("multi-character constants are endian dependent\n");
+        else
+        {
+            e->is_const = TRUE;
+            e->cval = *val;
+        }
+        break;
+    default:
+        break;
     }
     return e;
 }
@@ -457,6 +474,11 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
         result.is_temporary = TRUE;
         result.type = type_new_pointer(RPC_FC_UP, type_new_int(TYPE_BASIC_WCHAR, 0), NULL);
         break;
+    case EXPR_CHARCONST:
+        result.is_variable = FALSE;
+        result.is_temporary = TRUE;
+        result.type = type_new_int(TYPE_BASIC_CHAR, 0);
+        break;
     case EXPR_DOUBLE:
         result.is_variable = FALSE;
         result.is_temporary = TRUE;
@@ -655,6 +677,9 @@ void write_expr(FILE *h, const expr_t *e, int brackets,
     case EXPR_WSTRLIT:
         fprintf(h, "L\"%s\"", e->u.sval);
         break;
+    case EXPR_CHARCONST:
+        fprintf(h, "'%s'", e->u.sval);
+        break;
     case EXPR_LOGNOT:
         fprintf(h, "!");
         write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
@@ -804,6 +829,7 @@ int compare_expr(const expr_t *a, const expr_t *b)
         case EXPR_IDENTIFIER:
         case EXPR_STRLIT:
         case EXPR_WSTRLIT:
+        case EXPR_CHARCONST:
             return strcmp(a->u.sval, b->u.sval);
         case EXPR_COND:
             ret = compare_expr(a->ref, b->ref);
diff --git a/tools/widl/parser.l b/tools/widl/parser.l
index f509cb1..a72c454 100644
--- a/tools/widl/parser.l
+++ b/tools/widl/parser.l
@@ -37,6 +37,7 @@ double	[0-9]+\.[0-9]+([eE][+-]?[0-9]+)*
 %x WSTRQUOTE
 %x ATTR
 %x PP_LINE
+%x SQUOTE
 
 %{
 
@@ -157,10 +158,17 @@ UUID *parse_uuid(const char *u)
 				parser_lval.str = get_buffered_cstring();
 				return aWSTRING;
 			}
-<QUOTE,WSTRQUOTE>\\\\	|
+<INITIAL,ATTR>\'	yy_push_state(SQUOTE); cbufidx = 0;
+<SQUOTE>\'		{
+				yy_pop_state();
+				parser_lval.str = get_buffered_cstring();
+				return aSQSTRING;
+			}
+<QUOTE,WSTRQUOTE,SQUOTE>\\\\	|
 <QUOTE,WSTRQUOTE>\\\"	addcchar(yytext[1]);
-<QUOTE,WSTRQUOTE>\\.	addcchar('\\'); addcchar(yytext[1]);
-<QUOTE,WSTRQUOTE>.	addcchar(yytext[0]);
+<SQUOTE>\\\'	addcchar(yytext[1]);
+<QUOTE,WSTRQUOTE,SQUOTE>\\.	addcchar('\\'); addcchar(yytext[1]);
+<QUOTE,WSTRQUOTE,SQUOTE>.	addcchar(yytext[0]);
 <INITIAL,ATTR>\[	yy_push_state(ATTR); return '[';
 <ATTR>\]		yy_pop_state(); return ']';
 <ATTR>{cident}		return attr_token(yytext);
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index dda4a37..2af7742 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -186,7 +186,7 @@ static statement_list_t *append_statement(statement_list_t *list, statement_t *s
 %token <str> aKNOWNTYPE
 %token <num> aNUM aHEXNUM
 %token <dbl> aDOUBLE
-%token <str> aSTRING aWSTRING
+%token <str> aSTRING aWSTRING aSQSTRING
 %token <uuid> aUUID
 %token aEOF
 %token SHL SHR
@@ -632,6 +632,7 @@ expr:	  aNUM					{ $$ = make_exprl(EXPR_NUM, $1); }
 	| tTRUE					{ $$ = make_exprl(EXPR_TRUEFALSE, 1); }
 	| aSTRING				{ $$ = make_exprs(EXPR_STRLIT, $1); }
 	| aWSTRING				{ $$ = make_exprs(EXPR_WSTRLIT, $1); }
+	| aSQSTRING				{ $$ = make_exprs(EXPR_CHARCONST, $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); }
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index f4ee7f0..a44e02a 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -186,6 +186,7 @@ enum expr_type
     EXPR_POS,
     EXPR_STRLIT,
     EXPR_WSTRLIT,
+    EXPR_CHARCONST,
 };
 
 enum type_kind




More information about the wine-cvs mailing list