F diff --git a/lex/lexer.c b/lex/lexer.c --- a/lex/lexer.c +++ b/lex/lexer.c{++src->token_size;++src->which_column;+ ++src->where_in_src;src->is_in_the_begining_of_line=0;return '\\';}F diff --git a/lex/preprocessing.c b/lex/preprocessing.c --- a/lex/preprocessing.c +++ b/lex/preprocessing.cfree(hold);push_lexing_error("unmatched elif",src,translation_data);return;+ case PKW_LINE:+ free(hold);+ parse_preproc_line_line(src,translation_data);+ return;case PKW_ERROR:free(hold);parse_preproc_error_line(src,translation_data);}free(hold_token);}- hold_token=get_next_token(src,&chonky[0],0);}else if(hold_token->type==KW_NOTYPE){- //push_lexing_error("empty define directive",src,translation_data);free(hold_token);- /*TODO destroy new define directive*/- /*TODO there is a memory leak here*/- // return ;}/*push things*/new_macro->number_of_arguments=number_of_arguments;/*there is something in hold_token*/- do{+ while( (hold_token=get_next_token(src,&chonky[0],0))->type != KW_NOTYPE)+ {expand_macro(hold_token,src,translation_data);- }while( (hold_token=get_next_token(src,&chonky[0],0))->type != KW_NOTYPE);+ }/*removing the notype token*/free(hold_token);*/void parse_preproc_if_line(struct Source_File *src,struct Translation_Data *translation_data){- size_t hold_line;- struct Queue hold_tokens;- struct Queue *swap_tokens;++ struct Queue *tokens;+ struct Queue *swap;+ struct AST *condition;+ struct Scope *null_scope;struct token *hold_token;- struct Scope *empty_scope;- struct AST *expression;int result;- hold_line=src->which_row;- Queue_Init(&hold_tokens);- hold_token=get_next_token(src,&chonky[0],0);- empty_scope=get_normal_scope(NULL,EXTERN_SCOPE);+ null_scope=get_normal_scope(NULL,EXTERN_SCOPE);- swap_tokens=translation_data->tokens;- translation_data->tokens=&hold_tokens;- while(hold_token->type!=KW_NOTYPE && hold_token->line==hold_line)- {- expand_macro(hold_token,src,translation_data);- hold_token=get_next_token(src,&chonky[0],0);- }+ tokens=lex_line(src,translation_data,1);- /*NOTYPE*/- free(hold_token);-- expression=parse_expression(translation_data,empty_scope);- result=evaluate_const_expression_integer(expression);+ swap=translation_data->tokens;+ translation_data->tokens=tokens;- delete_ast(expression);- delete_scope(empty_scope);- translation_data->tokens=swap_tokens;+ condition=parse_expression(translation_data,null_scope);+ result=evaluate_const_expression_integer(condition);+ delete_normal_scope((struct Normal_Scope*)null_scope);+ delete_ast(condition);- if(hold_tokens.size>0)- {- push_lexing_error("unexpected token",src,translation_data);- while(hold_tokens.size>0)- free(Queue_Pop(&hold_tokens));- }-- if(has_new_errors(translation_data))+ if(result){- push_lexing_error("fatal error",src,translation_data);- return ;+ preproc_lex_first_part(src,translation_data);}else{-- if(result)+ hold_token=preproc_find_else(src,translation_data,0);+ if(hold_token!=NULL && hold_token->type==PKW_ELIF){- preproc_lex_first_part(src,translation_data);- }else+ parse_preproc_if_line(src,translation_data);+ }+ else if(hold_token!=NULL){- hold_token=preproc_find_else(src,translation_data,0);- if(hold_token!=NULL && hold_token->type==PKW_ELIF)- {- //preproc_find_else(src,translation_data,0);- parse_preproc_if_line(src,translation_data);- }else if(hold_token!=NULL)- {- preproc_lex_first_part(src,translation_data);- }- }+ preproc_lex_first_part(src,translation_data);+ }+ }- }}struct token* preproc_find_else(struct Source_File *src,struct Translation_Data *translation_data,char jump_before)struct token *hold_token;struct Source_File temp_src;int indentation=1;- if(!jump_before)- {- free(get_next_token(src,&chonky[0],1));- free(get_next_token(src,&chonky[0],1));- return NULL;- }temp_src=*src;while(src->src[src->where_in_src]!='\0' && indentation){/*BEWARE*/- goto_new_line(src,translation_data);temp_src=*src;/*END BEWARE*/break;}case PKW_NOTYPE:- push_lexing_error("unexpected character",src,translation_data);free(hold_token);+ goto_new_line(src,translation_data);return NULL;}free(hold_token);free(hold_token);return NULL;}+ goto_new_line(src,translation_data);}/*BEWARE*///goto_new_line(src,translation_data);struct token *hold_line;struct token *hold_name;- tokens=lex_line(src,translation_data);+ tokens=lex_line(src,translation_data,0);hack=*translation_data;hack.tokens=tokens;- if(check(&hack,KW_NUMBER,1))+ if(check(&hack,KW_NUMBER,0)){hold_line=(struct token*)Queue_Pop(tokens);- if(check(&hack,KW_STRING,1))+ src->which_row=evaluate_number_literal(hold_line);+ if(check(&hack,KW_STRING,0)){hold_name=(struct token*)Queue_Pop(tokens);hold_name->data[hold_name->data_size]='\0';{#define AS_MACRO(x) ((struct define_directive*)macro)free(AS_MACRO(macro)->macro_name);- while(AS_MACRO(macro)->macro_tokens->size>0)- free(Queue_Pop(AS_MACRO(macro)->macro_tokens));+ flush_tokens(AS_MACRO(macro)->macro_tokens);free(AS_MACRO(macro)->macro_tokens);Map_Map(AS_MACRO(macro)->arguments,free);free(AS_MACRO(macro)->arguments);free(macro);#undef AS_MACRO}- struct Queue* lex_line(struct Source_File *src,struct Translation_Data *translation_data)+ struct Queue* lex_line(struct Source_File *src,struct Translation_Data *translation_data,char lex_defined_token){struct Source_File temp_src;struct token *hold_token;struct Queue *tokens;char just_in_case;+tokens=malloc(sizeof(struct Queue));Queue_Init(tokens);src->src[src->where_in_src]='\0';translation_data->tokens=tokens;++ while((hold_token=get_next_token(&temp_src,&chonky[0],0))->type!=KW_NOTYPE)+ {+ if(lex_defined_token && hold_token->type==KW_ID && hold_token->data_size==7 && gstrn_cmp(hold_token->data,"defined",7))+ {+ free(hold_token);+ hold_token=get_next_token(&temp_src,&chonky[0],0);+ if(hold_token->type==KW_OPEN_NORMAL)+ {+ free(hold_token);+ hold_token=get_next_token(&temp_src,&chonky[0],0);+ if(hold_token->type!=KW_ID)+ {+ push_lexing_error("expected an id after '(' in defined",src,translation_data);+ }else+ {+ struct token *hold_closing_token;+ hold_closing_token=get_next_token(&temp_src,&chonky[0],0);+ if(hold_closing_token->type!=KW_CLOSE_NORMAL)+ {+ push_lexing_error("expected an ')' after id in define",src,translation_data);+ }else+ {+ if(!Map_Check(translation_data->macros,hold_token->data,hold_token->data_size))+ {+ hold_token->type=KW_NUMBER;+ hold_token->data="0";+ hold_token->data_size=1;+ }else+ {+ hold_token->type=KW_NUMBER;+ hold_token->data="1";+ hold_token->data_size=1;+ }- lex(&temp_src,translation_data);+ }+ }+ }else if(hold_token->type!=KW_ID)+ {+ push_lexing_error("expected an id after define",src,translation_data);+ }else+ {+ if(!Map_Check(translation_data->macros,hold_token->data,hold_token->data_size))+ {+ hold_token->type=KW_NUMBER;+ hold_token->data="0";+ hold_token->data_size=1;+ }else+ {+ hold_token->type=KW_NUMBER;+ hold_token->data="1";+ hold_token->data_size=1;+ }+ }+ }+ Queue_Push(tokens,hold_token);+ }+ free(hold_token);src->src[src->where_in_src]=just_in_case;return tokens;F diff --git a/lex/preprocessing.h b/lex/preprocessing.h --- a/lex/preprocessing.h +++ b/lex/preprocessing.hvoid parse_preproc_line_line(struct Source_File *src,struct Translation_Data *translation_data);- struct Queue* lex_line(struct Source_File *src,struct Translation_Data *translation_data);+ struct Queue* lex_line(struct Source_File *src,struct Translation_Data *translation_data,char lex_defined_token);/*preproc if stuff*//*returns an else or elif token, or if it hits matching endif before that return NULL*/struct token* preproc_find_else(struct Source_File *src,struct Translation_Data *translation_data,char jump_before);F diff --git a/misc/gcc_string.c b/misc/gcc_string.c --- a/misc/gcc_string.c +++ b/misc/gcc_string.celsereturn 0;}+ char gstrn_cmp(const char *a,const char *b,size_t size)+ {+ size_t i;+ for(i=0;i<size;++i)+ if(a[i]!=b[i])+ return 0;+ return 1;+ }#endifF diff --git a/misc/gcc_string.h b/misc/gcc_string.h --- a/misc/gcc_string.h +++ b/misc/gcc_string.hchar* gstr_append(char *lead,char *follower);char* gstrcpy(char *str);char gstr_cmp(const char *a,const char *b);+ char gstrn_cmp(const char *a,const char *b,size_t size);void strmv(char *target,char *source);F diff --git a/parse/parse_expression.c b/parse/parse_expression.c --- a/parse/parse_expression.c +++ b/parse/parse_expression.cstruct AST *hold;hold=parse_logical_and_expression(translation_data,scope);- while(get_and_check(translation_data,KW_AND_AND))+ while(get_and_check(translation_data,KW_PIPE_PIPE)){hold=(struct AST*)get_binary_expression_tree(hold,parse_logical_and_expression(translation_data,scope),OP_LOGICAL_OR);}F diff --git a/semantics/ast.h b/semantics/ast.h --- a/semantics/ast.h +++ b/semantics/ast.h- #define BIN_EXPR_PTR(x) ((struct AST_Binary_Expression*)(x))- #define UN_EXPR_PTR(x) ((struct AST_Unary_Expression*)(x))- #define LVAL_EXPR_PTR(x) ((struct AST_Lvalue_Expression*)(x))- #define RVAL_EXPR_PTR(x) ((struct AST_Rvalue_Expression*)(x))- #define DECLR_PTR(x) ((struct AST_Declaration*)(x))- #define IF_ST_PTR(s) ((struct AST_If_Statement*)(x))F diff --git a/semantics/ast.hh b/semantics/ast.hh --- a/semantics/ast.hh +++ b/semantics/ast.hh#ifndef GCC_AST_HH#define GCC_AST_HH GCC_AST_HH+ #define BIN_EXPR_PTR(x) ((struct AST_Binary_Expression*)(x))+ #define UN_EXPR_PTR(x) ((struct AST_Unary_Expression*)(x))+ #define LVAL_EXPR_PTR(x) ((struct AST_Lvalue_Expression*)(x))+ #define RVAL_EXPR_PTR(x) ((struct AST_Rvalue_Expression*)(x))+ #define DECLR_PTR(x) ((struct AST_Declaration*)(x))+ #define IF_ST_PTR(s) ((struct AST_If_Statement*)(x))+enum AST_Type{OP_COMMA,OP_ADDITION,OP_SUBTRACTION,OP_MUL,OP_DIV,OP_REMAINDERF diff --git a/semantics/semantics.c b/semantics/semantics.c --- a/semantics/semantics.c +++ b/semantics/semantics.clong long int evaluate_const_expression_integer(struct AST *expression){+ #define RET_BIN_EXPR(x,operator) return \+ evaluate_const_expression_integer(BIN_EXPR_PTR(x)->left)\+ operator\+ evaluate_const_expression_integer(BIN_EXPR_PTR(x)->right);+ #define RET_UNARY_EXPR(x,operator) return \+ operator evaluate_const_expression_integer(UN_EXPR_PTR(x)->operand);+switch(expression->type){+ case OP_COMMA:case OP_ADDITION:- return- evaluate_const_expression_integer(BIN_EXPR_PTR(expression)->left)- +- evaluate_const_expression_integer(BIN_EXPR_PTR(expression)->right);- break;+ RET_BIN_EXPR(expression,+);case OP_SUBTRACTION:- return- evaluate_const_expression_integer(BIN_EXPR_PTR(expression)->left)- -- evaluate_const_expression_integer(BIN_EXPR_PTR(expression)->right);- break;- case OP_DIV:- return- evaluate_const_expression_integer(BIN_EXPR_PTR(expression)->left)- /- evaluate_const_expression_integer(BIN_EXPR_PTR(expression)->right);- break;+ RET_BIN_EXPR(expression,-);case OP_MUL:- return- evaluate_const_expression_integer(BIN_EXPR_PTR(expression)->left)- *- evaluate_const_expression_integer(BIN_EXPR_PTR(expression)->right);- break;+ RET_BIN_EXPR(expression,*);+ case OP_DIV:+ RET_BIN_EXPR(expression,/);+ case OP_REMAINDER:+ RET_BIN_EXPR(expression,%);+ case OP_COND:+ return (+ evaluate_const_expression_integer(((struct AST_Conditional_Expression*)expression)->left)?+ evaluate_const_expression_integer(((struct AST_Conditional_Expression*)expression)->center):+ evaluate_const_expression_integer(((struct AST_Conditional_Expression*)expression)->right)+ );++ case OP_LOGICAL_OR:+ RET_BIN_EXPR(expression,||);+ case OP_LOGICAL_AND:+ RET_BIN_EXPR(expression,&&);+ case OP_LOGICAL_NOT:+ RET_UNARY_EXPR(expression,!);+ case OP_BITWISE_OR:+ RET_BIN_EXPR(expression,|);+ case OP_BITWISE_AND:+ RET_BIN_EXPR(expression,&);+ case OP_BITWISE_XOR:+ RET_BIN_EXPR(expression,^);+ case OP_BITWISE_NOT:+ RET_UNARY_EXPR(expression,~);+ case OP_UNARY_PLUS:+ RET_UNARY_EXPR(expression,+);+ case OP_UNARY_MINUS:+ RET_UNARY_EXPR(expression,-);+ case OP_SHIFT_LEFT:+ RET_BIN_EXPR(expression,<<);+ case OP_SHIFT_RIGHT:+ RET_BIN_EXPR(expression,>>);+ case OP_LESS_EQ:+ RET_BIN_EXPR(expression,<=);+ case OP_GREATER_EQ:+ RET_BIN_EXPR(expression,>=);+ case OP_LESS:+ RET_BIN_EXPR(expression,<);+ case OP_GREATER:+ RET_BIN_EXPR(expression,>);+ case OP_EQUAL:+ RET_BIN_EXPR(expression,==);+ case OP_NOT_EQUAL:+ RET_BIN_EXPR(expression,!=);case OP_RVALUE:if(RVAL_EXPR_PTR(expression)->id->type==KW_NUMBER){}+ long long int evaluate_number_literal(struct token *token)+ {+ return evaluate_literal_integer_dec(token);+ }#endifF diff --git a/semantics/semantics.h b/semantics/semantics.h --- a/semantics/semantics.h +++ b/semantics/semantics.hlong long int evaluate_const_expression_integer(struct AST *expression);long long int evaluate_literal_integer_dec(struct token *token);+ long long int evaluate_number_literal(struct token *token);#endifF diff --git a/tests/test3.c b/tests/test3.c --- a/tests/test3.c +++ b/tests/test3.c- #define VERSION 2- #ifndef VERSION- #define VERSION 1+ #define max(x,y) (x>y?x:y)+ #if defined VERSION == 1int kak;#elseint err;#endif- #undef VERSION- #ifdef VERSION- char asdf;- #endif++int external_int;int static_int;int fib(int n){+ max(1,max(1,2));int a=1,b=1,c;for(n;n>0;--n){F diff --git a/tests/test4.c b/tests/test4.c new file mode 100644 --- /dev/null +++ b/tests/test4.c++ #include <limits.h>+++ int main()+ {+ printf("asdf\n");+ return 0;+ }