shithub: scc

Download patch

ref: e55a366ab763ffa5706625ad27271384eee6e857
parent: 4b7c7bc9c581cd8305bd2b7f9741c25f6ec5943f
author: Roberto E. Vargas Caballero <[email protected]>
date: Wed Apr 23 08:42:42 EDT 2014

Add hexadecimal, octal, negative and unsigned constants

The code already was prepared for this point. This code only
insert a first version of the conversion based in the local
data system, that in some moment must be changed to a
target data system.

--- a/lex.c
+++ b/lex.c
@@ -25,22 +25,34 @@
 {
 	static Type *tp;
 	static Symbol *sym;
-	static char ch;
+	static char ch, size, sign;
+	static long v;
 
-	/* TODO: implement again */
+	size = sign = 0;
 type:
 	switch (ch = toupper(getc(yyin))) {
 	case 'L':
+		if (size == LONG + LONG)
+			goto wrong_type;
+		size += LONG;
 		goto type;
 	case 'U':
+		if (sign == UNSIGNED)
+			goto wrong_type;
 		goto type;
 	default:
 		ungetc(ch, yyin);
+		tp = ctype(INT, sign, size);
+		break;
+	wrong_type:
+		error("invalid suffix in integer constant");
 	}
 
 	sym = install("", NS_IDEN);
-	sym->type = inttype;
-	sym->u.i = atoi(yybuf);
+	sym->type = tp;
+	v = strtol(yybuf, NULL, base);
+	if (tp == inttype)
+		sym->u.i = v;
 	yynlval.sym = sym;
 	return CONSTANT;
 }
@@ -48,9 +60,14 @@
 static uint8_t
 number(void)
 {
-	register char *bp, ch;
-	static char base, type, sign;
+	register char ch, *bp = yybuf;
+	static char base;
 
+	if ((ch = getc(yyin)) == '+' || ch == '-')
+		*bp++ = ch;
+	else
+		ungetc(ch, yyin);
+
 	if ((ch = getc(yyin)) == '0') {
 		if (toupper(ch = getc(yyin)) == 'X') {
 			base = 16;
@@ -63,7 +80,7 @@
 		ungetc(ch, yyin);
 	}
 
-	for (bp = yybuf; bp < &yybuf[IDENTSIZ]; *bp++ = ch) {
+	for ( ; bp < &yybuf[IDENTSIZ]; *bp++ = ch) {
 		ch = getc(yyin);
 		switch (base) {
 		case 8:
@@ -303,7 +320,7 @@
 	ungetc(c, yyin);
 	if (isalpha(c) || c == '_')
 		yyntoken = iden();
-	else if (isdigit(c))
+	else if (isdigit(c) || c == '-' || c == '+')
 		yyntoken = number();
 	else
 		yyntoken = operator();