shithub: scc

Download patch

ref: 7cfabdc237c6b5e499064d71430c0c82f479e3ee
parent: 20617bae7d7e87b7c3a924395850abb957f3aa35
author: Roberto E. Vargas Caballero <[email protected]>
date: Fri Oct 25 14:46:27 EDT 2013

Add integer function

This function parses a integer constant, with all the possible
formats that integers accept.

--- a/decl.c
+++ b/decl.c
@@ -47,7 +47,7 @@
 				len = 0;
 			} else {
 				expect(CONSTANT);
-				len = atoi(yytext);
+				len = yyval->i;
 				expect(']');
 			}
 			pushtype(len);
@@ -101,7 +101,7 @@
 			switch (tp->type) {
 			case INT: case BOOL:
 				tp = btype(NULL, BITFLD);
-				tp->len = atoi(yytext);
+				tp->len = yyval->i;
 				break;
 			default:
 				error("bit-field '%s' has invalid type",
@@ -155,9 +155,9 @@
 		sym->ctype = tp;
 		if (accept('=')) {
 			expect(CONSTANT);
-			val = atoi(yytext);
+			val = yyval->i;
 		}
-		sym->val = val++;
+		sym->i = val++;
 	} while (accept(','));
 
 	expect('}');
--- a/expr.c
+++ b/expr.c
@@ -24,7 +24,7 @@
 		np = nodesym(sym);
 		break;
 	case CONSTANT:
-		sym = lookup(NULL, NS_IDEN);
+		sym = yyval;
 		next();
 		np = nodesym(sym);
 		break;
--- a/lex.c
+++ b/lex.c
@@ -26,12 +26,58 @@
 static FILE *yyin;
 static struct keyword *ktab[NR_KEYW_HASH];
 
+struct symbol *yyval;
 
+struct symbol *
+integer(char *s, char base)
+{
+	register struct ctype *tp;
+	register struct symbol *sym;
+	static long long v;
+	static char ch;
+
+	tp = btype(NULL, INT);
+
+type:	switch (ch = toupper(getc(yyin))) {
+	case 'L':
+		tp = btype(tp, LONG);
+		goto type;
+	case 'U':
+		tp = btype(tp, UNSIGNED);
+		goto type;
+	default:
+		ungetc(ch, yyin);
+	}
+
+	v = strtoll(s, NULL, base);
+	sym = lookup(NULL, NS_IDEN);
+	sym->ctype = tp;
+
+	switch (sym->ctype->type) {
+	case INT:
+		sym->i = v;
+		break;
+	case SHORT:
+		sym->s = v;
+		break;
+	case LONG:
+		sym->l = xmalloc(sizeof(long));
+		*sym->l = v;
+		break;
+	case LLONG:
+		sym->ll = xmalloc(sizeof(long long));
+		*sym->ll = v;
+		break;
+	}
+
+	return sym;
+}
+
 static char
 number(void)
 {
 	register char *bp, ch;
-	static char base;
+	static char base, type, sign;
 
 	if ((ch = getc(yyin)) == '0') {
 		if (toupper(ch = getc(yyin)) == 'X') {
@@ -67,6 +113,7 @@
 		error("identifier too long %s", yytext);
 	*bp = '\0';
 	ungetc(ch, yyin);
+	yyval = integer(yytext, base);
 
 	return CONSTANT;
 }
--- a/symbol.h
+++ b/symbol.h
@@ -49,7 +49,11 @@
 	char *name;
 	struct {
 		union {
-			short val;	/* used in integer constant */
+			char c;   /* numerical constants */
+			short s;
+			int i;
+			long *l;
+			long long *ll;
 			unsigned char label;
 		};
 	};
--- a/tokens.h
+++ b/tokens.h
@@ -31,7 +31,7 @@
 
 
 struct symbol;
-
+extern struct symbol *yyval;
 
 extern char yytext[];
 extern size_t yylen;