diff options
author | Søren Sandmann <sandmann@redhat.com> | 2007-09-06 20:00:36 -0400 |
---|---|---|
committer | Søren Sandmann <sandmann@redhat.com> | 2007-09-06 20:00:36 -0400 |
commit | e6dd81037f39cf197e1b50bf867521a54722d24f (patch) | |
tree | 3aa08d18e1c8f669379d31ccea9b86889001e7c0 /switch.c | |
parent | 8a69bd70d7193253325bb94195a9e049921112d3 (diff) |
Evaluate expressions in switch cases
Diffstat (limited to 'switch.c')
-rw-r--r-- | switch.c | 47 |
1 files changed, 37 insertions, 10 deletions
@@ -50,16 +50,27 @@ compare_cases (const void *a, } static gboolean -constant_expression (ast_expression_t *expr) +constant_expression (ast_expression_t *expr, + value_t *value) { + value_t left; + value_t right; + value_t result; + g_assert (((ast_t *)expr)->common.type == AST_EXPRESSION); switch (expr->common.type) { case AST_INT_LITERAL_EXPRESSION: + value->int32_val = expr->int_literal.value; + break; + case AST_BOOL_LITERAL_EXPRESSION: + value->bool_val = expr->bool_literal.value; + break; + case AST_NULL_EXPRESSION: - return TRUE; + value->pointer_val = NULL; break; case AST_IDENTIFIER_EXPRESSION: @@ -78,29 +89,43 @@ constant_expression (ast_expression_t *expr) break; case AST_UNARY_EXPRESSION: - if (!constant_expression (expr->unary.expr)) + if (!constant_expression (expr->unary.expr, &result)) return FALSE; + + evaluate_unary_operator (expr->unary.operator, + expr->unary.expr->common.type_spec, &result, + expr->common.type_spec, value); break; case AST_BINARY_EXPRESSION: - if (!constant_expression (expr->binary.left)) + if (!constant_expression (expr->binary.left, &left)) return FALSE; - if (!constant_expression (expr->binary.right)) + if (!constant_expression (expr->binary.right, &right)) return FALSE; + + evaluate_binary_operator (expr->binary.operator, + expr->binary.left->common.type_spec, &left, + expr->binary.right->common.type_spec, &right, + expr->common.type_spec, value); break; case AST_TERNARY_EXPRESSION: - if (!constant_expression (expr->ternary.cond)) + if (!constant_expression (expr->ternary.cond, &result)) return FALSE; /* FIXME: we could require only the taken branch to be constant */ - - if (!constant_expression (expr->ternary.then_expr)) + + if (!constant_expression (expr->ternary.then_expr, &left)) return FALSE; - if (!constant_expression (expr->ternary.else_expr)) + if (!constant_expression (expr->ternary.else_expr, &right)) return FALSE; + + if (result.bool_val) + *value = left; + else + *value = right; break; } @@ -120,10 +145,12 @@ check_constant_case_expressions (ast_t *ast) if (ast_is (ast, AST_CASE, AST_EXPRESSION_CASE)) { + value_t value; + /* FIXME: check that we are dealing with a constant expression, * and store the value of that expression in the case clause */ - if (!constant_expression (ast->case_.expression.expression)) + if (!constant_expression (ast->case_.expression.expression, &value)) { g_print ("Expression in case clause must be constant\n"); |