F diff --git a/src/backend/print/print.c b/src/backend/print/print.c --- a/src/backend/print/print.c +++ b/src/backend/print/print.c}void print_unary_expression_tree(FILE *out,struct AST_Unary_Expression *unary_expression){- print_ast_enum(out,unary_expression->type);if(unary_expression->type==OP_CAST){fprintf(out,"(");- //print_type(out,unary_expression->value_type,1);+ print_expression_value_type(out,unary_expression->value);+ fprintf(out,")(");++ print_ast(out,(struct AST*)unary_expression->operand);fprintf(out,")");+ }else+ {+ print_ast_enum(out,unary_expression->type);+ print_ast(out,(struct AST*)unary_expression->operand);}- print_ast(out,(struct AST*)unary_expression->operand);}void print_labeled_statement_tree(FILE *out,struct AST_Labeled_Statement *lab){void print_type(FILE *out,struct Type *type,char should_print_struct_union){print_type_qualifier(out,type);+ print_type_sign(out,type);+ print_type_constraint(out,type);switch(type->specifier){case TS_VOID:}}+ void print_type_constraint_enum(FILE *out,enum Type_Specifier specifier)+ {+ switch(specifier)+ {+ case TC_LONG:+ fprintf(out,"long ");+ break;+ case TC_LONG_LONG:+ fprintf(out,"long long ");+ break;+ case TC_SHORT:+ fprintf(out,"short ");+ break;+ }+ }+ void print_type_sign_enum(FILE *out,enum Type_Signedness sign)+ {++ if(sign==TSIGN_UNSIGNED)+ fprintf(out,"unsigned ");+ }++ void print_type_constraint(FILE *out,struct Type *type)+ {+ switch(type->specifier)+ {+ case TS_VOID:+ case TS_CHAR:+ case TS_INT:+ case TS_FLOAT:+ case TS_DOUBLE:+ print_type_constraint_enum(out,AS_BASIC_TYPE_PTR(type)->constraint);+ }+ }+ void print_type_sign(FILE *out,struct Type *type)+ {+ switch(type->specifier)+ {+ case TS_VOID:+ case TS_CHAR:+ case TS_INT:+ case TS_FLOAT:+ case TS_DOUBLE:+ print_type_sign_enum(out,AS_BASIC_TYPE_PTR(type)->sign);+ break;+ }+ }void print_constant_tree(FILE *out,struct AST_Constant *constant){//print_token(out,string->string);}+ void print_expression_value(FILE *out,struct Expression_Value *value)+ {+ fprintf(out,"EXPRESSION VALUE OF TYPE");+ print_expression_value_type(out,value);+ }+ void print_expression_value_type(FILE *out,struct Expression_Value *expression_value)+ {+ switch(expression_value->type)+ {+ case VALUE_LVALUE:+ print_type(out, ((struct Expression_Value_LValue*)expression_value)->object->type,1);+ return;+ case VALUE_TEMP:+ print_type(out,((struct Expression_Value_RValue*)expression_value)->temp_object->type,1);+ return;+ case VALUE_FUNCTION_DESIGNATOR:+ print_type(out,((struct Expression_Value_Function_Designator*)expression_value)->function->type,1);+ return;+ case VALUE_CONSTANT:+ print_type(out, ((struct Expression_Value_Constant*)expression_value)->constant->type,1);+ return;+ case VALUE_VOID:+ fprintf(out,"void");+ return;+ }+ assert(0);+ }+#undef TOK#undef INDENTF diff --git a/src/backend/print/print.h b/src/backend/print/print.h --- a/src/backend/print/print.h +++ b/src/backend/print/print.hvoid print_errors(FILE *out,struct Queue *errors);void print_function_args(FILE *out,struct Type_Function *func);void print_type_qualifier(FILE *out,struct Type *type);+ void print_type_constraint_enum(FILE *out,enum Type_Specifier specifier);+ void print_type_sign_enum(FILE *out,enum Type_Signedness sign);+ void print_type_constraint(FILE *out,struct Type *type);+ void print_type_sign(FILE *out,struct Type *type);+ void print_expression_value(FILE *out,struct Expression_Value *value);+ void print_expression_value_type(FILE *out,struct Expression_Value *value);#endifF diff --git a/src/frontend/lex/lexer.c b/src/frontend/lex/lexer.c --- a/src/frontend/lex/lexer.c +++ b/src/frontend/lex/lexer.creturn ((struct token*)(translation_data->tokens->first->data))->type;}+ char compare_tokens(struct token *a,struct token *b)+ {+ size_t i;+ if(a->data_size!=b->data_size)+ return 0;+ for(i=0;i<a->data_size;++i)+ {+ if(a->data[i]!=b->data[i])+ return 0;+ }+ return 1;+ }struct token* get_next_token(struct Source_File *src,struct automata_entry *start_state,char skip_new_line){F diff --git a/src/frontend/lex/lexer.h b/src/frontend/lex/lexer.h --- a/src/frontend/lex/lexer.h +++ b/src/frontend/lex/lexer.hchar get_and_check_unsafe(struct Translation_Data *translation_data,enum KEYWORDS kw);void chomp(struct Translation_Data *translation_data);enum KEYWORDS kw_get(struct Translation_Data *translation_data);+ char compare_tokens(struct token *a,struct token *b);char src_getc(struct Source_File *src,char skip_line_splice,char skip_comments,char skip_new_line);void src_ungetc(struct Source_File *src);F diff --git a/src/frontend/parse/parse_declaration.c b/src/frontend/parse/parse_declaration.c --- a/src/frontend/parse/parse_declaration.c +++ b/src/frontend/parse/parse_declaration.cstruct Type *ret;- get_denoted_base(prototype);+ base=get_denoted_base(prototype);parse_declarator_inner(translation_data,scope,base);if(base->denotation==DT_Error || base->id!=NULL){/*TODO error*/push_translation_error("unexpedted id in abstract declarator",translation_data);- delete_denoted_prototype(prototype);- ret=base->type;delete_denoted_base(base);+ ret=base->type;return ret;}- delete_denoted_prototype(prototype);ret=base->type;delete_denoted_base(base);return ret;F diff --git a/src/frontend/parse/parse_expression.c b/src/frontend/parse/parse_expression.c --- a/src/frontend/parse/parse_expression.c +++ b/src/frontend/parse/parse_expression.cif(get_and_check(translation_data,KW_CLOSE_NORMAL)){operand=parse_cast_expression(translation_data,scope);-return (struct AST_Expression*)get_cast_expression_tree(operand,cast_type,translation_data);}else{F diff --git a/src/frontend/parse/parse_statement.c b/src/frontend/parse/parse_statement.c --- a/src/frontend/parse/parse_statement.c +++ b/src/frontend/parse/parse_statement.creturn (struct AST*)hold;}hold=parse_expression(translation_data,scope);+ if(hold==NULL)+ {+ push_translation_error(" in statement",translation_data);+ return (struct AST*)get_error_tree(hold);+ }if(get_and_check(translation_data,KW_SEMI_COLUMN)){return hold;F diff --git a/src/semantics/ast.c b/src/semantics/ast.c --- a/src/semantics/ast.c +++ b/src/semantics/ast.coperand_type=extract_expresion_value_type(operand->value,translation_data);promotion_type=get_type_for_promotion(operand_type,translation_data);- if(types_are_identical(operand_type,promotion_type))+ if(!types_are_identical(operand_type,promotion_type))return get_cast_expression_tree(operand,promotion_type,translation_data);elsereturn operand;return (struct AST_Expression*) get_unary_expression_tree(operand,- get_expression_value_rvalue(get_temp_object(extract_expresion_value_type(operand->value,translation_data))),+ get_expression_value_rvalue(get_temp_object(type)),OP_CAST);}else if(right_type->specifier==TS_FLOAT){left=get_cast_expression_tree(left,(struct Type*)right_type,translation_data);- }else if(!types_are_identical((struct Type*)left_type,(struct Type*)right_type))+ }else if(type_is_arithmetic((struct Type*)left_type) && type_is_arithmetic((struct Type*)right_type) && !types_are_identical((struct Type*)left_type,(struct Type*)right_type)){/*should have integers by now*/int left_rank;F diff --git a/src/semantics/identifiers/denoted.c b/src/semantics/identifiers/denoted.c --- a/src/semantics/identifiers/denoted.c +++ b/src/semantics/identifiers/denoted.c{if( AS_DENOTED_OBJECT_PTR(denoted)->linkage!=LINKAGE_NONE )return;+ }else if( ((struct Denoted*)denoted)->denotation == DT_Function )+ {+ if( AS_DENOTED_FUNCTION(denoted)->linkage!=LINKAGE_NONE )+ return;}delete_denoted(denoted);}F diff --git a/src/semantics/identifiers/scope.c b/src/semantics/identifiers/scope.c --- a/src/semantics/identifiers/scope.c +++ b/src/semantics/identifiers/scope.cif(has_new_errors(translation_data)){PF_ERROR("in declaration");}+ hold_function=CHECK_AND_PUSH(denoted_function,&AS_NORMAL_SCOPE(current)->ordinary);if(denoted_function->linkage==LINKAGE_NONE){- hold_function=CHECK_AND_PUSH(denoted_function,&AS_NORMAL_SCOPE(current)->ordinary);if(hold_function!=NULL){PF_ERROR("id with function type without linkage");}}else if(denoted_function->linkage==LINKAGE_EXTERNAL || denoted_function->linkage==LINKAGE_INTERNAL)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.creturn 1;}else{+ push_translation_error("constraint check violation in multiplicative expression",translation_data);return 0;}}return 1;}else{+ push_translation_error("constraint check violation in simple assignment expression",translation_data);return 0;}//TODO ADD _BOOL TSreturn 1;}else{+ push_translation_error("constraint check violation in compound assignment expression",translation_data);return 0;}assert(0);return 1;}else{+ push_translation_error("constraint check violation in array subscript expression",translation_data);return 0;}return type_is_struct_union(left_type);}else{+ push_translation_error("constraint check violation in member access expression",translation_data);return 0;}}return 1;}else{+ push_translation_error("constraint check violation in member contitional expression",translation_data);return 0;}}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/*TODO !!!*/char types_are_identical(struct Type *a,struct Type *b){+ return a==b;+ }++ /* 6.2.7+ * two types have compatible type if their types are the same.+ * Additional+ *+ * */+ char types_are_compatible(struct Type *a,struct Type *b)+ {+ return types_are_identical(a,b) || ( type_is_constant(a)==type_is_constant(b) && type_is_volatile(a)==type_is_volatile(b)+ && types_are_compatible_inner(a,b) );+ }+ char types_are_compatible_unqualified(struct Type *a,struct Type *b)+ {+ return types_are_identical(a,b) || types_are_compatible_inner(a,b);+ }+ char types_are_compatible_inner(struct Type *a,struct Type *b)+ {+ switch(a->specifier)+ {+ case TS_STRUCT:+ case TS_UNION:+ if(b->specifier!=a->specifier)+ return 0;+ else+ return types_of_struct_unions_are_compatible_unqualified(+ ((struct Type_Struct_Union*)a)->struct_union,+ ((struct Type_Struct_Union*)b)->struct_union);+ case TS_POINTER:+ if(b->specifier!=TS_POINTER)+ return 0;+ else+ return types_of_pointers_are_compatible_unqualified((struct Type_Pointer*)a,(struct Type_Pointer*)b);+ case TS_ARRAY:+ if(b->specifier!=TS_ARRAY)+ return 0;+ else+ return types_of_arrays_are_compatible_unqualified((struct Type_Array*)a,(struct Type_Array*)b);+ case TS_BITFIELD:+ if(b->specifier!=TS_BITFIELD)+ return 0;+ else+ return types_of_bitfields_are_compatible_unqalified((struct Type_Bit_Field*)a,(struct Type_Bit_Field*)b);+ case TS_FUNC:+ if(b->specifier!=TS_FUNC)+ return 0;+ else+ return types_of_functions_are_compatible_unqualified((struct Type_Function*)a,(struct Type_Function*)b);+ case TS_VOID:+ case TS_CHAR:+ case TS_INT:+ case TS_FLOAT:+ case TS_DOUBLE:+ if(b->specifier!=a->specifier)+ {+ return 0;+ }+ else+ {+ struct Type_Basic *basic_a;+ struct Type_Basic *basic_b;++ basic_a=(struct Type_Basic*)a;+ basic_b=(struct Type_Basic*)b;++ if(basic_a->constraint!=basic_b->constraint)+ return 0;+ if(basic_a->sign!=basic_b->sign)+ return 0;++ return 1;+ }+ }+ assert(0);+ return 0;+ }+ char types_of_pointers_are_compatible_unqualified(struct Type_Pointer *a,struct Type_Pointer *b)+ {+ return types_are_compatible(a->points_to,b->points_to);+ }+ char types_of_arrays_are_compatible_unqualified(struct Type_Array *a,struct Type_Array *b)+ {+ if(!types_are_compatible(a->is_array_of,b->is_array_of))+ return 0;+ /*0 number of elements means incomplete array type*/+ if(a->number_of_elements==0 || b->number_of_elements==0)+ return 1;+ return a->number_of_elements==b->number_of_elements;+ }+ char types_of_functions_are_compatible_unqualified(struct Type_Function *a,struct Type_Function *b)+ {+ size_t current_argument;++ if(!types_are_compatible(a->return_type,b->return_type))+ return 0;+ /*TODO add check for variadic function*/+ if(a->number_of_arguments!=b->number_of_arguments)+ return 0;++ for(current_argument=0;current_argument<a->number_of_arguments;++current_argument)+ {+ if(!types_are_compatible(a->arguments[current_argument]->object->type,b->arguments[current_argument]->object->type))+ return 0;+ }return 1;}+ char types_of_struct_unions_are_compatible_unqualified(struct Struct_Union *a,struct Struct_Union *b)+ {+ struct Queue_Node *it_a;+ struct Queue_Node *it_b;+ if( (a->id==NULL || b->id==NULL ) && b->id!=a->id)+ return 0;+ if(a->id!=NULL && !compare_tokens(a->id,b->id))+ return 0;+ if(a->members->size!=b->members->size)+ return 0;+ for(it_a=a->members->first,it_b=a->members->first;it_a!=NULL && it_b!=NULL; it_a=it_a->prev,it_b=it_b->prev)+ {+ struct Denoted_Object *object_a;+ struct Denoted_Object *object_b;- char types_are_compatible(struct Type *a,struct Type *b)+ object_a=(struct Denoted_Object*)it_a->data;+ object_b=(struct Denoted_Object*)it_b->data;++ if(!types_are_compatible( object_a->object->type, object_b->object->type))+ return 0;+ if((object_a->id==NULL || object_b->id==NULL) && object_b->id!=object_a->id)+ return 0;+ if(object_a->id!=NULL && !compare_tokens(object_a->id,object_b->id))+ return 0;+ }+ return 1;+ }+ char types_of_bitfields_are_compatible_unqalified(struct Type_Bit_Field *a,struct Type_Bit_Field *b){return 1;}- char types_are_compatible_unqualified(struct Type *a,struct Type *b)+ char types_of_enum_are_compatible_unqualified(struct Type_Enum *a,struct Type_Enum *b){return 1;}+char type_is_scalar(struct Type *type){return (type->specifier==TS_CHAR || type->specifier==TS_INT || type->specifier==TS_FLOAT || type->specifier==TS_DOUBLE || type->specifier==TS_POINTER);}char type_is_basic(struct Type *type){- return (type->specifier==TS_INT || type->specifier==TS_CHAR || type->specifier==TS_DOUBLE || type->specifier==TS_FLOAT );+ return (type->specifier==TS_INT || type->specifier==TS_CHAR || type->specifier==TS_DOUBLE || type->specifier==TS_FLOAT || type->specifier==TS_VOID);}char type_is_arithmetic(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);}+ char type_is_constant(struct Type *type)+ {+ switch(type->specifier)+ {+ case TS_VOID:+ case TS_CHAR:+ case TS_INT:+ case TS_FLOAT:+ case TS_DOUBLE:+ return ((struct Type_Basic*)type)->is_const;+ case TS_STRUCT:+ case TS_UNION:+ return ((struct Type_Struct_Union*)type)->is_const ||+ ((struct Type_Struct_Union*)type)->struct_union->has_constant_member;+ case TS_ENUM:+ return ((struct Type_Enum*)type)->is_const;+ case TS_POINTER:+ return ((struct Type_Pointer*)type)->is_const;+ case TS_BITFIELD:+ return type_is_constant(((struct Type_Bit_Field*)type)->base);+ }+ return 0;+ }+ char type_is_volatile(struct Type *type)+ {+ switch(type->specifier)+ {+ case TS_VOID:+ case TS_CHAR:+ case TS_INT:+ case TS_FLOAT:+ case TS_DOUBLE:+ return ((struct Type_Basic*)type)->is_volatile;+ case TS_STRUCT:+ case TS_UNION:+ /*+ return ((struct Type_Struct_Union*)type)->is_const ||+ ((struct Type_Struct_Union*)type)->struct_union->has_volatile_member;+ */+ return ((struct Type_Struct_Union*)type)->is_volatile;+ case TS_ENUM:+ return ((struct Type_Enum*)type)->is_const;+ case TS_POINTER:+ return ((struct Type_Pointer*)type)->is_const;+ case TS_BITFIELD:+ return type_is_volatile(((struct Type_Bit_Field*)type)->base);+ }+ return 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.hchar 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 types_are_compatible_inner(struct Type *a,struct Type *b);+ char types_of_pointers_are_compatible_unqualified(struct Type_Pointer *a,struct Type_Pointer *b);+ char types_of_arrays_are_compatible_unqualified(struct Type_Array *a,struct Type_Array *b);+ char types_of_functions_are_compatible_unqualified(struct Type_Function *a,struct Type_Function *b);+ char types_of_struct_unions_are_compatible_unqualified(struct Struct_Union *a,struct Struct_Union *b);+ char types_of_bitfields_are_compatible_unqalified(struct Type_Bit_Field *a,struct Type_Bit_Field *b);+ char types_of_enum_are_compatible_unqualified(struct Type_Enum *a,struct Type_Enum *b);char type_is_of_object(struct Type *type);char type_is_complete(struct Type *type);char type_is_pointer_to_incomplete_type(struct Type *type);char type_is_pointer_to_void(struct Type *type);+ /*these return 0 if constant/volatile-ness make no sense for the type*/+ char type_is_constant(struct Type *type);+ char type_is_volatile(struct Type *type);+int type_get_integer_conversion_rank(struct Type_Basic *type);