F diff --git a/src/backend/asm/intel/intel_compile.c b/src/backend/asm/intel/intel_compile.c --- a/src/backend/asm/intel/intel_compile.c +++ b/src/backend/asm/intel/intel_compile.c}void compile_assign_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin){- push_intel_asm_instruction(compile_data,get_intel_asm_simple_instruction(INTEL_ASM_OP_NOP));+ if(type_is_scalar(extract_expresion_value_type(bin->left->value)))+ {+ compile_ast_to_intel_asm(compile_data,(struct AST*)bin->left);+ compile_ast_to_intel_asm(compile_data,(struct AST*)bin->right);++ push_intel_asm_instruction(compile_data,intel_asm_get_pop(INTEL_ASM_REGISTER_RAX));++ push_intel_asm_instruction(compile_data,+ get_intel_asm_binary_instruction(+ (struct Intel_Asm_Memory_Location*)((struct Expression_Value_LValue*)(bin->left->value))->object->location,+ get_intel_asm_register(INTEL_ASM_REGISTER_RAX),+ INTEL_ASM_OP_MOV)+ );++ }else+ {+ push_intel_asm_instruction(compile_data,get_intel_asm_simple_instruction(INTEL_ASM_OP_NOP));+ }}void compile_add_assign_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Binary_Expression *bin){F diff --git a/src/semantics/ast.c b/src/semantics/ast.c --- a/src/semantics/ast.c +++ b/src/semantics/ast.cstruct Type *operand_type;struct Type *promotion_type;- operand_type=extract_expresion_value_type(operand->value,translation_data);+ operand_type=extract_expresion_value_type(operand->value);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);if(operand->type==ERROR)return operand;- operand_type=extract_expresion_value_type(operand->value,translation_data);+ operand_type=extract_expresion_value_type(operand->value);if(operand_type->specifier==TS_FLOAT){return get_cast_expression_tree(operand,(struct Type*)get_type_insecure(TS_DOUBLE,TSIGN_NONE,TC_NONE,DOUBLE_SIZE,translation_data),translation_data);}else{- operand_type=extract_expresion_value_type(operand->value,translation_data);+ operand_type=extract_expresion_value_type(operand->value);if(types_are_identical(operand_type,type))return operand;if(expression->type==ERROR)return expression;- expression_type=extract_expresion_value_type(expression->value,translation_data);+ expression_type=extract_expresion_value_type(expression->value);if(expression_type->specifier==TS_ARRAY){array_type=(struct Type_Array*)expression_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->value,translation_data);- right_type=(struct Type_Basic*)extract_expresion_value_type(right->value,translation_data);+ left_type=(struct Type_Basic*)extract_expresion_value_type(left->value);+ right_type=(struct Type_Basic*)extract_expresion_value_type(right->value);if(left_type->specifier==TS_DOUBLE){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)));+ value=get_expression_value_rvalue(get_temp_object((struct Type*)extract_expresion_value_type(left->value)));return get_binary_expression_tree(left,right,value,type);}{if(constraint_check_shift_expression(left,right,operation,translation_data)){- return get_binary_expression_tree(left,right,get_expression_value_rvalue(get_temp_object(extract_expresion_value_type(left->value,translation_data))),operation);+ return get_binary_expression_tree(left,right,get_expression_value_rvalue(get_temp_object(extract_expresion_value_type(left->value))),operation);}else{return (struct AST_Binary_Expression*) get_error_tree((struct AST*)get_binary_expression_tree(left,right,NULL,operation));{struct Type *left_type;- left_type=extract_expresion_value_type(left->value,translation_data);+ left_type=extract_expresion_value_type(left->value);left_type=get_unqualified_version_of_type(left_type,translation_data);if(constraint_check_compound_assignment_expression(left,right,operation,translation_data)){struct Type *left_type;- left_type=extract_expresion_value_type(left->value,translation_data);+ left_type=extract_expresion_value_type(left->value);left_type=get_unqualified_version_of_type(left_type,translation_data);right=get_cast_expression_tree(right,left_type,translation_data);{if(left->type!=ERROR && right->type!=ERROR){- return get_binary_expression_tree(left,right,get_expression_value_rvalue(get_temp_object((extract_expresion_value_type(right->value,translation_data)))),OP_COMMA);+ return get_binary_expression_tree(left,right,get_expression_value_rvalue(get_temp_object((extract_expresion_value_type(right->value)))),OP_COMMA);}else{return get_binary_expression_tree(left,right,NULL,OP_COMMA);left=get_degraded_array_expression_if_it_has_the_right_type(left,translation_data);right=get_degraded_array_expression_if_it_has_the_right_type(right,translation_data);- left_type=extract_expresion_value_type(left->value,translation_data);+ left_type=extract_expresion_value_type(left->value);if(left_type->specifier!=TS_POINTER){push_translation_error("Expected a pointer type in array subscript",translation_data);return (struct AST_Binary_Expression*)get_error_tree((struct AST*)left);}- left_type=(struct Type_Struct_Union*)extract_expresion_value_type(left->value,translation_data);+ left_type=(struct Type_Struct_Union*)extract_expresion_value_type(left->value);wonky_assert(left_type->specifier==TS_STRUCT || left_type->specifier==TS_UNION);ret->right=right;if(!constraint_check_conditional_expression(left,center,right,translation_data))return (struct AST_Conditional_Expression*)get_error_tree((struct AST*)ret);- ret->value=get_expression_value_rvalue(get_temp_object(extract_expresion_value_type(center->value,translation_data)));+ ret->value=get_expression_value_rvalue(get_temp_object(extract_expresion_value_type(center->value)));return ret;}}else{- id_type=(struct Type_Function*)extract_expresion_value_type(id->value,translation_data);+ id_type=(struct Type_Function*)extract_expresion_value_type(id->value);if(type_is_pointer_to_function((struct Type*)id_type))id_type=(struct Type_Function*)((struct Type_Pointer*)id_type)->points_to;elseret=wonky_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);+ operand_type=(struct Type_Pointer*)extract_expresion_value_type(operand->value);ret->value=get_expression_value_lvalue(get_temp_object(operand_type->points_to));return ret;ret->type=OP_ADDR_OF;ret->operand=operand;- operand_type=extract_expresion_value_type(operand->value,translation_data);+ operand_type=extract_expresion_value_type(operand->value);ret->value=get_expression_value_rvalue(get_temp_object(get_pointer_type(operand_type,0,0,translation_data)));return ret;if(constraint_check_unary_plus_minus(operand,operation,translation_data)){operand=get_promoted_expression(operand,translation_data);- operand_type=extract_expresion_value_type(operand->value,translation_data);+ operand_type=extract_expresion_value_type(operand->value);return get_unary_expression_tree(operand,get_expression_value_rvalue(get_temp_object(operand_type)),operation);}else{if(constraint_check_unary_bitwise_not(operand,translation_data)){operand=get_promoted_expression(operand,translation_data);- operand_type=extract_expresion_value_type(operand->value,translation_data);+ operand_type=extract_expresion_value_type(operand->value);return get_unary_expression_tree(operand,get_expression_value_rvalue(get_temp_object(operand_type)),OP_BITWISE_NOT);}else{if(constraint_check_unary_logical_not(operand,translation_data)){operand=get_promoted_expression(operand,translation_data);- operand_type=extract_expresion_value_type(operand->value,translation_data);+ operand_type=extract_expresion_value_type(operand->value);return get_unary_expression_tree(operand,get_expression_value_rvalue(get_temp_object(operand_type)),OP_LOGICAL_NOT);}else{{struct Type *operand_type;operand=get_degraded_array_expression_if_it_has_the_right_type(operand,translation_data);- operand_type=extract_expresion_value_type(operand->value,translation_data);+ operand_type=extract_expresion_value_type(operand->value);if(constraint_check_postfix_inc_dec_expression(operand,operation,translation_data)){return get_unary_expression_tree(operand,get_expression_value_rvalue(get_temp_object(operand_type)),operation); /*TODO return expression value rvaluesness is under question*/return (struct AST_Unary_Expression*)operand;operand=get_degraded_array_expression_if_it_has_the_right_type(operand,translation_data);- operand_type=extract_expresion_value_type(operand->value,translation_data);+ operand_type=extract_expresion_value_type(operand->value);if(constraint_check_prefix_inc_dec_expression(operand,operation,translation_data)){return get_unary_expression_tree(operand,get_expression_value_rvalue(get_temp_object(operand_type)),operation); /*TODO return expression value rvaluesness is under question*/}- struct AST* get_nop_tree()+ struct AST* get_nop_tree(struct Translation_Data *translation_data){struct AST_Expression* ret;ret=wonky_malloc(sizeof(struct AST_Expression*));ret->type=OP_NOP;- ret->value=get_expression_value_void();+ ret->value=get_expression_value_void(translation_data);return (struct AST*)ret;}F diff --git a/src/semantics/constraints/expression_constraints.c b/src/semantics/constraints/expression_constraints.c --- a/src/semantics/constraints/expression_constraints.c +++ b/src/semantics/constraints/expression_constraints.cif(left->type==ERROR || right->type==ERROR)return 0;- left_type=extract_expresion_value_type(left->value,translation_data);- right_type=extract_expresion_value_type(right->value,translation_data);+ left_type=extract_expresion_value_type(left->value);+ right_type=extract_expresion_value_type(right->value);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->value,translation_data);- right_type=extract_expresion_value_type(right->value,translation_data);+ left_type=extract_expresion_value_type(left->value);+ right_type=extract_expresion_value_type(right->value);if(type_is_arithmetic(left_type) && type_is_arithmetic(right_type)){wonky_assert(operation==OP_SUBTRACTION || operation==OP_ADDITION);- left_type=extract_expresion_value_type(left->value,translation_data);- right_type=extract_expresion_value_type(right->value,translation_data);+ left_type=extract_expresion_value_type(left->value);+ right_type=extract_expresion_value_type(right->value);if(operation==OP_ADDITION) // operation is '+'{if(type_is_arithmetic(left_type))if(left->type==ERROR || right->type==ERROR)return 0;- left_type=extract_expresion_value_type(left->value,translation_data);- right_type=extract_expresion_value_type(right->value,translation_data);+ left_type=extract_expresion_value_type(left->value);+ right_type=extract_expresion_value_type(right->value);if(type_is_integer_type(left_type) && type_is_integer_type(right_type)){return 1;if(left->type==ERROR || right->type==ERROR)return 0;- left_type=extract_expresion_value_type(left->value,translation_data);- right_type=extract_expresion_value_type(right->value,translation_data);+ left_type=extract_expresion_value_type(left->value);+ right_type=extract_expresion_value_type(right->value);if(type_is_arithmetic(left_type) && type_is_arithmetic(right_type)){return 1;if(left->type==ERROR || right->type==ERROR)return 0;- left_type=extract_expresion_value_type(left->value,translation_data);- right_type=extract_expresion_value_type(right->value,translation_data);+ left_type=extract_expresion_value_type(left->value);+ right_type=extract_expresion_value_type(right->value);if(type_is_scalar(left_type) && type_is_scalar(right_type)){return 0;}- left_type=extract_expresion_value_type(left->value,translation_data);- right_type=extract_expresion_value_type(right->value,translation_data);+ left_type=extract_expresion_value_type(left->value);+ right_type=extract_expresion_value_type(right->value);if(type_is_arithmetic(left_type) && type_is_arithmetic(right_type)){case OP_ADD_ASSIGN:case OP_SUBTRACT_ASSIGN:- left_type=extract_expresion_value_type(left->value,translation_data);- right_type=extract_expresion_value_type(right->value,translation_data);+ left_type=extract_expresion_value_type(left->value);+ right_type=extract_expresion_value_type(right->value);if(left_type->specifier==TS_POINTER && type_is_integer_type(right_type)){return 1;return 0;- left_type=extract_expresion_value_type(left->value,translation_data);- right_type=extract_expresion_value_type(right->value,translation_data);+ left_type=extract_expresion_value_type(left->value);+ right_type=extract_expresion_value_type(right->value);if(type_is_pointer(left_type) && type_is_integer_type(right_type)){if(left->type==ERROR)return 0;- left_type=extract_expresion_value_type(left->value,translation_data);+ left_type=extract_expresion_value_type(left->value);if(!type_is_struct_union(left_type)){if(left->type==ERROR)return 0;- left_type=extract_expresion_value_type(left->value,translation_data);+ left_type=extract_expresion_value_type(left->value);if(type_is_pointer_to_object(left_type)){left_type=((struct Type_Pointer*)left_type)->points_to;if(left->type==ERROR || center->type==ERROR || right->type==ERROR)return 0;- left_type=extract_expresion_value_type(left->value,translation_data);+ left_type=extract_expresion_value_type(left->value);if(!type_is_arithmetic(left_type)){push_translation_error("first operand of conditional expression must be of arithmetic type",translation_data);struct Type *center_type;struct Type *right_type;- right_type=extract_expresion_value_type(right->value,translation_data);- center_type=extract_expresion_value_type(center->value,translation_data);+ right_type=extract_expresion_value_type(right->value);+ center_type=extract_expresion_value_type(center->value);if(type_is_arithmetic(right_type) && type_is_arithmetic(center_type)){if(proposed_function->type==ERROR || proposed_function->id->type==ERROR)return 0;- proposed_function_pointer_type=(struct Type_Pointer*)extract_expresion_value_type(proposed_function->id->value,translation_data);+ proposed_function_pointer_type=(struct Type_Pointer*)extract_expresion_value_type(proposed_function->id->value);if(proposed_function_pointer_type->specifier!=TS_POINTER){push_translation_error("%T is not a pointer to function",translation_data,proposed_function_pointer_type);return 0;expected_argument_type=proposed_function_type->arguments[i]->object->type;- given_argument_type=extract_expresion_value_type(proposed_function->arg_list[i]->value,translation_data);+ given_argument_type=extract_expresion_value_type(proposed_function->arg_list[i]->value);if(!types_are_compatible_unqualified(expected_argument_type,given_argument_type)){if(operand->type==ERROR)return 0;- operand_type=extract_expresion_value_type(operand->value,translation_data);+ operand_type=extract_expresion_value_type(operand->value);if(operand_type->specifier==TS_POINTER){return 1;if(operand->type==ERROR)return 0;- operand_type=extract_expresion_value_type(operand->value,translation_data);+ operand_type=extract_expresion_value_type(operand->value);if(operand->value->type==VALUE_FUNCTION_DESIGNATOR || operand->type==OP_ARR_SUBSCRIPT || operand->type==OP_DEREFERENCE){return 1;if(operand->type==ERROR)return 0;- operand_type=extract_expresion_value_type(operand->value,translation_data);+ operand_type=extract_expresion_value_type(operand->value);if(type_is_arithmetic(operand_type)){return 1;if(operand->type==ERROR)return 0;- operand_type=extract_expresion_value_type(operand->value,translation_data);+ operand_type=extract_expresion_value_type(operand->value);if(type_is_integer_type(operand_type)){return 1;if(operand->type==ERROR)return 0;- operand_type=extract_expresion_value_type(operand->value,translation_data);+ operand_type=extract_expresion_value_type(operand->value);if(type_is_scalar(operand_type)){return 1;push_translation_error("expected modifiable lvalue as operand to the ++/-- operator",translation_data);return 0;}- operand_type=extract_expresion_value_type(operand->value,translation_data);+ operand_type=extract_expresion_value_type(operand->value);if(type_is_real(operand_type) || type_is_pointer(operand_type)){return 1;F diff --git a/src/semantics/constraints/statement_constraints.c b/src/semantics/constraints/statement_constraints.c --- a/src/semantics/constraints/statement_constraints.c +++ b/src/semantics/constraints/statement_constraints.cstruct Expression_Value *value;value=((struct AST_Expression*)return_expression)->value;- expression_type=extract_expresion_value_type(value,translation_data);+ expression_type=extract_expresion_value_type(value);if(!types_are_identical(expression_type,return_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#include <value.h>- struct Expression_Value* get_expression_value_void()+ struct Expression_Value* get_expression_value_void(struct Translation_Data *translation_data){- struct Expression_Value *ret;- ret=wonky_malloc(sizeof(struct Expression_Value));+ struct Expression_Value_Void *ret;+ ret=wonky_malloc(sizeof(struct Expression_Value_Void));ret->type=VALUE_VOID;+ ret->void_type=(struct Type*)get_type_insecure(TS_VOID,TSIGN_NONE,TC_NONE,0,translation_data);- wonky_assert(is_valid_value(ret));- return ret;+ wonky_assert(is_valid_value((struct Expression_Value*)ret));+ return (struct Expression_Value*)ret;}struct Expression_Value* get_expression_value_lvalue(struct Object *object){return expression_value->type==VALUE_LVALUE && ((struct Expression_Value_LValue*)expression_value)->is_modifiable;}- struct Type* extract_expresion_value_type(struct Expression_Value *expression_value,struct Translation_Data *translation_data)+ struct Type* extract_expresion_value_type(struct Expression_Value *expression_value){switch(expression_value->type){case VALUE_CONSTANT:return ((struct Expression_Value_Constant*)expression_value)->constant->type;case VALUE_VOID:- return (struct Type*)get_type_insecure(TS_VOID,TSIGN_NONE,TC_NONE,0,translation_data);+ return ((struct Expression_Value_Void*)expression_value)->void_type;}wonky_assert(SHOULD_NOT_REACH_HERE);}F diff --git a/src/semantics/value/value.h b/src/semantics/value/value.h --- a/src/semantics/value/value.h +++ b/src/semantics/value/value.henum Expression_Value_Type type;struct Denoted_Function *function;};+ struct Expression_Value_Void+ {+ enum Expression_Value_Type type;+ struct Type *void_type;+ };- struct Expression_Value* get_expression_value_void();+ struct Expression_Value* get_expression_value_void(struct Translation_Data *translation_data);struct Expression_Value* get_expression_value_lvalue(struct Object *object);struct Expression_Value_Constant* get_expression_value_constant(struct Constant *constant);struct Expression_Value* get_expression_value_rvalue(struct Object *temp_object);struct Expression_Value* get_expression_value_function_designator(struct Denoted_Function *function);- struct Type* extract_expresion_value_type(struct Expression_Value *expression_value,struct Translation_Data *translation_data);+ struct Type* extract_expresion_value_type(struct Expression_Value *expression_value);size_t get_expression_value_size(struct Expression_Value *expression_value);char expression_value_is_modifiable(struct Expression_Value *expression_value);