WONKY



LOG | FILES | OVERVIEW


F diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt
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/identifiers/denoted.c
src/semantics/identifiers/scope.c
F diff --git a/src/backend/print/print.c b/src/backend/print/print.c --- a/src/backend/print/print.c +++ b/src/backend/print/print.c
void print_token(FILE *out,struct token *token)
{
size_t i;
- // fprintf(out,"[");
if(token==NULL)return;
for(i=0;i<token->data_size;++i)
{
fprintf(out,"%c",token->data[i]);
}
- // fprintf(out,"]");
}
char print_tokens_of_program(FILE *out,char **base_source_names)
{
switch(op)
{
- case OP_COMMA:
- fprintf(out,",");break;
- case OP_ADDITION:
- fprintf(out,"+");break;
- case OP_SUBTRACTION:
- fprintf(out,"-");break;
- case OP_MUL:
- fprintf(out,"*");break;
- case OP_DIV:
- fprintf(out,"/");break;
- case OP_REMAINDER:
- fprintf(out,"%");break;
- case OP_COND:
- fprintf(out,"CONDITIONAL");break;
- case OP_FUNCTION:
- fprintf(out,"FUNCTION_CALL");break;
- case OP_ASSIGN:
- fprintf(out,"=");break;
- case OP_ADD_ASSIGN:
- fprintf(out,"+=");break;
- case OP_SUBTRACT_ASSIGN:
- fprintf(out,"-=");break;
- case OP_MULTIPLY_ASSIGN:
- fprintf(out,"*=");break;
- case OP_REMAINDER_ASSIGN:
- fprintf(out,"%=");break;
- case OP_DIV_ASSIGN:
- fprintf(out,"/=");break;
- case OP_SHIFT_LEFT_ASSIGN:
- fprintf(out,">>=");break;
- case OP_SHIFT_RIGHT_ASSIGN:
- fprintf(out,"<<=");break;
- case OP_AND_ASSIGN:
- fprintf(out,"&=");break;
- case OP_XOR_ASSIGN:
- fprintf(out,"^=");break;
- case OP_PIPE_ASSIGN:
- fprintf(out,"|=");break;
- case OP_NOP:
- fprintf(out,"NOP");break;
- case OP_LOGICAL_OR:
- fprintf(out,"||");break;
- case OP_LOGICAL_AND:
- fprintf(out,"&&");break;
- case OP_LOGICAL_NOT:
- fprintf(out,"!");break;
- case OP_BITWISE_OR:
- fprintf(out,"|");break;
- case OP_BITWISE_AND:
- fprintf(out,"&");break;
- case OP_BITWISE_XOR:
- fprintf(out,"^");break;
- case OP_BITWISE_NOT:
- fprintf(out,"~");break;
- case OP_ADDR_OF:
- fprintf(out,"&");break;
- case OP_DEREFERENCE:
- fprintf(out,"*");break;
- case OP_MEMBER_TROUGH_PTR:
- fprintf(out,"->");break;
- case OP_MEMBER:
- fprintf(out,".");break;
- case OP_ARR_SUBSCRIPT:
- fprintf(out,"ARR_SUBSCRIPT");break;
- case OP_POSTFIX_INC:
- fprintf(out,"++");break;
- case OP_POSTFIX_DEC:
- fprintf(out,"--");break;
- case OP_PREFIX_INC:
- fprintf(out,"++");break;
- case OP_PREFIX_DEC:
- fprintf(out,"--");break;
- case OP_UNARY_PLUS:
- fprintf(out,"+");break;
- case OP_UNARY_MINUS:
- fprintf(out,"-");break;
- case OP_CAST:
- fprintf(out,"CAST");break;
- case OP_SIZEOF:
- fprintf(out,"sizeof");break;
- case OP_SHIFT_LEFT:
- fprintf(out,"<<");break;
- case OP_SHIFT_RIGHT:
- fprintf(out,">>");break;
- case OP_LESS_EQ:
- fprintf(out,"<=");break;
- case OP_GREATER_EQ:
- fprintf(out,">=");break;
- case OP_LESS:
- fprintf(out,"<");break;
- case OP_GREATER:
- fprintf(out,">");break;
- case OP_EQUAL:
- fprintf(out,"==");break;
- case OP_NOT_EQUAL:
- fprintf(out,"!=");break;
- case OP_CONSTANT:
- fprintf(out,"CONSTANT");break;
- case OP_STRING_LITERAL:
- fprintf(out,"STRING_LITERAL");break;
- case ST_COMPOUND:
- fprintf(out,"COMPOUND");break;
- case ST_EXPRESSION:
- fprintf(out,"EXPRESSION");break;
- case ST_SWITCH:
- fprintf(out,"switch");break;
- case ST_IF:
- fprintf(out,"if");break;
- case ST_WHILE:
- fprintf(out,"while");break;
- case ST_DO_WHILE:
- fprintf(out,"do_while");break;
- case ST_GOTO:
- fprintf(out,"goto");break;
- case ST_LABEL:
- fprintf(out,"LABEL");break;
- case ST_CASE:
- fprintf(out,"case");break;
- case ST_DEFAULT:
- fprintf(out,"default");break;
- case ST_CONTINUE:
- fprintf(out,"continue");break;
- case ST_BREAK:
- fprintf(out,"break");break;
- case ST_RETURN:
- fprintf(out,"return");break;
- case ST_FOR:
- fprintf(out,"for");break;
-
- /*TODO obj dec obj def func decl*/
- case ST_FUNCTION_DEFINITION:
- fprintf(out,"FUNCTION_DEFINITION");break;
- case TRANSLATION_UNIT:
- fprintf(out,"TRANSLATION_UNIT");break;
- case ERROR:
- fprintf(out,"ERROR");break;
- default:
- fprintf(out,"NOT_POSSIBLE");break;
+ case OP_COMMA:
+ fprintf(out,",");break;
+ case OP_ADDITION:
+ fprintf(out,"+");break;
+ case OP_SUBTRACTION:
+ fprintf(out,"-");break;
+ case OP_MUL:
+ fprintf(out,"*");break;
+ case OP_DIV:
+ fprintf(out,"/");break;
+ case OP_REMAINDER:
+ fprintf(out,"%");break;
+ case OP_COND:
+ fprintf(out,"CONDITIONAL");break;
+ case OP_FUNCTION:
+ fprintf(out,"FUNCTION_CALL");break;
+ case OP_ASSIGN:
+ fprintf(out,"=");break;
+ case OP_ADD_ASSIGN:
+ fprintf(out,"+=");break;
+ case OP_SUBTRACT_ASSIGN:
+ fprintf(out,"-=");break;
+ case OP_MULTIPLY_ASSIGN:
+ fprintf(out,"*=");break;
+ case OP_REMAINDER_ASSIGN:
+ fprintf(out,"%=");break;
+ case OP_DIV_ASSIGN:
+ fprintf(out,"/=");break;
+ case OP_SHIFT_LEFT_ASSIGN:
+ fprintf(out,">>=");break;
+ case OP_SHIFT_RIGHT_ASSIGN:
+ fprintf(out,"<<=");break;
+ case OP_AND_ASSIGN:
+ fprintf(out,"&=");break;
+ case OP_XOR_ASSIGN:
+ fprintf(out,"^=");break;
+ case OP_PIPE_ASSIGN:
+ fprintf(out,"|=");break;
+ case OP_NOP:
+ fprintf(out,"NOP");break;
+ case OP_LOGICAL_OR:
+ fprintf(out,"||");break;
+ case OP_LOGICAL_AND:
+ fprintf(out,"&&");break;
+ case OP_LOGICAL_NOT:
+ fprintf(out,"!");break;
+ case OP_BITWISE_OR:
+ fprintf(out,"|");break;
+ case OP_BITWISE_AND:
+ fprintf(out,"&");break;
+ case OP_BITWISE_XOR:
+ fprintf(out,"^");break;
+ case OP_BITWISE_NOT:
+ fprintf(out,"~");break;
+ case OP_ADDR_OF:
+ fprintf(out,"&");break;
+ case OP_DEREFERENCE:
+ fprintf(out,"*");break;
+ case OP_MEMBER_TROUGH_PTR:
+ fprintf(out,"->");break;
+ case OP_MEMBER:
+ fprintf(out,".");break;
+ case OP_ARR_SUBSCRIPT:
+ fprintf(out,"ARR_SUBSCRIPT");break;
+ case OP_POSTFIX_INC:
+ fprintf(out,"++");break;
+ case OP_POSTFIX_DEC:
+ fprintf(out,"--");break;
+ case OP_PREFIX_INC:
+ fprintf(out,"++");break;
+ case OP_PREFIX_DEC:
+ fprintf(out,"--");break;
+ case OP_UNARY_PLUS:
+ fprintf(out,"+");break;
+ case OP_UNARY_MINUS:
+ fprintf(out,"-");break;
+ case OP_CAST:
+ fprintf(out,"CAST");break;
+ case OP_SIZEOF:
+ fprintf(out,"sizeof");break;
+ case OP_SHIFT_LEFT:
+ fprintf(out,"<<");break;
+ case OP_SHIFT_RIGHT:
+ fprintf(out,">>");break;
+ case OP_LESS_EQ:
+ fprintf(out,"<=");break;
+ case OP_GREATER_EQ:
+ fprintf(out,">=");break;
+ case OP_LESS:
+ fprintf(out,"<");break;
+ case OP_GREATER:
+ fprintf(out,">");break;
+ case OP_EQUAL:
+ fprintf(out,"==");break;
+ case OP_NOT_EQUAL:
+ fprintf(out,"!=");break;
+ case OP_CONSTANT:
+ fprintf(out,"CONSTANT");break;
+ case OP_STRING_LITERAL:
+ fprintf(out,"STRING_LITERAL");break;
+ case ST_COMPOUND:
+ fprintf(out,"COMPOUND");break;
+ case ST_EXPRESSION:
+ fprintf(out,"EXPRESSION");break;
+ case ST_SWITCH:
+ fprintf(out,"switch");break;
+ case ST_IF:
+ fprintf(out,"if");break;
+ case ST_WHILE:
+ fprintf(out,"while");break;
+ case ST_DO_WHILE:
+ fprintf(out,"do_while");break;
+ case ST_GOTO:
+ fprintf(out,"goto");break;
+ case ST_LABEL:
+ fprintf(out,"LABEL");break;
+ case ST_CASE:
+ fprintf(out,"case");break;
+ case ST_DEFAULT:
+ fprintf(out,"default");break;
+ case ST_CONTINUE:
+ fprintf(out,"continue");break;
+ case ST_BREAK:
+ fprintf(out,"break");break;
+ case ST_RETURN:
+ fprintf(out,"return");break;
+ case ST_FOR:
+ fprintf(out,"for");break;
+
+ /*TODO obj dec obj def func decl*/
+ case ST_FUNCTION_DEFINITION:
+ fprintf(out,"FUNCTION_DEFINITION");break;
+ case TRANSLATION_UNIT:
+ fprintf(out,"TRANSLATION_UNIT");break;
+ case ERROR:
+ fprintf(out,"ERROR");break;
+ default:
+ fprintf(out,"NOT_POSSIBLE");break;
}
}
void print_conditional_expression_tree(FILE *out,struct AST_Conditional_Expression *cond)
{
fprintf(out,"(");
- print_ast(out,(struct AST*)(struct AST*)cond->left);
+ print_ast(out,(struct AST*)cond->left);
fprintf(out,"?");
- print_ast(out,(struct AST*)(struct AST*)cond->center);
+ print_ast(out,(struct AST*)cond->center);
fprintf(out,":");
- print_ast(out,(struct AST*)(struct AST*)cond->right);
+ print_ast(out,(struct AST*)cond->right);
fprintf(out,")");
}
void print_function_expression_tree(FILE *out,struct AST_Function_Expression *function_call)
{
struct Queue_Node *it;
struct AST* hold;
- for(it=unit->components.first;it!=NULL;it=it->prev)
+ for(it=unit->components->first;it!=NULL;it=it->prev)
{
hold=(struct AST*)(it->data);
print_ast(out,(struct AST*)hold);
break;
case ST_OBJECT_DECLARATION:
print_denoted(out,(struct Denoted*)((struct AST_Object_Declaration*)tree)->object);
- fprintf(out,"=");
- print_ast(out,(struct AST*)((struct AST_Object_Declaration*)tree)->object->initializer);
break;
case ST_TYPE_DEFINITION:
print_denoted(out,(struct Denoted*)((struct AST_Type_Definition*)tree)->definition);
print_denoted(out,(struct Denoted*)((struct AST_Function_Declaration*)tree)->function);
break;
case ST_FUNCTION_DEFINITION:
- print_function_definition(out,((struct AST_Function_Declaration*)tree)->function);
+ print_function_definition(out,(struct AST_Function_Definition*)tree);
break;
case TRANSLATION_UNIT:
print_translation_unit_tree(out,(struct AST_Translation_Unit*)tree);
}
- void print_function_definition(FILE *out,struct Denoted_Function *function)
+ void print_function_definition(FILE *out,struct AST_Function_Definition *function)
{
- print_token(out,function->id);
+ print_token(out,function->function->id);
fprintf(out," is");
- switch(function->linkage)
+ switch(function->function->linkage)
{
case LINKAGE_EXTERNAL:
fprintf(out," an externally linked ");
default:
assert(0);
}
- print_type(out,function->type,1);
- print_ast(out,(struct AST*)(struct AST*)function->body);
+ print_type(out,function->function->type,1);
+ print_compound_statement_tree(out,function->body);
}
void print_program_ast(FILE *out,struct Program *program)
{
F diff --git a/src/backend/print/print.h b/src/backend/print/print.h --- a/src/backend/print/print.h +++ b/src/backend/print/print.h
void print_program_tokens(FILE *out,struct Program *program);
void print_program_ast(FILE *out,struct Program *program);
void print_keyword_enum(FILE *out,enum KEYWORDS kw);
- void print_function_definition(FILE *out,struct Denoted_Function *function);
+ void print_function_definition(FILE *out,struct AST_Function_Definition *function);
void print_errors(FILE *out,struct Queue *errors);
void print_function_args(FILE *out,struct Type_Function *func);
void print_type_qualifier(FILE *out,struct Type *type);
F diff --git a/src/frontend/parse/parse_declaration.c b/src/frontend/parse/parse_declaration.c --- a/src/frontend/parse/parse_declaration.c +++ b/src/frontend/parse/parse_declaration.c
{
struct Type_Function *function_type;
struct Denoted_Function *hold_function;
+ struct AST_Compound_Statement *function_body;
hold_function=(struct Denoted_Function*)hold;
function_type=(struct Type_Function*)((struct Denoted_Function*)hold)->type;
function_type->function_prototype_scope->parent=(struct Scope*)hold_function->function_scope;
- hold_function->body
+ function_body
=
(struct AST_Compound_Statement*)
parse_finish_compound_statement(
}
);
- Queue_Push(where_to_push,get_function_definition_tree(scope,(struct Denoted_Function*)hold,translation_data));
+ Queue_Push(where_to_push,get_function_definition_tree(scope,(struct Denoted_Function*)hold,function_body,translation_data));
break;
}
/*this is a function declaration*/
Queue_Push(where_to_push,get_type_definition_tree((struct Denoted_Type*)hold));
}else if(hold->denotation==DT_Object)
{
- Queue_Push(where_to_push,get_object_declaration_tree((struct Denoted_Object*)hold));
+ struct AST_Expression *initializer=NULL;
if(get_and_check(translation_data,KW_EQ))
- ((struct Denoted_Object*)hold)->initializer=parse_initializer(translation_data,scope,(struct Denoted_Object*)hold);
+ initializer=(struct AST_Expression*)parse_initializer(translation_data,scope,(struct Denoted_Object*)hold);
+ Queue_Push(where_to_push,get_object_declaration_tree((struct Denoted_Object*)hold,initializer));
}else
{
/*TODO error*/
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
case KW_UNSIGNED_LONG_LONG_OCTAL_CONSTANT:
case KW_LONG_OCTAL_CONSTANT:
case KW_LONG_LONG_OCTAL_CONSTANT:
- assert(!"make octal constants");
+ return (struct AST_Expression*)get_constant_tree(get_expression_value_constant(extract_literal_integer_octal(hold_token,translation_data)));
case KW_DOUBLE_DECIMAL_CONSTANT:
case KW_LONG_DOUBLE_DECIMAL_CONSTANT:
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
if(is_type(translation_data,hold->file_scope) || kw_get(translation_data)==KW_ID)
{
- parse_declaration(translation_data,hold->file_scope,&hold->components,1);
+ parse_declaration(translation_data,hold->file_scope,hold->components,1);
if(has_new_errors(translation_data))
{
chase_next_semicolumn(translation_data);
F diff --git a/src/semantics/ast.c b/src/semantics/ast.c --- a/src/semantics/ast.c +++ b/src/semantics/ast.c
return ret;
}
- struct AST_Object_Declaration* get_object_declaration_tree(struct Denoted_Object *object)
+ struct AST_Object_Declaration* get_object_declaration_tree(struct Denoted_Object *object,struct AST_Expression *initialiser)
{
struct AST_Object_Declaration *ret;
ret=malloc(sizeof(struct AST_Object_Declaration));
ret->type=ST_OBJECT_DECLARATION;
ret->object=object;
+ ret->initializer=initialiser;
return ret;
}
- struct AST_Function_Definition* get_function_definition_tree(struct Scope *scope,struct Denoted_Function *function,struct Translation_Data *translation_data)
+ 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_Function_Definition *ret;
ret=malloc(sizeof(struct AST_Function_Definition));
ret->type=ST_FUNCTION_DEFINITION;
ret->function=function;
+ ret->body=function_body;
if(!constraint_check_function_definition(ret,translation_data))
return (struct AST_Function_Definition*)get_error_tree((struct AST*)ret);
{
struct AST_Translation_Unit *ret;
ret=malloc(sizeof(struct AST_Translation_Unit));
+ ret->type=TRANSLATION_UNIT;
+ ret->components=malloc(sizeof(struct Queue));
ret->internal_linkage=get_linkage();
ret->file_scope=get_normal_scope(NULL,FILE_SCOPE);
+ ret->static_declarations=malloc(sizeof(struct Queue));
- Queue_Init(&ret->components);
- Queue_Init(&ret->static_objects);
- ret->type=TRANSLATION_UNIT;
- return ret;
- }
+ Queue_Init(ret->components);
+ Queue_Init(ret->static_declarations);
- /*
- * TODO
- */
- _Bool ast_is_a_constant_expression(struct AST *ast,struct Translation_Data *translation_data)
- {
- return 0;
+ return ret;
}
void delete_ast(struct AST* ast)
}
void delete_ast_translation_unit(struct AST_Translation_Unit *translation_unit)
{
- while(translation_unit->components.size>0)
- delete_ast((struct AST*)Queue_Pop(&translation_unit->components));
+ while(translation_unit->components->size>0)
+ delete_ast((struct AST*)Queue_Pop(translation_unit->components));
if(translation_unit->file_scope!=NULL)
delete_scope(translation_unit->file_scope);
delete_linkage(translation_unit->internal_linkage);
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 Denoted_Object *object;
+ struct AST_Expression *initializer;
};
struct AST_Function_Definition
{
enum AST_Type type;
struct Denoted_Function *function;
+ struct AST_Compound_Statement *body;
};
struct AST_Function_Declaration
{
struct AST_Translation_Unit
{
enum AST_Type type;
- struct Queue components;
+ struct Queue *components; /*Queue of external declarations*/
struct Scope *file_scope;
struct Linkage *internal_linkage;
- struct Queue static_objects;
+
+ struct Queue *static_declarations; /*Queue of declarations*/
};
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_Object_Declaration* get_object_declaration_tree(struct Denoted_Object *object,struct AST_Expression *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 Translation_Data *translation_data);
+ 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();
- _Bool ast_is_a_constant_expression(struct AST *ast,struct Translation_Data *translation_data);
void delete_ast(struct AST* ast);
void delete_ast_error(struct AST_Error *error);
F diff --git a/src/semantics/constraints/constraints.h b/src/semantics/constraints/constraints.h --- a/src/semantics/constraints/constraints.h +++ b/src/semantics/constraints/constraints.h
#ifndef WONKY_CONSTRAINTS_H
#define WONKY_CONSTRAINTS_H WONKY_CONSTRAINTS_H
- #include<expression_constraints.h>
- #include<statement_constraints.h>
+ #include <expression_constraints.h>
+ #include <statement_constraints.h>
+ #include <linkage_constraints.h>
#endif
F diff --git a/src/semantics/constraints/linkage_constraints.c b/src/semantics/constraints/linkage_constraints.c new file mode 100644 --- /dev/null +++ b/src/semantics/constraints/linkage_constraints.c
+ #ifndef WONKY_LINKAGE_CONSTRAINTS_C
+ #define WONKY_LINKAGE_CONSTRAINTS_C WONKY_LINKAGE_CONSTRAINTS_C
+ #include <linkage_constraints.h>
+
+ _Bool constraint_check_object_linkage(struct Denoted_Object *denoted_object ,struct Denoted *previous_denoted_with_same_id, struct Scope *current,struct Translation_Data *translation_data)
+ {
+ struct Linkage *linkage;
+ struct Denoted_Object *hold_object;
+
+ assert(current->type!=FUNCTION_SCOPE);
+
+ if(previous_denoted_with_same_id==NULL) /*NOTE*/
+ return 1;
+
+ if(previous_denoted_with_same_id->denotation!=DT_Object)
+ {
+ push_translation_error("redeclaration of %D",translation_data,denoted_object);
+ push_translation_note("previously declared as %D",translation_data,previous_denoted_with_same_id);
+ return 0;
+ }
+
+ hold_object=(struct Denoted_Object*)previous_denoted_with_same_id;
+
+ if(hold_object->linkage==LINKAGE_NONE)
+ {
+ push_translation_error("redeclaration of identifier %t",translation_data,denoted_object->id);
+ return 0;
+ }
+
+ if(denoted_object->linkage==LINKAGE_NONE)
+ {
+ push_translation_error("redeclaration of identifier %t",translation_data,denoted_object->id);
+ return 0;
+ }else if(denoted_object->linkage==LINKAGE_EXTERNAL || denoted_object->linkage==LINKAGE_INTERNAL)
+ {
+ linkage=(denoted_object->linkage==LINKAGE_EXTERNAL?translation_data->external_linkage:translation_data->internal_linkage);
+ hold_object=check_and_push_id(denoted_object,&linkage->ids,denoted_object->id);
+
+
+ if(hold_object!=NULL)
+ {
+ if(hold_object->denotation!=DT_Object)
+ {
+ push_translation_error("linking an object to a function %D",translation_data,denoted_object);
+ push_translation_note("linking against %D",translation_data,hold_object);
+ return 0;
+ }else if(!types_are_identical(hold_object->object->type,denoted_object->object->type))
+ {
+ push_translation_error("linking objects with mismatching types",translation_data);
+ push_translation_note("%t has type %T",translation_data,denoted_object->id,denoted_object->object->type);
+ push_translation_note("whilst %t has type %T",translation_data,hold_object->id,hold_object->object->type);
+ return 0;
+ }
+
+ }else
+ {
+ return 1;
+ }
+ }else
+ {
+ assert(0);
+ }
+
+ }
+ _Bool constraint_check_function_linkage(struct Denoted_Function *denoted_function,struct Denoted *previous_denoted_with_same_id,struct Scope *current,struct Translation_Data *translation_data)
+ {
+ struct Linkage *linkage;
+ struct Denoted_Function *hold_function;
+
+ assert(current->type!=FUNCTION_SCOPE);
+
+ if(previous_denoted_with_same_id==NULL)
+ return 1;
+
+ if(denoted_function->linkage==LINKAGE_NONE)
+ {
+ push_translation_error("redeclaration of %D",translation_data,denoted_function);
+ push_translation_note("previously declared as %D",translation_data,previous_denoted_with_same_id);
+ return 0;
+ }else if(denoted_function->linkage==LINKAGE_EXTERNAL || denoted_function->linkage==LINKAGE_INTERNAL)
+ {
+ linkage=(denoted_function->linkage==LINKAGE_EXTERNAL?translation_data->external_linkage:translation_data->internal_linkage);
+ hold_function=check_and_push_id(denoted_function,&linkage->ids,denoted_function->id);
+
+ if(hold_function!=NULL)
+ {
+ if(hold_function->denotation!=DT_Function)
+ {
+ push_translation_error("linking an function to a object",translation_data);
+ return 0;
+ }
+ if(!types_are_identical(hold_function->type,denoted_function->type))
+ {
+ push_translation_error("linking functions with mismatching types",translation_data);
+ return 0;
+ }
+ }else
+ {
+ return 1;
+ }
+ }else
+ {
+ assert(0);
+ }
+ }
+ #endif
F diff --git a/src/semantics/constraints/linkage_constraints.h b/src/semantics/constraints/linkage_constraints.h new file mode 100644 --- /dev/null +++ b/src/semantics/constraints/linkage_constraints.h
+ #ifndef WONKY_LINKAGE_CONSTRAINTS_H
+ #define WONKY_LINKAGE_CONSTRAINTS_H WONKY_LINKAGE_CONSTRAINTS_H
+
+ #include <program.h>
+ #include <scope.h>
+ #include <denoted.h>
+
+ _Bool constraint_check_object_linkage(struct Denoted_Object *denoted_object ,struct Denoted *previous_denoted_with_same_id, struct Scope *current,struct Translation_Data *translation_data);
+ _Bool constraint_check_function_linkage(struct Denoted_Function *denoted_function,struct Denoted *previous_denoted_with_same_id,struct Scope *current,struct Translation_Data *translation_data);
+ #endif
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.c
return 0;
}
assert(case_statement->control!=NULL);
+
+ /*
if(!ast_is_a_constant_expression((struct AST*)case_statement->control,translation_data))
{
push_translation_error("control expression in case statement is not a constant expression",translation_data);
return 0;
}
+ */
return 1;
}
_Bool constraint_check_labeled_statement(struct AST_Labeled_Statement *label,struct Translation_Data *translation_data)
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
ret->type=type;
ret->location=NULL;
ret->function_specifier=fs;
- ret->body=NULL;
ret->function_scope=NULL;
return (struct Denoted*)ret;
ret->id=id;
ret->object=get_object(type,sc);
-
- ret->initializer=initializer;
-
return (struct Denoted*)ret;
}
{
if(function->id!=NULL)
free(function->id);
- if(function->body!=NULL)
- delete_ast_compound_statement(function->body);
free(function);
}
void delete_denoted_object(struct Denoted_Object *object)
free(object->id);
if(object->object!=NULL)
delete_object(object->object);
- if(object->initializer!=NULL)
- delete_ast(object->initializer);
free(object);
}
void delete_denoted_typedef(struct Denoted_Type *typedefed)
F diff --git a/src/semantics/identifiers/denoted.h b/src/semantics/identifiers/denoted.h --- a/src/semantics/identifiers/denoted.h +++ b/src/semantics/identifiers/denoted.h
enum Function_Specifier function_specifier;
struct Function_Scope *function_scope;
- struct AST_Compound_Statement *body;
};
struct Denoted_Object
{
struct token *id;
struct Object *object;
-
- struct AST *initializer;
};
struct Denoted_Type
{
F diff --git a/src/semantics/identifiers/linkage.c b/src/semantics/identifiers/linkage.c --- a/src/semantics/identifiers/linkage.c +++ b/src/semantics/identifiers/linkage.c
denoted_function->linkage=( (hold_function->linkage==LINKAGE_NONE) ? LINKAGE_EXTERNAL : hold_function->linkage);
}else
{
- push_translation_error("linking mismatching things",translation_data);
+ push_translation_error("mismtatching types for %t",translation_data,denoted_function->id);
+ push_translation_note("first it was declared with type %T",translation_data,hold_function->type);
+ push_translation_note("now it's declared with type %T",translation_data,denoted_function->type);
return;
}
}else
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
#ifndef WONKY_SCOPE_C
#define WONKY_SCOPE_C WONKY_SCOPE_C
- #include "scope.h"
+ #include <scope.h>
struct Scope* get_normal_scope(struct Scope *parent,enum Scope_Type type)
}
- #define CHECK_AND_PUSH(thing,scope) Map_Check_And_Push(scope,thing->id->data,thing->id->data_size,thing)
void push_object(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Object *denoted_object)
{
- #define PO_ERROR(msg) push_translation_error(msg,translation_data,denoted_object->id);delete_denoted_object(denoted_object);return;
+ struct Denoted *hold_previous;
+
+ assert(current->type!=FUNCTION_SCOPE);
- struct Denoted_Object *hold_object;
- struct Linkage *linkage;
+
+
resolve_object_linkage(current,translation_data,denoted_object);
- if(has_new_errors(translation_data))
- {
- push_translation_note("in declaration %D",translation_data,denoted_object);
- delete_denoted_object(denoted_object);
- return;
- }
- hold_object=CHECK_AND_PUSH(denoted_object,&AS_NORMAL_SCOPE(current)->ordinary);
- if(hold_object!=NULL && hold_object->linkage==LINKAGE_NONE)
- {
- push_translation_error("redeclaration of identifier %t",translation_data,denoted_object->id);
- delete_denoted_object(denoted_object);
- return;
- }
+ hold_previous=check_and_push_id(denoted_object,&AS_NORMAL_SCOPE(current)->ordinary,denoted_object->id);
- if(denoted_object->linkage==LINKAGE_NONE)
- {
- if(hold_object!=NULL)
- {
- push_translation_error("redeclaration of identifier %t",translation_data,denoted_object->id);
- delete_denoted_object(denoted_object);
- return;
- }
- }else if(denoted_object->linkage==LINKAGE_EXTERNAL || denoted_object->linkage==LINKAGE_INTERNAL)
- {
- linkage=(denoted_object->linkage==LINKAGE_EXTERNAL?translation_data->external_linkage:translation_data->internal_linkage);
- hold_object=CHECK_AND_PUSH(denoted_object,&linkage->ids);
- if(hold_object!=NULL)
- {
- if(hold_object->denotation!=DT_Object)
- {
- push_translation_error("linking an object to a function %D",translation_data,denoted_object);
- push_translation_note("linking against %D",translation_data,hold_object);
- delete_denoted_object(denoted_object);
- return;
- }else if(!types_are_identical(hold_object->object->type,denoted_object->object->type))
- {
- push_translation_error("linking objects with mismatching types",translation_data);
- push_translation_note("%t has type %T",translation_data,denoted_object->id,denoted_object->object->type);
- push_translation_note("whilst %t has type %T",translation_data,hold_object->id,hold_object->object->type);
- delete_denoted_object(denoted_object);
- return;
- }else if(denoted_object->initializer!=NULL)
- {
- if(hold_object->initializer==NULL)
- hold_object->initializer=denoted_object->initializer;
- else
- {PO_ERROR("two initialisers for static storage duration object");}
- //delete_denoted_object(denoted_object);
- }
- }
- }else
+ if(has_new_errors(translation_data) || !constraint_check_object_linkage(denoted_object,hold_previous,current,translation_data) )
{
- assert(0);
+ translation_data->number_of_errors_when_last_checked--; /*TODO make a new function for this for gods sake*/
+ //delete_denoted_object(denoted_object);
}
- #undef PO_ERROR
}
void push_function(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Function *denoted_function)
{
- #define PF_ERROR(msg) delete_denoted_function(denoted_function);push_translation_error(msg,translation_data);return;
+ struct Denoted *hold_previous;
+
+ assert(current->type!=FUNCTION_SCOPE);
+
- struct Denoted_Function *hold_function;
- struct Linkage *linkage;
resolve_function_linkage(current,translation_data,denoted_function);
- if(has_new_errors(translation_data))
- {PF_ERROR("in declaration");}
- hold_function=CHECK_AND_PUSH(denoted_function,&AS_NORMAL_SCOPE(current)->ordinary);
- if(denoted_function->linkage==LINKAGE_NONE)
- {
- if(hold_function!=NULL)
- {PF_ERROR("id with function type without linkage");}
- }else if(denoted_function->linkage==LINKAGE_EXTERNAL || denoted_function->linkage==LINKAGE_INTERNAL)
- {
- linkage=(denoted_function->linkage==LINKAGE_EXTERNAL?translation_data->external_linkage:translation_data->internal_linkage);
- hold_function=CHECK_AND_PUSH(denoted_function,&linkage->ids);
- if(hold_function!=NULL)
- {
- if(hold_function->denotation!=DT_Function)
- {PF_ERROR("linking an function to a object");}
- if(!types_are_identical(hold_function->type,denoted_function->type))
- {PF_ERROR("linking functions with mismatching types");}
- if(hold_function->body!=NULL && denoted_function->body!=NULL)
- {PF_ERROR("redefinition of a function");}
- if(denoted_function->body!=NULL)
- {
- hold_function->body=denoted_function->body;
- denoted_function->body=NULL;
- // delete_denoted_function(denoted_function);
- }
- }
- }else
+ hold_previous=check_and_push_id(denoted_function,&AS_NORMAL_SCOPE(current)->ordinary,denoted_function->id);
+
+ if(has_new_errors(translation_data) || !constraint_check_function_linkage(denoted_function,hold_previous,current,translation_data))
{
- assert(0);
+ //delete_denoted_function(denoted_function);
+ translation_data->number_of_errors_when_last_checked--;
}
-
- #undef PF_ERROR
}
+ #define CHECK_AND_PUSH(thing,scope) Map_Check_And_Push(scope,thing->id->data,thing->id->data_size,thing)
void push_typedef(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Type *denoted_typedef)
{
struct Denoted *hold_denotated;
push_translation_error("redefinition of tag",translation_data);
}
}
+
void push_denoted_enum_constant(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Enum_Const *denoted_enum_constant)
{
struct Denoted *hold_denotated;
push_translation_error("redefinition of tag",translation_data);
}
}
- #undef CHECK_AND_PUSH
+ void* check_and_push_id(void *data,struct Map *scope_map,struct token *id)
+ {
+ return Map_Check_And_Push(scope_map,id->data,id->data_size,data);
+ }
#endif
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
#include <denoted.h>
#include <location.h>
#include <queue.h>
+ #include <constraints.h>
enum Scope_Type;
+ void* check_and_push_id(void *data,struct Map *scope_map,struct token *id);
+
_Bool check_if_typedefed(struct Scope* scope,struct token *id);
#endif
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
}
struct Constant* extract_literal_integer_dec(struct token *token,struct Translation_Data *translation_data)
{
- /*the sign is acounted for during parsing*/
+ /*the sign is acounted for during parsing ( not lexing )*/
unsigned long long int cache=0;
unsigned long long int *ret_component;
struct Constant *ret;
}
+ struct Constant* extract_literal_integer_octal(struct token *token,struct Translation_Data *translation_data)
+ {
+ unsigned long long int cache=0;
+ unsigned long long int *ret_component;
+ struct Constant *ret;
+ size_t i;
+
+ ret_component=malloc(sizeof(unsigned long long int));
+ ret=malloc(sizeof(struct Constant));
+
+ for(i=0;i<token->data_size;++i)
+ cache*=8 , cache+=token->data[i]-'0';
+
+ *ret_component=cache;
+ ret->value=ret_component;
+ ret->type=(struct Type*)get_type_insecure(TS_INT,TSIGN_NONE,TC_NONE,INT_SIZE,translation_data);
+
+ return ret;
+ }
struct Constant* extract_literal_integer_hex(struct token *token,struct Translation_Data *translation_data)
{
unsigned long long int cache=0;
F diff --git a/src/semantics/value/constant.h b/src/semantics/value/constant.h --- a/src/semantics/value/constant.h +++ b/src/semantics/value/constant.h
};
struct Constant* extract_constant(struct token *token,struct Translation_Data *translation_data);
+ struct Constant* extract_literal_integer_octal(struct token *token,struct Translation_Data *translation_data);
struct Constant* extract_literal_integer_dec(struct token *token,struct Translation_Data *translation_data);
struct Constant* extract_literal_integer_hex(struct token *token,struct Translation_Data *translation_data);
struct Constant* extract_literal_double_dec(struct token *token,struct Translation_Data *translation_data);
+
+ struct Constant* get_unsigned_int_constant();
+ struct Constant* get_signed_int_constant();
+
+
char ast_is_null_pointer_constant(struct AST *tree);
char constant_is_null_pointer(struct Constant *constant);
F diff --git a/src/semantics/value/evaluation.c b/src/semantics/value/evaluation.c --- a/src/semantics/value/evaluation.c +++ b/src/semantics/value/evaluation.c
- #ifndef WONKY_SEMANTICS_C
- #define WONKY_SEMANTICS_C WONKY_SEMANTICS_C
+ #ifndef WONKY_EVALUATION_C
+ #define WONKY_EVALUATION_C WONKY_EVALUATION_C
#include <evaluation.h>
+ /*Returns NULL if it can reduce expression to a constant*/
+ struct Constant* try_to_evaluate_expression(struct AST_Expression *expression,struct Translation_Data *translation_data)
+ {
+ switch(expression->type)
+ {
+ case OP_ADDITION:
+
+
+
+ default:
+ return NULL;
+ }
+ assert(0);
+ }
+
+
+
+
+
+
+
+
long long int evaluate_const_expression_integer(struct AST *expression,struct Translation_Data *translation_data)
{
F diff --git a/src/semantics/value/evaluation.h b/src/semantics/value/evaluation.h --- a/src/semantics/value/evaluation.h +++ b/src/semantics/value/evaluation.h
- #ifndef WONKY_SEMANTICS_H
- #define WONKY_SEMANTICS_H WONKY_SEMANTICS_H
+ #ifndef WONKY_EVALUATION_H
+ #define WONKY_EVALUATION_H WONKY_EVALUATION_H
#include <ast.h>
+ #include <constant.h>
#include <lexer.h>
#include <program.h>
+
+ struct Constant* try_to_evaluate_expression(struct AST_Expression *expression,struct Translation_Data *translation_data);
+
+
+
long long int evaluate_const_expression_integer(struct AST *expression,struct Translation_Data *translation_data);
F diff --git a/src/semantics/value/type.c b/src/semantics/value/type.c --- a/src/semantics/value/type.c +++ b/src/semantics/value/type.c
/*TODO !!!*/
_Bool types_are_identical(struct Type *a,struct Type *b)
{
- return a==b;
+ if(a->specifier!=b->specifier)
+ return 0;
+
+ switch(a->specifier)
+ {
+ case TS_VOID:
+ case TS_CHAR:
+ case TS_INT:
+ case TS_FLOAT:
+ case TS_DOUBLE:
+ return 1;
+
+ case TS_UNION:
+ case TS_STRUCT:
+ return 1;
+ case TS_ENUM:
+ return 1;
+ case TS_POINTER:
+ {
+ struct Type_Pointer *ap,*bp;
+ ap=(struct Type_Pointer*)a;
+ bp=(struct Type_Pointer*)b;
+
+ return
+ types_are_identical(ap->points_to,bp->points_to)
+ &&
+ ap->is_const==bp->is_const
+ &&
+ ap->is_volatile==bp->is_volatile
+ ;
+
+ }
+ case TS_ARRAY:
+ {
+ struct Type_Array *aa,*ba;
+ aa=(struct Type_Array*)a;
+ ba=(struct Type_Array*)b;
+ return
+ types_are_identical(aa->is_array_of,ba->is_array_of)
+ &&
+ aa->number_of_elements==ba->number_of_elements
+ ;
+ }
+ case TS_FUNC:
+ {
+ struct Type_Function *af,*bf;
+ size_t i;
+
+ af=(struct Type_Function*)a;
+ bf=(struct Type_Function*)b;
+
+ if(af->number_of_arguments!=bf->number_of_arguments
+ || !types_are_identical(af->return_type,bf->return_type))
+ return 0;
+
+ for(i=0;i<af->number_of_arguments;++i)
+ {
+ if(!types_are_identical(af->arguments[i]->object->type,bf->arguments[i]->object->type))
+ return 0;
+ }
+ return 1;
+ }
+ default:
+ return 0;
+ }
+ assert(0);
}
/* 6.2.7
* two types have compatible type if their types are the same.
- * Additional
+ * Additionally ... TODO
*
* */
_Bool types_are_compatible(struct Type *a,struct Type *b)
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
size_t number_of_elements;
struct Type *is_array_of;
};
+ struct Type_Variable_Length_Array
+ {
+ enum Type_Specifier specifier;
+ struct Map *node;
+ size_t size;
+ struct AST_Expression *number_of_elements;
+ struct Type *is_array_of;
+ };
struct Type_Function
{
enum Type_Specifier specifier;
F diff --git a/src/semantics/value/type.hh b/src/semantics/value/type.hh --- a/src/semantics/value/type.hh +++ b/src/semantics/value/type.hh
struct Type_Basic;
struct Type_Pointer;
struct Type_Array;
+ struct Type_Variable_Length_Array;
struct Type_Function;
struct Type_Enum;
struct Enum;