F diff --git a/all.h b/all.h
--- a/all.h
+++ b/all.h
- #include "lexer.h"
- #include "program.h"
- #include "scope.h"
+ #include "all.h"
+ #include "ast.h"
#include "denoted.h"
- #include "type.h"
+ #include "lexer.h"
+ #include "location.h"
#include "parse_declaration.h"
#include "parse_expression.h"
#include "parse_statement.h"
#include "parse_translation_unit.h"
- #include "ast.h"
+ #include "preprocessing.h"
+ #include "program.h"
+ #include "scope.h"
#include "semantics.h"
+ #include "type.h"
- #include "lexer.c"
- #include "program.c"
- #include "scope.c"
+ #include "ast.c"
+ #include "chonky.c"
+ #include "chonky_jr.c"
+ #include "compile.c"
+ #include "context.c" //delete
#include "denoted.c"
- #include "type.c"
+ #include "lexer.c"
+ #include "location.c"
+ #include "map.c"
+ #include "parse.c"
#include "parse_declaration.c"
#include "parse_expression.c"
#include "parse_statement.c"
#include "parse_translation_unit.c"
- #include "ast.c"
+ #include "preprocessing.c"
+ #include "print.c"
+ #include "program.c"
+ #include "queue.c"
+ #include "scope.c"
#include "semantics.c"
+ #include "stack.c"
+ #include "type.c"
+
+
+
#endif
F diff --git a/ast.c b/ast.c
--- a/ast.c
+++ b/ast.c
struct AST_Declaration_Error* get_declaration_error_tree(struct Denoted *error)
{
- struct AST_Error *ret;
- ret=malloc(sizeof(struct AST_Error));
+ struct AST_Declaration_Error *ret;
+ ret=malloc(sizeof(struct AST_Declaration_Error));
ret->type=ERROR_DECLARATION;
ret->error=error;
return ret;
- struct AST_Type_Definition* get_type_definition_tree(struct Denoted_Typedef *definition,struct Scope *scope);
+ struct AST_Type_Definition* get_type_definition_tree(struct Denoted_Typedef *definition,struct Scope *scope)
{
struct AST_Type_Definition *ret;
ret=malloc(sizeof(struct AST_Type_Definition));
struct AST_Function_Declaration* get_function_declaration_tree(struct Scope *scope,struct Denoted_Function *function)
{
- struct AST_Function_Definition *ret;
- ret=malloc(sizeof(struct AST_Function_Definition));
+ struct AST_Function_Declaration *ret;
+ ret=malloc(sizeof(struct AST_Function_Declaration));
ret->type=ST_FUNCTION_DECLARATION;
ret->function=function;
ret->scope=scope;
F diff --git a/ast.h b/ast.h
--- a/ast.h
+++ b/ast.h
struct AST_Declaration_Error
{
enum AST_Type type;
- struct Denotation *error;
+ struct Denoted *error;
};
struct AST_Binary_Expression
{
F diff --git a/context.c b/context.c
--- a/context.c
+++ b/context.c
#include<assert.h>
- struct Scope
- {
- unsigned used_types;
- unsigned used_vars;
- Map *types;
- Map *variables;
- }
-
- /*use a different function for global scope*/
- struct Scope get_scope(struct Scope *upper_scope)
- {
- struct Scope ret;
- assert(upper_scope==NULL);
-
- ret.used_types=upper_scope->used_types;
- ret.used_vars=upper_scope->used_vars;
-
- ret.types=upper_scope->types;
- ret.variables=upper_scope->variables;
-
- return ret;
- }
-
#endif
F diff --git a/denoted.c b/denoted.c
--- a/denoted.c
+++ b/denoted.c
return (struct Denoted*)ret;
}
- struct Denoted* get_denoted_object(struct token *id, enum Storage_Class sc,struct Location *where,struct Type *type)
+ struct Denoted* get_denoted_object(struct token *id, enum Storage_Class sc,struct Type *type)
{
struct Denoted_Object *ret;
ret=malloc(sizeof(struct Denoted_Object));
ret->object=malloc(sizeof(struct Object));
ret->object->type=type;
- ret->object->location=get_location_for_denoted_object(where,type,id);
+ ret->object->location=NULL;
ret->object->storage_class=sc;
return (struct Denoted*)ret;
return (struct Denoted*)ret;
}
- struct Denoted* get_denoted_enum_const(struct token *id,struct Type_Enum *parent,int value)
+ struct Denoted* get_denoted_enum_const_expr(struct token *id,struct Enum *parent,struct AST* expression)
{
struct Denoted_Enum_Const *ret;
ret=malloc(sizeof(struct Denoted_Enum_Const));
ret->denotation=DT_Enum_Constant;
ret->id=id;
ret->parent=parent;
- ret->value=value;
+ ret->expression=expression;
+ ret->value=evaluate_const_expression_integer(expression);
return (struct Denoted*)ret;
}
+ struct Denoted* get_denoted_enum_const_num(struct token *id,struct Enum *parent,int value)
+ {
+ struct Denoted_Enum_Const *ret;
+ ret=malloc(sizeof(struct Denoted_Enum_Const));
+ ret->denotation=DT_Enum_Constant;
+ ret->id=id;
+ ret->parent=parent;
+ ret->expression=NULL;
+ ret->value=value;
+
+ return (struct Denoted*)ret;
+ }
struct Denoted* get_denoted_enum(struct token *id,struct Enum *enumerator)
{
struct Denoted_Enum *ret;
return (struct Denoted*)ret;
}
+ struct Denoted* extract_denoted(struct Denoted_Base *base,struct Denotation_Prototype *prototype,char allow_abstract)
+ {
+ if(base->type->specifier==TS_FUNC)
+ {
+ if(base->id==NULL && !allow_abstract)
+ {
+ return get_denoted_error(get_denoted_function(NULL,((struct Type_Function*)base->type)->return_type,prototype->function_specifier));
+ }else
+ {
+ return get_denoted_function(base->id,((struct Type_Function*)base->type)->return_type,prototype->function_specifier);
+ }
+ }else if(prototype->storage_class==SC_TYPEDEF)
+ {
+ if(base->id==NULL && !allow_abstract)
+ {
+ return get_denoted_error(get_denoted_typedef(base));
+ }else
+ {
+ return get_denoted_typedef(base);
+ }
+ }else
+ {
+ if(base->id==NULL && !allow_abstract)
+ {
+ return get_denoted_error(get_denoted_object(base->id,prototype->storage_class,base->type));
+ }else
+ {
+ return get_denoted_object(base->id,prototype->storage_class,base->type);
+ }
+ }
+ }
#endif
F diff --git a/denoted.h b/denoted.h
--- a/denoted.h
+++ b/denoted.h
enum Denotation_Type denotation;
struct token *id;
- struct Type_Enum *parent;
+ struct Enum *parent;
int value;
+ struct AST* expression;
};
struct Denoted_Struct_Union
struct Denoted* get_denoted_error(struct Denoted *error);
struct Denoted* get_denoted_function(struct token *id,struct Type *return_type,enum Function_Specifier fs);
- struct Denoted* get_denoted_object(struct token *id, enum Storage_Class sc,struct Location *where,struct Type *type);
+ struct Denoted* get_denoted_object(struct token *id, enum Storage_Class sc,struct Type *type);
struct Denoted* get_denoted_typedef(struct Denoted_Base *base);
- struct Denoted* get_denoted_enum_const(struct token *id,struct Type_Enum *parent,int value);
+ struct Denoted* get_denoted_enum_const_expr(struct token *id,struct Enum *parent,struct AST* expression);
+ struct Denoted* get_denoted_enum_const_num(struct token *id,struct Enum *parent,int value);
struct Denoted* get_denoted_enum(struct token *id,struct Enum *enumerator);
struct Denoted* get_denoted_struct_union(struct token *id,struct Struct_Union *struct_union);
+ struct Denoted* get_denoted_base(struct token *id,struct Type *type,enum Denotation_Type denotation);
+ struct Denoted* extract_denoted(struct Denoted_Base *base,struct Denotation_Prototype *prototype,char allow_abstract);
struct Denoted* get_denotation_prototype();
#endif
F diff --git a/location.c b/location.c
--- a/location.c
+++ b/location.c
struct Location_Stack *hold;
hold=malloc(sizeof(struct Location_Stack));
*hold=*(struct Location_Stack*)base;
- base->offset+=type->size;
+ ((struct Location_Stack*)base)->offset+=get_type_size(type);
return (struct Location*)hold;
}else if(base->type==LT_RELATIVE)
hold=malloc(sizeof(struct Location_Labeled));
hold->id=id;
- return hold;
+ return (struct Location*)hold;
}
}
+ struct Location *get_global_location()
+ {
+ struct Location *ret;
+ ret=malloc(sizeof(struct Location));
+ ret->type=LT_GLOBAL;
+
+ return ret;
+ }
#endif
F diff --git a/location.h b/location.h
--- a/location.h
+++ b/location.h
struct token *id;
};
+ struct Location_Stack* get_location_on_stack(size_t offset);
+ struct Location* get_global_location();
+ struct Location_Raw* get_location_raw(size_t address);
+ struct Location_Relative* get_relative_location(struct Location *base,size_t offset);
+ struct Location* get_location_for_denoted_object(struct Location *base,struct Type *type,struct token *id);
#endif
F diff --git a/main.exe b/main.exe
new file mode 100755
B Binary files /dev/null and b/main.exe differ
F diff --git a/parse_declaration.c b/parse_declaration.c
--- a/parse_declaration.c
+++ b/parse_declaration.c
- #ifndef GCC_PARSE_DECLARATION_CCOMMA
+ #ifndef GCC_PARSE_DECLARATION_C
#define GCC_PARSE_DECLARATION_C GCC_PARSE_DECLARATION_C
#include"parse_declaration.h"
/*declaration-specifiers init-declarator (,init-declarator)* ;*/
/* init-declarator: declarator [ = initializer ] */
- void parse_declaration(struct Queue *tokens,struct Scope *scope,struct Queue *where_to_push,char parse_function_definitions,struct Location *where)
+ void parse_declaration(struct Queue *tokens,struct Scope *scope,struct Queue *where_to_push,char parse_function_definitions)
{
struct Denotation_Prototype *prototype;
struct Denoted *hold;
prototype=parse_declaration_specifiers(tokens,scope);
while(!get_and_check(tokens,KW_SEMI_COLUMN))
{
- hold=parse_declarator(tokens,scope,prototype,where);
+ hold=parse_declarator(tokens,scope,prototype);
if(hold->denotation==DT_Function && parse_function_definitions==1)
{
if(get_and_check(tokens,KW_OPEN_CURLY))
{
- ((struct Denoted_Function*)hold)->body=parse_finish_compound_statement(tokens,scope);
+ ((struct Denoted_Function*)hold)->body=(struct AST_Compound_Statement*)parse_finish_compound_statement(tokens,scope);
Queue_Push(where_to_push,get_function_declaration_tree(scope,(struct Denoted_Function*)hold));
+ Scope_Push(scope,hold);
+ free(prototype);
return;
}
+
Queue_Push(where_to_push,get_function_declaration_tree(scope,(struct Denoted_Function*)hold));
}else if(hold->denotation==DT_Typedef)
{
- Queue_Push(where_to_push,get_type_definition_tree((struct Denoted_Typedef*)hold,scope);
+ Queue_Push(where_to_push,get_type_definition_tree((struct Denoted_Typedef*)hold,scope));
}else if(hold->denotation==DT_Object)
{
Queue_Push(where_to_push,get_object_declaration_tree((struct Denoted_Object*)hold,NULL,scope));
{
/*TODO error*/
Queue_Push(where_to_push,get_declaration_error_tree(hold));
+ free(prototype);
return;
}
+
+ Scope_Push(scope,hold);
parse_function_definitions=0;
}
+ free(prototype);
}
- /*hack*/
struct Denotation_Prototype* parse_specifier_qualifier_list(struct Queue *tokens,struct Scope *scope)
{
- enum KEYWORDS hold_kw;
- struct Denotation_Prototype *ret;
- ret=get_denotation_prototype();
- while(1)
- {
- hold_kw=kw_get(tokens);
- switch(hold_kw)
- {
- case KW_CONST:
- chomp(tokens);
- ret->is_const=1;
- break;
- case KW_VOLATILE:
- chomp(tokens);
- ret->is_volatile=1;
- break;
- case KW_INT:
- chomp(tokens);
- if(ret->specifier!=TS_NONE)
- {
- return get_denotation_error((struct Denoted*)ret);
- }
- ret->specifier=TS_INT;
- break;
- case KW_VOID:
- chomp(tokens);
- if(ret->specifier!=TS_NONE)
- {
- return get_denotation_error((struct Denoted*)ret);
- }
- ret->specifier=TS_VOID;
- break;
- case KW_CHAR:
- chomp(tokens);
- if(ret->specifier!=TS_NONE)
- {
- return get_denotation_error((struct Denoted*)ret);
- }
- ret->specifier=TS_CHAR;
- break;
- case KW_DOUBLE:
- chomp(tokens);
- if(ret->specifier!=TS_NONE)
- {
- return get_denotation_error((struct Denoted*)ret);
- }
- ret->specifier=TS_DOUBLE;
- break;
- case KW_FLOAT:
- chomp(tokens);
- if(ret->specifier!=TS_NONE)
- {
- return get_denotation_error((struct Denoted*)ret);
- }
- ret->specifier=TS_FLOAT;
- break;
- case KW_LONG:
- chomp(tokens);
- if(ret->constraint!=TC_NONE)
- {
- return get_denotation_error((struct Denoted*)ret);
- }
- ret->constraint=TC_LONG;
- break;
- case KW_SHORT:
- chomp(tokens);
- if(ret->constraint!=TC_NONE)
- {
- return get_denotation_error((struct Denoted*)ret);
- }
- ret->constraint=TC_SHORT;
- break;
- case KW_STRUCT:
- ret->specifier=TS_STRUCT;
- goto hack;
- case KW_UNION:
- ret->specifier=TS_UNION;
- hack:
- chomp(tokens);
- if(check(tokens,KW_ID))
- {
- struct token *id;
- struct Denoted_Struct_Union *tag;
- id=Queue_Pop(tokens);
- tag=check_tag(scope,id);
-
- if(tag==NULL)
- {
- struct Struct_Union *body;
- body=parse_struct_union_specifier_finish(tokens,scope);
- tag=get_denoted_struct_union(id,body);
- Scope_Push(scope,(struct Denoted*)tag);
- ret->struct_union=body;
- }else
- {
- ret->struct_union=tag->struct_union;
- if(ret->struct_union->specifier!=ret->specifier)
- {
- return get_denotation_error((struct Denoted*)ret);
- }
- }
-
- }else
- {
- ret->struct_union=parse_struct_union_specifier_finish(tokens,scope);
- }
- break;
- case KW_ENUM:
- chomp(tokens);
- ret->specifier=TS_ENUM;
- if(check(tokens,KW_ID))
- {
- struct token *id;
- struct Denoted_Enum *enumerator;
- id=Queue_Pop(tokens);
- enumerator=check_tag(scope,id);
- if(enumerator==NULL)
- {
- struct Enum body;
- body=parse_enum_specifier_finish(tokens,scope);
- enumerator=get_denoted_enum(id,body);
- Scope_Push(scope,(struct Denoted*)enumerator);
- ret->enumerator=body;
- }else
- {
- ret->enumerator=enumerator->enumeration;
- if(enumeration->enumeration->specifier!=TS_ENUM)
- {
- return get_denotation_error((struct Denoted*)ret);
- }
- }
-
- }else
- {
- ret->enumeration=parse_enum_specifier_finish(tokens,scope);
- }
- break;
- case KW_ID:
- if(ret->specifier==TS_NONE)
- {
- struct Denoted *hold;
- hold=check_ordinary(scope,(struct token*)tokens->first.data);
- if(hold!=NULL && hold->denotation==DT_Typedef)
- {
- chomp();
- ret->type=((struct Denoted_Typedef*)hold)->type;
- break;
- }
- /*falltrough - this has not been typedefed*/
- }
- /*falltrough (it is possible to overwrite typedef id from upper scope)*/
- default:
- if(ret->specifier==TS_ENUM)
- {
- ret->type=get_enum_type(ret);
- }else if(ret->specifier==TS_STRUCT || ret->specifier==TS_UNION)
- {
- ret->type=get_struct_union_type(ret);
- }else if(ret->type==NULL)
- {
- ret->type=get_basic_type(ret);
- }
- return ret;
- }
- }
+ return parse_declaration_specifiers_inner(tokens,scope,0);
}
+ struct Denotation_Prototype* parse_declaration_specifiers(struct Queue *tokens,struct Scope *scope)
+ {
+ return parse_declaration_specifiers_inner(tokens,scope,1);
}
/*declaration-specifiers:
( storage-class-specifier type-specifier type-qualifier function-specifier)* */
- struct Denotation_Prototype* parse_declaration_specifiers(struct Queue *tokens,struct Scope *scope)
+ struct Denotation_Prototype* parse_declaration_specifiers_inner(struct Queue *tokens,struct Scope *scope,char parse_storage_class)
{
enum KEYWORDS hold_kw;
struct Denotation_Prototype *ret;
- ret=get_denotation_prototype();
+ ret=(struct Denotation_Prototype*)get_denotation_prototype();
while(1)
{
chomp(tokens);
if(ret->specifier!=TS_NONE)
{
- return get_denotation_error((struct Denoted*)ret);
+ return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);
}
ret->specifier=TS_INT;
break;
chomp(tokens);
if(ret->specifier!=TS_NONE)
{
- return get_denotation_error((struct Denoted*)ret);
+ return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);
}
ret->specifier=TS_VOID;
break;
chomp(tokens);
if(ret->specifier!=TS_NONE)
{
- return get_denotation_error((struct Denoted*)ret);
+ return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);
}
ret->specifier=TS_CHAR;
break;
chomp(tokens);
if(ret->specifier!=TS_NONE)
{
- return get_denotation_error((struct Denoted*)ret);
+ return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);
}
ret->specifier=TS_DOUBLE;
break;
chomp(tokens);
if(ret->specifier!=TS_NONE)
{
- return get_denotation_error((struct Denoted*)ret);
+ return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);
}
ret->specifier=TS_FLOAT;
break;
chomp(tokens);
if(ret->constraint!=TC_NONE)
{
- return get_denotation_error((struct Denoted*)ret);
+ return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);
}
ret->constraint=TC_LONG;
break;
chomp(tokens);
if(ret->constraint!=TC_NONE)
{
- return get_denotation_error((struct Denoted*)ret);
+ return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);
}
ret->constraint=TC_SHORT;
break;
case KW_EXTERN:
+ if(!parse_storage_class)
+ goto exit;
chomp(tokens);
if(ret->storage_class!=SC_NONE)
{
- return get_denotation_error((struct Denoted*)ret);
+ return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);
}
ret->storage_class=SC_EXTERN;
break;
case KW_STATIC:
+ if(!parse_storage_class)
+ goto exit;
chomp(tokens);
if(ret->storage_class!=SC_NONE)
{
- return get_denotation_error((struct Denoted*)ret);
+ return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);
}
ret->storage_class=SC_STATIC;
break;
case KW_TYPEDEF:
+ if(!parse_storage_class)
+ goto exit;
chomp(tokens);
if(ret->storage_class!=SC_NONE)
{
- return get_denotation_error((struct Denoted*)ret);
+ return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);
}
ret->storage_class=SC_TYPEDEF;
break;
ret->specifier=TS_UNION;
hack:
chomp(tokens);
- if(check(tokens,KW_ID))
+ if(check(tokens,KW_ID,0))
{
struct token *id;
struct Denoted_Struct_Union *tag;
id=Queue_Pop(tokens);
- tag=check_tag(scope,id);
+ tag=(struct Denoted_Struct_Union*)check_tag(scope,id);
if(tag==NULL)
{
struct Struct_Union *body;
- body=parse_struct_union_specifier_finish(tokens,scope);
- tag=get_denoted_struct_union(id,body);
- Scope_Push(scope,(struct Denoted*)tag);
+ body=get_struct_union_base(ret->specifier);
+ parse_struct_union_specifier_finish(tokens,scope,body);
+ Scope_Push(scope,get_denoted_struct_union(id,body));
ret->struct_union=body;
}else
{
ret->struct_union=tag->struct_union;
if(ret->struct_union->specifier!=ret->specifier)
{
- return get_denotation_error((struct Denoted*)ret);
+ return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);
+ }
+ if(ret->struct_union->members->size==0)
+ {
+ /*then this could be a definition*/
+ parse_struct_declaration(tokens,scope,ret->struct_union->members);
}
}
}else
{
- ret->struct_union=parse_struct_union_specifier_finish(tokens,scope);
+ ret->struct_union=get_struct_union_base(ret->specifier);
+ parse_struct_union_specifier_finish(tokens,scope,ret->struct_union);
}
break;
case KW_ENUM:
chomp(tokens);
ret->specifier=TS_ENUM;
- if(check(tokens,KW_ID))
+ if(check(tokens,KW_ID,0))
{
struct token *id;
struct Denoted_Enum *enumerator;
id=Queue_Pop(tokens);
- enumerator=check_tag(scope,id);
+ enumerator=(struct Denoted_Enum*)check_tag(scope,id);
if(enumerator==NULL)
{
- struct Enum body;
- body=parse_enum_specifier_finish(tokens,scope);
- enumerator=get_denoted_enum(id,body);
- Scope_Push(scope,(struct Denoted*)enumerator);
+ struct Enum *body;
+ body=get_enum_base();
+ parse_enum_specifier_finish(tokens,scope,body);
+ Scope_Push(scope,get_denoted_enum(id,body));
ret->enumerator=body;
}else
{
ret->enumerator=enumerator->enumeration;
- if(enumeration->enumeration->specifier!=TS_ENUM)
+ if(enumerator->denotation!=DT_Enum)
+ {
+ return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);
+ }
+ if(ret->enumerator->consts->size==0)
{
- return get_denotation_error((struct Denoted*)ret);
+ /*this could be an enum definition*/
+ parse_enum_specifier_finish(tokens,scope,ret->enumerator);
}
}
}else
{
- ret->enumeration=parse_enum_specifier_finish(tokens,scope);
+ parse_enum_specifier_finish(tokens,scope,ret->enumerator);
}
break;
case KW_ID:
if(ret->specifier==TS_NONE)
{
struct Denoted *hold;
- hold=check_ordinary(scope,(struct token*)tokens->first.data);
+ hold=check_ordinary(scope,(struct token*)tokens->first->data);
if(hold!=NULL && hold->denotation==DT_Typedef)
{
ret->type=((struct Denoted_Typedef*)hold)->type;
- chomp();
+ chomp(tokens);
break;
}
/*falltrough - this has not been typedefed*/
}
/*falltrough (it is possible to overwrite typedef id from upper scope)*/
default:
+ exit:
if(ret->specifier==TS_ENUM)
{
ret->type=get_enum_type(ret);
declarator:
( pointer ( type-qualifier )* )* direct-declarator
*/
- struct Denoted* parse_declarator(struct Queue *tokens,struct Scope *scope,struct Denotation_Prototype *prototype,struct Location *where)
+ struct Denoted* parse_declarator(struct Queue *tokens,struct Scope *scope,struct Denotation_Prototype *prototype)
{
struct Denoted_Base temp;
temp.id=NULL;
temp.denotation=DT_Prototype;
temp.type=prototype->type;
parse_declarator_inner(tokens,scope,&temp);
- if(temp.type->specifier==TS_FUNC)
- {
- if(temp.id==NULL)
- {
- return get_denotation_error(get_denoted_function(NULL,((struct Type_Function*)temp.type)->return_type,prototype->function_specifier));
- }else
- {
- return get_denotation_error(get_denoted_function(temp.id,((struct Type_Function*)temp.type)->return_type,prototype->function_specifier));
- }
- }else if(temp.type->specifier==TS_TYPEDEF)
- {
- if(temp.id==NULL)
- {
- return get_denoted_error(get_denoted_typedef(&temp));
- }else
- {
- return get_denoted_typedef(&temp);
- }
- }else
- {
- if(temp.id==NULL)
- {
- return get_denoted_error(get_denoted_object(temp.id,prototype->storage_class,where,temp.type));
- }else
- {
- return get_denoted_object(temp.id,prototype->storage_class,where,temp.type);
- }
- }
+ return extract_denoted(&temp,prototype,0);
}
{
if(hold==KW_CONST)
{
- (struct Type_Pointer*)(base->type)->is_const=1;
+ ((struct Type_Pointer*)(base->type))->is_const=1;
}else if(hold==KW_VOLATILE)
{
- (struct Type_Pointer*)(base->type)->is_volatile=1;
+ ((struct Type_Pointer*)(base->type))->is_volatile=1;
}else
{
break;
*/
void parse_direct_declarator(struct Queue *tokens,struct Scope *scope,struct Denoted_Base *base)
{
- if(check(tokens,KW_ID))
+ if(check(tokens,KW_ID,0))
{
base->id=Queue_Pop(tokens);
parse_direct_declarator_finish(tokens,scope,base);
struct Queue *hack;
hack=malloc(sizeof(struct Queue));
Queue_Init(hack);
- while(!check(tokens,KW_CLOSE_NORMAL))
+ while(!check(tokens,KW_CLOSE_NORMAL,0))
{
Queue_Push(hack,Queue_Pop(tokens));
}
if(hack->size!=0)
{
/*TODO error*/
+ base->denotation=DT_Error;
while(hack->size)
{
free(Queue_Pop(hack));
}else
{
- /*TODO error*/
- return;
+ /*this might be an abstract declarator*/
+ parse_direct_declarator_finish(tokens,scope,base);
}
}
if(!get_and_check(tokens,KW_CLOSE_NORMAL))
{
base->type=get_type_error(base->type);
+ base->denotation=DT_Error;
return;
}
}else if(get_and_check(tokens,KW_OPEN_NORMAL))
{
struct Queue *parameters;
+ struct Scope *function_prototype_scope;
+
+ function_prototype_scope=get_scope(scope);
+
parameters=malloc(sizeof(struct Queue));
Queue_Init(parameters);
- parse_paramenter_list(tokens,scope,parameters);
- base->type=get_function_type(base->type,parameters);
+
+ parse_paramenter_list(tokens,function_prototype_scope,parameters);
+ base->type=get_function_type(base->type,parameters,function_prototype_scope);
}else
{
struct-union-specifier-finish:
{ ( struct-declaration )* }
*/
- struct Struct_Union* parse_struct_union_specifier_finish(struct Queue *tokens,struct Scope *scope)
+ void parse_struct_union_specifier_finish(struct Queue *tokens,struct Scope *scope,struct Struct_Union *base)
{
- struct Struct_Union *ret;
- ret=get_struct_union_base();
if(get_and_check(tokens,KW_OPEN_CURLY))
{
- while(parse_struct_declaration(tokens,ret->inner_namespace,ret->members));
- if(get_and_check(tokens,KW_CLOSE_CURLY))
- {
- return ret;
- }else
+ while(parse_struct_declaration(tokens,base->inner_namespace,base->members))
{
- /*TODO error*/
- return ret;
+
+ if(get_and_check(tokens,KW_CLOSE_CURLY))
+ {
+ return ;
+ }
}
+ /*TODO error*/
+ return ;
+
}else
{
/*if this isnt a struct definition return an incomplete struct-union*/
- return ret;
+ return ;
}
char parse_struct_declaration(struct Queue *tokens,struct Scope *struct_scope,struct Queue* members)
{
struct Denotation_Prototype *prototype;
- prototype=parse_specifier_qualifier_list(tokens,scope);
+ struct Denoted *hold;
+ prototype=parse_specifier_qualifier_list(tokens,struct_scope);
+ while(!get_and_check(tokens,KW_SEMI_COLUMN))
+ {
+ hold=parse_struct_declarator(tokens,struct_scope,prototype);
+ if(hold!=NULL && hold->denotation!=DT_Error)
+ {
+ Scope_Push(struct_scope,hold);
+ Queue_Push(members,hold);
+
+ }else
+ {
+ free(prototype);
+ /*todo error*/
+ return 0;
+ }
+ }
+ free(prototype);
+ return 1;
}
/*
declarator
[ declarator ] : constant-expression
*/
- struct Denoted* parse_struct_declarator(struct Queue *tokens,struct Scope *struct_scope,struct Denoted *origin)
+ struct Denoted* parse_struct_declarator(struct Queue *tokens,struct Scope *scope,struct Denotation_Prototype *prototype)
{
+ struct Denoted *hold;
+ if(get_and_check(tokens,KW_COLUMN))
+ {
+ /*unnamed bitfields are possible*/
+ struct Denoted_Object *obj;
+ obj=(struct Denoted_Object*)get_denoted_object(NULL,SC_NONE,prototype->type);
+ obj->object->type=get_type_bitfield(prototype->type,parse_expression(tokens,scope));
+ return (struct Denoted*)obj;
+ }else
+ {
+ hold=parse_declarator(tokens,scope,prototype);
+ if(get_and_check(tokens,KW_COLUMN))
+ {
+ if(hold->denotation==DT_Object)
+ {
+ ((struct Denoted_Object*)hold)->object->type=get_type_bitfield(((struct Denoted_Object*)hold)->object->type,parse_expression(tokens,scope));
+ return hold;
+ }else
+ {
+ /*TODO error*/
+ return get_denoted_error(hold);
+ }
+ }
+ }
+
}
/*
enum-specifier-finish
- { ( enumeration-constant [ = constant-expression ] )* }
+ { ( enumeration-constant [ = constant-expression ] , )* }
*/
- struct Enum* parse_enum_specifier_finish(struct Queue *tokens,struct Scope *scope)
+ void parse_enum_specifier_finish(struct Queue *tokens,struct Scope *scope,struct Enum *enumeration)
{
+ struct token *id;
+ struct Denoted_Enum_Const *hold;
+ int where_in_enumeration=0;
+ if(get_and_check(tokens,KW_OPEN_CURLY))
+ {
+ do
+ {
+ if(check(tokens,KW_ID,0))
+ {
+ id=Queue_Pop(tokens);
+ if(get_and_check(tokens,KW_EQ))
+ {
+ hold=(struct Denoted_Enum_Const*)get_denoted_enum_const_expr(id,enumeration,parse_expression(tokens,scope));
+ Queue_Push(enumeration->consts,hold);
+ where_in_enumeration=hold->value+1;
+ }else
+ {
+ Queue_Push(enumeration->consts,get_denoted_enum_const_num(id,enumeration,where_in_enumeration));
+ ++where_in_enumeration;
+ }
+ if(!get_and_check(tokens,KW_COMMA) && get_and_check(tokens,KW_CLOSE_CURLY))
+ {
+ return;
+ }else
+ {
+ /*TODO error*/
+ Queue_Push(enumeration->consts,get_denoted_error(NULL));
+ return ;
+ }
+ }else
+ {
+ /*TODO error*/
+ Queue_Push(enumeration->consts,get_denoted_error(NULL));
+ return ;
+ }
+ }while(!get_and_check(tokens,KW_CLOSE_CURLY));
+ }
}
/*
parameter-list:
(declaratoion-specifiers (declarator | abstract-declarator),)+
*/
- void parse_paramenter_list(struct Queue *tokens,struct Scope *scope,struct Queue *parameters)
- {
-
- }
- /*
- id-list:
- id,...
- */
- void parse_id_list(struct Queue *tokens,struct Scope *scope,struct Queue *ids)
+ void parse_paramenter_list(struct Queue *tokens,struct Scope *function_prototype_scope,struct Queue *parameters)
{
+ struct Denotation_Prototype *prototype;
+ struct Denoted_Base temp;
+ struct Denoted *hold;
+ temp.denotation=DT_Prototype;
+ do
+ {
+ prototype=parse_declaration_specifiers(tokens,function_prototype_scope);
- }
+ temp.id=NULL;
+ temp.type=prototype->type;
+
+ parse_declarator_inner(tokens,function_prototype_scope,&temp);
+ hold=extract_denoted(&temp,prototype,1);
+
+ Scope_Push(function_prototype_scope,hold);
+ Queue_Push(parameters,hold);
+
+ free(prototype);
+ }while(get_and_check(tokens,KW_COMMA));
+
+ }
/*
type-name:
specifier-qualifier-list [abstract-declarator]
*/
struct Type* parse_type_name(struct Queue *tokens,struct Scope *scope)
{
-
+ struct Denotation_Prototype *prototype;
+ struct Type *ret;
+ prototype=parse_specifier_qualifier_list(tokens,scope);
+ ret=parse_abstract_declarator(tokens,scope,prototype->type);
+ free(prototype);
+ return ret;
}
/*
abstract-declarator:
*/
struct Type* parse_abstract_declarator(struct Queue *tokens,struct Scope *scope,struct Type *base)
{
+ struct Denoted_Base hold;
+ hold.denotation=DT_Prototype;
+ hold.id=NULL;
+ hold.type=base;
+ parse_declarator_inner(tokens,scope,&hold);
+ if(hold.denotation==DT_Error || hold.id!=NULL)
+ {
+ /*TODO error*/
+ return get_type_error(hold.type);
+ }
+ return hold.type;
}
/*
- abstract-direct-declarator:
- ( abstract-declarator )
- abstract-declarator-finish
- */
- struct Type* parse_abstract_direct_declarator(struct Queue *tokens,struct Scope *scope,struct Type *base)
- {
-
- }
-
- /*
- abstract-declarator-finish:
- ( [ constant-expression] | ( parameter-type-list) )*
- */
- struct Type* parse_abstract_declarator_finish(struct Queue *tokens,struct Scope *scope,struct Type *base)
- {
-
- }
- /*
initializer:
assignment-expression
{ initializer , ... [,] }
*/
struct AST* parse_initializer(struct Queue *tokens,struct Scope *scope,struct Denoted_Object *base)
{
-
+
}
#endif
F diff --git a/parse_declaration.h b/parse_declaration.h
--- a/parse_declaration.h
+++ b/parse_declaration.h
#include "lexer.h"
#include <assert.h>
- struct AST* parse_declaration(struct Queue *tokens,struct Scope *scope);
+ struct Denoted_Base;
+ struct Denotation_Prototype;
+ struct Struct_Union;
+ struct Denoted_Object;
+
+
+ void parse_declaration(struct Queue *tokens,struct Scope *scope,struct Queue *where_to_push,char parse_function_definitions);
+ struct Denotation_Prototype* parse_specifier_qualifier_list(struct Queue *tokens,struct Scope *scope);
+ struct Denotation_Prototype* parse_declaration_specifiers(struct Queue *tokens,struct Scope *scope);
+ struct Denotation_Prototype* parse_declaration_specifiers_inner(struct Queue *tokens,struct Scope *scope,char parse_storage_class);
+ struct Denoted* parse_declarator(struct Queue *tokens,struct Scope *scope,struct Denotation_Prototype *prototype);
+ void parse_declarator_inner(struct Queue *tokens,struct Scope *scope,struct Denoted_Base *base);
+ void parse_direct_declarator(struct Queue *tokens,struct Scope *scope,struct Denoted_Base *base);
+ void parse_direct_declarator_finish(struct Queue *tokens,struct Scope *scope,struct Denoted_Base *base);
+ void parse_struct_union_specifier_finish(struct Queue *tokens,struct Scope *scope,struct Struct_Union *base);
+ char parse_struct_declaration(struct Queue *tokens,struct Scope *struct_scope,struct Queue* members);
+ struct Denoted* parse_struct_declarator(struct Queue *tokens,struct Scope *scope,struct Denotation_Prototype *prototype);
+ void parse_enum_specifier_finish(struct Queue *tokens,struct Scope *scope,struct Enum *enumeration);
+ void parse_paramenter_list(struct Queue *tokens,struct Scope *function_prototype_scope,struct Queue *parameters);
+ struct Type* parse_type_name(struct Queue *tokens,struct Scope *scope);
+ struct Type* parse_abstract_declarator(struct Queue *tokens,struct Scope *scope,struct Type *base);
+ struct AST* parse_initializer(struct Queue *tokens,struct Scope *scope,struct Denoted_Object *base);
#endif
F diff --git a/parse_statement.c b/parse_statement.c
--- a/parse_statement.c
+++ b/parse_statement.c
{
if(is_type(tokens,scope))
{
- Queue_Push(&hold->components,parse_declaration(tokens,hold->scope));
+ parse_declaration(tokens,hold->scope,&hold->components,0);
}else
{
Queue_Push(&hold->components,parse_statement(tokens,hold->scope));
F diff --git a/parse_translation_unit.c b/parse_translation_unit.c
--- a/parse_translation_unit.c
+++ b/parse_translation_unit.c
#include "parse_declaration.h"
#include "parse_statement.h"
/*
-
- function-definition:
- [ declaration-specifiers ] declarator
- [ declaration-list ] compound-statement
- */
-
- struct AST* parse_function_definition(struct Queue *tokens,struct Scope *scope)
- {
- struct AST_Function_Definition *ret;
- ret=get_function_definition_tree(scope);
-
- if(is_type(tokens,scope))
- ret->base_type=parse_declaration_specifiers(tokens,scope);
- else
- ret->base_type=NULL;
-
-
- ret->declarator=get_declarator(ret->base_type);
- parse_declarator(tokens,ret->declarator,scope);
- /*TODO*/
- //[ declaration-list ] compound-statement
- if(get_and_check(tokens,KW_OPEN_CURLY))
- {
- ret->body_statement=parse_finish_compound_statement(tokens,scope);
- }else
- {
- return (struct AST*)get_error_tree((struct AST*)ret);
- }
-
- return (struct AST*)ret;
- }
-
- /*
- translation_unit_step:
- declaration
- function-definition
-
- delcaration:
- declaration-specifiers [ init-declarator-list ] ;
-
- */
- struct AST* parse_translation_unit_step(struct Queue *tokens,struct Scope *scope)
- {
- struct Type_Node *base_type;
- struct Declarator *declarator;
-
- if(!is_type(tokens,scope))
- {
- /*this is a function definition with default base_type of int*/
- return (struct AST*)parse_function_definition(tokens,scope);
- }
- base_type=parse_declaration_specifiers(tokens,scope);
- declarator=get_declarator(base_type);
- parse_declarator(tokens,declarator,scope);
- if(get_and_check(tokens,KW_COMMA))
- {
- /*this is a declaration*/
- struct AST_Declaration *ret;
- ret=get_declaration_tree(scope);
- ret->base_type=base_type;
- Queue_Push(&ret->declarators,declarator);
- Scope_Push(scope,declarator);
-
- do
- {
- parse_declarator(tokens,declarator,scope);
- Queue_Push(&ret->declarators,declarator);
- Scope_Push(scope,declarator);
- }while(get_and_check(tokens,KW_COMMA));
-
- if(get_and_check(tokens,KW_SEMI_COLUMN))
- {
- return (struct AST*)ret;
- }else
- {
- return (struct AST*)get_error_tree((struct AST*)ret);
- }
-
- }else if(get_and_check(tokens,KW_SEMI_COLUMN))
- {
- struct AST_Declaration *ret;
- ret=get_declaration_tree(scope);
- ret->base_type=base_type;
- Queue_Push(&ret->declarators,declarator);
- Scope_Push(scope,declarator);
- return (struct AST*)ret;
-
- }else
- {
- /*this is a function call*/
- struct AST_Function_Definition *ret;
- ret=get_function_definition_tree(scope);
- ret->base_type=base_type;
- ret->declarator=declarator;
- if(get_and_check(tokens,KW_OPEN_CURLY))
- {
- ret->body_statement=parse_finish_compound_statement(tokens,scope);
- ret->scope=scope;
- return (struct AST*)ret;
- }else
- {
- return (struct AST*)get_error_tree((struct AST*)ret);
- }
-
- }
-
-
- }
-
- /*
translation-unit:
declaration [ translation-unit ]
function-definition [ translation-unit ]
struct AST* parse_translation_unit(struct Queue *tokens,struct Scope *scope)
{
struct AST_Translation_Unit *hold;
- struct AST *temp;
hold=get_translation_unit_tree(scope);
while(tokens->size>0)
{
- temp=parse_translation_unit_step(tokens,hold->scope);
- Queue_Push(&hold->components,temp);
- if(temp->type==ERROR)
- {
- return (struct AST*)get_error_tree((struct AST*)hold);
- }
-
+ parse_declaration(tokens,hold->scope,&hold->components,1);
}
return (struct AST*)hold;
F diff --git a/print.c b/print.c
--- a/print.c
+++ b/print.c
#ifndef GCC_PRINT
#define GCC_PRINT GCC_PRINT
- #include<stdio.h>
- #include<assert.h>
- #include "all.h"
+ #include "print.h"
- #define INDENT for(int j=0;j<indent;++j) fprintf(out," ");
- #define TOK(s) ((struct token*)(s))
- #define ASTPTR(s) ((struct AST*)(s))
- int indent;
- void print_ast(FILE *out,struct AST* tree);
- void print_type_giberish(FILE* out,struct Type* type);
- void print_keyword_enum(FILE *out,enum KEYWORDS kw);
-
void print_token(FILE *out,struct token *token)
{
size_t i;
}
}
- void print_declarators(FILE *out,struct Queue *declarators)
- {
- struct Queue_Node *it;
- struct Declarator *dec;
- for(it=declarators->first;NULL;it=it->prev)
- {
- dec=(struct Declarator*)(it->data);
- print_type_giberish(out,dec->type);
- fprintf(out,",");
- }
- }
- void print_struct_union_node(FILE *out,struct Type_Node *type)
- {
- struct Queue_Node *it;
- struct AST *dec;
- assert(type->type_specifier==TS_UNION || type->type_specifier==TS_STRUCT);
- if(type->specifics.struct_union->id!=NULL)
- {
- print_token(out,type->specifics.struct_union->id);
- fprintf(out,"\n{");
- }
- for(it=type->specifics.struct_union->declarations.first;it!=NULL;it=it->prev)
- {
- dec=(struct AST*)(it->data);
- print_ast(out,dec);
- fprintf(out,";\n");
- }
-
- }
-
- void print_type_node(FILE* out,struct Type_Node* type)
- {
- short i;
- struct Queue_Node *it;
- struct Declarator *dec;
-
- if(type->type_def)
- {
- print_type_giberish(out,type->type_def);
- return;
- }
-
- if(type->is_const)
- fprintf(out,"CONSTANT ");
- if(type->is_volatile)
- fprintf(out,"VOLATILE ");
-
- switch(type->type_specifier)
- {
- case TS_VOID:
- fprintf(out,"VOID");break;
- case TS_CHAR:
- fprintf(out,"CHAR");break;
- case TS_INT:
- fprintf(out,"INT");break;
- case TS_FLOAT:
- fprintf(out,"FLOAT");break;
- case TS_DOUBLE:
- fprintf(out,"DOUBLE");break;
- case TS_STRUCT:
- fprintf(out,"\nstruct ");
- print_struct_union_node(out,type);
- fprintf(out,"\n}\n");
- break;
- case TS_UNION:
- fprintf(out,"\nunion ");
- print_struct_union_node(out,type);
- fprintf(out,"\n}\n");
- break;
- case TS_ENUM:
- fprintf(out,"ENUM");
- break;
- case TS_TYPEDEF:
- fprintf(out,"TYPEDEF");break;
- case TS_POINTER:
- fprintf(out,"POINTER to ");
- break;
- case TS_ARRAY:
- fprintf(out,"ARRAY[");
- if(type->specifics.arr.number_of_elements_expr!=NULL)
- //print_ast(out,type->specifics.number_of_elements);
- fprintf(out,"%i",type->specifics.arr.number_of_elements);
- fprintf(out,"] of ");
- break;
- case TS_FUNC:
- fprintf(out,"FUNC taking argumens (");
- for(it=type->specifics.arg_types.first;it!=type->specifics.arg_types.last;it=it->prev)
- {
- dec=(struct Declarator*)(it->data);
- print_type_giberish(out,dec->type);
- fprintf(out,",");
- }
- if(it!=NULL)
- {
- dec=(struct Declarator*)(it->data);
- print_type_giberish(out,dec->type);
- fprintf(out,",");
- }
- fprintf(out,") returning ");
- break;
- case TS_NONE:
- fprintf(out,"NONE");break;
- case TS_PTR_ERROR:
- fprintf(out,"PTR_ERROR");break;
- case TS_ARR_ERROR:
- fprintf(out,"ARR_ERROR");break;
- case TS_FUNC_ERROR:
- fprintf(out,"FUNC_ERROR");break;
- case TS_GROUP_ERROR:
- fprintf(out,"GROUP_ERROR");break;
- }
- }
- void print_type_giberish(FILE* out,struct Type* type)
- {
- if(type!=NULL)
- {
- struct Queue_Node *it;
- for(it=type->components.first;it!=NULL;it=it->prev)
- {
- print_type_node(out,(struct Type_Node*)(it->data));
- }
- fprintf(out," SIZE=%zu",type->size);
- }
- }
void print_ast_enum(FILE *out,enum AST_Type op)
{
switch(op)
fprintf(out,"return");break;
case ST_FOR:
fprintf(out,"for");break;
- case ST_DECLARATION:
- fprintf(out,"DECLARATION");break;
+
+ /*TODO obj dec obj def func decl*/
case ST_FUNCTION_DEFINITION:
fprintf(out,"FUNCTION_DEFINITION");break;
case TRANSLATION_UNIT:
fprintf(out,"ERROR");
if(error->error!=NULL)
{
- if(error->error->type==ST_DECLARATION)
- {
- fprintf(out,"ST_DECLARATION");
- }else
- {
- print_ast(out,error->error);
- }
+ print_ast(out,error->error);
}
}
void print_binary_expression_tree(FILE *out,struct AST_Binary_Expression *bin)
if(unary_expression->type==OP_CAST)
{
fprintf(out,"(");
- print_type_giberish(out,unary_expression->value_type);
+ print_type(out,unary_expression->value_type);
fprintf(out,")");
}
print_ast(out,unary_expression->operand);
fprintf(out,"goto ");
print_token(out,got->label);
}
- void print_declaration_tree(FILE *out,struct AST_Declaration *declaration)
+
+ void print_type(FILE *out,struct Type *type)
{
- struct Queue_Node *it;
- struct Declarator *hold;
- fprintf(out,"DECLARATION {[\n");
- for(it=declaration->declarators.first;it!=NULL;it=it->prev)
+ switch(type->specifier)
{
- hold=(struct Declarator*)(it->data);
- if(hold->id!=NULL)
- {
- print_token(out,hold->id);
- fprintf(out," IS a/an ");
- }
- print_type_giberish(out,hold->type);
+ case TS_VOID:
+ fprintf(out,"void");return;
+ case TS_CHAR:
+ fprintf(out,"char");return;
+ case TS_INT:
+ fprintf(out,"int");return;
+ case TS_FLOAT:
+ fprintf(out,"float");return;
+ case TS_DOUBLE:
+ fprintf(out,"double");return;
+ case TS_UNION:
+ case TS_STRUCT:
+ print_struct_union(out,((struct Type_Struct_Union*)type)->struct_union);
+ return;
+ case TS_ENUM:
+ print_enumeration(out,((struct Type_Enum*)type)->enumeration);
+ return;
+ case TS_POINTER:
+ fprintf(out,"pointer to ");
+
+ print_type(out,((struct Type_Pointer*)type)->points_to);
+ return;
+ case TS_ARRAY:
+ fprintf(out,"array [%zu] of ",((struct Type_Array*)type)->number_of_elements);
+ print_type(out,((struct Type_Array*)type)->is_array_of);
+ return;
+ case TS_FUNC:
+ fprintf(out,"a function taking arguments ");
+ print_list_of_denoted(out,((struct Type_Function*)type)->parameters);
+ fprintf(out,"returning ");
+ print_type(out,((struct Type_Function*)type)->return_type);
+ return;
+ case TS_BITFIELD:
+ fprintf(out,"%zu bits of ",((struct Type_Bit_Field*)type)->number_of_bits);
+ print_type(out,((struct Type_Bit_Field*)type)->base);
+ return;
+ case TS_NONE:
+ fprintf(out,"NONE");return;
+ case TS_ERROR:
+ fprintf(out,"ERROR!");return;
- fprintf(out,"\n");
- if(hold->initialiser!=NULL)
- {
- fprintf(out,"\tINITIALISED WITH ");
- print_ast(out,hold->initialiser);
- fprintf(out,"\n");
- }
}
- fprintf(out,"END DECLARATION]}\n");
+ assert(1==0);
}
- void print_function_definition_tree(FILE *out,struct AST_Function_Definition *def)
+ void print_denoted(FILE *out,struct Denoted *denoted)
{
- fprintf(out,"FUNCTION DEFINITION:\n");
- print_token(out,def->declarator->id);
- print_type_giberish(out,def->declarator->type);
- print_ast(out,def->body_statement);
+ switch(denoted->denotation)
+ {
+ case DT_Macro:
+ fprintf(out,"macro ");return;
+ case DT_Macro_Parameter:
+ fprintf(out,"macro parameter ");return;
+ case DT_Label:
+ fprintf(out,"label ");return;
+ case DT_Object:
+ fprintf(out,"object");return;
+ case DT_Typedef:
+ fprintf(out,"typedef ");
+ print_token(out,((struct Denoted_Typedef*)denoted)->id);
+ fprintf(out,"to ");
+ print_type(out,((struct Denoted_Typedef*)denoted)->type);
+ return;
+ case DT_Function:
+ print_token(out,((struct Denoted_Function*)denoted)->id);
+ fprintf(out,"is a");
+ print_type(out,((struct Denoted_Function*)denoted)->return_type);
+ return;
+ case DT_Enum:
+ print_token(out,((struct Denoted_Enum*)denoted)->id);
+ fprintf(out,"is a");
+ print_enumeration(out,((struct Denoted_Enum*)denoted)->enumeration);
+ return;
+ case DT_Enum_Constant:
+ fprintf(out,"%i ",((struct Denoted_Enum_Const*)denoted)->value);
+ return;
+ case DT_Struct_Union_Tag:
+ print_token(out,((struct Denoted_Struct_Union*)denoted)->id);
+ fprintf(out,"is a");
+ print_struct_union(out,((struct Denoted_Struct_Union*)denoted)->struct_union);
+ case DT_Error:
+ fprintf(out,"denotation error");return;
+ case DT_Prototype:
+ fprintf(out,"denotation prototyep");return;
+
+ }
+ }
+ void print_list_of_denoted(FILE *out,struct Queue *denoted)
+ {
+ struct Queue_Node *it;
+ for(it=denoted->first;it!=NULL;it=it->prev)
+ {
+ print_denoted(out,(struct Denoted*)it->data);
+ if(it->prev!=NULL)
+ fprintf(out,",");
+ }
+ }
+ void print_enumeration(FILE *out,struct Enum *enumeration)
+ {
+ fprintf(out,"enum ");
+ print_list_of_denoted(out,enumeration->consts);
+ }
+ void print_struct_union(FILE *out,struct Struct_Union *struct_union)
+ {
+ switch(struct_union->specifier)
+ {
+ case TS_UNION:
+ fprintf(out,"union ");
+ break;
+ case TS_STRUCT:
+ fprintf(out,"struct ");
+ break;
+ default:
+ assert(1==0);
+ }
+ print_list_of_denoted(out,struct_union->members);
+
}
void print_translation_unit_tree(FILE *out,struct AST_Translation_Unit *unit)
{
{
hold=(struct AST*)(it->data);
print_ast(out,hold);
- if(hold->type==ST_DECLARATION)
+ if(hold->type!=ST_FUNCTION_DEFINITION)
{
fprintf(out,";\n");
}
case ST_COMPOUND:
print_compound_statement_tree(out,(struct AST_Compound_Statement*)tree);
break;
- case ST_DECLARATION:
- print_declaration_tree(out,(struct AST_Declaration*)tree);
+ case ST_OBJECT_DECLARATION:
+ print_denoted(out,(struct Denoted*)((struct AST_Object_Declaration*)tree)->object);
+ fprintf(out,"=");
+ print_ast(out,((struct AST_Object_Declaration*)tree)->initializer);
+ break;
+ case ST_FUNCTION_DECLARATION:
+ print_denoted(out,(struct Denoted*)((struct AST_Function_Declaration*)tree)->function);
break;
case ST_FUNCTION_DEFINITION:
- print_function_definition_tree(out,(struct AST_Function_Definition*)tree);
+ print_function_definition(out,((struct AST_Function_Declaration*)tree)->function);
break;
case TRANSLATION_UNIT:
print_translation_unit_tree(out,(struct AST_Translation_Unit*)tree);
}
}
+
+ void print_function_definition(FILE *out,struct Denoted_Function *function)
+ {
+ print_token(out,function->id);
+ fprintf(out,"is a ");
+ print_type(out,function->return_type);
+ print_ast(out,(struct AST*)function->body);
+ }
void print_program_tokens(FILE *out,struct Program *program)
{
struct Queue_Node *it;
F diff --git a/print.h b/print.h
new file mode 100644
--- /dev/null
+++ b/print.h
+ #ifndef GCC_PRINT_H
+ #define GCC_PRINT_H GCC_PRINT_H
+
+ #include<stdio.h>
+ #include<assert.h>
+ #include "all.h"
+
+
+ #define INDENT for(int j=0;j<indent;++j) fprintf(out," ");
+ #define TOK(s) ((struct token*)(s))
+ #define ASTPTR(s) ((struct AST*)(s))
+
+ int indent;
+
+ void print_token(FILE *out,struct token *token);
+ void print_tokens(FILE *out,struct Queue *tokens);
+ void print_ast_enum(FILE *out,enum AST_Type op);
+ void print_error_tree(FILE *out,struct AST_Error *error);
+ void print_binary_expression_tree(FILE *out,struct AST_Binary_Expression *bin);
+ void print_conditional_expression_tree(FILE *out,struct AST_Conditional_Expression *cond);
+ void print_function_expression_tree(FILE *out,struct AST_Function_Expression *function_call);
+ void print_unary_expression_tree(FILE *out,struct AST_Unary_Expression *unary_expression);
+ void print_rvalue_expression_tree(FILE *out,struct AST_Rvalue_Expression *rval);
+ void print_lvalue_expression_tree(FILE *out,struct AST_Lvalue_Expression *lval);
+ void print_labeled_statement_tree(FILE *out,struct AST_Labeled_Statement *lab);
+ void print_compound_statement_tree(FILE *out,struct AST_Compound_Statement *comp);
+ void print_if_statement_tree(FILE *out,struct AST_If_Statement *ifs);
+ void print_switch_statement_tree(FILE *out,struct AST_Switch_Statement *swi);
+ void print_while_statement_tree(FILE *out,struct AST_While_Statement *whi);
+ void print_do_while_statement_tree(FILE *out,struct AST_Do_While_Statement *whi);
+ void print_for_statement_tree(FILE *out,struct AST_For_Statement *fo);
+ void print_return_statement_tree(FILE *out,struct AST_Return_Statement *return_expression);
+ void print_goto_statement_tree(FILE *out,struct AST_Goto_Statement *got);
+ void print_type(FILE *out,struct Type *type);
+ void print_denoted(FILE *out,struct Denoted *denoted);
+ void print_list_of_denoted(FILE *out,struct Queue *denoted);
+ void print_enumeration(FILE *out,struct Enum *enumeration);
+ void print_struct_union(FILE *out,struct Struct_Union *struct_union);
+ void print_translation_unit_tree(FILE *out,struct AST_Translation_Unit *unit);
+ void print_ast(FILE *out,struct AST* tree);
+ 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);
+
+
+ #endif
F diff --git a/scope.c b/scope.c
--- a/scope.c
+++ b/scope.c
Map_Init(&ret->tags);
Map_Init(&ret->ordinary);
ret->parent=parent;
+ if(parent==NULL)
+ {
+ ret->location=get_global_location();
+ }else
+ {
+ ret->location=(struct Location*)get_relative_location(parent->location,0);
+ }
return ret;
}
return hold;
}
- struct Denoted_Struct_Union* check_tag(struct Scope *current,struct token *id)
+ struct Denoted* check_tag(struct Scope *current,struct token *id)
{
void *hold;
hold=NULL;
hold=Map_Check(¤t->tags,id->data,id->data_size);
current=current->parent;
}
- return (struct Denoted_Struct_Union*)hold;
+ return hold;
}
void* check_ordinary(struct Scope *current,struct token *id)
{
F diff --git a/scope.h b/scope.h
--- a/scope.h
+++ b/scope.h
#define GCC_SCOPE_H GCC_SCOPE_H
#include "map.c"
#include "denoted.h"
+ #include "location.h"
struct Scope
{
Map ordinary;
struct Scope *parent;
+ struct Location *location;
};
struct Scope* get_scope(struct Scope *parent);
void* check_label(struct Scope *current,struct token *id);
- struct Denoted_Struct_Union* check_tag(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);
char Scope_Push(struct Scope *scope,struct Denoted* denoted);
char check_if_typedefed(struct Scope* scope,struct token *id);
F diff --git a/type.c b/type.c
--- a/type.c
+++ b/type.c
struct Enum *ret;
ret=malloc(sizeof(struct Enum));
ret->specifier=TS_ENUM;
- ret->number_of_constants=0;
- ret->consts=NULL;
+ ret->consts=malloc(sizeof(struct Queue));
+ Queue_Init(ret->consts);
return ret;
}
}
return (struct Type*)ret;
}
- struct Type* get_type_bitfield(struct Type* base,size_t number_of_bits)
+ struct Type* get_type_bitfield(struct Type* base,struct AST* number_of_bits)
{
struct Type_Bit_Field *ret;
ret=malloc(sizeof(struct Type_Bit_Field));
ret->specifier=TS_BITFIELD;
- ret->number_of_bits=number_of_bits;
+ ret->expression=number_of_bits;
+ ret->number_of_bits=evaluate_const_expression_integer(number_of_bits);
ret->base=base;
return (struct Type*)ret;
}
- struct Type* get_function_type(struct Type* return_type,struct Queue *parameters)
+ struct Type* get_function_type(struct Type* return_type,struct Queue *parameters,struct Scope* function_prototype_scope)
{
struct Type_Function *ret;
ret=malloc(sizeof(struct Type_Function));
ret->specifier=TS_FUNC;
ret->return_type=return_type;
ret->parameters=parameters;
+ ret->function_prototype_scope=function_prototype_scope;
return (struct Type*)ret;
}
+ char is_type(struct Queue *tokens,struct Scope *scope)
+ {
+ struct token *hold;
+ struct Denoted *thing;
+
+ hold=tokens->first->data;
+
+ switch(hold->type)
+ {
+ case KW_ID:
+ thing=check_ordinary(scope,hold);
+ if(thing->denotation==DT_Typedef)
+ return 1;
+ else return 0;
+ case KW_CONST:
+ case KW_VOLATILE:
+ case KW_INT:
+ case KW_VOID:
+ case KW_CHAR:
+ case KW_DOUBLE:
+ case KW_FLOAT:
+ case KW_LONG:
+ case KW_SHORT:
+ case KW_EXTERN:
+ case KW_STATIC:
+ case KW_TYPEDEF:
+ case KW_STRUCT:
+ case KW_UNION:
+ case KW_ENUM:
+ return 1;
+ default:
+ return 0;
+
+ }
+ }
+ size_t get_type_size(struct Type *type)
+ {
+ switch(type->specifier)
+ {
+ case TS_VOID:
+ return 0;
+ case TS_CHAR:
+ return 1;
+ case TS_INT:
+ return INT_SIZE;
+ case TS_FLOAT:
+ return FLOAT_SIZE;
+ case TS_DOUBLE:
+ return FLOAT_SIZE*2;
+ case TS_STRUCT:
+ return ((struct Type_Struct_Union*)type)->struct_union->size;
+ case TS_ENUM:
+ return INT_SIZE;
+ case TS_UNION:
+ return ((struct Type_Struct_Union*)type)->struct_union->size;
+ case TS_POINTER:
+ return PTR_SIZE;
+ case TS_ARRAY:
+ return ((struct Type_Array*)type)->size;
+ case TS_FUNC:
+ return 0;
+ case TS_BITFIELD:
+ return ((struct Type_Bit_Field*)type)->number_of_bits;
+ case TS_NONE:
+ return 0;
+ case TS_ERROR:
+ return 0;
+
+ }
+ }
#endif
F diff --git a/type.h b/type.h
--- a/type.h
+++ b/type.h
TS_STRUCT,
TS_ENUM,
TS_UNION,
- TS_TYPEDEF,
TS_POINTER,
TS_ARRAY,
TS_FUNC,
enum Type_Specifier specifier;
struct Type *return_type;
struct Queue *parameters;
+ struct Scope *function_prototype_scope;
};
struct Type_Enum
struct Enum
{
enum Type_Specifier specifier;
- size_t number_of_constants;
- struct Denoted_Enum_Const **consts;
+ struct Queue *consts;
};
struct Type* get_type_error(struct Type* error);
struct Type* get_struct_union_type(struct Denotation_Prototype *prototype);
- struct Struct_Union* get_struct_union_base();
+ struct Struct_Union* get_struct_union_base(enum Type_Specifier struct_or_union);
struct Enum *get_enum_base();
struct Type* get_basic_type(struct Denotation_Prototype *prototype);
struct Type* get_pointer_type(struct Type* points_to);
struct Type* get_array_type(struct Type *is_array_of,struct AST* number_of_elements);
struct Type* get_enum_type(struct Denotation_Prototype *prototype);
- struct Type* get_type_bitfield(struct Type* base,size_t number_of_bits);
- struct Type* get_function_type(struct Type* return_type,struct Queue *parameters);
+ struct Type* get_type_bitfield(struct Type* base,struct AST* number_of_bits);
+ struct Type* get_function_type(struct Type* return_type,struct Queue *parameters,struct Scope* function_prototype_scope);
+ char is_type(struct Queue *tokens,struct Scope *scope);
+ size_t get_type_size(struct Type *type);