Commit 80ab2a7c authored by Rob Shearman's avatar Rob Shearman Committed by Alexandre Julliard

widl: Move expression functions to a new file, expr.c.

parent 6244565d
......@@ -10,6 +10,7 @@ MODULE = none
C_SRCS = \
client.c \
expr.c \
hash.c \
header.c \
proxy.c \
......
......@@ -36,6 +36,7 @@
#include "widltypes.h"
#include "typegen.h"
#include "expr.h"
static FILE* client;
static int indent = 0;
......
/*
* Expression Abstract Syntax Tree Functions
*
* 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
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
struct expr_loc
{
const var_t *v;
const char *attr;
};
extern expr_t *make_expr(enum expr_type type);
extern expr_t *make_exprl(enum expr_type type, long val);
extern expr_t *make_exprd(enum expr_type type, double val);
extern expr_t *make_exprs(enum expr_type type, char *val);
extern expr_t *make_exprt(enum expr_type type, type_t *tref, expr_t *expr);
extern expr_t *make_expr1(enum expr_type type, expr_t *expr);
extern expr_t *make_expr2(enum expr_type type, expr_t *exp1, expr_t *exp2);
extern expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3);
extern const type_t *expr_resolve_type(const struct expr_loc *expr_loc, const type_t *cont_type, const expr_t *expr);
extern int compare_expr(const expr_t *a, const expr_t *b);
extern void write_expr(FILE *h, const expr_t *e, int brackets);
......@@ -33,6 +33,7 @@
#include "utils.h"
#include "parser.h"
#include "header.h"
#include "expr.h"
typedef struct _user_type_t generic_handle_t;
......@@ -472,143 +473,6 @@ void write_typedef(type_t *type)
fprintf(header, ";\n");
}
void write_expr(FILE *h, const expr_t *e, int brackets)
{
switch (e->type) {
case EXPR_VOID:
break;
case EXPR_NUM:
fprintf(h, "%lu", e->u.lval);
break;
case EXPR_HEXNUM:
fprintf(h, "0x%lx", e->u.lval);
break;
case EXPR_DOUBLE:
fprintf(h, "%#.15g", e->u.dval);
break;
case EXPR_TRUEFALSE:
if (e->u.lval == 0)
fprintf(h, "FALSE");
else
fprintf(h, "TRUE");
break;
case EXPR_IDENTIFIER:
fprintf(h, "%s", e->u.sval);
break;
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);
break;
case EXPR_CAST:
fprintf(h, "(");
write_type_decl(h, e->u.tref, NULL);
fprintf(h, ")");
write_expr(h, e->ref, 1);
break;
case EXPR_SIZEOF:
fprintf(h, "sizeof(");
write_type_decl(h, e->u.tref, NULL);
fprintf(h, ")");
break;
case EXPR_SHL:
case EXPR_SHR:
case EXPR_MOD:
case EXPR_MUL:
case EXPR_DIV:
case EXPR_ADD:
case EXPR_SUB:
case EXPR_AND:
case EXPR_OR:
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_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);
if (brackets) fprintf(h, ")");
break;
case EXPR_MEMBER:
if (brackets) fprintf(h, "(");
if (e->ref->type == EXPR_PPTR)
{
write_expr(h, e->ref->ref, 1);
fprintf(h, "->");
}
else
{
write_expr(h, e->ref, 1);
fprintf(h, ".");
}
write_expr(h, e->u.ext, 1);
if (brackets) fprintf(h, ")");
break;
case EXPR_COND:
if (brackets) fprintf(h, "(");
write_expr(h, e->ref, 1);
fprintf(h, " ? ");
write_expr(h, e->u.ext, 1);
fprintf(h, " : ");
write_expr(h, e->ext2, 1);
if (brackets) fprintf(h, ")");
break;
case EXPR_ARRAY:
if (brackets) fprintf(h, "(");
write_expr(h, e->ref, 1);
fprintf(h, "[");
write_expr(h, e->u.ext, 1);
fprintf(h, "]");
if (brackets) fprintf(h, ")");
break;
}
}
void write_constdef(const var_t *v)
{
fprintf(header, "#define %s (", v->name);
......
......@@ -56,7 +56,6 @@ extern void write_locals(FILE *fp, const type_t *iface, int body);
extern void write_coclass(type_t *cocl);
extern void write_coclass_forward(type_t *cocl);
extern void write_typedef(type_t *type);
extern void write_expr(FILE *h, const expr_t *e, int brackets);
extern void write_constdef(const var_t *v);
extern void write_externdef(const var_t *v);
extern void write_library(const char *name, const attr_list_t *attr);
......
......@@ -35,6 +35,7 @@
#include "parser.h"
#include "header.h"
#include "typegen.h"
#include "expr.h"
#define END_OF_LIST(list) \
do { \
......
......@@ -39,6 +39,7 @@
#include "wine/list.h"
#include "typegen.h"
#include "expr.h"
static const func_t *current_func;
static const type_t *current_structure;
......@@ -307,91 +308,6 @@ static const char *get_context_handle_type_name(const type_t *type)
return NULL;
}
/* This is actually fairly involved to implement precisely, due to the
effects attributes may have and things like that. Right now this is
only used for optimization, so just check for a very small set of
criteria that guarantee the types are equivalent; assume every thing
else is different. */
static int compare_type(const type_t *a, const type_t *b)
{
if (a == b
|| (a->name
&& b->name
&& strcmp(a->name, b->name) == 0))
return 0;
/* Ordering doesn't need to be implemented yet. */
return 1;
}
static int compare_expr(const expr_t *a, const expr_t *b)
{
int ret;
if (a->type != b->type)
return a->type - b->type;
switch (a->type)
{
case EXPR_NUM:
case EXPR_HEXNUM:
case EXPR_TRUEFALSE:
return a->u.lval - b->u.lval;
case EXPR_DOUBLE:
return a->u.dval - b->u.dval;
case EXPR_IDENTIFIER:
return strcmp(a->u.sval, b->u.sval);
case EXPR_COND:
ret = compare_expr(a->ref, b->ref);
if (ret != 0)
return ret;
ret = compare_expr(a->u.ext, b->u.ext);
if (ret != 0)
return ret;
return compare_expr(a->ext2, b->ext2);
case EXPR_OR:
case EXPR_AND:
case EXPR_ADD:
case EXPR_SUB:
case EXPR_MOD:
case EXPR_MUL:
case EXPR_DIV:
case EXPR_SHL:
case EXPR_SHR:
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;
return compare_expr(a->u.ext, b->u.ext);
case EXPR_CAST:
ret = compare_type(a->u.tref, b->u.tref);
if (ret != 0)
return ret;
/* Fall through. */
case EXPR_NOT:
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);
case EXPR_VOID:
return 0;
}
return -1;
}
#define WRITE_FCTYPE(file, fctype, typestring_offset) \
do { \
if (file) \
......
......@@ -362,6 +362,10 @@ int cant_be_null(const var_t *v);
int is_struct(unsigned char tc);
int is_union(unsigned char tc);
var_t *find_const(const char *name, int f);
type_t *find_type(const char *name, int t);
type_t *make_type(unsigned char type, type_t *ref);
static inline type_t *get_func_return_type(const func_t *func)
{
return func->def->type->ref;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment