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.c
free(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.h
void 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.c
else
return 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;
+ }
#endif
F diff --git a/misc/gcc_string.h b/misc/gcc_string.h
--- a/misc/gcc_string.h
+++ b/misc/gcc_string.h
char* 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.c
struct 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_REMAINDER
F diff --git a/semantics/semantics.c b/semantics/semantics.c
--- a/semantics/semantics.c
+++ b/semantics/semantics.c
long 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);
+ }
#endif
F diff --git a/semantics/semantics.h b/semantics/semantics.h
--- a/semantics/semantics.h
+++ b/semantics/semantics.h
long 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);
#endif
F 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 == 1
int kak;
#else
int 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;
+ }