#ifndef WONKY_EVALUATION_C
#define WONKY_EVALUATION_C WONKY_EVALUATION_C
#include <evaluation.h>
/*Returns NULL if it can reduce expression to a constant*/
struct Constant* try_to_evaluate_expression(struct AST_Expression *expression,struct Translation_Data *translation_data)
{
switch(expression->type)
{
case OP_ADDITION:
default:
return NULL;
}
wonky_assert(SHOULD_NOT_REACH_HERE);
}
long long int evaluate_const_expression_integer(struct AST *expression,struct Translation_Data *translation_data)
{
#define RET_BIN_EXPR(x,operator) return \
evaluate_const_expression_integer((struct AST*)BIN_EXPR_PTR(x)->left,translation_data)\
operator\
evaluate_const_expression_integer((struct AST*)BIN_EXPR_PTR(x)->right,translation_data);
#define RET_UNARY_EXPR(x,operator) return \
operator evaluate_const_expression_integer((struct AST*)UN_EXPR_PTR(x)->operand,translation_data);
switch(expression->type)
{
case OP_COMMA:
case OP_ADDITION:
RET_BIN_EXPR(expression,+);
case OP_SUBTRACTION:
RET_BIN_EXPR(expression,-);
case OP_MUL:
RET_BIN_EXPR(expression,*);
case OP_DIV:
RET_BIN_EXPR(expression,/);
case OP_REMAINDER:
RET_BIN_EXPR(expression,%);
case OP_COND:
return (
evaluate_const_expression_integer((struct AST*)((struct AST_Conditional_Expression*)expression)->left,translation_data)?
evaluate_const_expression_integer((struct AST*)((struct AST_Conditional_Expression*)expression)->center,translation_data):
evaluate_const_expression_integer((struct AST*)((struct AST_Conditional_Expression*)expression)->right,translation_data)
);
case OP_LOGICAL_OR:
RET_BIN_EXPR(expression,||);
case OP_LOGICAL_AND:
RET_BIN_EXPR(expression,&&);
case OP_LOGICAL_NOT:
RET_UNARY_EXPR(expression,!);
case OP_BITWISE_OR:
RET_BIN_EXPR(expression,|);
case OP_BITWISE_AND:
RET_BIN_EXPR(expression,&);
case OP_BITWISE_XOR:
RET_BIN_EXPR(expression,^);
case OP_BITWISE_NOT:
RET_UNARY_EXPR(expression,~);
case OP_UNARY_PLUS:
RET_UNARY_EXPR(expression,+);
case OP_UNARY_MINUS:
RET_UNARY_EXPR(expression,-);
case OP_SHIFT_LEFT:
RET_BIN_EXPR(expression,<<);
case OP_SHIFT_RIGHT:
RET_BIN_EXPR(expression,>>);
case OP_LESS_EQ:
RET_BIN_EXPR(expression,<=);
case OP_GREATER_EQ:
RET_BIN_EXPR(expression,>=);
case OP_LESS:
RET_BIN_EXPR(expression,<);
case OP_GREATER:
RET_BIN_EXPR(expression,>);
case OP_EQUAL:
RET_BIN_EXPR(expression,==);
case OP_NOT_EQUAL:
RET_BIN_EXPR(expression,!=);
case OP_CONSTANT:
{
struct Constant *c;
c=((struct AST_Constant*)expression)->value->constant;
/*TODO add other types*/
if(type_is_integer_type(c->type))
return *(long long int*)c->value;
}
}
/*shouldnt reach here*/
return 0;
}
#endif