implement builtin_isgreater and friends
authorMatthias Braun <matze@braunis.de>
Fri, 30 Nov 2007 23:09:55 +0000 (23:09 +0000)
committerMatthias Braun <matze@braunis.de>
Fri, 30 Nov 2007 23:09:55 +0000 (23:09 +0000)
[r18585]

Makefile
ast2firm.c
ast_t.h
parser.c

index 12c03fd..2e6e0c0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -15,6 +15,8 @@ CFLAGS += -Wall -W -Wstrict-prototypes -Wmissing-prototypes -Werror -std=c99 -pe
 CFLAGS += -O0 -g3
 ICC_CFLAGS = -O0 -g3 -std=c99 -Wall -Werror
 #CFLAGS += -O3 -march=pentium4 -fomit-frame-pointer -DNDEBUG
+ICC    ?= true
+GCCO1  ?= true
 
 LFLAGS = $(FIRM_LIBS)
 
@@ -67,7 +69,8 @@ build/adt:
 
 build/%.o: %.c
        @echo '===> CC $<'
-#      $(Q)icc $(CPPFLAGS) $(ICC_CFLAGS) -c $< -o $@
+       $(Q)$(ICC) $(CPPFLAGS) $(ICC_CFLAGS) -c $< -o $@
+       $(Q)$(GCCO1) $(CPPFLAGS) $(CFLAGS) -O1 -c $< -o $@
        $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
 
 clean:
index 2c53676..0551fb7 100644 (file)
@@ -1125,15 +1125,22 @@ static ir_node *unary_expression_to_firm(const unary_expression_t *expression)
        panic("invalid UNEXPR type found");
 }
 
-static long get_pnc(expression_type_t type)
+static long get_pnc(const expression_type_t type)
 {
        switch(type) {
-       case EXPR_BINARY_EQUAL:        return pn_Cmp_Eq;
-       case EXPR_BINARY_NOTEQUAL:     return pn_Cmp_Lg;
-       case EXPR_BINARY_LESS:         return pn_Cmp_Lt;
-       case EXPR_BINARY_LESSEQUAL:    return pn_Cmp_Le;
-       case EXPR_BINARY_GREATER:      return pn_Cmp_Gt;
-       case EXPR_BINARY_GREATEREQUAL: return pn_Cmp_Ge;
+       case EXPR_BINARY_EQUAL:         return pn_Cmp_Eq;
+       case EXPR_BINARY_ISLESSGREATER: return pn_Cmp_Lg;
+       case EXPR_BINARY_NOTEQUAL:      return pn_Cmp_Ne;
+       case EXPR_BINARY_ISLESS:
+       case EXPR_BINARY_LESS:          return pn_Cmp_Lt;
+       case EXPR_BINARY_ISLESSEQUAL:
+       case EXPR_BINARY_LESSEQUAL:     return pn_Cmp_Le;
+       case EXPR_BINARY_ISGREATER:
+       case EXPR_BINARY_GREATER:       return pn_Cmp_Gt;
+       case EXPR_BINARY_ISGREATEREQUAL:
+       case EXPR_BINARY_GREATEREQUAL:  return pn_Cmp_Ge;
+       case EXPR_BINARY_ISUNORDERED:   return pn_Cmp_Uo;
+
        default:
                break;
        }
@@ -1408,7 +1415,13 @@ static ir_node *binary_expression_to_firm(const binary_expression_t *expression)
        case EXPR_BINARY_LESS:
        case EXPR_BINARY_LESSEQUAL:
        case EXPR_BINARY_GREATER:
-       case EXPR_BINARY_GREATEREQUAL: {
+       case EXPR_BINARY_GREATEREQUAL:
+       case EXPR_BINARY_ISGREATER:
+       case EXPR_BINARY_ISGREATEREQUAL:
+       case EXPR_BINARY_ISLESS:
+       case EXPR_BINARY_ISLESSEQUAL:
+       case EXPR_BINARY_ISLESSGREATER:
+       case EXPR_BINARY_ISUNORDERED: {
                dbg_info *dbgi = get_dbg_info(&expression->expression.source_position);
                ir_node *left  = expression_to_firm(expression->left);
                ir_node *right = expression_to_firm(expression->right);
diff --git a/ast_t.h b/ast_t.h
index e68c781..342d546 100644 (file)
--- a/ast_t.h
+++ b/ast_t.h
@@ -144,7 +144,7 @@ typedef enum {
        case EXPR_UNARY_CAST_IMPLICIT:
 
 struct context_t {
-       declaration_t   *declarations;
+       declaration_t *declarations;
 };
 
 struct expression_base_t {
index f595d06..a92c7e7 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -74,6 +74,8 @@ static declaration_t *parse_declarator(
                const declaration_specifiers_t *specifiers, bool may_be_abstract);
 static declaration_t *record_declaration(declaration_t *declaration);
 
+static void semantic_comparison(binary_expression_t *expression);
+
 #define STORAGE_CLASSES     \
        case T_typedef:         \
        case T_extern:          \
@@ -1129,11 +1131,13 @@ static initializer_t *initializer_from_expression(type_t *type,
                                                        expression->string.value);
                                        }
 
-                               case EXPR_WIDE_STRING_LITERAL:
-                                       if (get_unqualified_type(element_type) == skip_typeref(type_wchar_t)) {
+                               case EXPR_WIDE_STRING_LITERAL: {
+                                       type_t *bare_wchar_type = skip_typeref(type_wchar_t);
+                                       if (get_unqualified_type(element_type) == bare_wchar_type) {
                                                return initializer_from_wide_string(array_type,
                                                        &expression->wide_string.value);
                                        }
+                               }
 
                                default: break;
                        }
@@ -3358,7 +3362,9 @@ static expression_t *parse_compare_builtin(void)
                break;
        default:
                panic("invalid compare builtin found");
+               break;
        }
+       next_token();
 
        expect('(');
        expression->binary.left = parse_assignment_expression();
@@ -3366,7 +3372,19 @@ static expression_t *parse_compare_builtin(void)
        expression->binary.right = parse_assignment_expression();
        expect(')');
 
-       /* TODO: semantic */
+       type_t *orig_type_left  = expression->binary.left->base.datatype;
+       type_t *orig_type_right = expression->binary.right->base.datatype;
+       if(orig_type_left == NULL || orig_type_right == NULL)
+               return expression;
+
+       type_t *type_left  = skip_typeref(orig_type_left);
+       type_t *type_right = skip_typeref(orig_type_right);
+       if(!is_type_floating(type_left) && !is_type_floating(type_right)) {
+               type_error_incompatible("invalid operands in comparison",
+                                       token.source_position, type_left, type_right);
+       } else {
+               semantic_comparison(&expression->binary);
+       }
 
        return expression;
 }