improve number lexing even more
authorMatthias Braun <matze@braunis.de>
Wed, 21 Nov 2007 00:32:23 +0000 (00:32 +0000)
committerMatthias Braun <matze@braunis.de>
Wed, 21 Nov 2007 00:32:23 +0000 (00:32 +0000)
[r18503]

ast.c
ast2firm.c
ast_t.h
lexer.c
main.c
parser.c
token_t.h
write_fluffy.c

diff --git a/ast.c b/ast.c
index 77821bc..27105f6 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -35,7 +35,7 @@ static void print_const(const const_t *cnst)
                return;
 
        if(is_type_integer(cnst->expression.datatype)) {
-               fprintf(out, "%d", cnst->v.int_value);
+               fprintf(out, "%lld", cnst->v.int_value);
        } else if(is_type_floating(cnst->expression.datatype)) {
                fprintf(out, "%Lf", cnst->v.float_value);
        }
index 721c92d..c7764f4 100644 (file)
@@ -555,12 +555,19 @@ static ir_node *const_to_firm(const const_t *cnst)
        dbg_info *dbgi = get_dbg_info(&cnst->expression.source_position);
        ir_mode  *mode = get_ir_mode(cnst->expression.datatype);
 
-       tarval   *tv;
+       char    buf[128];
+       tarval *tv;
+       size_t  len;
        if(mode_is_float(mode)) {
-               tv = new_tarval_from_double(cnst->v.float_value, mode);
+               len = snprintf(buf, sizeof(buf), "%LF", cnst->v.float_value);
        } else {
-               tv = new_tarval_from_long(cnst->v.int_value, mode);
+               if(mode_is_signed(mode)) {
+                       len = snprintf(buf, sizeof(buf), "%lld", cnst->v.int_value);
+               } else {
+                       len = snprintf(buf, sizeof(buf), "%llu", cnst->v.int_value);
+               }
        }
+       tv = new_tarval_from_str(buf, len, mode);
 
        return new_d_Const(dbgi, mode, tv);
 }
diff --git a/ast_t.h b/ast_t.h
index b893982..b965ff6 100644 (file)
--- a/ast_t.h
+++ b/ast_t.h
@@ -47,7 +47,7 @@ struct expression_t {
 struct const_t {
        expression_t  expression;
        union {
-               int         int_value;
+               long long   int_value;
                long double float_value;
        } v;
 };
diff --git a/lexer.c b/lexer.c
index de2cac8..ef98a4a 100644 (file)
--- a/lexer.c
+++ b/lexer.c
@@ -6,6 +6,7 @@
 #include "adt/error.h"
 #include "adt/strset.h"
 #include "adt/util.h"
+#include "type_t.h"
 
 #include <assert.h>
 #include <errno.h>
@@ -25,6 +26,16 @@ static const char *bufend;
 static const char *bufpos;
 static strset_t    stringset;
 
+static type_t     *type_int        = NULL;
+static type_t     *type_uint       = NULL;
+static type_t     *type_long       = NULL;
+static type_t     *type_ulong      = NULL;
+static type_t     *type_longlong   = NULL;
+static type_t     *type_ulonglong  = NULL;
+static type_t     *type_float      = NULL;
+static type_t     *type_double     = NULL;
+static type_t     *type_longdouble = NULL;
+
 static void error_prefix_at(const char *input_name, unsigned linenr)
 {
        fprintf(stderr, "%s:%u: Error: ", input_name, linenr);
@@ -256,13 +267,17 @@ end_symbol:
 static void parse_integer_suffix(void)
 {
        if(c == 'U' || c == 'U') {
-               /* TODO do something with the suffixes... */
                next_char();
                if(c == 'L' || c == 'l') {
                        next_char();
                        if(c == 'L' || c == 'l') {
                                next_char();
+                               lexer_token.datatype = type_ulonglong;
+                       } else {
+                               lexer_token.datatype = type_ulong;
                        }
+               } else {
+                       lexer_token.datatype = type_uint;
                }
        } else if(c == 'l' || c == 'L') {
                next_char();
@@ -270,10 +285,18 @@ static void parse_integer_suffix(void)
                        next_char();
                        if(c == 'u' || c == 'U') {
                                next_char();
+                               lexer_token.datatype = type_ulonglong;
+                       } else {
+                               lexer_token.datatype = type_longlong;
                        }
                } else if(c == 'u' || c == 'U') {
                        next_char();
+                       lexer_token.datatype = type_ulong;
+               } else {
+                       lexer_token.datatype = type_int;
                }
+       } else {
+               lexer_token.datatype = type_int;
        }
 }
 
@@ -283,11 +306,16 @@ static void parse_floating_suffix(void)
        /* TODO: do something usefull with the suffixes... */
        case 'f':
        case 'F':
+               next_char();
+               lexer_token.datatype = type_float;
+               break;
        case 'l':
        case 'L':
                next_char();
+               lexer_token.datatype = type_longdouble;
                break;
        default:
+               lexer_token.datatype = type_double;
                break;
        }
 }
