F diff --git a/src/semantics/ast.c b/src/semantics/ast.c --- a/src/semantics/ast.c +++ b/src/semantics/ast.cret->error=error;return ret;}-+ /*if an int can represent all the values of the original type the value is converted to int+ * otherwise to unsigned int. other types are untouched+ * 6.3.1.1 */struct AST_Expression* get_promoted_expression(struct AST_Expression *operand,struct Translation_Data *translation_data){struct Type *operand_type;struct AST_Binary_Expression* get_modulo_tree(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data){- return get_binary_expression_after_conversion(left,right,OP_REMAINDER,translation_data);-+ if(constraint_check_modulo_expression(left,right,translation_data))+ {+ return get_binary_expression_after_conversion(left,right,OP_REMAINDER,translation_data);+ }else+ {+ delete_ast(left), delete_ast(right);+ return NULL;+ }}struct AST_Binary_Expression* get_multiplicative_expression_tree(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data){- struct Type *hold_type;- hold_type=extract_expresion_value_type(left,translation_data);- if(!type_is_arithmetic(hold_type))- { push_translation_error("expected arithmetic type in multiplicative operation",translation_data); return get_error_tree(get_binary_expression_tree(left,right,operation)); }-- hold_type=extract_expresion_value_type(right,translation_data);- if(!type_is_arithmetic(hold_type))- { push_translation_error("expected arithmetic type in multiplicative operation",translation_data); return get_error_tree(get_binary_expression_tree(left,right,OP_REMAINDER)); }- return get_binary_expression_after_conversion(left,right,operation,translation_data);+ if(constraint_check_multiplicative_expression(left,right,operation,translation_data))+ {+ return get_binary_expression_after_conversion(left,right,operation,translation_data);+ }else+ {+ delete_ast(left), delete_ast(right);+ return NULL;+ }}struct AST_Binary_Expression* get_additive_expression_tree(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data){- struct Type *left_type;- struct Type *right_type;-- left_type=extract_expresion_value_type(left,translation_data);- right_type=extract_expresion_value_type(left,translation_data);-- if(!type_is_arithmetic(left_type))- {- if(left_type->specifier==TS_POINTER && type_is_integer_type(right_type))- {- return get_binary_expression_tree(left,right,get_expression_value_rvalue(get_temp_object(left_type)),OP_POINTER_ADDITION);- }else- {- push_translation_error("expected arithmetic type in additive operation",translation_data);- return get_error_tree(get_binary_expression_tree(left,right,operation));- }- }else if(!type_is_arithmetic(right_type))- {- if(right_type->specifier==TS_POINTER && type_is_integer_type(left_type))- {- return get_binary_expression_tree(right,left,get_expression_value_rvalue(get_temp_object(right_type)),OP_POINTER_ADDITION);- }else- {- push_translation_error("expected arithmetic type in additive operation",translation_data);- return get_error_tree(get_binary_expression_tree(left,right,operation));- }- }else+ if(constraint_check_additive_expression(left,right,operation,translation_data)){return get_binary_expression_after_conversion(left,right,operation,translation_data);+ }else+ {+ delete_ast(left), delete_ast(right);+ return NULL;}}struct AST_Binary_Expression* get_shift_expression_tree(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data){- struct Type *left_type;- struct Type *right_type;-- left_type=extract_expresion_value_type(left,translation_data);- right=extract_expresion_value_type(right,translation_data);-- if(!type_is_integer_type(left_type) || !type_is_integer_type(right_type))+ if(constraint_check_shift_expression(left,right,operation,translation_data)){- push_translation_error("expected integer type in shift operation",translation_data);- return get_error_tree(get_binary_expression_tree(left,right,operation));+ return get_binary_expression_tree(left,right,get_expression_value_rvalue(get_temp_object(left_type)),operation);+ }else+ {+ delete_ast(left), delete_ast(right);+ return NULL;}- left=get_promoted_expression(left,translation_data);- right=get_promoted_expression(right,translation_data);-- left_type=extract_expresion_value_type(left,translation_data);- right=extract_expresion_value_type(right,translation_data);-- return get_binary_expression_tree(left,right,get_expression_value_rvalue(get_temp_object(left_type)),operation);-}struct AST_Binary_Expression* get_bitwise_expression_tree(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data){- struct Type *left_type;- struct Type *right_type;-- left_type=extract_expresion_value_type(left,translation_data);- right=extract_expresion_value_type(right,translation_data);-- if(!type_is_integer_type(left_type) || !type_is_integer_type(right_type))+ if(constraint_check_bitwise_expression(left,right,operation,translation_data))+ {+ return get_binary_expression_after_conversion(left,right,operation,translation_data);+ }else{- push_translation_error("expected integer type in bitwise operation",translation_data);- return get_error_tree(get_binary_expression_tree(left,right,operation));+ delete_ast(left), delete_ast(right);+ return NULL;}- return get_binary_expression_after_conversion(left,right,operation,translation_data);}- /*TODO*/struct AST_Binary_Expression* get_equality_expression_tree(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data){- return get_binary_expression_tree(left,right,get_expression_value_rvalue(get_temp_object(get_type_insecure(TS_INT,TSIGN_SIGNED,TC_NONE,INT_SIZE,translation_data))),operation);-+ if(constraint_check_equality_expression(left,right,operation,translation_data))+ {+ return get_binary_expression_tree(left,right,get_expression_value_rvalue(get_temp_object(get_type_insecure(TS_INT,TSIGN_SIGNED,TC_NONE,INT_SIZE,translation_data))),operation);+ }else+ {+ delete_ast(left), delete_ast(right);+ return NULL;+ }}struct AST_Binary_Expression* get_logical_expression_tree(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data){- struct Type *left_type;- struct Type *right_type;-- left_type=extract_expresion_value_type(left,translation_data);- right=extract_expresion_value_type(right,translation_data);-- if(!type_is_scalar(left_type) || !type_is_scalar(right_type))- {- push_translation_error("expected scalar type in logical expression",translation_data);- return get_error_tree(get_binary_expression_tree(left,right,operation));- }return get_binary_expression_tree(left,right,get_expression_value_rvalue(get_temp_object(get_type_insecure(TS_INT,TSIGN_SIGNED,TC_NONE,INT_SIZE,translation_data))),operation);}- /*TODO*/struct AST_Binary_Expression* get_simple_assignment_expression_tree(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data){- struct Expression_Value_LValue *left_value;- struct Type *left_type;- struct Type *right_type;-- left_value=left->value;- left_type=extract_expresion_value_type(left->value);- right_type=extract_expresion_value_type(right->value);- if(left_value->type!=VALUE_LVALUE || !type_is_complete(left_type) || !left_value->is_modifiable)+ if(constraint_check_simple_assignment_expression(left,right,translation_data)){- push_translation_error("expected modifiable lvalue in left operand of assignment expression",translation_data);- return get_error_tree(get_binary_expression_tree(left,right,operation));+ struct Type *left_type;+ left_type=extract_expresion_value_type(left->value);+ left_type=get_unqualified_version_of_type(left_type);++ right=get_cast_expression_tree(right,left_type,translation_data);+ return get_binary_expression_tree(left,right,get_expression_value_rvalue(get_temp_object(left_type)),OP_ASSIGN);}else{- int flag=0;- flag=(type_is_arithmetic(left_type) && type_is_arithmetic(right_type));- flag|=(type_is_struct_union(left_type) && types_are_compatible(left_type,right_type));- flag|=(left_type->specifier==TS_POINTER && types_are_compatible(left_type,right_type));- /*TODO add ( pointer void ) ( _Bool pointer )*/-- if(!flag)- {- left_type=get_unqualified_version_of_type(left_type);- right=get_cast_expression_tree(right,left_type,translation_data);- return get_binary_expression_tree(left,right,get_expression_value_rvalue(get_temp_object(left_type)),OP_ASSIGN);- }else- {- push_translation_error("in assignment expression",translation_data);- return get_error_tree(get_binary_expression_tree(left,right,operation));- }+ delete_ast(left), delete_ast(right);+ return NULL;}}struct AST_Binary_Expression* get_compound_assignment_expression_tree(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data){+ if(constraint_check_compound_assignment_expression(left,right,operation,translation_data))+ {+ struct Type *left_type;+ left_type=extract_expresion_value_type(left->value);+ left_type=get_unqualified_version_of_type(left_type);+ right=get_cast_expression_tree(right,left_type,translation_data);+ return get_binary_expression_tree(left,right,get_expression_value_rvalue(get_temp_object(left_type)),OP_ASSIGN);+ }else+ {+ delete_ast(left), delete_ast(right);+ return NULL;+ }}+ /*+ * it finds the common real type of the operands then 'upgrades' them+ * realise the usual arithmetic conversions in 6.3.1.8+ * */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 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 *ret;- operand_type=extract_expresion_value_type(operand->value,translation_data);- if(operand_type->specifier!=TS_POINTER)- { push_translation_error("using non pointer type in indirection operator",translation_data);return NULL; }-- ret=malloc(sizeof(struct AST_Unary_Expression));- ret->type=OP_DEREFERENCE;- ret->operand=operand;- ret->value=get_expression_value_lvalue(get_temp_object(operand_type->points_to));+ if(constraint_check_indirection_expression(operand,translation_data))+ {+ ret=malloc(sizeof(struct AST_Unary_Expression));+ ret->type=OP_DEREFERENCE;+ ret->operand=operand;+ ret->value=get_expression_value_lvalue(get_temp_object(operand_type->points_to));- return ret;+ return ret;+ }else+ {+ delete_ast(operand);+ return NULL;+ }}struct AST_Unary_Expression* get_address_expression_tree(struct AST_Expression *operand)F diff --git a/src/semantics/ast.hh b/src/semantics/ast.hh --- a/src/semantics/ast.hh +++ b/src/semantics/ast.hh#define LVAL_EXPR_PTR(x) ((struct AST_Lvalue_Expression*)(x))#define DECLR_PTR(x) ((struct AST_Declaration*)(x))#define IF_ST_PTR(s) ((struct AST_If_Statement*)(x))+ #define AS_AST_CONSTANT(x) ((struct AST_Constant*)(x))enum AST_Type{OP_COMMAF diff --git a/src/semantics/value/constant.c b/src/semantics/value/constant.c --- a/src/semantics/value/constant.c +++ b/src/semantics/value/constant.cvoid resolve_char_escape_sequence(struct token *token,struct Translation_Data *translation_data){++ }+ char constant_is_null_pointer(struct Constant *constant)+ {+ /*TODO make an abstraction over value==0*/+ return (constant->type->specifier==TS_POINTER && (char *)value==0);+ }+ char ast_is_null_pointer_constant(struct AST *tree)+ {+ return tree->type==OP_CONSTANT &&+ constant_is_null_pointer(AS_EXPRESSION_VALUE_CONSTANT(AS_AST_CONSTANT(tree)->value)->constant);}#endifF diff --git a/src/semantics/value/constant.h b/src/semantics/value/constant.h --- a/src/semantics/value/constant.h +++ b/src/semantics/value/constant.h+ char ast_is_null_pointer_constant(struct AST *tree);+ char constant_is_null_pointer(struct Constant *constant);++void resolve_char_escape_sequence(struct token *token,struct Translation_Data *translation_data);void delete_constant(struct Constant *constant);#endifF diff --git a/src/semantics/value/constant.hh b/src/semantics/value/constant.hh --- a/src/semantics/value/constant.hh +++ b/src/semantics/value/constant.hh#define WONKY_CONSTANT_HH WONKY_CONSTANT_HH+struct Constant;#endifF diff --git a/src/semantics/value/constraints.c b/src/semantics/value/constraints.c --- a/src/semantics/value/constraints.c +++ b/src/semantics/value/constraints.c#ifndef WONKY_CONSTRAINTS_C#define WONKY_CONSTRAINTS_C WONKY_CONSTRAINTS_C+ /*the operands of % shall both have an integer type 6.5.5*/+ char constraint_check_modulo_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data)+ {+ struct Type *left_type;+ struct Type *right_type;+ left_type=extract_expresion_value_type(left,translation_data);+ right_type=extract_expresion_value_type(right,translation_data);+ if(!type_is_integer_type(left_type))+ {+ push_translation_error("expected integer type in right operand of modulo operation",translation_data);+ return 0;+ }+ if(!type_is_integer_type(right_type))+ {+ push_translation_error("expected integer type in right operand of modulo operation",translation_data);+ return 0;+ }+ return 1;+ }+ /*constraints only on modulo operation 6.5.5*/+ char constraint_check_multiplicative_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)+ {+ if(operation==OP_REMAINDER)+ {+ return constraint_check_modulo_expression(left,right,translation_data);+ }else+ {+ struct Type *left_type;+ struct Type *right_type;+ left_type=extract_expresion_value_type(left,translation_data);+ right_type=extract_expresion_value_type(right,translation_data);+ if(type_is_arithmetic(left_type) && type_is_arithmetic(right_type))+ {+ return 1;+ }else+ {+ return 0;+ }+ }+ assert(0);+ }+ /*for addition both operands shall have arithmetic type, or one operand shall be of pointer type and the other of integer type.+ * for subtraction one of the following shall hold+ * both operands shall have arihtmetic type+ * both operands are pointers to qualified or unqualified versions of compatible object types+ * left operand is a pointer to an object type and the right operand has integer type*/+ char constraint_check_additive_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)+ {+ struct Type *left_type;+ struct Type *right_type;++ assert(operation==OP_SUBTRACTION || operation==OP_ADDITION);+++ left_type=extract_expresion_value_type(left,translation_data);+ right_type=extract_expresion_value_type(right,translation_data);+ if(operation==OP_ADDITION) // operation is '+'+ {+ if(type_is_arithmetic(left_type))+ {+ if(type_is_arithmetic(right_type))+ {+ return 1;+ }else if(type_is_pointer_to_object(right_type))+ {+ return 1;+ }else+ {+ push_translation_error("unexpected type of right operand of addition",translation_data);+ return 0;+ }+ }else if(type_is_pointer_to_object(left_type))+ {+ if(type_is_arithmetic(right_type))+ {+ return 1;+ }else+ {+ push_translation_error("unexpected type of right operand of addition",translation_data);+ return 0;+ }+ }else+ {+ push_translation_error("unexpected type of left operand of addition",translation_data);+ return 0+ }+ }else // operation is '-'+ {+ if(type_is_arithmetic(left_type) && type_is_arithmetic(right_type))+ {+ return 1;+ }else if(type_is_pointer_to_object(left_type))+ {+ if(type_is_integer_type(right_type) || type_is_pointer_to_object(right_type))+ {+ return 1;+ }else+ {+ push_translation_error("unexpected type of right operand of addition",translation_data);+ return 0;+ }+ }else+ {+ push_translation_error("unexpected type of left operand of addition",translation_data);+ return 0;+ }+ }++ }+ /*each of the operands shall have integer type 6.5.7*/+ char constraint_check_shift_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)+ {+ struct Type *left_type;+ struct Type *right_type;+ left_type=extract_expresion_value_type(left,translation_data);+ right_type=extract_expresion_value_type(right,translation_data);+ if(type_is_integer_type(left_type) && type_is_integer_type(right_type))+ {+ return 1;+ }else+ {+ push_translation_error("both operands of shift operation must be of integer type",translation_data);+ return 0;+ }+ }+ char constraint_check_bitwise_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)+ {++ }+ /* One of the following shall hold:+ * both operands have arithmetic type+ * both operands are pointers to qualified or unqualified versions of compatible types+ * one operand is a pointer to object or incomplete type and the other is a pointer to a qualified or unqualified version of void+ * one operand is a pointer and the other is a null pointer constant*/+ char constraint_check_equality_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)+ {+ struct Type *left_type;+ struct Type *right_type;+ left_type=extract_expresion_value_type(left,translation_data);+ right_type=extract_expresion_value_type(right,translation_data);+ if(type_is_arithmetic(left_type) && type_is_arithmetic(right_type))+ {+ return 1;+ }else if(type_is_pointer_to_object(left_type))+ {+ if(type_is_pointer_to_object(right_type))+ {+ if(types_are_compatible(left_type,right_type))+ {+ return 1;+ }else+ {+ push_translation_error("checking for equality between pointers of incompatible types",translation_data);+ return 0;+ }+ }else if(ast_is_null_pointer_constant(right) || type_is_pointer_to_void(right_type))+ {+ return 1;+ }else+ {+ push_translation_error("rhs is not a pointer",translation_data);+ return 0;+ }+ }else if(type_is_pointer_to_object(right_type))+ {+ if(ast_is_null_pointer_constant(left) || type_is_pointer_to_void(left_type))+ return 1;+ else+ {+ push_translation_error("lhs is not a pointer",translation_data);+ return 0;+ }+ }else if(type_is_pointer_to_incomplete_type(left_type))+ {+ if(type_is_pointer_to_void(right_type) || ast_is_null_pointer_constant(right))+ {+ return 1;+ }else+ {+ push_translation_error("rhs is not a pointer",translation_data);+ return 0;+ }+ }else if(type_is_pointer_to_incomplete_type(right_type))+ {+ if(type_is_pointer_to_void(left_type) || ast_is_null_pointer_constant(left))+ {+ return 1;+ }+ else+ {+ push_translation_error("lhs is not a pointer",translation_data);+ return 0;+ }+ }else if(left_type->specifier==TS_POINTER)+ {+ if(ast_is_null_pointer_constant(right))+ {+ return 1;+ }else+ {+ push_translation_error("rhs is not a null constant",translation_data);+ return 0;+ }+ }else if(right_type->specifier==TS_POINTER)+ {+ if(ast_is_null_pointer_constant(left))+ {+ return 1;+ }else+ {+ push_translation_error("lhs is not a null constant",translation_data);+ return 0;+ }+ }+ }+ /*each of the operands shall have scallar type 6.5.13 6.5.14*/+ char constraint_check_logical_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)+ {+ struct Type *left_type;+ struct Type *right_type;+ left_type=extract_expresion_value_type(left,translation_data);+ right_type=extract_expresion_value_type(right,translation_data);++ if(type_is_scalar(left_type) && type_is_scalar(right_type))+ {+ return 1;+ }else+ {+ push_translation_error("both operands of logical expression must be of scallar type",translation_data);+ return 0;+ }+ }+ /*+ One of the following shall hold:+ 1. Left operand has qualified or unqualified arithmetic type and the+ right has arithmetic type++ 2. The left operand has a qualified or unqualified version of a+ structure or union type compatible with the type of the right++ 3. Both operands are pointers to qualified or unqualified versions+ of compatible types, and the type pointed ot by the left has all+ the qualifiers of the type pointed by the right++ 4. One operand is a pointer to an object to or incomplete type and the+ other is a pointer to a qualified or unqualified version of void,+ and the type pointed to by the left has all the qualifiers of the+ type pointed to by the right++ 5. The left operand is a pointer and the right is a null pointer+ constant++ 6. The left operand has type _Bool and+ the right is a pointer++ 6.5.16.1+ * */+ char constraint_check_simple_assignment_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data)+ {+ struct Type *left_type;+ struct Type *right_type;++ left_type=extract_expresion_value_type(left,translation_data);+ right_type=extract_expresion_value_type(right,translation_data);++ if(type_is_arithmetic(left_type) && type_is_arithmetic(right_type))+ {+ return 1;+ }else if(type_is_struct_union(left_type) && types_are_compatible_unqualified(left_type,right_type))+ {+ return 1;+ }else if(left_type->specifier==TS_POINTER && types_are_compatible_unqualified(left_type,right_type))+ {+ return 1;+ }else if(left_type->specifier==TS_POINTER && ast_is_null_pointer_constant(right))+ {+ return 1;+ }else+ {+ return 0;+ }+ //TODO ADD _BOOL TS+ }+ /*+ if += or -=+ 1. left operand shall be a pointer to an object and the right operand shall be of integer type+ 2. left operand shall be qualified or unqualified arithmetic type and the right shall be an arithmetic type+ else+ each operand shall have arithmetic type consistent with those allowed by the corresponding binary operator++ 6.5.16.2+ */+ char constraint_check_compound_assignment_expression(struct AST_Expression *left,struct AST_Expression *right,struct AST_Type operation,struct Translation_Data *translation_data)+ {+ switch(operation)+ {+ OP_ADD_ASSIGN:+ OP_SUBTRACT_ASSIGN:+ struct Type *left_type;+ struct Type *right_type;++ left_type=extract_expresion_value_type(left,translation_data);+ right_type=extract_expresion_value_type(right,translation_data);+ if(left_type->specifier==TS_POINTER && type_is_integer_type(right_type))+ {+ return 1;+ }else if(type_is_arithmetic(left_type) && type_is_arithmetic(right_type))+ {+ return 1;+ }else+ {+ return 0;+ }+ assert(0);+ OP_MULTIPLY_ASSIGN:+ OP_DIV_ASSIGN:+ OP_REMAINDER_ASSIGN:+ return constraint_check_multiplicative_expression(left,right,operation,translation_data);+ OP_SHIFT_RIGHT_ASSIGN:+ OP_SHIFT_LEFT_ASSIGN:+ return constraint_check_shift_expression(left,right,operation,translation_data);+ OP_AND_ASSIGN:+ OP_XOR_ASSIGN:+ OP_PIPE_ASSIGN:+ return constraint_check_bitwise_expression(left,right,operation,translation_data);+ default:+ assert(0);+ }+ }+ /*+ none that I could see+ */+ char constraint_check_comma_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data)+ {+ return 1;+ }+ /*+ one of the expressions shall have type pointer to object the other shall have integer+ */+ char constraint_check_array_subscript_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data)+ {+ struct Type *left_type;+ struct Type *right_type;++ left_type=extract_expresion_value_type(left,translation_data);+ right_type=extract_expresion_value_type(right,translation_data);++ if(type_is_pointer(left_type) && type_is_integer_type(right_type))+ {+ return 1;+ }else if(type_is_pointer(right_type) && type_is_integer_type(left_type))+ {+ return 1;+ }else+ {+ return 0;+ }++ }+ /*+ left is (un)qualified struct or union, second is an id of a memeber of the struct or union+ NOTE: we don't check if id is a member of the struct or union here+ */+ char constraint_check_struct_union_member_expression(struct AST_Expression *left,struct token *id,struct Translation_Data *translation_data)+ {+ struct Type *left_type;+ left_type=extract_expresion_value_type(left,translation_data);+ return type_is_struct_union(left_type);+ }+ /*+ see above+ */+ char constraint_check_struct_union_member_trough_ptr_expression(struct AST_Expression *left,struct token *id,struct Translation_Data *translation_data)+ {+ struct Type *left_type;+ left_type=extract_expresion_value_type(left,translation_data);+ if(type_is_pointer_to_object(left_type))+ {+ left_type=((struct Type_Pointer*)left_type)->points_to;+ return type_is_struct_union(left_type);+ }else+ {+ return 0;+ }+ }+ /*+ First operand shall have scaller type+ One of the following shall hold for the second and third operands+ both operands have arithmetic type+ both operands have the same structure or union type+ both operands have void type+ both operands are pointers of (un)qualified versions of compatible types+ one operand is a pointer and the other is a null pointer constant+ one operand is a pointer to an object or incomplete type and the other is a pointer to a (un)qualified version of void+ */+ char constraint_check_conditional_expression(struct AST_Expression *left,struct AST_Expression *center,struct AST_Expression *right,struct Translation_Data *translation_data)+ {+ struct Type *left_type;+ left_type=extract_expresion_value_type(left,translation_data);+ if(!type_is_arithmetic(left))+ {+ push_translation_error("first operand of conditional expression must be of arithmetic type",translation_data);+ return 0;+ }else+ {+ struct Type *center_type;+ struct Type *right_type;++ right_type=extract_expresion_value_type(right,translation_data);+ center_type=extract_expresion_value_type(center,translation_data);++ if(type_is_arithmetic(right_type) && type_is_arithmetic(center_type))+ {+ return 1;+ }else if(type_is_struct_union(center_type) && types_are_compatible(center_type,right_type))+ {+ return 1;+ }else if(center_type->specifier==TS_VOID && right_type->specifier==TS_VOID)+ {+ return 1;+ }else if(type_is_pointer(center_type) && types_are_compatible(center_type,right_type))+ {+ return 1;+ }else if(type_is_pointer(center_type) && ast_is_null_pointer_constant(right))+ {+ return 1;+ }else if(type_is_pointer(right_type) && ast_is_null_pointer_constant(center))+ {+ return 1;+ }else if( (type_is_pointer_to_object(center_type) || type_is_pointer_to_incomplete_type(center_type)) && type_is_pointer_to_void(right_type))+ {+ return 1;+ }else if( (type_is_pointer_to_object(center_type) || type_is_pointer_to_incomplete_type(center_type)) && type_is_pointer_to_void(right_type))+ {+ return 1;+ }else+ {+ return 0;+ }+ }+ }+ char constraint_check_function_expression(struct AST_Expression *id,struct Scope *scope,struct Translation_Data *translation_data)+ {+ return 1;+ }+ char constraint_check_indirection_expression(struct AST_Expression *operand,struct Translation_Data *translation_data)+ {+ return 1;+ }+ char constraint_check_address_expression(struct AST_Expression *operand,struct Translation_Data *translation_data)+ {+ return 1;+ }+ char constraint_check_sizeof_by_type(struct Type *type)+ {+ return 1;+ }+ char constraint_check_unary_arithmetic_expression(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data)+ {+ return 1;+ }+ char constraint_check_postfix_inc_dec_tree(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data)+ {+ return 1;+ }#endifF diff --git a/src/semantics/value/constraints.h b/src/semantics/value/constraints.h --- a/src/semantics/value/constraints.h +++ b/src/semantics/value/constraints.hchar constraint_check_equality_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data);char constraint_check_logical_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data);char constraint_check_simple_assignment_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data);- char constraint_check_compound_expression(struct AST_Expression *left,struct AST_Expression *right,struct AST_Type operation,struct Translation_Data *translation_data);+ char constraint_check_compound_assignment_expression(struct AST_Expression *left,struct AST_Expression *right,struct AST_Type operation,struct Translation_Data *translation_data);char constraint_check_comma_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data);char constraint_check_array_subscript_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data);char constraint_check_struct_union_member_expression(struct AST_Expression *left,struct token *id,struct Translation_Data *translation_data);char constraint_check_struct_union_member_trough_ptr_expression(struct AST_Expression *left,struct token *id,struct Translation_Data *translation_data);char constraint_check_conditional_expression(struct AST_Expression *left,struct AST_Expression *center,struct AST_Expression *right,struct Translation_Data *translation_data);- ;char constraint_check_function_expression(struct AST_Expression *id,struct Scope *scope,struct Translation_Data *translation_data);char constraint_check_indirection_expression(struct AST_Expression *operand,struct Translation_Data *translation_data);char constraint_check_address_expression(struct AST_Expression *operand,struct Translation_Data *translation_data);F diff --git a/src/semantics/value/constraints.hh b/src/semantics/value/constraints.hh --- a/src/semantics/value/constraints.hh +++ b/src/semantics/value/constraints.hh#ifndef WONKY_CONSTRAINTS_HH#define WONKY_CONSTRAINTS_HH WONKY_CONSTRAINTS_HH-- char constraint_check_modulo_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data)- {- struct Type *hold_type;- hold_type=extract_expresion_value_type(left,translation_data);- if(!type_is_integer_type(hold_type))- { push_translation_error("expected integer type in modulo operation",translation_data); return get_error_tree(get_binary_expression_tree(left,right,OP_REMAINDER)); }-- hold_type=extract_expresion_value_type(right,translation_data);- if(!type_is_integer_type(hold_type))- { push_translation_error("expected integer type in modulo operation",translation_data); return get_error_tree(get_binary_expression_tree(left,right,OP_REMAINDER)); }- }- char constraint_check_multiplicative_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)- {-- }- char constraint_check_additive_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)- {-- }- char constraint_check_shift_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)- {-- }- char constraint_check_bitwise_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)- {-- }- char constraint_check_equality_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)- {-- }- char constraint_check_logical_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)- {-- }- char constraint_check_simple_assignment_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data)- {-- }- char constraint_check_compound_expression(struct AST_Expression *left,struct AST_Expression *right,struct AST_Type operation,struct Translation_Data *translation_data)- {-- }- char constraint_check_comma_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data)- {-- }- char constraint_check_array_subscript_expression(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data)- {-- }- char constraint_check_struct_union_member_expression(struct AST_Expression *left,struct token *id,struct Translation_Data *translation_data)- {-- }- char constraint_check_struct_union_member_trough_ptr_expression(struct AST_Expression *left,struct token *id,struct Translation_Data *translation_data)- {-- }- char constraint_check_conditional_expression(struct AST_Expression *left,struct AST_Expression *center,struct AST_Expression *right,struct Translation_Data *translation_data)- {-- }- char constraint_check_function_expression(struct AST_Expression *id,struct Scope *scope,struct Translation_Data *translation_data)- {-- }- char constraint_check_indirection_expression(struct AST_Expression *operand,struct Translation_Data *translation_data)- {-- }- char constraint_check_address_expression(struct AST_Expression *operand,struct Translation_Data *translation_data)- {-- }- char constraint_check_sizeof_by_type(struct Type *type)- {-- }- char constraint_check_unary_arithmetic_expression(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data)- {-- }- char constraint_check_postfix_inc_dec_tree(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data)- {-- }-- #endifF 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.c{return 1;}+ char types_are_compatible_unqualified(struct Type *a,struct Type *b)+ {+ return 1;+ }char type_is_scalar(struct Type *type){assert(0);}}+ char type_is_pointer(struct Type *type)+ {+ return (type->specifier==TS_POINTER);+ }+ char type_is_pointer_to_object(struct Type *type)+ {+ return (type->specifier==TS_POINTER && type_is_of_object(AS_TYPE_PTR_PTR(type)->points_to));+ }+ char type_is_pointer_to_incomplete_type(struct Type *type)+ {+ return (type->specifier==TS_POINTER && !type_is_complete(AS_TYPE_PTR_PTR(type)->points_to));+ }+ char type_is_pointer_to_void(struct Type *type)+ {+ return (type->specifier==TS_POINTER && type_is_basic(AS_TYPE_PTR_PTR(type)->points_to) && AS_BASIC_TYPE_PTR(AS_TYPE_PTR_PTR(type)->points_to)->specifier==TS_VOID);+ }#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_Basic{enum Type_Specifier specifier;- enum Type_Constraint constraint;struct Map *node;+ enum Type_Constraint constraint;enum Type_Signedness sign;size_t size;char is_const:1;char types_are_identical(struct Type *a,struct Type *b);char types_are_compatible(struct Type *a,struct Type *b);+ char types_are_compatible_unqualified(struct Type *a,struct Type *b);char type_is_of_object(struct Type *type);char type_is_complete(struct Type *type);char type_is_struct_union(struct Type *type);char type_is_constant_or_has_constant_member(struct Type *type);char type_is_qualified(struct Type *type);+ char type_is_pointer(struct Type *type);+ char type_is_pointer_to_object(struct Type *type);+ char type_is_pointer_to_incomplete_type(struct Type *type);+ char type_is_pointer_to_void(struct Type *type);int type_get_integer_conversion_rank(struct Type_Basic *type);F diff --git a/src/semantics/value/value.hh b/src/semantics/value/value.hh --- a/src/semantics/value/value.hh +++ b/src/semantics/value/value.hh#ifndef WONKY_VALUE_HH#define WONKY_VALUE_HH WONKY_VALUE_HH+ #define AS_EXPRESSION_VALUE_CONSTANT(x) ((struct Expression_Value_Constant*)(x))enum Expression_Value_Type{