F diff --git a/src/semantics/ast.c b/src/semantics/ast.c
--- a/src/semantics/ast.c
+++ b/src/semantics/ast.c
ret->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_COMMA
F 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.c
void 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);
}
#endif
F 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);
#endif
F 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;
#endif
F 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;
+ }
#endif
F 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.h
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_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)
- {
-
- }
-
- #endif
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.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);
+ }
#endif
F 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.h
struct 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
{