commit 7cfabdc237c6b5e499064d71430c0c82f479e3ee
parent 20617bae7d7e87b7c3a924395850abb957f3aa35
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Fri, 25 Oct 2013 18:46:27 +0200
Add integer function
This function parses a integer constant, with all the possible
formats that integers accept.
Diffstat:
5 files changed, 59 insertions(+), 8 deletions(-)
diff --git a/decl.c b/decl.c
@@ -47,7 +47,7 @@ dirdcl(register struct ctype *tp, unsigned char ns)
len = 0;
} else {
expect(CONSTANT);
- len = atoi(yytext);
+ len = yyval->i;
expect(']');
}
pushtype(len);
@@ -101,7 +101,7 @@ field_dcl(unsigned char ns)
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 @@ enum_dcl(struct ctype *base)
sym->ctype = tp;
if (accept('=')) {
expect(CONSTANT);
- val = atoi(yytext);
+ val = yyval->i;
}
- sym->val = val++;
+ sym->i = val++;
} while (accept(','));
expect('}');
diff --git a/expr.c b/expr.c
@@ -24,7 +24,7 @@ primary(void)
np = nodesym(sym);
break;
case CONSTANT:
- sym = lookup(NULL, NS_IDEN);
+ sym = yyval;
next();
np = nodesym(sym);
break;
diff --git a/lex.c b/lex.c
@@ -26,12 +26,58 @@ struct keyword {
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 @@ end: if (bp == yytext + IDENTSIZ)
error("identifier too long %s", yytext);
*bp = '\0';
ungetc(ch, yyin);
+ yyval = integer(yytext, base);
return CONSTANT;
}
diff --git a/symbol.h b/symbol.h
@@ -49,7 +49,11 @@ struct symbol {
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;
};
};
diff --git a/tokens.h b/tokens.h
@@ -31,7 +31,7 @@ enum tokens {
struct symbol;
-
+extern struct symbol *yyval;
extern char yytext[];
extern size_t yylen;