support for pointer add/sub, no need for type_environment in ast2firm
[cparser] / lexer.c
diff --git a/lexer.c b/lexer.c
index ed0bab1..1300b3d 100644 (file)
--- a/lexer.c
+++ b/lexer.c
 #include <string.h>
 #include <ctype.h>
 
-#define DEBUG_CHARS
+//#define DEBUG_CHARS
 #define MAX_PUTBACK 3
 
 static int         c;
 token_t            lexer_token;
+symbol_t          *symbol_L;
 static FILE       *input;
 static char        buf[1024 + MAX_PUTBACK];
 static const char *bufend;
@@ -58,11 +59,16 @@ static inline void next_real_char(void)
 
 static inline void put_back(int pc)
 {
-       char *p = (char*) bufpos - 1;
-       bufpos--;
-       assert(p >= buf);
+       assert(bufpos >= buf);
+       assert(bufpos < buf+MAX_PUTBACK || *bufpos == pc);
+
+       char *p = buf + (bufpos - buf);
        *p = pc;
 
+       /* going backwards in the buffer is legal as long as it's not more often
+        * than MAX_PUTBACK */
+       bufpos--;
+
 #ifdef DEBUG_CHARS
        printf("putback '%c'\n", pc);
 #endif
@@ -83,11 +89,7 @@ static inline void next_char(void);
                lexer_token.source_position.linenr++; \
                code;
 
-static inline void eat(char c_type)
-{
-       assert(c == c_type);
-       next_char();
-}
+#define eat(c_type)  do { assert(c == c_type); next_char(); } while(0)
 
 static void maybe_concat_lines(void)
 {
@@ -108,6 +110,7 @@ static inline void next_char(void)
 {
        next_real_char();
 
+#if 0
        /* filter trigraphs */
        if(UNLIKELY(c == '\\')) {
                maybe_concat_lines();
@@ -143,6 +146,8 @@ static inline void next_char(void)
        }
 
 end_of_next_char:
+#endif
+       (void) maybe_concat_lines;
 #ifdef DEBUG_CHARS
        printf("nchar '%c'\n", c);
 #else
@@ -276,6 +281,21 @@ static void parse_integer_suffix(void)
        }
 }
 
+static void parse_floating_suffix(void)
+{
+       switch(c) {
+       /* TODO: do something usefull with the suffixes... */
+       case 'f':
+       case 'F':
+       case 'l':
+       case 'L':
+               next_char();
+               break;
+       default:
+               break;
+       }
+}
+
 static void parse_number_hex(void)
 {
        assert(c == 'x' || c == 'X');
@@ -360,6 +380,8 @@ static void parse_floatingpoint_exponent(long double value)
 
        lexer_token.type         = T_FLOATINGPOINT;
        lexer_token.v.floatvalue = value;
+
+       parse_floating_suffix();
 }
 
 static void parse_floatingpoint_fract(int integer_part)
@@ -381,6 +403,8 @@ static void parse_floatingpoint_fract(int integer_part)
 
        lexer_token.type         = T_FLOATINGPOINT;
        lexer_token.v.floatvalue = value;
+
+       parse_floating_suffix();
 }
 
 static void parse_number_dec(void)
@@ -781,7 +805,7 @@ static void parse_preprocessor_identifier(void)
        }
 }
 
-static void parse_preprocessor_directive()
+static void parse_preprocessor_directive(void)
 {
        next_pp_token();
 
@@ -839,6 +863,12 @@ void lexer_next_preprocessing_token(void)
 
                SYMBOL_CHARS
                        parse_symbol();
+                       /* might be a wide string ( L"string" ) */
+                       if(c == '"' && (lexer_token.type == T_IDENTIFIER &&
+                          lexer_token.v.symbol == symbol_L)) {
+                               parse_string_literal();
+                               return;
+                       }
                        return;
 
                DIGITS
@@ -1014,10 +1044,14 @@ void init_lexer(void)
 void lexer_open_stream(FILE *stream, const char *input_name)
 {
        input                                  = stream;
-       lexer_token.source_position.linenr     = 1;
+       lexer_token.source_position.linenr     = 0;
        lexer_token.source_position.input_name = input_name;
 
-       next_char();
+       symbol_L = symbol_table_insert("L");
+
+       /* place a virtual \n at the beginning so the lexer knows that we're
+        * at the beginning of a line */
+       c = '\n';
 }
 
 void exit_lexer(void)