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_function_expression_tree(FILE *out,struct AST_Function_Expression *function_call){- struct Queue_Node *it;+ size_t i;print_ast(out,(struct AST*)function_call->id);fprintf(out,"(");- if(function_call->arguments.size>0)+ if(function_call->number_of_arguments>0){- fprintf(out,"\n");- for(it=function_call->arguments.first;it!=function_call->arguments.last;it=it->prev)+ for(i=0;i<function_call->number_of_arguments;++i){- print_ast(out,(struct AST*)(struct AST*)(it->data));- fprintf(out,",\n");+ print_ast(out,(struct AST*)function_call->arg_list[i]);+ if(i!=function_call->number_of_arguments-1)+ fprintf(out,",");}- if(it!=NULL)- {- print_ast(out,(struct AST*)(struct AST*)(it->data));- }-}fprintf(out,")");}F 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.c/*check if this is a function definition*/if(parse_function_definitions && get_and_check(translation_data,KW_OPEN_CURLY)){+ struct Type_Function *function_type;+ function_type=(struct Type_Function*)((struct Denoted_Function*)hold)->type;((struct Denoted_Function*)hold) ->body=- (struct AST_Compound_Statement*)parse_finish_compound_statement(translation_data,scope);+ (struct AST_Compound_Statement*)parse_finish_compound_statement(translation_data,(struct Scope*)function_type->function_prototype_scope);Queue_Push(where_to_push,get_function_definition_tree(scope,(struct Denoted_Function*)hold));Scope_Push(scope,hold,translation_data);break;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.cstruct AST_Function_Expression* parse_arglist(struct Translation_Data *translation_data,struct Scope *scope,struct AST_Expression* id){struct AST_Function_Expression *ret;+ struct AST_Expression *hold_expression;+ struct Queue arg_list;++ Queue_Init(&arg_list);- ret=get_function_expression_tree(id,scope);- ret->id=id;if(get_and_check(translation_data,KW_CLOSE_NORMAL)){- return ret;+ return get_function_expression_tree(id,&arg_list,translation_data);}+do{- Queue_Push(&ret->arguments,parse_assignment_expression(translation_data,scope));- } while(get_and_check(translation_data,KW_COMMA));+ hold_expression=parse_assignment_expression(translation_data,scope);+ if(hold_expression==NULL)+ {+ while(arg_list.size>0)+ delete_ast((struct AST*)Queue_Pop(&arg_list));+ push_translation_error("error in argument list in function call expression",translation_data);+ return NULL;+ }+ Queue_Push(&arg_list,hold_expression);+ }while(get_and_check(translation_data,KW_COMMA));++ ret=get_function_expression_tree(id,&arg_list,translation_data);+ assert(arg_list.size==0);+if(get_and_check(translation_data,KW_CLOSE_NORMAL)){return ret;}else{push_translation_error("expected ')' here",translation_data);- return (struct AST_Function_Expression*)get_error_tree((struct AST*)ret);+ delete_ast((struct AST*)ret);+ return NULL;}}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_Function_Expression* get_function_expression_tree(struct AST_Expression *id,struct Scope *scope)+ struct AST_Function_Expression* get_function_expression_tree(struct AST_Expression *id,struct Queue *arg_list,struct Translation_Data *translation_data){struct AST_Function_Expression *ret;+ struct Type_Function *id_type;+ size_t i;++ id_type=(struct Type_Function*)extract_expresion_value_type(id->value,translation_data);ret=malloc(sizeof(struct AST_Function_Expression));ret->type=OP_FUNCTION;+ ret->value=get_expression_value_rvalue(get_temp_object(id_type->return_type));ret->id=id;- Queue_Init(&ret->arguments);- return ret;+ ret->number_of_arguments=arg_list->size;++ ret->arg_list=calloc(ret->number_of_arguments,sizeof(struct AST_Expression*));+ for(i=0;i<ret->number_of_arguments;++i)+ {+ assert(arg_list->size>0);+ ret->arg_list[i]=(struct AST_Expression*)Queue_Pop(arg_list);+ }+ assert(arg_list->size==0);+ if(constraint_check_function_expression(ret,translation_data))+ {+ return ret;+ }+ else+ {+ delete_ast((struct AST*)ret);+ push_translation_error("constraint check violation in function call expression",translation_data);+ return NULL;+ }}struct AST_Unary_Expression* get_unary_expression_tree(struct AST_Expression *operand,struct Expression_Value *value,enum AST_Type type){void delete_ast_function_expression(struct AST_Function_Expression *function_expression){struct Queue_Node *it;+ size_t i;+if(function_expression->id!=NULL)delete_ast((struct AST*)function_expression->id);- while(function_expression->arguments.size>0)- delete_ast(Queue_Pop(&function_expression->arguments));+ if(function_expression->number_of_arguments!=0)+ {+ for(i=0;i<function_expression->number_of_arguments;++i)+ {+ delete_ast((struct AST*)function_expression->arg_list[i]);+ }+ free(function_expression->arg_list);+ }free(function_expression);F diff --git a/src/semantics/ast.h b/src/semantics/ast.h --- a/src/semantics/ast.h +++ b/src/semantics/ast.hstruct Expression_Value *value;struct AST_Expression *id;- /*queue of astrees*/- struct Queue arguments;++ size_t number_of_arguments;+ struct AST_Expression **arg_list;};struct AST_Constantstruct AST_Binary_Expression* get_struct_union_member_trough_ptr_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 Translation_Data *translation_data);- struct AST_Function_Expression* get_function_expression_tree(struct AST_Expression *id,struct Scope *scope);+ struct AST_Function_Expression* get_function_expression_tree(struct AST_Expression *id,struct Queue *arg_list,struct Translation_Data *translation_data);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);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/value/constraints.c b/src/semantics/value/constraints.c --- a/src/semantics/value/constraints.c +++ b/src/semantics/value/constraints.c}}}- char constraint_check_function_expression(struct AST_Expression *id,struct Scope *scope,struct Translation_Data *translation_data)+ char constraint_check_function_expression(struct AST_Function_Expression *proposed_function,struct Translation_Data *translation_data){+ struct Type *expected_argument_type;+ struct Type *given_argument_type;+ struct Type_Function *proposed_function_type;+ size_t i;++ proposed_function_type=(struct Type_Function*)extract_expresion_value_type(proposed_function->id->value,translation_data);+ if(proposed_function_type->specifier!=TS_FUNC)+ {+ push_translation_error("is not a function",translation_data);+ return 0;+ }++ if(proposed_function_type->number_of_arguments!=proposed_function->number_of_arguments)+ {+ push_translation_error("mismatching number of arguments",translation_data);+ return 0;+ }++ for(i=0;i<proposed_function->number_of_arguments;++i)+ {+ expected_argument_type=proposed_function_type->arguments[i]->object->type;+ given_argument_type=extract_expresion_value_type(proposed_function->arg_list[i]->value,translation_data);+ if(!types_are_compatible_unqualified(expected_argument_type,given_argument_type))+ {+ push_translation_error("incompatible types of argument",translation_data);+ return 0;+ }+ }return 1;}char constraint_check_indirection_expression(struct AST_Expression *operand,struct Translation_Data *translation_data)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.hchar 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_function_expression(struct AST_Function_Expression *proposed_function,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);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 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 1;+ 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;++ 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_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_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);