@@ -322,7 +350,7 @@ static void parse_number_hex(void)
 
        char *endptr;
        lexer_token.type       = T_INTEGER;
-       lexer_token.v.intvalue = strtoll(string, &endptr, 16);
+       lexer_token.v.intvalue = strtoull(string, &endptr, 16);
        if(*endptr != '\0') {
                parse_error("hex number literal too long");
        }
@@ -346,7 +374,7 @@ static void parse_number_oct(void)
 
        char *endptr;
        lexer_token.type       = T_INTEGER;
-       lexer_token.v.intvalue = strtoll(string, &endptr, 8);
+       lexer_token.v.intvalue = strtoull(string, &endptr, 8);
        if(*endptr != '\0') {
                parse_error("octal number literal too long");
        }
@@ -404,7 +432,7 @@ static void parse_number_dec(void)
                parse_floating_suffix();
        } else {
                lexer_token.type       = T_INTEGER;
-               lexer_token.v.intvalue = strtoll(string, &endptr, 10);
+               lexer_token.v.intvalue = strtoull(string, &endptr, 10);
 
                if(*endptr != '\0') {
                        parse_error("invalid number literal");
@@ -1016,6 +1044,21 @@ newline_found:
 void init_lexer(void)
 {
        strset_init(&stringset);
+
+       type_int       = make_atomic_type(ATOMIC_TYPE_INT, TYPE_QUALIFIER_CONST);
+       type_uint      = make_atomic_type(ATOMIC_TYPE_UINT, TYPE_QUALIFIER_CONST);
+       type_long      = make_atomic_type(ATOMIC_TYPE_LONG, TYPE_QUALIFIER_CONST);
+       type_ulong     = make_atomic_type(ATOMIC_TYPE_ULONG, TYPE_QUALIFIER_CONST);
+       type_longlong  = make_atomic_type(ATOMIC_TYPE_LONGLONG,
+                                         TYPE_QUALIFIER_CONST);
+       type_ulonglong = make_atomic_type(ATOMIC_TYPE_ULONGLONG,
+                                         TYPE_QUALIFIER_CONST);
+
+       type_float      = make_atomic_type(ATOMIC_TYPE_FLOAT, TYPE_QUALIFIER_CONST);
+       type_double     = make_atomic_type(ATOMIC_TYPE_DOUBLE,
+                                          TYPE_QUALIFIER_CONST);
+       type_longdouble = make_atomic_type(ATOMIC_TYPE_LONG_DOUBLE,
+                                          TYPE_QUALIFIER_CONST);
 }
 
 void lexer_open_stream(FILE *stream, const char *input_name)
diff --git a/main.c b/main.c
index b97fa45..4930eaf 100644 (file)
--- a/main.c
+++ b/main.c
@@ -294,9 +294,9 @@ int main(int argc, char **argv)
 
        init_symbol_table();
        init_tokens();
-       init_lexer();
        init_types();
        init_typehash();
+       init_lexer();
        init_ast();
        init_parser();
        init_ast2firm();
@@ -436,9 +436,9 @@ int main(int argc, char **argv)
        exit_ast2firm();
        exit_parser();
        exit_ast();
+       exit_lexer();
        exit_typehash();
        exit_types();
-       exit_lexer();
        exit_tokens();
        exit_symbol_table();
        return 0;
index 16410fd..e151f5e 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -2354,7 +2354,7 @@ static expression_t *parse_int_const(void)
        const_t *cnst = allocate_ast_zero(sizeof(cnst[0]));
 
        cnst->expression.type     = EXPR_CONST;
-       cnst->expression.datatype = type_int;
+       cnst->expression.datatype = token.datatype;
        cnst->v.int_value         = token.v.intvalue;
 
        next_token();
@@ -2367,7 +2367,7 @@ static expression_t *parse_float_const(void)
        const_t *cnst = allocate_ast_zero(sizeof(cnst[0]));
 
        cnst->expression.type     = EXPR_CONST;
-       cnst->expression.datatype = type_double;
+       cnst->expression.datatype = token.datatype;
        cnst->v.float_value       = token.v.floatvalue;
 
        next_token();
index 0cc82d3..762f143 100644 (file)
--- a/token_t.h
+++ b/token_t.h
@@ -4,6 +4,7 @@
 #include <stdio.h>
 #include "symbol.h"
 #include "symbol_table.h"
+#include "type.h"
 
 typedef enum {
 #define T(x,str,val) T_##x val,
@@ -38,6 +39,7 @@ typedef struct {
                long double floatvalue;
                const char *string;
        } v;
+       type_t            *datatype;
        source_position_t  source_position;
 } token_t;
 
index e2d9aac..3e6ba08 100644 (file)
@@ -221,7 +221,7 @@ static void write_expression(const expression_t *expression)
        case EXPR_CONST:
                constant = (const const_t*) expression;
                if(is_type_integer(expression->datatype)) {
-                       fprintf(out, "%d", constant->v.int_value);
+                       fprintf(out, "%lld", constant->v.int_value);
                } else {
                        fprintf(out, "%Lf", constant->v.float_value);
                }