F diff --git a/src/semantics/ast.c b/src/semantics/ast.c --- a/src/semantics/ast.c +++ b/src/semantics/ast.creturn ret;}+ struct AST_Expression* get_promoted_expression(struct AST_Expression *operand,struct Translation_Data *translation_data)+ {+ struct Type *operand_type;+ struct Type *promotion_type;++ operand_type=extract_expresion_value_type(operand,translation_data);+ promotion_type=get_type_for_promotion(operand_type,translation_data);+ if(types_are_identical(operand_type,promotion_type))+ return get_cast_expression_tree(operand,promotion_type,translation_data);+ else+ return operand;+ }+/*TODO remove this*/- struct AST_Binary_Expression* get_binary_expression_tree(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type type)+ struct AST_Binary_Expression* get_binary_expression_tree(struct AST_Expression *left,struct AST_Expression *right,struct Expression_Value *value,enum AST_Type type){struct AST_Binary_Expression *ret;ret=malloc(sizeof(struct AST_Binary_Expression));ret->type=type;ret->left=left;ret->right=right;+ ret->value=value;return ret;}+ struct AST_Binary_Expression* get_binary_expression_after_conversion(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type type,struct Translation_Data *translation_data)+ {+ struct Type_Basic *left_type;+ struct Type_Basic *right_type;++ left=get_promoted_expression(left,translation_data);+ right=get_promoted_expression(right,translation_data);++ left_type=(struct Type_Basic*)extract_expresion_value_type(left,translation_data);+ right_type=(struct Type_Basic*)extract_expresion_value_type(right,translation_data);++ if(left_type->specifier==TS_DOUBLE)+ {+ if(right_type->specifier==TS_DOUBLE && right_type->constraint==TC_LONG)+ left=get_cast_expression_tree(left,(struct Type*)right_type);+ else+ right=get_cast_expression_tree(right,(struct Type*)left_type);++ }else if(right_type->specifier==TS_DOUBLE)+ {+ if(left_type->specifier==TS_DOUBLE && left_type->constraint==TC_LONG)+ right=get_cast_expression_tree(right,(struct Type*)left_type);+ else+ left=get_cast_expression_tree(left,(struct Type*)right_type);+ }else if(left_type->specifier==TS_FLOAT)+ {+ right=get_cast_expression_tree(right,left_type);+ }else if(right_type->specifier==TS_FLOAT)+ {+ left=get_cast_expression_tree(left,right_type);+ }else if(!types_are_identical(left_type,right_type))+ {+ /*should have integers by now*/+ int left_rank;+ int right_rank;+ struct Type_Basic *greater_type;+++ left_rank=type_get_integer_conversion_rank(left_type);+ right_rank=type_get_integer_conversion_rank(right_type);++ if(left_type->sign==TSIGN_SIGNED)+ {+ if(right_type->sign==TSIGN_SIGNED || left_rank!=right_rank)+ greater_type=(left_rank<right_rank?right_type:left_type);+ else+ greater_type=get_type_insecure(left_type->specifier,TSIGN_UNSIGNED,left_type->constraint,left_type->size,translation_data);+ }+ else+ {+ if(right_type->sign==TSIGN_UNSIGNED || left_rank!=right_rank)+ greater_type=(left_rank<right_rank?right_type:left_type);+ else+ greater_type=get_type_insecure(right_type->specifier,TSIGN_UNSIGNED,right_type->constraint,right_type->size,translation_data);+ }++ left=get_cast_expression_tree(left,greater_type,translation_data);+ right=get_cast_expression_tree(right,greater_type,translation_data);+ }++ return get_binary_expression_tree(left,right,type);+ }++struct AST_Unary_Expression* get_indirection_expression_tree(struct AST_Expression *operand,struct Translation_Data *translation_data){struct Type_Pointer *operand_type;}- struct AST_Unary_Expression* get_cast_expression_tree(struct AST_Expression *operand,struct Type *type,struct Translation_Data *translation_data)+ struct AST_Expression* get_cast_expression_tree(struct AST_Expression *operand,struct Type *type,struct Translation_Data *translation_data){- struct AST_Unary_Expression *ret;+ struct Type *operand_type;if(!type_is_scalar(type))- { push_translation_error("cast type needs to be of scalar type",translation_data);return NULL; }+ { push_translation_error("cast type needs to be of scalar type",translation_data);return NULL; }+ operand_type=extract_expresion_value_type(operand,translation_data);+ if(types_are_identical(operand_type,type))+ return operand;- ret=malloc(sizeof(struct AST_Unary_Expression));- ret->type=OP_CAST;- ret->value=get_expression_value_rvalue(get_temp_object(extract_expresion_value_type(operand->value,translation_data)));- ret->operand=operand;+ return get_unary_expression_tree(+ operand,+ get_expression_value_rvalue(get_temp_object(extract_expresion_value_type(operand->value,translation_data))),+ OP_CAST+ );return ret;}struct AST_Unary_Expression* get_sizeof_by_type_tree(struct Type *type){- struct AST_Unary_Expression *ret;-- ret=malloc(sizeof(struct AST_Unary_Expression));- ret->type=OP_SIZEOF;- ret->value=get_expression_value_rvalue(get_temp_object(type));- ret->operand=NULL;- return ret;+ return get_unary_expression_tree(NULL,get_expression_value_rvalue(get_temp_object(type)),OP_SIZEOF);}{struct Type *left_type;struct Type *member_type;- struct AST_Binary_Expression *ret;left_type=extract_expresion_value_type(left->value,translation_data);if(left_type->specifier!=TS_POINTER)if(!type_is_of_object(member_type)){push_translation_error("expected pointer to object type in array subscript",translation_data);return NULL;}- ret=malloc(sizeof(struct AST_Binary_Expression));- ret->type=OP_ARR_SUBSCRIPT;- ret->value=get_expression_value_lvalue(get_temp_object(member_type));-- ret->left=left;- ret->right=right;-- return ret;+ return get_binary_expression_tree(left,right,get_expression_value_lvalue(get_temp_object(member_type)),OP_ARR_SUBSCRIPT);}struct AST_Binary_Expression* get_struct_union_member_tree(struct AST_Expression *left,struct token *id,struct Translation_Data *translation_data)struct AST_Unary_Expression* get_unary_arithmetic_tree(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data){struct Type *operand_type;- struct AST_Unary_Expression *ret;- operand_type=extract_expresion_value_type(operand->value);if(operation==OP_UNARY_PLUS || operation==OP_UNARY_MINUS){+ operand=get_promoted_expression(operand);+ operand_type=extract_expresion_value_type(operand->value);+if(type_is_arithmetic(operand_type)){- ret=malloc(sizeof(struct AST_Unary_Expression));- ret->type=operand;- ret->operand=operand;- ret->value=get-+ return get_unary_expression_tree(+ operand,+ get_expression_value_rvalue(get_temp_object(operand_type)),+ operation+ );}else{push_translation_error("expected scalar type for operand in unary operation",translation_data);- return NULL;+ return get_error_tree(operand);}}}Queue_Init(&ret->arguments);return ret;}- struct AST_Unary_Expression* get_unary_expression_tree(struct AST_Expression *operand,enum AST_Type type)+ struct AST_Unary_Expression* get_unary_expression_tree(struct AST_Expression *operand,struct Expression_Value *value,enum AST_Type type){struct AST_Unary_Expression *ret;ret=malloc(sizeof(struct AST_Unary_Expression));ret->operand=operand;ret->type=type;+ ret->value=value;return ret;}F diff --git a/src/semantics/ast.h b/src/semantics/ast.h --- a/src/semantics/ast.h +++ b/src/semantics/ast.hstruct AST_Error* get_error_tree(struct AST *error);struct AST_Declaration_Error* get_declaration_error_tree(struct Denoted *error);+ struct AST_Expression* get_promoted_expression(struct AST_Expression *operand,struct Translation_Data *translation_data);+ struct AST_Expression* get_cast_expression_tree(struct AST_Expression *operand,struct Type *type,struct Translation_Data *translation_data);- struct AST_Binary_Expression* get_binary_expression_tree(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type type);+ struct AST_Binary_Expression* get_binary_expression_tree(struct AST_Expression *left,struct AST_Expression *right,struct Expression_Value *value,enum AST_Type type);+ struct AST_Binary_Expression* get_binary_expression_after_conversion(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type type,struct Translation_Data *translation_data);+struct AST_Binary_Expression* get_array_subscript_tree(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data);struct AST_Binary_Expression* get_struct_union_member_tree(struct AST_Expression *left,struct token *id,struct Translation_Data *translation_data);struct AST_Conditional_Expression* get_conditional_expression_tree(struct AST_Expression *left,struct AST_Expression *center,struct AST_Expression *right);struct AST_Function_Expression* get_function_expression_tree(struct AST_Expression *id,struct Scope *scope);- struct AST_Unary_Expression* get_unary_expression_tree(struct AST_Expression *operand,enum AST_Type type);+ struct AST_Unary_Expression* get_unary_expression_tree(struct AST_Expression *operand,struct Expression_Value *value,enum AST_Type type);struct AST_Unary_Expression* get_indirection_expression_tree(struct AST_Expression *operand,struct Translation_Data *translation_data);struct AST_Unary_Expression* get_address_expression_tree(struct AST_Expression *operand);struct AST_Unary_Expression* get_sizeof_by_type_tree(struct Type *type);- struct AST_Unary_Expression* get_cast_expression_tree(struct AST_Expression *operand,struct Type *type,struct Translation_Data *translation_data);struct AST_Unary_Expression* get_unary_arithmetic_tree(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data);F diff --git a/src/semantics/value/type.c b/src/semantics/value/type.c --- a/src/semantics/value/type.c +++ b/src/semantics/value/type.creturn 0;}}++ struct Type* get_type_for_promotion(struct Type *type,struct Translation_Data *translation_data)+ {+ if(type->specifier==TS_CHAR)+ {+ return get_type_insecure(TS_INT,TSIGN_NONE,TC_NONE,INT_SIZE,translation_data);+ }+ else if(type->specifier==TS_INT)+ {+ struct Type_Basic *cache_type;+ cache_type=(struct Type_Basic*)type;+ if(cache_type->constraint==TC_SHORT)+ return get_type_insecure(TS_INT,TSIGN_NONE,TC_NONE,INT_SIZE,translation_data);+ else+ return type;++ }else if(type->specifier==TS_BITFIELD)+ {+ struct Type_Bit_Field *cache_type;+ cache_type=(struct Type_Bit_Field*)type;+ if(cache_type->number_of_bits< 8 * INT_SIZE)+ return get_type_insecure(TS_INT,TSIGN_NONE,TC_NONE,INT_SIZE,translation_data);+ else if(cache_type->number_of_bits== 8 * INT_SIZE)+ return get_type_insecure(TS_INT,TSIGN_UNSIGNED,TC_NONE,INT_SIZE,translation_data);+ else+ return type;+ }else+ {+ return type;+ }++++ }+ /*TODO*/+ int type_get_integer_conversion_rank(struct Type_Basic *type)+ {+ switch(type->specifier)+ {+ case TS_CHAR:+ return 0;+ case TS_INT:+ switch(type->constraint)+ {+ case TC_LONG_LONG:+ return 4;+ case TC_LONG:+ return 3;+ case TC_NONE:+ return 2;+ case TC_SHORT:+ return 1;+ default:+ assert(0);+ }+ default:+ assert(0);+ }+ }+#endifF diff --git a/src/semantics/value/type.h b/src/semantics/value/type.h --- a/src/semantics/value/type.h +++ b/src/semantics/value/type.hstruct Type* get_type_insecure(enum Type_Specifier type_specifier,enum Type_Signedness sign,enum Type_Constraint constraint,size_t type_size,struct Translation_Data *translation_data);--+ struct Type* get_type_for_promotion(struct Type *type,struct Translation_Data *translation_data);void delete_enum(struct Enum *enumeration);char type_is_struct_union(struct Type *type);char type_is_constant_or_has_constant_member(struct Type *type);+ int type_get_integer_conversion_rank(struct Type_Basic *type);