Rename orig_type to src_type in semantic_cast(), to avoid confusion with the usual...
[cparser] / lexer.c
diff --git a/lexer.c b/lexer.c
index f1b00e3..5ca734a 100644 (file)
--- a/lexer.c
+++ b/lexer.c
@@ -487,34 +487,74 @@ end:
  */
 static void parse_number_hex(void)
 {
+       bool is_float = false;
        assert(c == 'x' || c == 'X');
        next_char();
 
+       obstack_1grow(&symbol_obstack, '0');
+       obstack_1grow(&symbol_obstack, 'x');
+
        while(isxdigit(c)) {
                obstack_1grow(&symbol_obstack, (char) c);
                next_char();
        }
-       obstack_1grow(&symbol_obstack, '\0');
-       char *string = obstack_finish(&symbol_obstack);
 
-       if(c == '.' || c == 'p' || c == 'P') {
+       if (c == '.') {
+               obstack_1grow(&symbol_obstack, (char) c);
+               next_char();
+
+               while (isxdigit(c)) {
+                       obstack_1grow(&symbol_obstack, (char) c);
+                       next_char();
+               }
+               is_float = true;
+       }
+       if (c == 'p' || c == 'P') {
+               obstack_1grow(&symbol_obstack, (char) c);
                next_char();
-               internal_error("Hex floating point numbers not implemented yet");
+
+               if (c == '-' || c == '+') {
+                       obstack_1grow(&symbol_obstack, (char) c);
+                       next_char();
+               }
+
+               while (isxdigit(c)) {
+                       obstack_1grow(&symbol_obstack, (char) c);
+                       next_char();
+               }
+               is_float = true;
        }
+
+       obstack_1grow(&symbol_obstack, '\0');
+       char *string = obstack_finish(&symbol_obstack);
        if(*string == '\0') {
                parse_error("invalid hex number");
                lexer_token.type = T_ERROR;
+               obstack_free(&symbol_obstack, string);
+               return;
        }
 
-       const char *endptr;
-       lexer_token.type       = T_INTEGER;
-       lexer_token.v.intvalue = parse_int_string(string, &endptr, 16);
-       if(*endptr != '\0') {
-               parse_error("hex number literal too long");
+       if (is_float) {
+               char *endptr;
+               lexer_token.type         = T_FLOATINGPOINT;
+               lexer_token.v.floatvalue = strtold(string, &endptr);
+
+               if(*endptr != '\0') {
+                       parse_error("invalid hex float literal");
+               }
+
+               parse_floating_suffix();
+       } else {
+               const char *endptr;
+               lexer_token.type       = T_INTEGER;
+               lexer_token.v.intvalue = parse_int_string(string + 2, &endptr, 16);
+               if(*endptr != '\0') {
+                       parse_error("hex number literal too long");
+               }
+               parse_integer_suffix(true);
        }
 
        obstack_free(&symbol_obstack, string);
-       parse_integer_suffix(true);
 }
 
 /**
@@ -569,23 +609,23 @@ static void parse_number_oct(void)
 static void parse_number_dec(void)
 {
        bool is_float = false;
-       while(isdigit(c)) {
+       while (isdigit(c)) {
                obstack_1grow(&symbol_obstack, (char) c);
                next_char();
        }
 
-       if(c == '.') {
+       if (c == '.') {
                obstack_1grow(&symbol_obstack, '.');
                next_char();
 
-               while(isdigit(c)) {
+               while (isdigit(c)) {
                        obstack_1grow(&symbol_obstack, (char) c);
                        next_char();
                }
                is_float = true;
        }
        if(c == 'e' || c == 'E') {
-               obstack_1grow(&symbol_obstack, 'e');
+               obstack_1grow(&symbol_obstack, (char) c);
                next_char();
 
                if(c == '-' || c == '+') {
@@ -1110,7 +1150,10 @@ static void skip_multiline_comment(void)
                case '/':
                        next_char();
                        if (c == '*') {
-                               /* TODO: nested comment, warn here */
+                               /* nested comment, warn here */
+                               if (warning.comment) {
+                                       warningf(&lexer_token.source_position, "'/*' within comment");
+                               }
                        }
                        break;
                case '*':
@@ -1152,6 +1195,15 @@ static void skip_line_comment(void)
                case '\r':
                        return;
 
+               case '\\':
+                       next_char();
+                       if (c == '\n' || c == '\r') {
+                               if (warning.comment)
+                                       warningf(&lexer_token.source_position, "multi-line comment");
+                               return;
+                       }
+                       break;
+
                default:
                        next_char();
                        break;