commit 373ea4b9ebd3324e7b8cd683643dc52566b10b97
parent 93b37d4f0e0edb56f793ccab58f4800bf16f508d
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Thu, 7 May 2015 10:01:19 +0200
Add hexadecimal and octal constants
Diffstat:
M | cc1/lex.c | | | 73 | ++++++++++++++++++++++++++++++++++++++++++++----------------------------- |
1 file changed, 44 insertions(+), 29 deletions(-)
diff --git a/cc1/lex.c b/cc1/lex.c
@@ -54,23 +54,10 @@ type:
return CONSTANT;
}
-static uint8_t
-number(void)
+static char *
+digits(uint8_t base)
{
char ch, *bp;
- static char base;
-
- if ((ch = getchar()) == '0') {
- if (toupper(ch = getchar()) == 'X') {
- base = 16;
- } else {
- base = 8;
- ungetc(ch, stdin);
- }
- } else {
- base = 10;
- ungetc(ch, stdin);
- }
for (bp = yytext ; bp < &yytext[IDENTSIZ]; *bp++ = ch) {
ch = getchar();
@@ -89,35 +76,63 @@ number(void)
break;
}
}
-
end:
if (bp == &yytext[IDENTSIZ])
- error("identifier too long %s", yytext);
+ error("number too long %s", yytext);
*bp = '\0';
ungetc(ch, stdin);
- return integer(yytext, base);
+ return yytext;
+}
+
+static uint8_t
+number(void)
+{
+ char ch;
+ static char base;
+
+ if ((ch = getchar()) == '0') {
+ if (toupper(ch = getchar()) == 'X') {
+ base = 16;
+ } else {
+ base = 8;
+ ungetc(ch, stdin);
+ }
+ } else {
+ base = 10;
+ ungetc(ch, stdin);
+ }
+
+ return integer(digits(base), base);
}
static char *
escape(char *s)
{
- char c;
+ uint8_t base;
+ int c;
repeat:
switch (getchar()) {
case '\\': c = '\''; break;
- case 'a': c = '\a'; break;
- case 'f': c = '\f'; break;
- case 'n': c = '\n'; break;
- case 'r': c = '\r'; break;
- case 't': c = '\t'; break;
- case 'v': c = '\v'; break;
+ case 'a': c = '\a'; break;
+ case 'f': c = '\f'; break;
+ case 'n': c = '\n'; break;
+ case 'r': c = '\r'; break;
+ case 't': c = '\t'; break;
+ case 'v': c = '\v'; break;
case '\'': c = '\\'; break;
- case '"': c ='"'; break;
- case '?': c = '?'; break;
- case 'x': /* TODO: */
- case '0': /* TODO: */
+ case '"': c ='"'; break;
+ case '?': c = '?'; break;
case 'u': /* TODO: */
+ case 'x':
+ base = 16;
+ goto number;
+ case '0':
+ base = 8;
+ number:
+ if ((c = atoi(digits(base))) > 255)
+ warn("character constant out of range");
+ break;
case '\n':
++linenum;
if ((c = getchar()) == '\\')