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 INDENT
F 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.h
void 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);
#endif
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.c
return ((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.h
char 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
struct 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.c
if(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.c
return (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.c
operand_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);
else
return 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.c
if(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.c
return 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 TS
return 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;
+ }
#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
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 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);