WONKY



LOG | FILES | OVERVIEW


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_goto_statement_tree(FILE *out,struct AST_Goto_Statement *got)
{
fprintf(out,"goto ");
- print_token(out,got->label);
+ print_denoted(out,(struct Denoted*)got->label);
}
void print_type(FILE *out,struct Type *type,char should_print_struct_union)
fprintf(out,"macro ");return;
case DT_Macro_Parameter:
fprintf(out,"macro parameter ");return;
- case DT_Label:
+ case DT_Statement:
fprintf(out,"label ");return;
case DT_Object:
switch(((struct Denoted_Object*)denoted)->linkage)
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_PLUSPLUS:
chomp(translation_data);
- hold_postfix_expression=(struct AST_Expression*)get_postfix_inc_dec_tree(hold_postfix_expression,OP_POINTER_ADDITION,translation_data);
+ hold_postfix_expression=(struct AST_Expression*)get_postfix_inc_dec_tree(hold_postfix_expression,OP_POSTFIX_INC,translation_data);
break;
case KW_MINUSMINUS:
chomp(translation_data);
- hold_postfix_expression=(struct AST_Expression*)get_postfix_inc_dec_tree(hold_postfix_expression,OP_POINTER_ADDITION,translation_data);
+ hold_postfix_expression=(struct AST_Expression*)get_postfix_inc_dec_tree(hold_postfix_expression,OP_POSTFIX_DEC,translation_data);
break;
case KW_DOT:
chomp(translation_data);
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
}
/*
- expression :
+ constant :
statement
*/
struct AST* parse_finish_case_statement(struct Translation_Data *translation_data,struct Scope *scope,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch)
{
+ struct AST_Expression *hold_expression;
+ struct AST *hold_statement;
+
}
/*
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_Goto_Statement* get_goto_statement_tree(struct token *label,struct Scope *scope)
{
struct AST_Goto_Statement *ret;
+ struct Denoted_Statement *hold_statement;
+
ret=malloc(sizeof(struct AST_Goto_Statement));
ret->type=ST_GOTO;
- ret->label=label;
+
+ hold_statement=check_label(scope,label);
+ if(hold_statement==NULL)
+ {
+ hold_statement=(struct Denoted_Statement*)get_denoted_statement(label,NULL,NULL);
+ }
+
+ ret->label=hold_statement;
+
+ Queue_Push(hold_statement->gotos_jumping_to_this_statement,ret);
+
+ ret->previous_denoted_object=(struct Denoted_Object*)get_last_known_denoted_object((struct Normal_Scope*)scope);
return ret;
}
F diff --git a/src/semantics/ast.h b/src/semantics/ast.h --- a/src/semantics/ast.h +++ b/src/semantics/ast.h
struct token *label;
struct AST *statement;
};
+ struct AST_Case_Statement
+ {
+ enum AST_Type type;
+ struct AST_Expression *expression;
+ struct AST *statement;
+ };
struct AST_Compound_Statement
{
enum AST_Type type;
struct AST_Goto_Statement
{
enum AST_Type type;
- struct token *label;
+ struct Denoted_Statement *label;
+ struct Denoted_Object *previous_denoted_object;
};
struct AST_Switch_Statement
{
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
}
}
+ struct Denoted* get_denoted_statement(struct token *id,struct AST *statement,struct Denoted_Object *previous_denoted_object)
+ {
+ struct Denoted_Statement *ret;
+ ret=malloc(sizeof(struct Denoted_Statement));
+ ret->denotation=DT_Statement;
+ ret->label=id;
+ ret->statement=statement;
+
+ ret->previous_denoted_object=previous_denoted_object;
+ ret->gotos_jumping_to_this_statement=malloc(sizeof(struct Queue));
+
+ Queue_Init(ret->gotos_jumping_to_this_statement);
+
+ return (struct Denoted*)ret;
+ }
void delete_denoted(struct Denoted *denoted)
{
switch(denoted->denotation)
{
- case DT_Label:
- free(denoted);
+ case DT_Statement:
+ delete_denoted_statement((struct Denoted_Statement*)denoted);
break;
case DT_Object:
delete_denoted_object((struct Denoted_Object*)denoted);
{
free(base);
}
+ void delete_denoted_statement(struct Denoted_Statement *statement)
+ {
+ if(statement->label) free(statement->label);
+ if(statement->statement) delete_ast(statement->statement);
+ if(statement->gotos_jumping_to_this_statement)
+ {
+ while(statement->gotos_jumping_to_this_statement->size>0)
+ Queue_Pop(statement->gotos_jumping_to_this_statement);
+ }
+ free(statement);
+ }
void delete_denoted_wrapper(void *denoted)
{
delete_denoted(denoted);
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 Denotation_Type denotation;
struct Struct_Union *struct_union;
};
+ struct Denoted_Statement
+ {
+ enum Denotation_Type denotation;
+
+ struct token *label;
+ struct AST *statement;
+ struct Queue *gotos_jumping_to_this_statement;
+
+ struct Denoted_Object *previous_denoted_object;
+ };
struct Denotation_Prototype
{
enum Denotation_Type denotation;
struct Denoted* get_denoted_struct_union(struct Struct_Union *struct_union);
struct Denoted* extract_denoted(struct Denoted_Base *base,struct Denotation_Prototype *prototype,_Bool allow_abstract);
+ struct Denoted* get_denoted_statement(struct token *id,struct AST *statement,struct Denoted_Object *previous_denoted_object);
struct Denoted* get_denotation_prototype(struct Map *types);
void delete_denoted_struct_union(struct Denoted_Struct_Union *su);
void delete_denoted_prototype(struct Denotation_Prototype *prototype);
void delete_denoted_base(struct Denoted_Base *base);
+ void delete_denoted_statement(struct Denoted_Statement *statement);
enum Storage_Class_Specifier get_denoted_function_storage_class(struct Denoted_Function *function);
F diff --git a/src/semantics/identifiers/denoted.hh b/src/semantics/identifiers/denoted.hh --- a/src/semantics/identifiers/denoted.hh +++ b/src/semantics/identifiers/denoted.hh
#define AS_DENOTED_ENUM(x) ((struct Denoted_Enum*)x)
#define AS_DENOTED_ENUM_CONST(x) ((struct Denoted_Enum_Const*)x)
#define AS_DENOTED_STRUCT_UNION(x) ((struct Denoted_Struct_Union*)x)
+ #define AS_DENOTED_STATEMENT(x) ((struct Denoted_Statement*)x)
enum Denotation_Type
{
DT_Macro,
DT_Macro_Parameter,
- DT_Label,
+ DT_Statement,
DT_Object,
DT_Typedef,
DT_Function,
struct Denoted_Enum;
struct Denoted_Enum_Const;
struct Denoted_Struct_Union;
+ struct Denoted_Statement;
struct Denotation_Prototype;
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
Map_Init(&ret->tags);
Map_Init(&ret->ordinary);
+ ret->object_order=malloc(sizeof(struct Queue));
+ Queue_Init(ret->object_order);
+
return (struct Scope*)ret;
}
Map_Init(&ret->labels);
+ ret->label_order=malloc(sizeof(struct Queue));
+ Queue_Init(ret->label_order);
return (struct Scope*)ret;
}
}
- void* check_label(struct Scope *current,struct token *id)
+ struct Denoted_Statement* check_label(struct Scope *current,struct token *id)
{
- void *hold;
- hold=NULL;
- while(current!=NULL && current->type!=FUNCTION_SCOPE)
- {
- current=current->parent;
- }
+ struct Denoted_Statement *hold=NULL;
+ struct Function_Scope *function_scope;
+
+ function_scope=get_enclosing_function_scope(current);
+
+ if(function_scope!=NULL)
+ hold=Map_Check(&function_scope->labels,id->data,id->data_size);
- if(current!=NULL)
- {
- hold=Map_Check(&((struct Function_Scope*)current)->labels,id->data,id->data_size);
- }
return hold;
}
switch(declarator->denotation)
{
- case DT_Label:
+ case DT_Statement:
/*perhaps lables should be denoted*/
assert(0);
case DT_Function:
}
- struct Denoted_Function* get_enclosing_function(struct Scope *scope)
+ struct Function_Scope* get_enclosing_function_scope(struct Scope *scope)
{
struct Scope *current;
current=scope;
assert(current->type!=FILE_SCOPE);
current=current->parent;
}
+ return (struct Function_Scope*)current;
+ }
+ struct Denoted_Object* get_last_known_denoted_object(struct Normal_Scope *scope)
+ {
+ if(scope->object_order->last==NULL)
+ return NULL;
+ else
+ return (struct Denoted_Object*)scope->object_order->last->data;
+ }
+ struct Denoted_Function* get_enclosing_function(struct Scope *scope)
+ {
+ struct Function_Scope *function_scope;
+
+ function_scope=get_enclosing_function_scope(scope);
- if(current==NULL)
+ if(function_scope==NULL)
return NULL;/*TODO maybe return a denoted_error*/
- return ((struct Function_Scope*)current)->function;
+ return function_scope->function;
}
_Bool check_if_typedefed(struct Scope* scope,struct token *id)
{
return 1;
}
- #define CHECK_AND_PUSH(thing,scope) Map_Check_And_Push(scope,thing->id->data,thing->id->data_size,thing)
+ void push_label(struct Scope *current,struct token *label,struct AST *statement,struct Translation_Data *translation_data)
+ {
+ struct Denoted_Statement *hold_statement;
+ struct Function_Scope *current_function_scope;
+ current_function_scope=get_enclosing_function_scope(current);
+
+ hold_statement=(struct Denoted_Statement*)Map_Check(&current_function_scope->labels,label->data,label->data_size);
+
+ if(hold_statement!=NULL)
+ {
+ assert(hold_statement->denotation==DT_Statement);
+
+ if(hold_statement->statement!=NULL)
+ {
+ push_translation_error("Redeclaration of label id %t",translation_data,label);
+ return;
+ }else
+ {
+ assert(hold_statement->label!=NULL);
+ assert(hold_statement->gotos_jumping_to_this_statement->size>0);
+ assert(hold_statement->previous_denoted_object==NULL);
+
+ hold_statement->label=label;
+ hold_statement->statement=statement;
+
+ /*note the use of the current scope instead of the function scope*/
+ hold_statement->previous_denoted_object=get_last_known_denoted_object((struct Normal_Scope*)current);
+
+ assert(hold_statement->previous_denoted_object->denotation==DT_Object);
+ }
+ }else
+ {
+
+ hold_statement=(struct Denoted_Statement*)get_denoted_statement(label,statement,get_last_known_denoted_object((struct Normal_Scope*)current));
+ Map_Push(&current_function_scope->labels,label->data,label->data_size,hold_statement);
+ }
+ }
+
+
+ #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;
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 <map.h>
#include <denoted.h>
#include <location.h>
+ #include <queue.h>
enum Scope_Type;
Map tags;
Map ordinary;
+
+ /*we need the object order for the unconditional jumps*/
+ struct Queue *object_order; /*queue of denoted objects*/
};
struct Function_Scope
{
struct Denoted_Function *function;
Map labels;
+
+ /*here to ease checking of undeclared but used labels*/
+ struct Queue *label_order; /*queue of denoted statements*/
};
struct Scope* get_normal_scope(struct Scope *parent,enum Scope_Type type);
struct Scope* get_function_scope(struct Scope *parent,struct Denoted_Function *function);
- void* check_label(struct Scope *current,struct token *id);
+ 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 push_label(struct Scope *current,struct token *id);/*TODO*/
+ void push_label(struct Scope *current,struct token *label,struct AST *statement,struct Translation_Data *translation_data);
void push_object(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Object *denoted_object);
void push_function(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Function *denoted_function);
void push_typedef(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Type *denoted_typedef);
struct Denoted_Function* get_enclosing_function(struct Scope *scope);
+ struct Function_Scope* get_enclosing_function_scope(struct Scope *scope);
+ struct Denoted_Object* get_last_known_denoted_object(struct Normal_Scope *scope);
void delete_scope(struct Scope *scope);
void delete_normal_scope(struct Normal_Scope *scope);
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
{
return (type->specifier==TS_POINTER || type->specifier==TS_ARRAY || type->specifier==TS_FUNC);
}
+ _Bool type_is_a_variable_length_array(struct Type *type)
+ {
+ return 0;
+ }
_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
_Bool type_is_real(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);
/*these return 0 if constant/volatile-ness make no sense for the type*/
_Bool type_is_constant(struct Type *type);