scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit 475fa03250d04142fb1aeb9635ffe7e3eac434c8
parent c3b8a3ef1ef7df8ae85b1d0b9061725a02c356dc
Author: Roberto E. Vargas Caballero <k0ga@shike2.net>
Date:   Fri, 30 Jan 2026 15:44:17 +0100

cc1: Add support for float constant

Strtold already manages all the complexity of dealing with floating
point numbers.

Diffstat:
Msrc/cmd/scc-cc/cc1/code.c | 18+++++++++++++++++-
Msrc/cmd/scc-cc/cc1/fold.c | 3++-
Msrc/cmd/scc-cc/cc1/lex.c | 47++++++++++++++++++++++++++++++++++++++++-------
3 files changed, 59 insertions(+), 9 deletions(-)

diff --git a/src/cmd/scc-cc/cc1/code.c b/src/cmd/scc-cc/cc1/code.c @@ -215,6 +215,8 @@ emitvar(Symbol *sym) static void emitconst(Node *np) { + int n; + unsigned char *fp, *p; Symbol *sym = np->sym; Type *tp = np->type; unsigned long long u; @@ -226,9 +228,23 @@ emitconst(Node *np) u = (tp->prop & TSIGNED) ? sym->u.i : sym->u.u; fprintf(outfp, "#%c%llX", - np->type->letter, + tp->letter, u & ones(tp->size)); break; + case FLOAT: + fp = (char *) &sym->u.f; + + if (tp == floattype) + n = sizeof(sym->u.f); + else if (tp == doubletype) + n = sizeof(sym->u.d); + else + n = sizeof(sym->u.ld); + + fprintf(outfp, "#%c", tp->letter); + for (p = fp; p < &fp[n]; ++p) + fprintf(outfp, "%02X", *p); + break; default: abort(); } diff --git a/src/cmd/scc-cc/cc1/fold.c b/src/cmd/scc-cc/cc1/fold.c @@ -451,7 +451,8 @@ foldcast(Node *np, Node *l) } break; case FLOAT: - /* FIXME: The cast can be from another float type */ + if (oldtp->op == FLOAT) + return np; aux.u.f = (oldtp->prop & TSIGNED) ? osym->u.i : osym->u.u; break; default: diff --git a/src/cmd/scc-cc/cc1/lex.c b/src/cmd/scc-cc/cc1/lex.c @@ -348,8 +348,9 @@ tok2str(void) } static Symbol * -readint(char *s, int base, int sign, Symbol *sym) +readint(int base, int sign, Symbol *sym) { + char *s = yytext; Type *tp = sym->type; struct limits *lim; unsigned long long u, val, max; @@ -402,7 +403,7 @@ overflow: } static int -integer(char *s, int base) +integer(int base) { Type *tp; Symbol *sym; @@ -433,11 +434,11 @@ convert: sym = newsym(NS_IDEN, NULL); sym->type = tp; sym->flags |= SCONSTANT; - yylval.sym = readint(s, base, sign, sym); + yylval.sym = readint(base, sign, sym); return CONSTANT; } -static char * +static void digits(int base) { char *p; @@ -461,13 +462,15 @@ digits(int base) } end: input->p = p; - return yytext; } static int number(void) { - int base; + Type *tp; + Symbol *sym; + int ch, base; + long double ld; if (*input->p != '0') { base = 10; @@ -479,8 +482,36 @@ number(void) base = 8; } } + digits(base); + + if (*input->p != '.') + return integer(base); + + sym = newsym(NS_IDEN, NULL); - return integer(digits(base), base); + ld = strtold(input->begin, &input->p); + switch (toupper(*input->p)) { + case 'F': + ++input->p; + tp = floattype; + sym->u.f = ld; + break; + case 'L': + ++input->p; + tp = ldoubletype; + sym->u.ld = ld; + break; + default: + tp = doubletype; + sym->u.d = ld; + break; + } + + tok2str(); + sym->type = tp; + sym->flags |= SCONSTANT; + yylval.sym = sym; + return CONSTANT; } static int @@ -792,6 +823,8 @@ dot(void) { int c; + if (isdigit(*input->p)) + return number(); if ((c = *input->p) != '.') return '.'; if ((c = *++input->p) != '.')