WONKY



LOG | FILES | OVERVIEW


F diff --git a/.gitignore b/.gitignore --- a/.gitignore +++ b/.gitignore
Makefile
build
tags
+ cscope.out
F diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt
set(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.c
src/frontend/parse/parse_declaration.c
src/frontend/parse/parse_expression.c
src/frontend/parse/parse_statement.c
src/frontend/parse/parse_translation_unit.c
+ src/misc/gcc_string.c
src/misc/map.c
src/misc/queue.c
src/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.c
src/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.c
src/semantics/constraints/expression_constraints.c
- src/semantics/constraints/statement_constraints.c
src/semantics/constraints/linkage_constraints.c
- src/semantics/value/value.c
+ src/semantics/constraints/statement_constraints.c
src/semantics/identifiers/denoted.c
- src/semantics/identifiers/scope.c
src/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.c
function_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.h
void 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);
+
#endif
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
return (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.c
hold=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);
}else
F 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.c
return 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_C
F diff --git a/src/misc/queue.h b/src/misc/queue.h --- a/src/misc/queue.h +++ b/src/misc/queue.h
void* 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);
#endif
F 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.c
case 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.c
return 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 above
return 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.h
struct 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;
+ }
+
+ #endif
F 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);
+
+ #endif
F 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;
+
+
+
+ #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
ret->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.h
void 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);