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:
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) != '.')