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
print_ast(out,(struct AST*)error->error);
}
}
+ void print_designator_expression_tree(FILE *out,struct AST_Designator *designator)
+ {
+ print_token(out,designator->id);
+ }
void print_binary_expression_tree(FILE *out,struct AST_Binary_Expression *bin)
{
if(bin->type==OP_ARR_SUBSCRIPT)
}
switch(tree->type)
{
+ case OP_DESIGNATOR:
+ print_designator_expression_tree(out,(struct AST_Designator*)tree);
+ break;
case OP_MEMBER_TROUGH_PTR:
case OP_MEMBER:
case OP_BITWISE_AND:
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
char print_tokens_of_program(FILE *out,char **base_names);
void print_ast_enum(FILE *out,enum AST_Type op);
void print_error_tree(FILE *out,struct AST_Error *error);
+ void print_designator_expression_tree(FILE *out,struct AST_Designator *designator);
void print_binary_expression_tree(FILE *out,struct AST_Binary_Expression *bin);
void print_conditional_expression_tree(FILE *out,struct AST_Conditional_Expression *cond);
void print_function_expression_tree(FILE *out,struct AST_Function_Expression *function_call);
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
char parse_struct_declaration(struct Translation_Data *translation_data,struct Struct_Union *base)
{
struct Denotation_Prototype *prototype;
- struct Denoted_Object *hold;
- prototype=parse_specifier_qualifier_list(translation_data,base->inner_namespace);
+ struct Denoted *hold_denoted;
+ struct Denoted_Object *hold_denoted_object;
+
+ prototype=parse_specifier_qualifier_list(translation_data,(struct Scope*)base->inner_namespace);
while(!get_and_check(translation_data,KW_SEMI_COLUMN))
{
- hold=parse_struct_declarator(translation_data,base->inner_namespace,prototype);
- if(hold!=NULL && hold->denotation!=DT_Error)
+ hold_denoted=parse_struct_declarator(translation_data,(struct Scope*)base->inner_namespace,prototype);
+ if(hold_denoted!=NULL && hold_denoted->denotation!=DT_Error)
{
- if(hold->denotation==DT_Object)
+ if(hold_denoted->denotation==DT_Object)
{
- Scope_Push(base->inner_namespace,hold,translation_data);
- Queue_Push(base->members,hold);
- if(type_is_constant_or_has_constant_member(hold->object->type))
+ hold_denoted_object=(struct Denoted_Object*)hold_denoted;
+
+ Scope_Push((struct Scope*)base->inner_namespace,hold_denoted,translation_data);
+ Queue_Push(base->members,hold_denoted);
+ if(type_is_constant_or_has_constant_member(hold_denoted_object->object->type))
base->has_constant_member=1;
}else
{
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
struct AST_Function_Expression* parse_arglist(struct Translation_Data *translation_data,struct Scope *scope,struct AST_Expression* id)
{
struct AST_Function_Expression *ret;
+
ret=get_function_expression_tree(id,scope);
ret->id=id;
if(get_and_check(translation_data,KW_CLOSE_NORMAL))
struct AST_Expression* parse_postfix_expression(struct Translation_Data *translation_data,struct Scope *scope)
{
- struct AST_Expression *hold;
- struct AST_Expression *hold_expr;
+ struct AST_Expression *hold_postfix_expression;
+ struct AST_Expression *hold_second_expr;
- hold=parse_primary_expression(translation_data,scope);
+ hold_postfix_expression=parse_primary_expression(translation_data,scope);
while(translation_data->tokens->size!=0)
{
- switch(((struct token*)translation_data->tokens->first->data)->type)
+ switch(kw_get(translation_data))
{
case KW_PLUSPLUS:
chomp(translation_data);
- hold=(struct AST_Expression*)get_unary_expression_tree(hold,OP_POSTFIX_INC);
+ hold_postfix_expression=(struct AST_Expression*)get_postfix_inc_dec_tree(hold_postfix_expression,OP_POINTER_ADDITION,translation_data);
break;
case KW_MINUSMINUS:
chomp(translation_data);
- hold=(struct AST_Expression*)get_unary_expression_tree(hold,OP_POSTFIX_DEC);
+ hold_postfix_expression=(struct AST_Expression*)get_postfix_inc_dec_tree(hold_postfix_expression,OP_POINTER_ADDITION,translation_data);
break;
case KW_DOT:
chomp(translation_data);
if(check(translation_data,KW_ID,0))
{
- hold=(struct AST_Expression*)get_struct_union_member_tree(hold,Queue_Pop(translation_data->tokens),translation_data);
+ hold_postfix_expression=(struct AST_Expression*)get_struct_union_member_tree(hold_postfix_expression,Queue_Pop(translation_data->tokens),translation_data);
}
break;
case KW_ARROW:
chomp(translation_data);
if(check(translation_data,KW_ID,0))
{
- hold=(struct AST_Expression*)get_struct_union_member_trough_ptr_tree(hold,Queue_Pop(translation_data->tokens),translation_data);
+ hold_postfix_expression=(struct AST_Expression*)get_struct_union_member_trough_ptr_tree(hold_postfix_expression,Queue_Pop(translation_data->tokens),translation_data);
}
break;
case KW_OPEN_SQUARE:
chomp(translation_data);
if(get_and_check(translation_data,KW_CLOSE_SQUARE))
{
- hold=(struct AST_Expression*)get_binary_expression_tree(hold,NULL,OP_ARR_SUBSCRIPT);
+ hold_postfix_expression=(struct AST_Expression*)get_array_subscript_tree(hold_postfix_expression,NULL,translation_data);
}else
{
- hold_expr=(struct AST_Expression*)parse_expression(translation_data,scope);
- hold=(struct AST_Expression*)get_binary_expression_tree(hold,hold_expr,OP_ARR_SUBSCRIPT);
+ hold_second_expr=(struct AST_Expression*)parse_expression(translation_data,scope);
+ hold_postfix_expression=(struct AST_Expression*)get_array_subscript_tree(hold_postfix_expression,hold_second_expr,translation_data);
if(!get_and_check(translation_data,KW_CLOSE_SQUARE))
{
push_translation_error("expected ']' here",translation_data);
- return (struct AST_Expression*)get_error_tree((struct AST*)hold);
+ delete_ast((struct AST*)hold_second_expr);
+ delete_ast((struct AST*)hold_postfix_expression);
+ return NULL;
}
}
break;
case KW_OPEN_NORMAL:
chomp(translation_data);
- return (struct AST_Expression*)parse_arglist(translation_data,scope,hold);
+ return (struct AST_Expression*)parse_arglist(translation_data,scope,hold_postfix_expression);
break;
default:
- return hold;
+ return hold_postfix_expression;
}
}
- return hold;
+ return hold_postfix_expression;
}
/*
struct AST_Expression* parse_unary_expression(struct Translation_Data *translation_data,struct Scope *scope)
{
- struct AST_Unary_Expression *hold;
+ struct AST_Expression *hold_expression;
+ enum AST_Type operation_type;
if(translation_data->tokens->size==0)
{
/*TODO error*/
push_translation_error("expected something here",translation_data);
- return (struct AST_Expression*)get_error_tree(NULL);
+ return NULL;
}
/*TODO make it iterative*/
switch(((struct token*)translation_data->tokens->first->data)->type)
{
case KW_PLUSPLUS:
- chomp(translation_data);
- return (struct AST_Expression*)get_unary_expression_tree(parse_unary_expression(translation_data,scope),OP_PREFIX_INC);
+ chomp(translation_data); hold_expression=parse_unary_expression(translation_data,scope);
+
+ if(hold_expression==NULL)
+ { push_translation_error("expected unary_expression after '++' operator",translation_data); goto error; }
+ else
+ return (struct AST_Expression*)get_prefix_inc_dec_tree(hold_expression,OP_PREFIX_INC,translation_data);
case KW_MINUSMINUS:
- chomp(translation_data);
- return (struct AST_Expression*)get_unary_expression_tree(parse_unary_expression(translation_data,scope),OP_PREFIX_DEC);
+ chomp(translation_data); hold_expression=parse_unary_expression(translation_data,scope);
+
+ if(hold_expression==NULL)
+ { push_translation_error("expected unary_expression after '--' operator",translation_data); goto error; }
+ else
+ return (struct AST_Expression*)get_prefix_inc_dec_tree(hold_expression,OP_PREFIX_DEC,translation_data);
case KW_PLUS:
- chomp(translation_data);
- return (struct AST_Expression*)get_unary_expression_tree(parse_cast_expression(translation_data,scope),OP_UNARY_PLUS);
+ chomp(translation_data); hold_expression=parse_cast_expression(translation_data,scope);
+
+ if(hold_expression==NULL)
+ { push_translation_error("expected cast expression after unary '+' operator",translation_data); goto error; }
+ else
+ return (struct AST_Expression*)get_unary_arithmetic_tree(hold_expression,OP_UNARY_PLUS,translation_data);
case KW_MINUS:
- chomp(translation_data);
- return (struct AST_Expression*)get_unary_expression_tree(parse_cast_expression(translation_data,scope),OP_UNARY_MINUS);
+ chomp(translation_data); hold_expression=parse_cast_expression(translation_data,scope);
+
+ if(hold_expression==NULL)
+ { push_translation_error("expected cast expression after unary '-' operator",translation_data); goto error; }
+ else
+ return (struct AST_Expression*)get_unary_arithmetic_tree(hold_expression,OP_UNARY_MINUS,translation_data);
case KW_EXCLAMATION:
- chomp(translation_data);
- return (struct AST_Expression*)get_unary_expression_tree(parse_cast_expression(translation_data,scope),OP_LOGICAL_NOT);
+ chomp(translation_data); hold_expression=parse_cast_expression(translation_data,scope);
+ if(hold_expression==NULL)
+ { push_translation_error("expected cast expression after unary '!' operator",translation_data); goto error; }
+ else
+ return (struct AST_Expression*) get_unary_arithmetic_tree(hold_expression,OP_LOGICAL_NOT,translation_data);
case KW_TILDE:
- chomp(translation_data);
- return (struct AST_Expression*)get_unary_expression_tree(parse_cast_expression(translation_data,scope),OP_BITWISE_NOT);
+ chomp(translation_data); hold_expression=parse_cast_expression(translation_data,scope);
+
+ if(hold_expression==NULL)
+ { push_translation_error("expected cast expression after unary '~' operator",translation_data); goto error; }
+ else
+ return (struct AST_Expression*) get_unary_arithmetic_tree(hold_expression,OP_BITWISE_NOT,translation_data);
case KW_STAR:
- chomp(translation_data);
- return (struct AST_Expression*)get_unary_expression_tree(parse_cast_expression(translation_data,scope),OP_DEREFERENCE);
+ chomp(translation_data); hold_expression=parse_cast_expression(translation_data,scope);
+
+ if(hold_expression==NULL)
+ { push_translation_error("expected cast expression after unary '*' operator",translation_data); goto error; }
+ else
+ return (struct AST_Expression*) get_unary_arithmetic_tree(hold_expression,OP_DEREFERENCE,translation_data);
case KW_AND:
- chomp(translation_data);
- return (struct AST_Expression*)get_unary_expression_tree(parse_cast_expression(translation_data,scope),OP_ADDR_OF);
+ chomp(translation_data); hold_expression=parse_cast_expression(translation_data,scope);
+
+ if(hold_expression==NULL)
+ { push_translation_error("expected cast expression after unary '&' operator",translation_data); goto error; }
+ else
+ return (struct AST_Expression*) get_unary_arithmetic_tree(hold_expression,OP_ADDR_OF,translation_data);
case KW_SIZEOF:
chomp(translation_data);
if(get_and_check(translation_data,KW_OPEN_NORMAL))
return (struct AST_Expression*)get_sizeof_by_type_tree(parse_type_name(translation_data,scope));
}else
{
- return (struct AST_Expression*)get_unary_expression_tree(parse_unary_expression(translation_data,scope),OP_SIZEOF);
+ hold_expression=parse_unary_expression(translation_data,scope);
+ if(hold_expression==NULL)
+ { push_translation_error("expected unary expression after 'sizeof' operator",translation_data); goto error; }
+ else
+ get_unary_sizeof_tree(hold_expression,translation_data);
}
default:
return parse_postfix_expression(translation_data,scope);
}
+ /*shouldn't reach here - the default of the switch returns*/
+ error:
+ if(hold_expression) delete_ast((struct AST*)hold_expression);
+ return NULL;
}
/*
multiplicative-expression:
*/
struct AST_Expression* parse_multiplicative_expression(struct Translation_Data *translation_data,struct Scope *scope)
{
- struct AST_Expression *hold;
- hold=parse_cast_expression(translation_data,scope);
- while(translation_data->tokens->size!=0)
+ struct AST_Expression *hold_left_expression;
+ struct AST_Expression *hold_right_expression;
+ enum AST_Type operation_type;
+
+ hold_left_expression=parse_cast_expression(translation_data,scope);
+
+ while(translation_data->tokens->size!=0 && hold_left_expression!=NULL)
{
- switch(((struct token*)translation_data->tokens->first->data)->type)
+ switch(kw_get(translation_data))
{
case KW_STAR:
- chomp(translation_data);
- hold=(struct AST_Expression*)get_binary_expression_tree(hold,parse_cast_expression(translation_data,scope),OP_MUL);
+ operation_type=OP_MUL;
break;
case KW_FORWARD_SLASH:
- chomp(translation_data);
- hold=(struct AST_Expression*)get_binary_expression_tree(hold,parse_cast_expression(translation_data,scope),OP_DIV);
+ operation_type=OP_DIV;
break;
case KW_PERCENT:
- chomp(translation_data);
- hold=(struct AST_Expression*)get_binary_expression_tree(hold,parse_cast_expression(translation_data,scope),OP_REMAINDER);
+ operation_type=OP_DIV;
break;
default:
- return hold;
+ return hold_left_expression; /*BEWARE*/
}
+
+ chomp(translation_data);
+ hold_right_expression=parse_cast_expression(translation_data,scope);
+
+ if(hold_right_expression==NULL)
+ {
+ push_translation_error("expected cast expression as the second operator in multiplicative expression",translation_data);
+
+ assert(hold_left_expression!=NULL);
+ delete_ast((struct AST*)hold_left_expression);
+
+ return NULL; /*BEWARE*/
+ }
+
+ hold_left_expression=(struct AST_Expression*)get_multiplicative_expression_tree(hold_left_expression,hold_right_expression,operation_type,translation_data);
}
- return hold;
+ return hold_left_expression; /*this could return null if there was a constraint check violation or the first cast operation is invalid*/
}
/*
additive-expression:
struct AST_Expression* parse_additive_expression(struct Translation_Data *translation_data,struct Scope *scope)
{
- struct AST_Expression *hold;
- hold=parse_multiplicative_expression(translation_data,scope);
+ struct AST_Expression *hold_left_expression;
+ struct AST_Expression *hold_right_expression;
+ enum AST_Type operation_type;
- while(translation_data->tokens->size!=0)
+ hold_left_expression=parse_multiplicative_expression(translation_data,scope);
+
+ while(translation_data->tokens->size!=0 && hold_left_expression!=NULL)
{
- switch(((struct token*)translation_data->tokens->first->data)->type)
+ switch(kw_get(translation_data))
{
case KW_PLUS:
- chomp(translation_data);
- hold=(struct AST_Expression*)get_binary_expression_tree(hold,parse_multiplicative_expression(translation_data,scope),OP_ADDITION);
+ operation_type=OP_ADDITION;
break;
case KW_MINUS:
- chomp(translation_data);
- hold=(struct AST_Expression*)get_binary_expression_tree(hold,parse_multiplicative_expression(translation_data,scope),OP_SUBTRACTION);
+ operation_type=OP_SUBTRACTION;
break;
default:
- return hold;
+ return hold_left_expression; /*BEWARE*/
+ }
+
+ chomp(translation_data);
+ hold_right_expression=parse_multiplicative_expression(translation_data,scope);
+
+ if(hold_right_expression==NULL)
+ {
+ push_translation_error("expected multiplicative expression in the additive expression",translation_data);
+
+ assert(hold_left_expression!=NULL);
+ delete_ast((struct AST*)hold_left_expression);
+
+ return NULL;
}
+
+ hold_left_expression=(struct AST_Expression*)get_additive_expression_tree(hold_left_expression,hold_right_expression,operation_type,translation_data);
+
}
- return hold;
+ return hold_left_expression; /*this could return null if there was a constraint check violation or the first cast operation is invalid*/
}
/*
bitwise-shift:
struct AST_Expression* parse_shift_expression(struct Translation_Data *translation_data,struct Scope *scope)
{
- struct AST_Expression *hold;
- hold=parse_additive_expression(translation_data,scope);
+ struct AST_Expression *hold_left_expression;
+ struct AST_Expression *hold_right_expression;
+ enum AST_Type operation_type;
- while(translation_data->tokens->size!=0)
+ hold_left_expression=parse_additive_expression(translation_data,scope);
+
+ while(translation_data->tokens->size!=0 && hold_left_expression!=NULL)
{
- switch(((struct token*)translation_data->tokens->first->data)->type)
+ switch(kw_get(translation_data))
{
case KW_SHIFT_LEFT:
- chomp(translation_data);
- hold=(struct AST_Expression*)get_binary_expression_tree(hold,parse_additive_expression(translation_data,scope),OP_SHIFT_LEFT);
+ operation_type=OP_SHIFT_LEFT;
break;
case KW_SHIFT_RIGHT:
- chomp(translation_data);
- hold=(struct AST_Expression*)get_binary_expression_tree(hold,parse_additive_expression(translation_data,scope),OP_SHIFT_RIGHT);
+ operation_type=OP_SHIFT_RIGHT;
break;
default:
- return hold;
+ return hold_left_expression; /*BEWARE*/
}
+ chomp(translation_data);
+ hold_right_expression=parse_additive_expression(translation_data,scope);
+ if(hold_right_expression==NULL)
+ {
+ push_translation_error("expected additive expression in second argument of the bitwise shift",translation_data);
+
+ assert(hold_left_expression!=NULL);
+ delete_ast((struct AST*)hold_left_expression);
+
+ return NULL;
+ }
+ hold_left_expression=(struct AST_Expression*)get_shift_expression_tree(hold_left_expression,hold_right_expression,operation_type,translation_data);
}
- return hold;
+ return hold_left_expression; /*this could return null if there was a constraint check violation or the first cast operation is invalid*/
}
/*
struct AST_Expression* parse_relational_expression(struct Translation_Data *translation_data,struct Scope *scope)
{
- struct AST_Expression *hold;
- hold=parse_shift_expression(translation_data,scope);
+ struct AST_Expression *hold_left_expression;
+ struct AST_Expression *hold_right_expression;
+ enum AST_Type operation_type;
- while(translation_data->tokens->size!=0)
+ hold_left_expression=parse_shift_expression(translation_data,scope);
+
+ while(translation_data->tokens->size!=0 && hold_left_expression!=NULL)
{
- switch(((struct token*)translation_data->tokens->first->data)->type)
+ switch(kw_get(translation_data))
{
case KW_LESS:
- chomp(translation_data);
- hold=(struct AST_Expression*)get_binary_expression_tree(hold,parse_shift_expression(translation_data,scope),OP_LESS);
+ operation_type=OP_LESS;
break;
case KW_LESS_EQ:
- chomp(translation_data);
- hold=(struct AST_Expression*)get_binary_expression_tree(hold,parse_shift_expression(translation_data,scope),OP_LESS_EQ);
+ operation_type=OP_LESS_EQ;
break;
case KW_MORE:
- chomp(translation_data);
- hold=(struct AST_Expression*)get_binary_expression_tree(hold,parse_shift_expression(translation_data,scope),OP_GREATER);
+ operation_type=OP_GREATER;
break;
case KW_MORE_EQ:
- chomp(translation_data);
- hold=(struct AST_Expression*)get_binary_expression_tree(hold,parse_shift_expression(translation_data,scope),OP_GREATER_EQ);
+ operation_type=OP_GREATER_EQ;
break;
default:
- return hold;
+ return hold_left_expression; /*BEWARE*/
}
+ chomp(translation_data);
+
+ hold_right_expression=parse_shift_expression(translation_data,scope);
+ if(hold_right_expression==NULL)
+ {
+ push_translation_error("expected shift expression as the second operand of the relational expression",translation_data);
+
+ assert(hold_left_expression!=NULL);
+ delete_ast((struct AST*)hold_right_expression);
+
+ return NULL;
+ }
+ hold_left_expression=(struct AST_Expression*)get_relation_expression_tree(hold_left_expression,hold_right_expression,operation_type,translation_data);
}
- return hold;
+ return hold_left_expression; /*this could return null if there was a constraint check violation or the first cast operation is invalid*/
}
*/
struct AST_Expression* parse_equality_expression(struct Translation_Data *translation_data,struct Scope *scope)
{
- struct AST_Expression *hold;
- hold=parse_relational_expression(translation_data,scope);
+ struct AST_Expression *hold_left_expression;
+ struct AST_Expression *hold_right_expression;
+ enum AST_Type operation_type;
- while(translation_data->tokens->size!=0)
+ hold_left_expression=parse_relational_expression(translation_data,scope);
+
+ while(translation_data->tokens->size!=0 && hold_left_expression!=NULL)
{
- switch(((struct token*)translation_data->tokens->first->data)->type)
+ switch(kw_get(translation_data))
{
case KW_EQEQ:
- chomp(translation_data);
- hold=(struct AST_Expression*)get_binary_expression_tree(hold,parse_relational_expression(translation_data,scope),OP_EQUAL);
+ operation_type=OP_EQUAL;
break;
case KW_NOT_EQ:
- chomp(translation_data);
- hold=(struct AST_Expression*)get_binary_expression_tree(hold,parse_relational_expression(translation_data,scope),OP_NOT_EQUAL);
+ operation_type=OP_NOT_EQUAL;
break;
default:
- return hold;
+ return hold_left_expression; /*BEWARE*/
}
+ chomp(translation_data);
+ hold_right_expression=parse_relational_expression(translation_data,scope);
+ if(hold_right_expression==NULL)
+ {
+ push_translation_error("expected relational expression as the second operand of the equality expression",translation_data);
+
+ assert(hold_left_expression!=NULL);
+ delete_ast((struct AST*)hold_left_expression);
+ return NULL;
+ }
+ hold_left_expression=(struct AST_Expression*)get_equality_expression_tree(hold_left_expression,hold_right_expression,operation_type,translation_data);
}
- return hold;
+ return hold_left_expression; /*this could return null if there was a constraint check violation or the first cast operation is invalid*/
}
/*
and-expression:
struct AST_Expression* parse_and_expression(struct Translation_Data *translation_data,struct Scope *scope)
{
- struct AST_Expression *hold;
- hold=parse_equality_expression(translation_data,scope);
- while(get_and_check(translation_data,KW_AND))
+ struct AST_Expression *hold_left_expression;
+ struct AST_Expression *hold_right_expression;
+
+ hold_left_expression=parse_equality_expression(translation_data,scope);
+
+ while(get_and_check(translation_data,KW_AND) && hold_left_expression!=NULL)
{
- hold=(struct AST_Expression*)get_binary_expression_tree(hold,parse_equality_expression(translation_data,scope),OP_BITWISE_AND);
+ hold_right_expression=parse_equality_expression(translation_data,scope);
+ if(hold_right_expression==NULL)
+ {
+ push_translation_error("expected equality expression as the second argument of the bitwise and operation",translation_data);
+
+ assert(hold_left_expression!=NULL);
+ delete_ast((struct AST*)hold_left_expression);
+
+ return NULL;
+ }
+ hold_left_expression=(struct AST_Expression*)get_bitwise_expression_tree(hold_left_expression,hold_right_expression,OP_BITWISE_AND,translation_data);
}
- return hold;
+ return hold_left_expression;
}
/*
exclusive-or-expression:
*/
struct AST_Expression* parse_exclusive_or_expression(struct Translation_Data *translation_data,struct Scope *scope)
{
- struct AST_Expression *hold;
- hold=parse_and_expression(translation_data,scope);
- while(get_and_check(translation_data,KW_HAT))
+ struct AST_Expression *hold_left_expression;
+ struct AST_Expression *hold_right_expression;
+
+ hold_left_expression=parse_and_expression(translation_data,scope);
+
+ while(get_and_check(translation_data,KW_HAT) && hold_left_expression!=NULL)
{
- hold=(struct AST_Expression*)get_binary_expression_tree(hold,parse_and_expression(translation_data,scope),OP_BITWISE_XOR);
+ hold_right_expression=parse_and_expression(translation_data,scope);
+ if(hold_right_expression==NULL)
+ {
+ push_translation_error("expected bitwise and expression as the second argument of the bitwise xor operation",translation_data);
+
+ assert(hold_left_expression!=NULL);
+ delete_ast((struct AST*)hold_left_expression);
+
+ return NULL;
+ }
+ hold_left_expression=(struct AST_Expression*)get_bitwise_expression_tree(hold_left_expression,hold_right_expression,OP_BITWISE_XOR,translation_data);
}
- return hold;
-
+ return hold_left_expression;
}
/*
inclusive-or-expression:
struct AST_Expression* parse_inclusive_or_expression(struct Translation_Data *translation_data,struct Scope *scope)
{
- struct AST_Expression *hold;
- hold=parse_exclusive_or_expression(translation_data,scope);
- while(get_and_check(translation_data,KW_PIPE))
+ struct AST_Expression *hold_left_expression;
+ struct AST_Expression *hold_right_expression;
+
+ hold_left_expression=parse_exclusive_or_expression(translation_data,scope);
+
+ while(get_and_check(translation_data,KW_PIPE) && hold_left_expression!=NULL)
{
- hold=(struct AST_Expression*)get_binary_expression_tree(hold,parse_exclusive_or_expression(translation_data,scope),OP_BITWISE_OR);
+ hold_right_expression=parse_exclusive_or_expression(translation_data,scope);
+ if(hold_right_expression==NULL)
+ {
+ push_translation_error("expected exclusive or expression as the second argument of the bitwise or operation",translation_data);
+
+ assert(hold_left_expression!=NULL);
+ delete_ast((struct AST*)hold_left_expression);
+
+ return NULL;
+ }
+ hold_left_expression=(struct AST_Expression*)get_bitwise_expression_tree(hold_left_expression,hold_right_expression,OP_BITWISE_OR,translation_data);
}
- return hold;
+ return hold_left_expression;
}
/*
logical-and-expression:
struct AST_Expression* parse_logical_and_expression(struct Translation_Data *translation_data,struct Scope *scope)
{
- struct AST_Expression *hold;
- hold=parse_inclusive_or_expression(translation_data,scope);
- while(get_and_check(translation_data,KW_AND_AND))
+ struct AST_Expression *hold_left_expression;
+ struct AST_Expression *hold_right_expression;
+
+ hold_left_expression=parse_inclusive_or_expression(translation_data,scope);
+
+ while(get_and_check(translation_data,KW_AND_AND) && hold_left_expression!=NULL)
{
- hold=(struct AST_Expression*)get_binary_expression_tree(hold,parse_inclusive_or_expression(translation_data,scope),OP_LOGICAL_AND);
+ hold_right_expression=parse_inclusive_or_expression(translation_data,scope);
+ if(hold_right_expression==NULL)
+ {
+ push_translation_error("expected or-expression as the second argument of the logical and operation",translation_data);
+
+ assert(hold_left_expression!=NULL);
+ delete_ast((struct AST*)hold_left_expression);
+
+ return NULL;
+ }
+ hold_left_expression=(struct AST_Expression*)get_logical_expression_tree(hold_left_expression,hold_right_expression,OP_LOGICAL_AND,translation_data);
}
- return hold;
+ return hold_left_expression;
}
/*
logical-or-expression:
struct AST_Expression* parse_logical_or_expression(struct Translation_Data *translation_data,struct Scope *scope)
{
- struct AST_Expression *hold;
- hold=parse_logical_and_expression(translation_data,scope);
- while(get_and_check(translation_data,KW_PIPE_PIPE))
+ struct AST_Expression *hold_left_expression;
+ struct AST_Expression *hold_right_expression;
+
+ hold_left_expression=parse_logical_and_expression(translation_data,scope);
+
+ while(get_and_check(translation_data,KW_PIPE_PIPE) && hold_left_expression!=NULL)
{
- hold=(struct AST_Expression*)get_binary_expression_tree(hold,parse_logical_and_expression(translation_data,scope),OP_LOGICAL_OR);
+ hold_right_expression=parse_logical_and_expression(translation_data,scope);
+ if(hold_right_expression==NULL)
+ {
+ push_translation_error("expected or-expression as the second argument of the logical and operation",translation_data);
+
+ assert(hold_left_expression!=NULL);
+ delete_ast((struct AST*)hold_left_expression);
+
+ return NULL;
+ }
+ hold_left_expression=(struct AST_Expression*)get_logical_expression_tree(hold_left_expression,hold_right_expression,OP_LOGICAL_OR,translation_data);
}
- return hold;
+ return hold_left_expression;
}
/*
struct AST_Expression* parse_conditional_expression(struct Translation_Data *translation_data,struct Scope *scope)
{
- struct AST_Expression *hold;
- hold=parse_logical_or_expression(translation_data,scope);
+ struct AST_Expression *hold_left_expression;
+ struct AST_Expression *hold_center_expression;
+ struct AST_Expression *hold_right_expression;
+
+ hold_left_expression=parse_logical_or_expression(translation_data,scope);
+ if(hold_left_expression==NULL)
+ return NULL;
+
if(get_and_check(translation_data,KW_QUESTION))
{
- hold=(struct AST_Expression*)get_conditional_expression_tree(hold,(struct AST_Expression*)parse_expression(translation_data,scope),NULL);
+ hold_center_expression=(struct AST_Expression*)parse_expression(translation_data,scope);
+
+ if(hold_center_expression==NULL)
+ {
+ push_translation_error("expected wellformed middle expression in the conditional expression",translation_data);
+ delete_ast((struct AST*)hold_left_expression);
+ return NULL;
+ }
+
if(get_and_check(translation_data,KW_COLUMN))
{
- ((struct AST_Conditional_Expression*)hold)->right=parse_conditional_expression(translation_data,scope);
- return hold;
+ hold_right_expression=parse_conditional_expression(translation_data,scope);
+ if(hold_right_expression)
+ {
+ push_translation_error("error in the third expression of the conditional expression",translation_data);
+ delete_ast((struct AST*)hold_left_expression);
+ delete_ast((struct AST*)hold_right_expression);
+
+ return NULL;
+ }
+
+ return (struct AST_Expression*)get_conditional_expression_tree(hold_right_expression,hold_center_expression,hold_right_expression,translation_data);
}else
{
push_translation_error("expected ':' here",translation_data);
- return (struct AST_Expression*)get_error_tree((struct AST*)hold);
+
+ if(hold_left_expression)delete_ast((struct AST*)hold_left_expression);
+ if(hold_center_expression)delete_ast((struct AST*)hold_center_expression);
+
+ return NULL;
}
}else
{
- return hold;
+ return hold_left_expression;
}
}
/*
*/
struct AST_Expression* parse_assignment_expression(struct Translation_Data *translation_data,struct Scope *scope)
{
- struct AST_Expression *hold;
+ struct AST_Expression *hold_left_expression;
+ struct AST_Expression *hold_right_expression;
+ enum AST_Type operation_type;
if(translation_data->tokens->size==0)
{
/*TODO error*/
push_translation_error("expected something here",translation_data);
- return (struct AST_Expression*)get_error_tree(NULL);
+ return NULL;
}
- hold=parse_conditional_expression(translation_data,scope);
+ hold_left_expression=parse_conditional_expression(translation_data,scope);
+ if(hold_left_expression==NULL)
+ return NULL;
if(translation_data->tokens->size==0)
- return hold;
- /*TODO make it iterative*/
- switch(((struct token*)translation_data->tokens->first->data)->type)
+ return hold_left_expression;
+
+ /*TODO make it iterative*/
+ switch(kw_get(translation_data))
{
case KW_EQ:
- chomp(translation_data);
- return (struct AST_Expression*)get_binary_expression_tree(hold,parse_assignment_expression(translation_data,scope),OP_ASSIGN);
+ operation_type=OP_ASSIGN;
+ break;
case KW_PLUS_EQ:
- chomp(translation_data);
- return (struct AST_Expression*)get_binary_expression_tree(hold,parse_assignment_expression(translation_data,scope),OP_ADD_ASSIGN);
+ operation_type=OP_ADD_ASSIGN;
+ break;
case KW_MINUS_EQ:
- chomp(translation_data);
- return (struct AST_Expression*)get_binary_expression_tree(hold,parse_assignment_expression(translation_data,scope),OP_SUBTRACT_ASSIGN);
+ operation_type=OP_SUBTRACT_ASSIGN;
+ break;
case KW_PERCENT_EQ:
- chomp(translation_data);
- return (struct AST_Expression*)get_binary_expression_tree(hold,parse_assignment_expression(translation_data,scope),OP_REMAINDER_ASSIGN);
+ operation_type=OP_REMAINDER_ASSIGN;
+ break;
case KW_DIV_EQ:
- chomp(translation_data);
- return (struct AST_Expression*)get_binary_expression_tree(hold,parse_assignment_expression(translation_data,scope),OP_DIV_ASSIGN);
+ operation_type=OP_DIV_ASSIGN;
+ break;
case KW_STAR_EQ:
- chomp(translation_data);
- return (struct AST_Expression*)get_binary_expression_tree(hold,parse_assignment_expression(translation_data,scope),OP_MULTIPLY_ASSIGN);
+ operation_type=OP_MULTIPLY_ASSIGN;
+ break;
case KW_SHIFT_RIGHT_EQ:
- chomp(translation_data);
- return (struct AST_Expression*)get_binary_expression_tree(hold,parse_assignment_expression(translation_data,scope),OP_SHIFT_RIGHT_ASSIGN);
+ operation_type=OP_SHIFT_RIGHT_ASSIGN;
+ break;
case KW_SHIFT_LEFT_EQ:
- chomp(translation_data);
- return (struct AST_Expression*)get_binary_expression_tree(hold,parse_assignment_expression(translation_data,scope),OP_SHIFT_LEFT_ASSIGN);
+ operation_type=OP_SHIFT_LEFT_ASSIGN;
+ break;
case KW_AND_EQ:
- chomp(translation_data);
- return (struct AST_Expression*)get_binary_expression_tree(hold,parse_assignment_expression(translation_data,scope),OP_AND_ASSIGN);
+ operation_type=OP_AND_ASSIGN;
+ break;
case KW_PIPE_EQ:
- chomp(translation_data);
- return (struct AST_Expression*)get_binary_expression_tree(hold,parse_assignment_expression(translation_data,scope),OP_PIPE_ASSIGN);
+ operation_type=OP_PIPE_ASSIGN;
+ break;
case KW_HAT_EQ:
- chomp(translation_data);
- return (struct AST_Expression*)get_binary_expression_tree(hold,parse_assignment_expression(translation_data,scope),OP_XOR_ASSIGN);
+ operation_type=OP_XOR_ASSIGN;
+ break;
default:
- return hold;
+ return hold_left_expression; /*BEWARE*/
+ }
+ chomp(translation_data);
+ hold_right_expression=parse_assignment_expression(translation_data,scope);
+ if(hold_right_expression==NULL)
+ {
+ push_translation_error("expected a second operand for the assignment expression",translation_data);
+ delete_ast((struct AST*)hold_left_expression);
+ return NULL;
}
+ if(operation_type==OP_ASSIGN)
+ return (struct AST_Expression*)get_simple_assignment_expression_tree(hold_left_expression,hold_right_expression,translation_data);
+ else
+ return (struct AST_Expression*)get_compound_assignment_expression_tree(hold_right_expression,hold_right_expression,operation_type,translation_data);
+
}
/*
comma-expression:
*/
struct AST_Expression* parse_comma_expression(struct Translation_Data *translation_data,struct Scope *scope)
{
- struct AST_Expression *hold;
- hold=parse_assignment_expression(translation_data,scope);
+ struct AST_Expression *hold_left_expression;
+ struct AST_Expression *hold_right_expression;
+
+ hold_left_expression=parse_assignment_expression(translation_data,scope);
+
+ if(hold_left_expression==NULL)
+ return NULL;
+
while(get_and_check(translation_data,KW_COMMA))
{
- hold=(struct AST_Expression*)get_binary_expression_tree(hold,parse_assignment_expression(translation_data,scope),OP_COMMA);
+ hold_right_expression=parse_assignment_expression(translation_data,scope);
+ if(hold_right_expression==NULL)
+ {
+ push_translation_error("expected an assignment expression after comma in comma operator",translation_data);
+
+ delete_ast((struct AST*)hold_left_expression);
+ return NULL;
+ }
+ hold_left_expression=(struct AST_Expression*)get_comma_expression_tree(hold_left_expression,hold_right_expression,translation_data);
}
- return hold;
+ return hold_left_expression;
}
#endif
F diff --git a/src/semantics/ast.c b/src/semantics/ast.c
--- a/src/semantics/ast.c
+++ b/src/semantics/ast.c
struct Type *operand_type;
struct Type *promotion_type;
- operand_type=extract_expresion_value_type(operand,translation_data);
+ 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))
return get_cast_expression_tree(operand,promotion_type,translation_data);
return operand;
}
+ struct AST_Expression* get_cast_expression_tree(struct AST_Expression *operand,struct Type *type,struct Translation_Data *translation_data)
+ {
+ struct Type *operand_type;
+ if(!type_is_scalar(type))
+ { push_translation_error("cast type needs to be of scalar type",translation_data);return NULL; }
+
+ operand_type=extract_expresion_value_type(operand->value,translation_data);
+ if(types_are_identical(operand_type,type))
+ 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))),
+ OP_CAST
+ );
+
+ }
+
+ /*
+ * 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 Type_Basic *right_type;
+ struct Expression_Value *value;
+
+ left=get_promoted_expression(left,translation_data);
+ right=get_promoted_expression(right,translation_data);
+
+ left_type=(struct Type_Basic*)extract_expresion_value_type(left->value,translation_data);
+ right_type=(struct Type_Basic*)extract_expresion_value_type(right->value,translation_data);
+
+ if(left_type->specifier==TS_DOUBLE)
+ {
+ if(right_type->specifier==TS_DOUBLE && right_type->constraint==TC_LONG)
+ left=get_cast_expression_tree(left,(struct Type*)right_type,translation_data);
+ else
+ right=get_cast_expression_tree(right,(struct Type*)left_type,translation_data);
+
+ }else if(right_type->specifier==TS_DOUBLE)
+ {
+ if(left_type->specifier==TS_DOUBLE && left_type->constraint==TC_LONG)
+ right=get_cast_expression_tree(right,(struct Type*)left_type,translation_data);
+ else
+ left=get_cast_expression_tree(left,(struct Type*)right_type,translation_data);
+ }else if(left_type->specifier==TS_FLOAT)
+ {
+ right=get_cast_expression_tree(right,(struct Type*)left_type,translation_data);
+ }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))
+ {
+ /*should have integers by now*/
+ int left_rank;
+ int right_rank;
+ struct Type_Basic *greater_type;
+
+
+ left_rank=type_get_integer_conversion_rank(left_type);
+ right_rank=type_get_integer_conversion_rank(right_type);
+
+ if(left_type->sign==TSIGN_SIGNED)
+ {
+ if(right_type->sign==TSIGN_SIGNED || left_rank!=right_rank)
+ greater_type=(left_rank<right_rank?right_type:left_type);
+ else
+ greater_type=get_type_insecure(left_type->specifier,TSIGN_UNSIGNED,left_type->constraint,left_type->size,translation_data);
+ }
+ else
+ {
+ if(right_type->sign==TSIGN_UNSIGNED || left_rank!=right_rank)
+ greater_type=(left_rank<right_rank?right_type:left_type);
+ else
+ greater_type=get_type_insecure(right_type->specifier,TSIGN_UNSIGNED,right_type->constraint,right_type->size,translation_data);
+ }
+
+ left=get_cast_expression_tree(left,(struct Type*)greater_type,translation_data);
+ right=get_cast_expression_tree(right,(struct Type*)greater_type,translation_data);
+ }
+
+ value=get_expression_value_rvalue(get_temp_object((struct Type*)extract_expresion_value_type(left->value,translation_data)));
+ return get_binary_expression_tree(left,right,value,type);
+ }
+
/*TODO remove this*/
struct AST_Binary_Expression* get_binary_expression_tree(struct AST_Expression *left,struct AST_Expression *right,struct Expression_Value *value,enum AST_Type type)
{
return get_binary_expression_after_conversion(left,right,OP_REMAINDER,translation_data);
}else
{
- delete_ast(left), delete_ast(right);
+ delete_ast((struct AST*)left), delete_ast((struct AST*)right);
return NULL;
}
}
return get_binary_expression_after_conversion(left,right,operation,translation_data);
}else
{
- delete_ast(left), delete_ast(right);
+ delete_ast((struct AST*)left), delete_ast((struct AST*)right);
return NULL;
}
}
return get_binary_expression_after_conversion(left,right,operation,translation_data);
}else
{
- delete_ast(left), delete_ast(right);
+ delete_ast((struct AST*)left), delete_ast((struct AST*)right);
return NULL;
}
}
{
if(constraint_check_shift_expression(left,right,operation,translation_data))
{
- return get_binary_expression_tree(left,right,get_expression_value_rvalue(get_temp_object(left_type)),operation);
+ return get_binary_expression_tree(left,right,get_expression_value_rvalue(get_temp_object(extract_expresion_value_type(left->value,translation_data))),operation);
}else
{
- delete_ast(left), delete_ast(right);
+ delete_ast((struct AST*)left), delete_ast((struct AST*)right);
return NULL;
}
}
return get_binary_expression_after_conversion(left,right,operation,translation_data);
}else
{
- delete_ast(left), delete_ast(right);
+ delete_ast((struct AST*)left), delete_ast((struct AST*)right);
return NULL;
}
}
+ struct AST_Binary_Expression* get_relation_expression_tree(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)
+ {
+ return NULL;
+ }
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)
{
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);
+ return get_binary_expression_tree(left,right,get_expression_value_rvalue(get_temp_object((struct Type*)get_type_insecure(TS_INT,TSIGN_SIGNED,TC_NONE,INT_SIZE,translation_data))),operation);
}else
{
- delete_ast(left), delete_ast(right);
+ delete_ast((struct AST*)left), delete_ast((struct 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)
{
- 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);
+ return get_binary_expression_tree(left,right,get_expression_value_rvalue(get_temp_object((struct Type*)get_type_insecure(TS_INT,TSIGN_SIGNED,TC_NONE,INT_SIZE,translation_data))),operation);
}
struct AST_Binary_Expression* get_simple_assignment_expression_tree(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data)
if(constraint_check_simple_assignment_expression(left,right,translation_data))
{
struct Type *left_type;
- left_type=extract_expresion_value_type(left->value);
+ left_type=extract_expresion_value_type(left->value,translation_data);
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);
+ delete_ast((struct AST*)left), delete_ast((struct AST*)right);
return NULL;
}
}
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=extract_expresion_value_type(left->value,translation_data);
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);
+ delete_ast((struct AST*)left), delete_ast((struct 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 Type_Basic *right_type;
-
- left=get_promoted_expression(left,translation_data);
- right=get_promoted_expression(right,translation_data);
-
- left_type=(struct Type_Basic*)extract_expresion_value_type(left,translation_data);
- right_type=(struct Type_Basic*)extract_expresion_value_type(right,translation_data);
-
- if(left_type->specifier==TS_DOUBLE)
- {
- if(right_type->specifier==TS_DOUBLE && right_type->constraint==TC_LONG)
- left=get_cast_expression_tree(left,(struct Type*)right_type);
- else
- right=get_cast_expression_tree(right,(struct Type*)left_type);
-
- }else if(right_type->specifier==TS_DOUBLE)
- {
- if(left_type->specifier==TS_DOUBLE && left_type->constraint==TC_LONG)
- right=get_cast_expression_tree(right,(struct Type*)left_type);
- else
- left=get_cast_expression_tree(left,(struct Type*)right_type);
- }else if(left_type->specifier==TS_FLOAT)
- {
- right=get_cast_expression_tree(right,left_type);
- }else if(right_type->specifier==TS_FLOAT)
- {
- left=get_cast_expression_tree(left,right_type);
- }else if(!types_are_identical(left_type,right_type))
- {
- /*should have integers by now*/
- int left_rank;
- int right_rank;
- struct Type_Basic *greater_type;
-
-
- left_rank=type_get_integer_conversion_rank(left_type);
- right_rank=type_get_integer_conversion_rank(right_type);
-
- if(left_type->sign==TSIGN_SIGNED)
- {
- if(right_type->sign==TSIGN_SIGNED || left_rank!=right_rank)
- greater_type=(left_rank<right_rank?right_type:left_type);
- else
- greater_type=get_type_insecure(left_type->specifier,TSIGN_UNSIGNED,left_type->constraint,left_type->size,translation_data);
- }
- else
- {
- if(right_type->sign==TSIGN_UNSIGNED || left_rank!=right_rank)
- greater_type=(left_rank<right_rank?right_type:left_type);
- else
- greater_type=get_type_insecure(right_type->specifier,TSIGN_UNSIGNED,right_type->constraint,right_type->size,translation_data);
- }
-
- left=get_cast_expression_tree(left,greater_type,translation_data);
- right=get_cast_expression_tree(right,greater_type,translation_data);
- }
-
- return get_binary_expression_tree(left,right,type);
- }
-
- struct AST_Unary_Expression* get_indirection_expression_tree(struct AST_Expression *operand,struct Translation_Data *translation_data)
+ struct AST_Binary_Expression* get_comma_expression_tree(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data)
{
- struct AST_Unary_Expression *ret;
-
- 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;
- }else
- {
- delete_ast(operand);
- return NULL;
- }
-
+ return get_binary_expression_tree(left,right,get_expression_value_rvalue(get_temp_object((extract_expresion_value_type(right->value,translation_data)))),OP_COMMA);
}
- struct AST_Unary_Expression* get_address_expression_tree(struct AST_Expression *operand)
- {
- struct AST_Unary_Expression *ret;
- struct Type *operand_type;
- operand_type=extract_expresion_value_type(operand->value);
- if(operand->value->type==VALUE_FUNCTION_DESIGNATOR || operand->type==OP_ARR_SUBSCRIPT || operand->type==OP_DEREFERENCE)
- {
- ret=malloc(sizeof(struct AST_Unary_Expression));
- ret->type=OP_ADDR_OF;
- ret->operand=operand;
- ret->value=get_expression_value_rvalue(get_temp_object(get_pointer_type(operand_type,0,0)));
-
- return ret;
- }else if(operand->value->type==Expression_Value_LValue)
- {
- if(operand_type->specifier==TS_BITFIELD || ((struct Expression_Value_LValue*)operand->value)->object->storage_class==SCS_REGISTER)
- { push_translation_error("can't get the addres of such an operand",translation_data);return NULL; }
-
- ret=malloc(sizeof(struct AST_Unary_Expression));
- ret->type=OP_ADDR_OF;
- ret->operand=operand;
- ret->value=get_expression_value_rvalue(get_temp_object(get_pointer_type(operand_type,0,0)));
-
- return ret;
- }else
- {
- push_translation_error("cast type needs to be of scalar type",translation_data);
- return NULL;
- }
- }
-
-
- struct AST_Expression* get_cast_expression_tree(struct AST_Expression *operand,struct Type *type,struct Translation_Data *translation_data)
- {
- struct Type *operand_type;
- if(!type_is_scalar(type))
- { push_translation_error("cast type needs to be of scalar type",translation_data);return NULL; }
-
- operand_type=extract_expresion_value_type(operand,translation_data);
- if(types_are_identical(operand_type,type))
- return operand;
-
- return get_unary_expression_tree(
- operand,
- get_expression_value_rvalue(get_temp_object(extract_expresion_value_type(operand->value,translation_data))),
- OP_CAST
- );
-
- return ret;
- }
- struct AST_Unary_Expression* get_sizeof_by_type_tree(struct Type *type)
- {
- return get_unary_expression_tree(NULL,get_expression_value_rvalue(get_temp_object(type)),OP_SIZEOF);
- }
-
-
+ /*TODO right might be null if so then it's a [] array */
struct AST_Binary_Expression* get_array_subscript_tree(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data)
{
struct Type *left_type;
/*TODO could optimise this*/
ret->right=(struct AST_Expression*)get_designator_tree(id,(struct Scope*)struct_union->inner_namespace,translation_data);
- if(struct_union_type->is_const || !(ret->right->is_modifiable))
+ /*
+ if(left_type->is_const || !(ret->right->is_modifiable))
ret->is_modifiable=0;
else
ret->is_modifiable=1;
+ */
return ret;
}
+
/*TODO beware const type qualifier*/
struct AST_Binary_Expression* get_struct_union_member_trough_ptr_tree(struct AST_Expression *left,struct token *id,struct Translation_Data *translation_data)
{
- return get_struct_union_member_tree(get_indirection_expression_tree(left,translation_data),id,translation_data);
- }
-
- struct AST_Unary_Expression* get_unary_arithmetic_tree(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data)
- {
- struct Type *operand_type;
-
- if(operation==OP_UNARY_PLUS || operation==OP_UNARY_MINUS)
- {
- operand=get_promoted_expression(operand);
- operand_type=extract_expresion_value_type(operand->value);
-
- if(type_is_arithmetic(operand_type))
- {
- return get_unary_expression_tree(
- operand,
- get_expression_value_rvalue(get_temp_object(operand_type)),
- operation
- );
- }else
- {
- push_translation_error("expected scalar type for operand in unary operation",translation_data);
- return get_error_tree(operand);
- }
- }
+ return get_struct_union_member_tree((struct AST_Expression*)get_indirection_expression_tree(left,translation_data),id,translation_data);
}
- struct AST_Conditional_Expression* get_conditional_expression_tree(struct AST_Expression *left,struct AST_Expression *center,struct AST_Expression *right)
+ 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_Conditional_Expression *ret;
ret=malloc(sizeof(struct AST_Conditional_Expression));
return ret;
}
+
+ struct AST_Unary_Expression* get_indirection_expression_tree(struct AST_Expression *operand,struct Translation_Data *translation_data)
+ {
+ struct AST_Unary_Expression *ret;
+ struct Type_Pointer *operand_type;
+
+ if(constraint_check_indirection_expression(operand,translation_data))
+ {
+ ret=malloc(sizeof(struct AST_Unary_Expression));
+ ret->type=OP_DEREFERENCE;
+ ret->operand=operand;
+ operand_type=(struct Type_Pointer*)extract_expresion_value_type(operand->value,translation_data);
+ ret->value=get_expression_value_lvalue(get_temp_object(operand_type->points_to));
+
+ return ret;
+ }else
+ {
+ delete_ast((struct AST*)operand);
+ return NULL;
+ }
+
+ }
+ struct AST_Unary_Expression* get_address_expression_tree(struct AST_Expression *operand,struct Translation_Data *translation_data)
+ {
+ struct AST_Unary_Expression *ret;
+ struct Type *operand_type;
+ if(constraint_check_indirection_expression(operand,translation_data))
+ {
+ ret=malloc(sizeof(struct AST_Unary_Expression));
+ ret->type=OP_ADDR_OF;
+ ret->operand=operand;
+
+ operand_type=extract_expresion_value_type(operand->value,translation_data);
+ ret->value=get_expression_value_rvalue(get_temp_object(get_pointer_type(operand_type,0,0)));
+
+ return ret;
+ }else
+ {
+ delete_ast((struct AST*)operand);
+ return NULL;
+ }
+ }
+
+ struct AST_Unary_Expression* get_sizeof_by_type_tree(struct Type *type)
+ {
+ return get_unary_expression_tree(NULL,get_expression_value_rvalue(get_temp_object(type)),OP_SIZEOF);
+ }
+
+
+
+
+ struct AST_Unary_Expression* get_unary_arithmetic_tree(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data)
+ {
+ struct Type *operand_type;
+
+ if(operation==OP_UNARY_PLUS || operation==OP_UNARY_MINUS)
+ {
+ operand=get_promoted_expression(operand,translation_data);
+ operand_type=extract_expresion_value_type(operand->value,translation_data);
+
+ if(type_is_arithmetic(operand_type))
+ {
+ return get_unary_expression_tree(
+ operand,
+ get_expression_value_rvalue(get_temp_object(operand_type)),
+ operation
+ );
+ }else
+ {
+ push_translation_error("expected scalar type for operand in unary operation",translation_data);
+ return NULL;
+ }
+ }
+ }
+
+
+ struct AST_Unary_Expression* get_postfix_inc_dec_tree(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data)
+ {
+ return NULL;
+ }
+ struct AST_Unary_Expression* get_prefix_inc_dec_tree(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data)
+ {
+ return NULL;
+ }
+ struct AST_Unary_Expression* get_unary_sizeof_tree(struct AST_Expression *operand,struct Translation_Data *translation_data)
+ {
+ return NULL;
+ }
struct AST_Constant* get_constant_tree(struct Expression_Value *value)
{
struct AST_Constant *ret;
}
}
+ ret->id=id;
return ret;
}
{
switch(ast->type)
{
+ case OP_DESIGNATOR:
+ delete_ast_designator_expression((struct AST_Designator*)ast);
+ break;
case OP_COMMA:
case OP_ADDITION:
case OP_SUBTRACTION:
F diff --git a/src/semantics/ast.h b/src/semantics/ast.h
--- a/src/semantics/ast.h
+++ b/src/semantics/ast.h
{
enum AST_Type type;
struct Expression_Value *value;
+ struct token *id;
};
struct AST_Unary_Expression
struct AST_Expression* get_cast_expression_tree(struct AST_Expression *operand,struct Type *type,struct Translation_Data *translation_data);
- struct AST_Binary_Expression* get_binary_expression_tree(struct AST_Expression *left,struct AST_Expression *right,struct Expression_Value *value,enum AST_Type type);
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 AST_Binary_Expression* get_binary_expression_tree(struct AST_Expression *left,struct AST_Expression *right,struct Expression_Value *value,enum AST_Type type);
struct AST_Binary_Expression* get_modulo_tree(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data);
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 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 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 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 AST_Binary_Expression* get_relation_expression_tree(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data);
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);
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 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);
- struct AST_Binary_Expression* get_comma_expression_tree(struct AST_Expression *left,struct AST_Expression *rightstruct Translation_Data *translation_data);
-
-
-
+ struct AST_Binary_Expression* get_comma_expression_tree(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data);
struct AST_Binary_Expression* get_array_subscript_tree(struct AST_Expression *left,struct AST_Expression *right,struct Translation_Data *translation_data);
struct 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 Translation_Data *translation_data);
+ struct AST_Function_Expression* get_function_expression_tree(struct AST_Expression *id,struct Scope *scope);
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);
struct AST_Unary_Expression* get_sizeof_by_type_tree(struct Type *type);
struct AST_Unary_Expression* get_unary_arithmetic_tree(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data);
struct AST_Unary_Expression* get_postfix_inc_dec_tree(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data);
+ struct AST_Unary_Expression* get_prefix_inc_dec_tree(struct AST_Expression *operand,enum AST_Type operation,struct Translation_Data *translation_data);
+ struct AST_Unary_Expression* get_unary_sizeof_tree(struct AST_Expression *operand,struct Translation_Data *translation_data);
//TODO compound literals
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
}
void delete_denoted_enum(struct Denoted_Enum *enumeration)
{
- if(enumeration->id!=NULL)
- free(enumeration->id);
if(enumeration->enumeration!=NULL)
delete_enum(enumeration->enumeration);
free(enumeration);
}
void delete_denoted_struct_union(struct Denoted_Struct_Union *su)
{
- if(su->id!=NULL)
- free(su->id);
if(su->struct_union!=NULL)
delete_struct_union(su->struct_union);
free(su);
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
void push_denoted_enum_tag(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Enum *denoted_enum)
{
struct Denoted *hold_denotated;
- hold_denotated=CHECK_AND_PUSH(denoted_enum,&AS_NORMAL_SCOPE(current)->tags);
+ hold_denotated=Map_Check_And_Push(&AS_NORMAL_SCOPE(current)->tags,denoted_enum->enumeration->id->data,denoted_enum->enumeration->id->data_size,denoted_enum);
if(hold_denotated)
{
delete_denoted_enum(denoted_enum);
void push_denoted_struct_union_tag(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Struct_Union *denoted_struct_union)
{
struct Denoted *hold_denotated;
- hold_denotated=CHECK_AND_PUSH(denoted_struct_union,&AS_NORMAL_SCOPE(current)->tags);
+ hold_denotated=Map_Check_And_Push(&AS_NORMAL_SCOPE(current)->tags,denoted_struct_union->struct_union->id->data,denoted_struct_union->struct_union->id->data_size,denoted_struct_union);
if(hold_denotated)
{
delete_denoted_struct_union(denoted_struct_union);
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
*ret_component=cache;
ret->value=ret_component;
- ret->type=get_type_insecure(TS_INT,TSIGN_NONE,TC_NONE,INT_SIZE,translation_data);
+ ret->type=(struct Type*)get_type_insecure(TS_INT,TSIGN_NONE,TC_NONE,INT_SIZE,translation_data);
return ret;
*ret_component=cache;
ret->value=ret_component;
- ret->type=get_type_insecure(TS_INT,TSIGN_NONE,TC_NONE,INT_SIZE,translation_data);
+ ret->type=(struct Type*)get_type_insecure(TS_INT,TSIGN_NONE,TC_NONE,INT_SIZE,translation_data);
return ret;
}
*ret_component=.0l;
ret->value=ret_component;
- ret->type=get_type_insecure(TS_INT,TSIGN_NONE,TC_NONE,INT_SIZE,translation_data);
+ ret->type=(struct Type*)get_type_insecure(TS_INT,TSIGN_NONE,TC_NONE,INT_SIZE,translation_data);
return ret;
}
*ret_component=.0l;
ret->value=ret_component;
- ret->type=get_type_insecure(TS_DOUBLE,TSIGN_NONE,TC_NONE,DOUBLE_SIZE,translation_data);
+ ret->type=(struct Type*)get_type_insecure(TS_DOUBLE,TSIGN_NONE,TC_NONE,DOUBLE_SIZE,translation_data);
return ret;
}
ret_component=gstrncpy(token->data+1,token->data_size-2);
ret->value=ret_component;
- ret->type=get_type_insecure(TS_CHAR,TSIGN_NONE,TC_NONE,CHAR_SIZE,translation_data);
+ ret->type=(struct Type*)get_type_insecure(TS_CHAR,TSIGN_NONE,TC_NONE,CHAR_SIZE,translation_data);
ret->type=get_pointer_type(ret->type,1,0);
return ret;
ret_component=gstrncpy(token->data+1,token->data_size-2);
ret->value=ret_component;
- ret->type=get_type_insecure(TS_CHAR,TSIGN_NONE,TC_NONE,CHAR_SIZE,translation_data);
+ ret->type=(struct Type*)get_type_insecure(TS_CHAR,TSIGN_NONE,TC_NONE,CHAR_SIZE,translation_data);
ret->type=get_pointer_type(ret->type,1,0);
return ret;
*ret_component=token->data[1];
ret->value=ret_component;
- ret->type=get_type_insecure(TS_CHAR,TSIGN_NONE,TC_NONE,CHAR_SIZE,translation_data);
+ ret->type=(struct Type*)get_type_insecure(TS_CHAR,TSIGN_NONE,TC_NONE,CHAR_SIZE,translation_data);
return ret;
}
*ret_component=token->data[1];
ret->value=ret_component;
- ret->type=get_type_insecure(TS_CHAR,TSIGN_NONE,TC_NONE,CHAR_SIZE,translation_data);
+ ret->type=(struct Type*)get_type_insecure(TS_CHAR,TSIGN_NONE,TC_NONE,CHAR_SIZE,translation_data);
return ret;
}
struct Constant* extract_enum_constant(struct Denoted_Enum_Const *constant,struct Translation_Data *translation_data)
ret=malloc(sizeof(struct Constant));
ret->value=malloc(sizeof(int));
*((int*)ret->value)=constant->value;
- ret->type=get_type_insecure(INT_SIZE,TSIGN_NONE,TC_NONE,INT_SIZE,translation_data);
+ ret->type=(struct Type*)get_type_insecure(INT_SIZE,TSIGN_NONE,TC_NONE,INT_SIZE,translation_data);
return ret;
char constant_is_null_pointer(struct Constant *constant)
{
/*TODO make an abstraction over value==0*/
- return (constant->type->specifier==TS_POINTER && (char *)value==0);
+ return (constant->type->specifier==TS_POINTER && (char *)constant->value==0);
}
char ast_is_null_pointer_constant(struct AST *tree)
{
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
+ #include <constraints.h>
/*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);
+ left_type=extract_expresion_value_type(left->value,translation_data);
+ right_type=extract_expresion_value_type(right->value,translation_data);
if(!type_is_integer_type(left_type))
{
push_translation_error("expected integer type in right operand of modulo operation",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);
+ left_type=extract_expresion_value_type(left->value,translation_data);
+ right_type=extract_expresion_value_type(right->value,translation_data);
if(type_is_arithmetic(left_type) && type_is_arithmetic(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);
+ left_type=extract_expresion_value_type(left->value,translation_data);
+ right_type=extract_expresion_value_type(right->value,translation_data);
if(operation==OP_ADDITION) // operation is '+'
{
if(type_is_arithmetic(left_type))
}else
{
push_translation_error("unexpected type of left operand of addition",translation_data);
- return 0
+ return 0;
}
}else // operation is '-'
{
{
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);
+ left_type=extract_expresion_value_type(left->value,translation_data);
+ right_type=extract_expresion_value_type(right->value,translation_data);
if(type_is_integer_type(left_type) && type_is_integer_type(right_type))
{
return 1;
}
char constraint_check_bitwise_expression(struct AST_Expression *left,struct AST_Expression *right,enum AST_Type operation,struct Translation_Data *translation_data)
{
-
+ return 1;
}
/* One of the following shall hold:
* both operands have arithmetic type
{
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);
+ left_type=extract_expresion_value_type(left->value,translation_data);
+ right_type=extract_expresion_value_type(right->value,translation_data);
if(type_is_arithmetic(left_type) && type_is_arithmetic(right_type))
{
return 1;
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))
+ }else if(ast_is_null_pointer_constant((struct AST*)right) || type_is_pointer_to_void(right_type))
{
return 1;
}else
}
}else if(type_is_pointer_to_object(right_type))
{
- if(ast_is_null_pointer_constant(left) || type_is_pointer_to_void(left_type))
+ if(ast_is_null_pointer_constant((struct AST*)left) || type_is_pointer_to_void(left_type))
return 1;
else
{
}
}else if(type_is_pointer_to_incomplete_type(left_type))
{
- if(type_is_pointer_to_void(right_type) || ast_is_null_pointer_constant(right))
+ if(type_is_pointer_to_void(right_type) || ast_is_null_pointer_constant((struct AST*)right))
{
return 1;
}else
}
}else if(type_is_pointer_to_incomplete_type(right_type))
{
- if(type_is_pointer_to_void(left_type) || ast_is_null_pointer_constant(left))
+ if(type_is_pointer_to_void(left_type) || ast_is_null_pointer_constant((struct AST*)left))
{
return 1;
}
}
}else if(left_type->specifier==TS_POINTER)
{
- if(ast_is_null_pointer_constant(right))
+ if(ast_is_null_pointer_constant((struct AST*)right))
{
return 1;
}else
}
}else if(right_type->specifier==TS_POINTER)
{
- if(ast_is_null_pointer_constant(left))
+ if(ast_is_null_pointer_constant((struct AST*)left))
{
return 1;
}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);
+ left_type=extract_expresion_value_type(left->value,translation_data);
+ right_type=extract_expresion_value_type(right->value,translation_data);
if(type_is_scalar(left_type) && type_is_scalar(right_type))
{
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);
+ left_type=extract_expresion_value_type(left->value,translation_data);
+ right_type=extract_expresion_value_type(right->value,translation_data);
if(type_is_arithmetic(left_type) && type_is_arithmetic(right_type))
{
}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))
+ }else if(left_type->specifier==TS_POINTER && ast_is_null_pointer_constant((struct AST*)right))
{
return 1;
}else
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)
+ char constraint_check_compound_assignment_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;
+
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);
+ left_type=extract_expresion_value_type(left->value,translation_data);
+ right_type=extract_expresion_value_type(right->value,translation_data);
if(left_type->specifier==TS_POINTER && type_is_integer_type(right_type))
{
return 1;
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);
+ left_type=extract_expresion_value_type(left->value,translation_data);
+ right_type=extract_expresion_value_type(right->value,translation_data);
if(type_is_pointer(left_type) && type_is_integer_type(right_type))
{
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);
+ left_type=extract_expresion_value_type(left->value,translation_data);
return type_is_struct_union(left_type);
}
/*
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);
+ left_type=extract_expresion_value_type(left->value,translation_data);
if(type_is_pointer_to_object(left_type))
{
left_type=((struct Type_Pointer*)left_type)->points_to;
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))
+ left_type=extract_expresion_value_type(left->value,translation_data);
+ if(!type_is_arithmetic(left_type))
{
push_translation_error("first operand of conditional expression must be of arithmetic type",translation_data);
return 0;
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);
+ right_type=extract_expresion_value_type(right->value,translation_data);
+ center_type=extract_expresion_value_type(center->value,translation_data);
if(type_is_arithmetic(right_type) && type_is_arithmetic(center_type))
{
}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))
+ }else if(type_is_pointer(center_type) && ast_is_null_pointer_constant((struct AST*)right))
{
return 1;
- }else if(type_is_pointer(right_type) && ast_is_null_pointer_constant(center))
+ }else if(type_is_pointer(right_type) && ast_is_null_pointer_constant((struct AST*)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))
}
char constraint_check_indirection_expression(struct AST_Expression *operand,struct Translation_Data *translation_data)
{
- return 1;
+ struct Type *operand_type;
+ operand_type=extract_expresion_value_type(operand->value,translation_data);
+ if(operand->value->type==VALUE_FUNCTION_DESIGNATOR || operand->type==OP_ARR_SUBSCRIPT || operand->type==OP_DEREFERENCE)
+ {
+ return 1;
+ }else if(operand->value->type==VALUE_LVALUE)
+ {
+ if(operand_type->specifier==TS_BITFIELD || ((struct Expression_Value_LValue*)operand->value)->object->storage_class==SCS_REGISTER)
+ {
+ push_translation_error("can't get the addres of such an operand",translation_data);
+ return 0;
+ }else
+ {
+ return 1;
+ }
+ }else
+ {
+ push_translation_error("cast type needs to be of scalar type",translation_data);
+ return 0;
+ }
}
char constraint_check_address_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.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_assignment_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,enum 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_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);
+ char constraing_check_sizeof(struct AST_Expression *expression,struct Translation_Data *translation_data);
#endif
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
+ #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
void delete_enum(struct Enum *enumeration)
{
+ if(enumeration->id!=NULL)
+ free(enumeration->id);
+
while(enumeration->consts->size>0)
Queue_Pop(enumeration->consts);
free(enumeration);
}
void delete_struct_union(struct Struct_Union *su)
{
+ if(su->id!=NULL)
+ free(su->id);
delete_scope((struct Scope*)su->inner_namespace);
while(su->members->size>0)
Queue_Pop(su->members);
- struct Type* get_type_insecure(enum Type_Specifier type_specifier,enum Type_Signedness sign,enum Type_Constraint constraint,size_t type_size,struct Translation_Data *translation_data)
+ struct Type_Basic* get_type_insecure(enum Type_Specifier type_specifier,enum Type_Signedness sign,enum Type_Constraint constraint,size_t type_size,struct Translation_Data *translation_data)
{
struct Type_Basic *ret;
ret=calloc(1,sizeof(struct Type_Basic));
ret->sign=sign;
ret=(struct Type_Basic*)type_check_and_push((struct Type*)ret,translation_data->types,sizeof(struct Type_Basic));
- return (struct Type*)ret;
+ return ret;
}
/*TODO !!!*/
char types_are_identical(struct Type *a,struct Type *b)
{
if(type->specifier==TS_CHAR)
{
- return get_type_insecure(TS_INT,TSIGN_NONE,TC_NONE,INT_SIZE,translation_data);
+ return (struct Type*)get_type_insecure(TS_INT,TSIGN_NONE,TC_NONE,INT_SIZE,translation_data);
}
else if(type->specifier==TS_INT)
{
struct Type_Basic *cache_type;
cache_type=(struct Type_Basic*)type;
if(cache_type->constraint==TC_SHORT)
- return get_type_insecure(TS_INT,TSIGN_NONE,TC_NONE,INT_SIZE,translation_data);
+ return (struct Type*)get_type_insecure(TS_INT,TSIGN_NONE,TC_NONE,INT_SIZE,translation_data);
else
return type;
struct Type_Bit_Field *cache_type;
cache_type=(struct Type_Bit_Field*)type;
if(cache_type->number_of_bits< 8 * INT_SIZE)
- return get_type_insecure(TS_INT,TSIGN_NONE,TC_NONE,INT_SIZE,translation_data);
+ return (struct Type*)get_type_insecure(TS_INT,TSIGN_NONE,TC_NONE,INT_SIZE,translation_data);
else if(cache_type->number_of_bits== 8 * INT_SIZE)
- return get_type_insecure(TS_INT,TSIGN_UNSIGNED,TC_NONE,INT_SIZE,translation_data);
+ return (struct Type*)get_type_insecure(TS_INT,TSIGN_UNSIGNED,TC_NONE,INT_SIZE,translation_data);
else
return type;
}else
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* get_function_type(struct Type *return_type,struct Queue *parameters,struct Normal_Scope* function_prototype_scope);
- struct Type* get_type_insecure(enum Type_Specifier type_specifier,enum Type_Signedness sign,enum Type_Constraint constraint,size_t type_size,struct Translation_Data *translation_data);
+ struct Type_Basic* get_type_insecure(enum Type_Specifier type_specifier,enum Type_Signedness sign,enum Type_Constraint constraint,size_t type_size,struct Translation_Data *translation_data);
struct Type* get_type_for_promotion(struct Type *type,struct Translation_Data *translation_data);
struct Type* get_unqualified_version_of_type(struct Type *type);
F diff --git a/src/semantics/value/value.c b/src/semantics/value/value.c
--- a/src/semantics/value/value.c
+++ b/src/semantics/value/value.c
}
struct Expression_Value* get_expression_value_rvalue(struct Object *temp_object)
{
- struct Expression_Value_Temp_Value *ret;
- ret=malloc(sizeof(struct Expression_Value_Temp_Value));
+ struct Expression_Value_RValue *ret;
+ ret=malloc(sizeof(struct Expression_Value_RValue));
+ ret->type=VALUE_TEMP;
ret->temp_object=temp_object;
return (struct Expression_Value*)ret;
{
struct Expression_Value_Function_Designator *ret;
ret=malloc(sizeof(struct Expression_Value_Function_Designator));
+
+ ret->type=VALUE_FUNCTION_DESIGNATOR;
ret->function=function;
return (struct Expression_Value*)ret;
case VALUE_LVALUE:
return ((struct Expression_Value_LValue*)expression_value)->object->type;
case VALUE_TEMP:
- return ((struct Expression_Value_Temp_Value*)expression_value)->temp_object->type;
+ return ((struct Expression_Value_RValue*)expression_value)->temp_object->type;
case VALUE_FUNCTION_DESIGNATOR:
return ((struct Expression_Value_Function_Designator*)expression_value)->function->type;
case VALUE_CONSTANT:
return ((struct Expression_Value_Constant*)expression_value)->constant->type;
case VALUE_VOID:
- return get_type_insecure(TS_VOID,TSIGN_NONE,TC_NONE,0,translation_data);
+ return (struct Type*)get_type_insecure(TS_VOID,TSIGN_NONE,TC_NONE,0,translation_data);
}
assert(0);
}
delete_expression_value_lvalue((struct Expression_Value_LValue*)expression_value);
return;
case VALUE_TEMP:
- delete_expression_value_rvalue((struct Expression_Value_Temp_Value*)expression_value);
+ delete_expression_value_rvalue((struct Expression_Value_RValue*)expression_value);
return;
case VALUE_FUNCTION_DESIGNATOR:
delete_expression_value_function_designator((struct Expression_Value_Function_Designator*)expression_value);
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
struct Expression_Value;
struct Expression_Value_LValue;
- struct Expression_Value_Temp_Value;
+ struct Expression_Value_RValue;
struct Expression_Value_Constant;
struct Expression_Value_Function_Designator;