F diff --git a/.gitignore b/.gitignore --- a/.gitignore +++ b/.gitignoreMakefilebuildtags+ cscope.outF diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txtset(SOURCES- src/wonky.c+ src/backend/print/print.c+ src/frontend/lex/automatas/chonky.c+ src/frontend/lex/automatas/chonky_jr.c+ src/frontend/lex/lexer.c+ src/frontend/lex/preprocessing.csrc/frontend/parse/parse_declaration.csrc/frontend/parse/parse_expression.csrc/frontend/parse/parse_statement.csrc/frontend/parse/parse_translation_unit.c+ src/misc/gcc_string.csrc/misc/map.csrc/misc/queue.csrc/misc/stack.c- src/misc/gcc_string.c- src/backend/print/print.c- src/frontend/lex/automatas/chonky.c- src/frontend/lex/automatas/chonky_jr.c- src/frontend/lex/lexer.c- src/frontend/lex/preprocessing.c+ src/program/gcc_arguments.c+ src/program/gcc_error.c+ src/program/program.csrc/semantics/ast.c- src/semantics/memory/location.c- src/semantics/memory/object.c- src/semantics/value/type.c- src/semantics/value/evaluation.c- src/semantics/value/constant.csrc/semantics/constraints/expression_constraints.c- src/semantics/constraints/statement_constraints.csrc/semantics/constraints/linkage_constraints.c- src/semantics/value/value.c+ src/semantics/constraints/statement_constraints.csrc/semantics/identifiers/denoted.c- src/semantics/identifiers/scope.csrc/semantics/identifiers/linkage.c- src/program/gcc_error.c- src/program/gcc_arguments.c- src/program/program.c+ src/semantics/identifiers/scope.c+ src/semantics/memory/location.c+ src/semantics/memory/object.c+ src/semantics/value/constant.c+ src/semantics/value/evaluation.c+ src/semantics/value/initialiser.c+ src/semantics/value/type.c+ src/semantics/value/value.c+ src/wonky.c)add_executable(wonky ${SOURCES})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.cfunction_type=(struct Type_Function*)((struct Denoted_Function*)hold)->type;- hold_function->function_scope=(struct Function_Scope*)get_function_scope(scope,(struct Denoted_Function*)hold);+ hold_function->function_scope=(struct Function_Scope*)get_function_scope(scope,hold_function);function_type->function_prototype_scope->parent=(struct Scope*)hold_function->function_scope;Queue_Push(where_to_push,get_type_definition_tree((struct Denoted_Type*)hold));}else if(hold->denotation==DT_Object){- struct AST_Expression *initializer=NULL;+ struct Initialiser *initializer=NULL;+ struct AST_Expression *to_be_initialised;+ struct Denoted_Object *real_type;++ real_type=(struct Denoted_Object*)hold;+ to_be_initialised=(struct AST_Expression*)get_designator_tree_from_denoted_object(real_type,translation_data);if(get_and_check(translation_data,KW_EQ))- initializer=(struct AST_Expression*)parse_initializer(translation_data,scope,(struct Denoted_Object*)hold);+ initializer=parse_initialiser(translation_data,scope,real_type->object->type);+Queue_Push(where_to_push,get_object_declaration_tree((struct Denoted_Object*)hold,initializer));+}else{/*TODO error*//*initializer:assignment-expression- { initializer , ... [,] }+ { initializer-list [,] }+ */++ struct Initialiser* parse_initialiser(struct Translation_Data *translation_data,struct Scope *scope,struct Type *type_of_initialised)+ {+ if(get_and_check(translation_data,KW_OPEN_CURLY))+ return parse_initialiser_list(translation_data,scope,type_of_initialised);+ else+ return parse_simple_initialiser(translation_data,scope,type_of_initialised);+ }++ /*+ initilizer-list:+ ( initialiser-list-component ',' )*++ */+ struct Initialiser* parse_initialiser_list(struct Translation_Data *translation_data,struct Scope *scope,struct Type *type_of_initialised)+ {+ if(type_is_an_array(type_of_initialised))+ return parse_initialiser_list_for_array(translation_data,scope,(struct Type_Array*)type_of_initialised);+ else if(type_is_struct_union(type_of_initialised))+ return parse_initialiser_list_for_struct_union(translation_data,scope,(struct Type_Struct_Union*)type_of_initialised);+ else+ {+ push_translation_error("expected aggregate type in compound initialisation, got %T instead",translation_data,type_of_initialised);+ return get_initialiser_error(NULL);+ }+ }++ /*+ initilizer-list:+ ( initialiser-list-component ',' )*++ */+ struct Initialiser* parse_initialiser_list_for_struct_union(struct Translation_Data *translation_data,struct Scope *scope,struct Type_Struct_Union *type_of_initialised)+ {+ struct Queue_Node *current_object;+ struct Initialiser *current_initialiser;+ struct Queue *components;++ current_object=type_of_initialised->struct_union->members->first;++ components=malloc(sizeof(struct Queue));+ Queue_Init(components);++ do{+ current_initialiser=parse_initialiser_list_component(translation_data,scope,(struct Type*)type_of_initialised);+ if(current_initialiser->kind==INITIALISER_ERROR)+ {+ return current_initialiser;+ }else if(current_initialiser->kind!=INITIALISER_DENOTED)+ {+ Queue_Push(+ components,+ get_denoted_initialiser((struct Denoted_Object*)current_object->data,current_initialiser,translation_data)+ );+ current_object=current_object->prev;+ }else+ {+ for(+ current_object=type_of_initialised->struct_union->members->first;+ current_object!=NULL && current_object->data!=((struct Initialiser_Denoted*)current_initialiser)->to_be_initialised;+ current_object=current_object->prev+ );+ current_object=current_object->prev;+ Queue_Push(components,current_initialiser);+++ }+ }while(get_and_check(translation_data,KW_COMMA));++ return get_compound_initialiser((struct Type*)type_of_initialised,components,translation_data);+ }++ /*+ initilizer-list:+ ( initialiser-list-component ',' )*++ */+ struct Initialiser* parse_initialiser_list_for_array(struct Translation_Data *translation_data,struct Scope *scope,struct Type_Array *type_of_initialised)+ {+ struct Queue *components;+ size_t current_object;+ struct Initialiser *current_initialiser;++ components=malloc(sizeof(struct Queue));+ Queue_Init(components);++ do{+ current_initialiser=parse_initialiser_list_component(translation_data,scope,(struct Type*)type_of_initialised);+ if(current_initialiser->kind==INITIALISER_ERROR)+ {+ return current_initialiser;+ }else if(current_initialiser->kind!=INITIALISER_INDEXED)+ {+ Queue_Push(+ components,+ get_indexed_initialiser(type_of_initialised->is_array_of,current_object,current_initialiser,translation_data)+ );+ ++current_object;+ }else+ {+ Queue_Push(components,current_initialiser);+ current_object=((struct Initialiser_Indexed*)current_initialiser)->index+1;+ }+ }while(get_and_check(translation_data,KW_COMMA));++ return get_compound_initialiser((struct Type*)type_of_initialised,components,translation_data);+ }++ /*+ assignment-expression+ */+ struct Initialiser* parse_simple_initialiser(struct Translation_Data *translation_data,struct Scope *scope,struct Type *type_of_initialised)+ {+ struct AST_Expression *assignment_expression;++ assignment_expression=parse_assignment_expression(translation_data,scope);++ return get_initialiser_expression(assignment_expression,type_of_initialised,translation_data);+ }++ /*+ initialiser-list-component:+ [ designation ] initialiser+ */+ struct Initialiser* parse_initialiser_list_component(struct Translation_Data *translation_data,struct Scope *scope,struct Type *type_of_initialised)+ {+ if(check(translation_data,KW_DOT,0) || check(translation_data,KW_OPEN_SQUARE,0))+ return parse_designation(translation_data,scope,type_of_initialised);+ else+ return parse_initialiser(translation_data,scope,type_of_initialised);+ }++ /*+ designation:+ designator-list '='+ designator-list:+ ( designator )++ designator:+ '[' constant-expression ']'+ '.' identifier*/- struct AST* parse_initializer(struct Translation_Data *translation_data,struct Scope *scope,struct Denoted_Object *base)+ /*TODO: make this iterative XD*/+ struct Initialiser* parse_designation(struct Translation_Data *translation_data,struct Scope *scope,struct Type *type_of_initialised)+ {+ if(get_and_check(translation_data,KW_OPEN_SQUARE))+ parse_indexed_initialiser(translation_data,scope,type_of_initialised);+ else if(get_and_check(translation_data,KW_DOT))+ parse_member_initialiser(translation_data,scope,type_of_initialised);+ else if(get_and_check(translation_data,KW_EQ))+ return parse_initialiser(translation_data,scope,type_of_initialised);+ else+ {+ push_translation_error("expected '=' in initialiser designation",translation_data);+ return get_initialiser_error(NULL);+ }++ }+ struct Initialiser* parse_indexed_initialiser(struct Translation_Data *translation_data,struct Scope *scope,struct Type *type_of_initialised){- /*TODO add compound initialiser*/- return (struct AST*)parse_assignment_expression(translation_data,scope);+ struct AST_Expression *index_expression;+ struct Type_Array *real_type;++ if(!type_is_an_array(type_of_initialised))+ {+ push_translation_error("expected array type in indexed initialiser, instead got a %T",translation_data,type_of_initialised);+ return get_initialiser_error(NULL);+ }++ real_type=(struct Type_Array*)type_of_initialised;+ index_expression=(struct AST_Expression*)parse_expression(translation_data,scope);++ if(get_and_check(translation_data,KW_CLOSE_CURLY))+ {+ size_t eval;+ eval=evaluate_const_expression_integer((struct AST*)index_expression,translation_data);+ return get_indexed_initialiser(real_type->is_array_of,eval,parse_designation(translation_data,scope,real_type->is_array_of),translation_data);+ }else+ {+ size_t eval;+ eval=evaluate_const_expression_integer((struct AST*)index_expression,translation_data);+ return get_initialiser_error(+ get_indexed_initialiser(real_type->is_array_of,eval,parse_designation(translation_data,scope,real_type->is_array_of),translation_data)+ );+ }+ }+ struct Initialiser* parse_member_initialiser(struct Translation_Data *translation_data,struct Scope *scope,struct Type *type_of_initialised)+ {+ struct Denoted_Object *member;+ struct Type_Struct_Union *real_type;+ struct token *id;++ if(!type_is_struct_union(type_of_initialised))+ {+ push_translation_error("expected struct/union type in initialiser, got %T instead",translation_data,type_of_initialised);+ return get_initialiser_error(NULL);+ }+ if(!check(translation_data,KW_ID,0))+ {+ push_translation_error("expected id in the initialisation of type %T",translation_data,type_of_initialised);+ return get_initialiser_error(NULL);+ }++ id=Queue_Pop(translation_data->tokens);+ real_type=(struct Type_Struct_Union*)type_of_initialised;+ member=check_struct_union_member(real_type->struct_union->inner_namespace,id);++ if(member==NULL)+ {+ push_translation_error("%t is not a member of %T",translation_data,id,type_of_initialised);+ push_translation_note("in initialiser",translation_data);+ return get_initialiser_error(NULL);+ }++ return get_denoted_initialiser(member,parse_initialiser(translation_data,scope,member->object->type),translation_data);}const const const const const const const const const const const const const const const const const const const const const const const char const const const constant;F diff --git a/src/frontend/parse/parse_declaration.h b/src/frontend/parse/parse_declaration.h --- a/src/frontend/parse/parse_declaration.h +++ b/src/frontend/parse/parse_declaration.hvoid parse_paramenter_list(struct Translation_Data *translation_data,struct Normal_Scope *function_prototype_scope,struct Queue *parameters);struct Type* parse_type_name(struct Translation_Data *translation_data,struct Scope *scope);struct Type* parse_abstract_declarator(struct Translation_Data *translation_data,struct Scope *scope,struct Denotation_Prototype *prototype);- struct AST* parse_initializer(struct Translation_Data *translation_data,struct Scope *scope,struct Denoted_Object *base);+++ struct Initialiser* parse_initialiser(struct Translation_Data *translation_data,struct Scope *scope,struct Type *type_of_initialised);+ struct Initialiser* parse_initialiser_list(struct Translation_Data *translation_data,struct Scope *scope,struct Type *type_of_initialised);+ struct Initialiser* parse_initialiser_list_for_struct_union(struct Translation_Data *translation_data,struct Scope *scope,struct Type_Struct_Union *type_of_initialised);+ struct Initialiser* parse_initialiser_list_for_array(struct Translation_Data *translation_data,struct Scope *scope,struct Type_Array *type_of_initialised);+ struct Initialiser* parse_simple_initialiser(struct Translation_Data *translation_data,struct Scope *scope,struct Type *type_of_initialised);+ struct Initialiser* parse_initialiser_list_component(struct Translation_Data *translation_data,struct Scope *scope,struct Type *type_of_initialised);+ struct Initialiser* parse_designation(struct Translation_Data *translation_data,struct Scope *scope,struct Type *type_of_initialised);+ struct Initialiser* parse_indexed_initialiser(struct Translation_Data *translation_data,struct Scope *scope,struct Type *type_of_initialised);+ struct Initialiser* parse_member_initialiser(struct Translation_Data *translation_data,struct Scope *scope,struct Type *type_of_initialised);+#endifF 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.creturn (struct AST_Expression*)get_error_tree(NULL);}hold_token=Queue_Pop(translation_data->tokens);- switch(hold_token->type)+ switch(hold_token->type) /*the token is not freed so there is a memory leak here*/{case KW_STRING:case KW_WIDE_STRING:struct AST_Expression* parse_cast_expression(struct Translation_Data *translation_data,struct Scope *scope){struct AST_Unary_Expression *ret;- if(get_and_check(translation_data,KW_OPEN_NORMAL))+ if(check(translation_data,KW_OPEN_NORMAL,0) && is_type(translation_data,scope,1)){- if(is_type(translation_data,scope))- {- struct Type *cast_type;- struct AST_Expression *operand;-- cast_type=parse_type_name(translation_data,scope);- if(get_and_check(translation_data,KW_CLOSE_NORMAL))- {- operand=parse_cast_expression(translation_data,scope);- return (struct AST_Expression*)get_cast_expression_tree(operand,cast_type,translation_data);- }else- {- push_translation_error("expected ')' here",translation_data);- return (struct AST_Expression*)get_error_tree((struct AST*)operand);-- }+ struct Type *cast_type;+ struct AST_Expression *operand;+ cast_type=parse_type_name(translation_data,scope);+ if(get_and_check(translation_data,KW_CLOSE_NORMAL))+ {+ operand=parse_cast_expression(translation_data,scope);+ return (struct AST_Expression*)get_cast_expression_tree(operand,cast_type,translation_data);}else{- ret=(struct AST_Unary_Expression*)parse_expression(translation_data,scope);- if(get_and_check(translation_data,KW_CLOSE_NORMAL))- {- return (struct AST_Expression*)ret;- }else- {- push_translation_error("expected ')' here",translation_data);- return (struct AST_Expression*)get_error_tree((struct AST*)ret);- }+ push_translation_error("expected ')' here",translation_data);+ return (struct AST_Expression*)get_error_tree((struct AST*)operand);}}else{-return parse_unary_expression(translation_data,scope);}}F diff --git a/src/frontend/parse/parse_statement.c b/src/frontend/parse/parse_statement.c --- a/src/frontend/parse/parse_statement.c +++ b/src/frontend/parse/parse_statement.chold=get_compound_statement_tree(scope);while(!get_and_check(translation_data,KW_CLOSE_CURLY) && !has_no_tokens(translation_data)){- if(is_type(translation_data,hold->scope))+ if(is_type(translation_data,hold->scope,0)){parse_declaration(translation_data,hold->scope,&hold->components,0);}elseF diff --git a/src/frontend/parse/parse_translation_unit.c b/src/frontend/parse/parse_translation_unit.c --- a/src/frontend/parse/parse_translation_unit.c +++ b/src/frontend/parse/parse_translation_unit.c{loop_preventer=translation_data->tokens->size;- if(is_type(translation_data,hold->file_scope) || kw_get(translation_data)==KW_ID)+ if(is_type(translation_data,hold->file_scope,0) || kw_get(translation_data)==KW_ID){parse_declaration(translation_data,hold->file_scope,hold->components,1);if(has_new_errors(translation_data))F diff --git a/src/misc/queue.c b/src/misc/queue.c --- a/src/misc/queue.c +++ b/src/misc/queue.creturn ret;}+ void *Queue_At(struct Queue *q,size_t where)+ {+ size_t i;+ struct Queue_Node *it;++ if(q->size<=where)+ return NULL;++ for(i=0,it=q->first; i<where ; ++i,it=it->prev)+ {+ assert(it!=NULL);+ }+ return it->data;+ }#endif //#ifndef GQUEUE_CF diff --git a/src/misc/queue.h b/src/misc/queue.h --- a/src/misc/queue.h +++ b/src/misc/queue.hvoid* Queue_Pop(Queue *q);void Queue_Append(struct Queue *lead,struct Queue *follower);void Queue_Destroy(Queue *q);+ void *Queue_At(struct Queue *q,size_t where);#endifF diff --git a/src/program/gcc_error.c b/src/program/gcc_error.c --- a/src/program/gcc_error.c +++ b/src/program/gcc_error.ccase TS_CHAR:ret=gstr_append_and_consume(gstr_to_heap("char"),ret);break;+ case TS_STRUCT:+ ret=gstr_append_and_consume(gstr_to_heap("struct "),ret);+ goto hack2;+ case TS_UNION:+ ret=gstr_append_and_consume(gstr_to_heap("struct "),ret);+ hack2:+ {+ struct token *id;+ id=((struct Type_Struct_Union*)current)->struct_union->id;++ ret=gstr_append_and_consume(ret,gstr_dup(id->data,id->data+id->data_size,id->data_size+1));+ }+ break;default:ret=gstr_append_and_consume(gstr_to_heap("type"),ret);}F diff --git a/src/semantics/ast.c b/src/semantics/ast.c --- a/src/semantics/ast.c +++ b/src/semantics/ast.c}struct AST_Binary_Expression* get_struct_union_member_tree(struct AST_Expression *left,struct token *id,struct Translation_Data *translation_data){-- /*TODO make the macros*/- struct Denoted_Object *hold_denoted_object;- struct Expression_Value_LValue *left_lvalue;- struct Struct_Union *struct_union;- struct Type_Struct_Union *left_type;-struct AST_Binary_Expression *ret;+ struct Type_Struct_Union *left_type;- assert(left->type!=OP_MEMBER);- left_lvalue=(struct Expression_Value_LValue*)left->value;- if(left_lvalue->type!=VALUE_LVALUE)+ if(!constraint_check_struct_union_member_expression(left,id,translation_data)){- struct AST_Expression *right;-- push_translation_error("nonlvalue on left side of . operator",translation_data);-- ret->right=(struct AST_Expression*)get_designator_tree(id,(struct Scope*)struct_union->inner_namespace,translation_data);- return (struct AST_Binary_Expression*) get_error_tree((struct AST*)get_binary_expression_tree(left,right,NULL,OP_MEMBER));+ free(id);/*welp*/+ return (struct AST_Binary_Expression*)get_error_tree((struct AST*)left);}- left_type=(struct Type_Struct_Union*)left_lvalue->object->type;+ left_type=(struct Type_Struct_Union*)extract_expresion_value_type(left->value,translation_data);- if(left_type->specifier!=TS_STRUCT && left_type->specifier!=TS_UNION)- {- struct AST_Expression *right;+ assert(left_type->specifier==TS_STRUCT || left_type->specifier==TS_UNION);- push_translation_error("expected struct or union type",translation_data);- push_translation_note("instead got %T",translation_data,left_type);-- ret->right=(struct AST_Expression*)get_designator_tree(id,(struct Scope*)struct_union->inner_namespace,translation_data);- return (struct AST_Binary_Expression*) get_error_tree((struct AST*)get_binary_expression_tree(left,right,NULL,OP_MEMBER));- }-- struct_union=left_type->struct_union;--ret=malloc(sizeof(struct AST_Binary_Expression));ret->type=OP_MEMBER;- ret->left=left;- /*TODO could optimise this*/- ret->right=(struct AST_Expression*)get_designator_tree(id,(struct Scope*)struct_union->inner_namespace,translation_data);+ ret->right=(struct AST_Expression*)get_struct_union_member_tree_designator(id,left_type->struct_union->inner_namespace,translation_data);+ ret->left=left;ret->value=ret->right->value; /*BEWARE*/+- return ret;+ if(ret->right->type==ERROR)+ return (struct AST_Binary_Expression *)get_error_tree((struct AST*)ret);+ else+ return ret;}/*TODO beware const type qualifier*/{struct AST_Unary_Expression *ret;struct Type *operand_type;- if(constraint_check_indirection_expression(operand,translation_data))+ if(constraint_check_address_expression(operand,translation_data)){ret=malloc(sizeof(struct AST_Unary_Expression));ret->type=OP_ADDR_OF;struct Denoted *hold_denoted;-ret=malloc(sizeof(struct AST_Designator));ret->type=OP_DESIGNATOR;return ret;}+ struct AST_Designator* get_designator_tree_from_denoted_object(struct Denoted_Object *object,struct Translation_Data *translation_data)+ {+ struct AST_Designator *ret;+ ret=malloc(sizeof(struct AST_Designator));+ ret->type=OP_DESIGNATOR;+ ret->value=get_expression_value_lvalue(object->object);+ ret->id=object->id;+++ return ret;+ }+ struct AST_Designator* get_struct_union_member_tree_designator(struct token *id,struct Normal_Scope *inner_scope,struct Translation_Data *translation_data)+ {+ struct AST_Designator *ret;+ struct Denoted *hold_denoted;+++ ret=malloc(sizeof(struct AST_Designator));+ ret->type=OP_DESIGNATOR;+++ hold_denoted=check_struct_union_member(inner_scope,id);++++ if(hold_denoted==NULL)+ {+ push_translation_error("%t is not a member of the structure",translation_data,id);+ free(ret);+ return (struct AST_Designator*)get_error_tree(NULL);+ }else+ {+ ret->value=get_expression_value_lvalue( ((struct Denoted_Object*)hold_denoted)->object );+ }++ ret->id=id;+ return ret;+ }struct AST_Case_Statement* get_case_statement_tree(struct AST *statement,struct AST_Expression *control,struct AST_Switch_Statement *parent,struct Translation_Data *translation_data){return ret;}- struct AST_Object_Declaration* get_object_declaration_tree(struct Denoted_Object *object,struct AST_Expression *initialiser)+ struct AST_Object_Declaration* get_object_declaration_tree(struct Denoted_Object *object,struct Initialiser *initialiser){struct AST_Object_Declaration *ret;ret=malloc(sizeof(struct AST_Object_Declaration));F diff --git a/src/semantics/ast.h b/src/semantics/ast.h --- a/src/semantics/ast.h +++ b/src/semantics/ast.h#include <linkage.h>#include <value.h>#include <constraints.h>+ #include <initialiser.h>};-struct AST_Type_Definition{enum AST_Type type;{enum AST_Type type;struct Denoted_Object *object;- struct AST_Expression *initializer;+ struct Initialiser *initializer;};struct AST_Function_Definition{struct AST_Constant* get_constant_tree(struct Expression_Value *value);struct AST_String_Literal* get_string_literal_tree(struct Expression_Value *value);- struct AST_Designator* get_designator_tree(struct token *id,struct Scope* scope,struct Translation_Data *translation_data);+ struct AST_Designator* get_designator_tree(struct token *id,struct Scope *scope,struct Translation_Data *translation_data);+ struct AST_Designator* get_designator_tree_from_denoted_object(struct Denoted_Object *object,struct Translation_Data *translation_data);+ struct AST_Designator* get_struct_union_member_tree_designator(struct token *id,struct Normal_Scope *inner_scope,struct Translation_Data *translation_data);struct AST_Goto_Statement* get_goto_statement_tree(struct token *label,struct Scope *scope,struct Translation_Data *translation_data);struct AST* get_nop_tree();struct AST_Type_Definition* get_type_definition_tree(struct Denoted_Type *definition);- struct AST_Object_Declaration* get_object_declaration_tree(struct Denoted_Object *object,struct AST_Expression *initialiser);+ struct AST_Object_Declaration* get_object_declaration_tree(struct Denoted_Object *object,struct Initialiser *initialiser);struct AST_Function_Declaration* get_function_declaration_tree(struct Scope *scope,struct Denoted_Function *function);struct AST_Function_Definition* get_function_definition_tree(struct Scope *scope,struct Denoted_Function *function,struct AST_Compound_Statement *function_body,struct Translation_Data *translation_data);struct AST_Translation_Unit* get_translation_unit_tree();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.creturn 0;left_type=extract_expresion_value_type(left->value,translation_data);- return type_is_struct_union(left_type);++ if(!type_is_struct_union(left_type))+ {+ push_translation_error("trying get struct/union member of non a %T type",translation_data,left_type);+ }else+ {+ return 1;+ }}/*see abovereturn 1;}else{- push_translation_error("needs pointer type",translation_data);+ push_translation_error("needs pointer type got %T instead",translation_data,operand_type);return 0;}}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 *hold;hold=NULL;- while(current!=NULL && hold==NULL && current->type!=FUNCTION_SCOPE)+ while(current!=NULL && hold==NULL){- hold=Map_Check(&((struct Normal_Scope*)current)->tags,id->data,id->data_size);+ switch(current->type)+ {+ case FILE_SCOPE:+ case BLOCK_SCOPE:+ case FUNCTION_PROTOTYPE_SCOPE:+ hold=Map_Check(&((struct Normal_Scope*)current)->tags,id->data,id->data_size);++ }current=current->parent;}return hold;hold=NULL;while(current!=NULL && hold==NULL){- hold=Map_Check(&((struct Normal_Scope*)current)->ordinary,id->data,id->data_size);+ switch(current->type)+ {+ case FILE_SCOPE:+ case BLOCK_SCOPE:+ case FUNCTION_PROTOTYPE_SCOPE:+ hold=Map_Check(&((struct Normal_Scope*)current)->ordinary,id->data,id->data_size);++ }current=current->parent;}return hold;}+ void* check_struct_union_member(struct Normal_Scope *inner,struct token *id)+ {+ return Map_Check(&inner->ordinary,id->data,id->data_size);+ }void Scope_Push(struct Scope *scope,struct Denoted *declarator,struct Translation_Data *translation_data){F diff --git a/src/semantics/identifiers/scope.h b/src/semantics/identifiers/scope.h --- a/src/semantics/identifiers/scope.h +++ b/src/semantics/identifiers/scope.hstruct Denoted_Statement* check_label(struct Scope *current,struct token *id);struct Denoted* check_tag(struct Scope *current,struct token *id);void* check_ordinary(struct Scope *current,struct token *id);+ void* check_struct_union_member(struct Normal_Scope *inner,struct token *id);/*F diff --git a/src/semantics/value/initialiser.c b/src/semantics/value/initialiser.c new file mode 100644 --- /dev/null +++ b/src/semantics/value/initialiser.c+ #ifndef WONKY_INITIALISER_C+ #define WONKY_INITIALISER_C WONKY_INITIALISER_C+ #include <initialiser.h>++++ struct Initialiser* get_denoted_initialiser(struct Denoted_Object *to_be_initialised,struct Initialiser *initialiser,struct Translation_Data *translation_data)+ {+ struct Initialiser_Denoted *ret;++ ret=malloc(sizeof(struct Initialiser_Denoted));+ ret->kind=INITIALISER_DENOTED;+ ret->to_be_initialised=to_be_initialised;+ ret->initialiser=initialiser;++ return (struct Initialiser*)ret;+ }+ struct Initialiser* get_indexed_initialiser(struct Type *type,size_t index,struct Initialiser *initialiser,struct Translation_Data *translation_data)+ {+ struct Initialiser_Indexed *ret;++ ret=malloc(sizeof(struct Initialiser_Indexed));+ ret->kind=INITIALISER_INDEXED;+ ret->type=type;+ ret->index=index;+ ret->initialiser=initialiser;++ return (struct Initialiser*)ret;++ }+ struct Initialiser* get_initialiser_expression(struct AST_Expression *expression,struct Type* type_of_initialised,struct Translation_Data *translation_data)+ {+ struct Initialiser_Expression *ret;++ ret=malloc(sizeof(struct Initialiser_Expression));+ ret->kind=INITIALISER_EXPRESSION;+ ret->expression=expression;++ return (struct Initialiser*)ret;+ }+ struct Initialiser* get_compound_initialiser(struct Type *type,struct Queue *components,struct Translation_Data *translation_data)+ {+ struct Initialiser_Compound *ret;+ size_t i;++ ret=malloc(sizeof(struct Initialiser_Compound));+ ret->kind=INITIALISER_COMPOUND;+ ret->type=type;+ ret->number_of_components=components->size;++ ret->components=malloc(sizeof(struct Initialiser**)*components->size);++ for(i=0;components->size>0;++i)+ ret->components[i]=Queue_Pop(components);++ free(components);/*BEWARE*/++ return (struct Initialiser*)ret;+ }+ struct Initialiser* get_initialiser_error(struct Initialiser *error)+ {+ struct Initialiser_Error *ret;++ ret=malloc(sizeof(struct Initialiser_Error));+ ret->kind=INITIALISER_ERROR;+ ret->error=error;++ return (struct Initialiser*)ret;+ }++ #endifF diff --git a/src/semantics/value/initialiser.h b/src/semantics/value/initialiser.h new file mode 100644 --- /dev/null +++ b/src/semantics/value/initialiser.h+ #ifndef WONKY_INITIALISER_H+ #define WONKY_INITIALISER_H WONKY_INITIALISER_H+ #include <initialiser.hh>+ #include <ast.h>+ #include <denoted.h>+ #include <queue.h>+ #include <type.h>++ struct Initialiser+ {+ enum Initialiser_Type kind;+ };+ struct Initialiser_Denoted+ {+ enum Initialiser_Type kind;++ struct Denoted_Object *to_be_initialised;+ struct Initialiser *initialiser;+ };+ struct Initialiser_Indexed+ {+ enum Initialiser_Type kind;+ struct Type *type;++ size_t index;+ struct Initialiser *initialiser;+ };+ struct Initialiser_Expression+ {+ enum Initialiser_Type kind;++ struct AST_Expression *expression;+ };+ struct Initialiser_Compound+ {+ enum Initialiser_Type kind;+ struct Type *type;++ size_t number_of_components;+ struct Initialiser **components;+ };+ struct Initialiser_Error+ {+ enum Initialiser_Type kind;++ struct Initialiser *error;+ };++ struct Initialiser* get_denoted_initialiser(struct Denoted_Object *to_be_initialised,struct Initialiser *initialiser,struct Translation_Data *translation_data);+ struct Initialiser* get_indexed_initialiser(struct Type *type,size_t index,struct Initialiser *initialiser,struct Translation_Data *translation_data);+ struct Initialiser* get_initialiser_expression(struct AST_Expression *expression,struct Type* type_of_initialised,struct Translation_Data *translation_data);+ struct Initialiser* get_compound_initialiser(struct Type *type,struct Queue *components,struct Translation_Data *translation_data);+ struct Initialiser* get_initialiser_error(struct Initialiser *error);++ #endifF diff --git a/src/semantics/value/initialiser.hh b/src/semantics/value/initialiser.hh new file mode 100644 --- /dev/null +++ b/src/semantics/value/initialiser.hh+ #ifndef WONKY_INITIALISER_HH+ #define WONKY_INITIALISER_HH WONKY_INITIALISER_HH++ enum Initialiser_Type { INITIALISER_DENOTED , INITIALISER_INDEXED , INITIALISER_COMPOUND , INITIALISER_EXPRESSION , INITIALISER_ERROR };++ struct Initialiser;+ struct Initialiser_Denoted;+ struct Initialiser_Indexed;+ struct Initialiser_Expression;+ struct Initialiser_Compound;+ struct Initialiser_Error;++++ #endifF 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.cret->members=malloc(sizeof(struct Queue));Queue_Init(ret->members);- ret->inner_namespace=(struct Normal_Scope*)get_normal_scope(scope,BLOCK_SCOPE);+ ret->inner_namespace=(struct Normal_Scope*)get_normal_scope(NULL,BLOCK_SCOPE);ret->is_finished=0;ret->has_constant_member=0;ret->id=id;ret=(struct Type_Function*)type_check_and_push((struct Type*)ret,return_type->node,sizeof(struct Type_Function));}- _Bool is_type(struct Translation_Data *translation_data,struct Scope *scope)+ _Bool is_type(struct Translation_Data *translation_data,struct Scope *scope,size_t look_ahead){struct token *hold;struct Denoted *thing;- hold=translation_data->tokens->first->data;+ hold=Queue_At(translation_data->tokens,look_ahead);switch(hold->type){{return 0;}+ _Bool type_is_an_array(struct Type *type)+ {+ return type->specifier==TS_ARRAY;+ }_Bool type_is_constant(struct Type *type){switch(type->specifier)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.hvoid delete_struct_union(struct Struct_Union *su);void delete_type(void *type);- _Bool is_type(struct Translation_Data *translation_data,struct Scope *scope);+ _Bool is_type(struct Translation_Data *translation_data,struct Scope *scope,size_t look_ahead);size_t get_type_size(struct Type *type);_Bool type_is_floating(struct Type *type);_Bool type_is_derivative(struct Type *type);_Bool type_is_a_variable_length_array(struct Type *type);+ _Bool type_is_an_array(struct Type *type);/*these return 0 if constant/volatile-ness make no sense for the type*/_Bool type_is_constant(struct Type *type);