shithub: scc

Download patch

ref: 373ea4b9ebd3324e7b8cd683643dc52566b10b97
parent: 93b37d4f0e0edb56f793ccab58f4800bf16f508d
author: Roberto E. Vargas Caballero <[email protected]>
date: Thu May 7 06:01:19 EDT 2015

Add hexadecimal and octal constants

--- a/cc1/lex.c
+++ b/cc1/lex.c
@@ -54,24 +54,11 @@
 	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();
 		switch (base) {
@@ -89,35 +76,63 @@
 			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()) == '\\')