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"+++#endifF diff --git a/ast.c b/ast.c --- a/ast.c +++ b/ast.cstruct 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.hstruct 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;- }-#endifF diff --git a/denoted.c b/denoted.c --- a/denoted.c +++ b/denoted.creturn (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);+ }+ }+ }#endifF diff --git a/denoted.h b/denoted.h --- a/denoted.h +++ b/denoted.henum Denotation_Type denotation;struct token *id;- struct Type_Enum *parent;+ struct Enum *parent;int value;+ struct AST* expression;};struct Denoted_Struct_Unionstruct 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();#endifF diff --git a/location.c b/location.c --- a/location.c +++ b/location.cstruct 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;+ }#endifF diff --git a/location.h b/location.h --- a/location.h +++ b/location.hstruct 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);#endifF diff --git a/main.exe b/main.exe new file mode 100755B Binary files /dev/null and b/main.exe differF 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){-+}#endifF 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);#endifF 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);+++ #endifF diff --git a/scope.c b/scope.c --- a/scope.c +++ b/scope.cMap_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.cstruct 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;++ }+ }#endifF diff --git a/type.h b/type.h --- a/type.h +++ b/type.hTS_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_Enumstruct 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);