commit 7a66e2a3991b2b7d203d1a8290951bbfd2db9511
parent 5956b8e016a018b2701f8651e328f7ddae62084f
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Thu, 10 Jul 2014 21:26:52 +0200
Remove prefecthing of tokens
This technique was generating a lot of problems in different situations.
For example the value of a symbol was calculated before of the end
of the previous statement, so blocks like:
typedef int pepe;
pepe j;
failed, because in the moment of the prefetch of second pepe, the
previous typedef was not finished.
Diffstat:
M | cc1/cc1.h | | | 8 | ++++---- |
M | cc1/expr.c | | | 75 | +++++++++++++++++++++++++++++++++++++++++++++++++-------------------------- |
M | cc1/lex.c | | | 132 | ++++++++++++++++++++++++++++++++++++++++++------------------------------------- |
3 files changed, 123 insertions(+), 92 deletions(-)
diff --git a/cc1/cc1.h b/cc1/cc1.h
@@ -138,7 +138,7 @@ enum {
#define REGISTER 5
#define accept(t) ((yytoken == (t)) ? next() : 0)
-#define ahead() yyntoken
+extern uint8_t ahead(void);
enum tokens {
TQUALIFIER = 128, TYPE, IDEN, SCLASS,
@@ -152,14 +152,14 @@ enum tokens {
CONTINUE, BREAK, RETURN, EOFTOK, NOTOK
};
-union yystype {
+struct yystype {
Symbol *sym;
uint8_t token;
};
-extern union yystype yylval;
+extern struct yystype yylval;
extern char yytext[];
-extern uint8_t yytoken, yyntoken;
+extern uint8_t yytoken;
extern uint8_t next(void);
extern void expect(uint8_t tok);
diff --git a/cc1/expr.c b/cc1/expr.c
@@ -468,6 +468,28 @@ postfix(void)
}
}
+static Node *unary(void);
+
+static Node *
+Sizeof(void)
+{
+ Type *tp;
+ Node *np;
+ bool paren = accept(')');
+
+ if (paren && yytoken == IDEN) {
+ tp = typename();
+ } else {
+ Node *np = unary();
+ tp = np->type;
+ /* TODO: free np */
+ }
+ np = sizeofcode(tp);
+ if (paren)
+ expect(')');
+ return np;
+}
+
static Node *cast(void);
static Node *
@@ -480,15 +502,7 @@ unary(void)
switch (yytoken) {
case SIZEOF:
next();
- if (yytoken == '(' && ahead() == TYPE) {
- next();
- tp = typename();
- expect(')');
- } else {
- tp = unary()->type;
- /* TODO: Free memory */
- }
- return sizeofcode(tp);
+ return Sizeof();
case INC: case DEC:
op = (yytoken == INC) ? OA_ADD : OA_SUB;
next();
@@ -507,28 +521,37 @@ unary(void)
}
static Node *
-cast(void)
+cast2(void)
{
- Type *tp;
register Node *np1, *np2;
+ register Type *tp;
- if (yytoken == '(') {
- switch(ahead()) {
- case TQUALIFIER: case TYPE:
- next();
- tp = typename();
- expect(')');
- np1 = eval(cast());
- if ((np2 = convert(np1, tp, 1)) == NULL)
- error("bad type convertion requested");
- np2->b.lvalue = np1->b.lvalue;
- return np2;
- default:
- break;
- }
+ switch(yytoken) {
+ case TQUALIFIER: case TYPE:
+ tp = typename();
+ expect(')');
+ np1 = eval(cast());
+ if ((np2 = convert(np1, tp, 1)) == NULL)
+ error("bad type convertion requested");
+ np2->b.lvalue = np1->b.lvalue;
+ return np2;
+ default:
+ return unary();
}
+}
- return unary();
+static Node *
+cast(void)
+{
+ register Node *np;
+
+ if (accept('(')) {
+ np = cast2();
+ expect('(');
+ } else {
+ np = unary();
+ }
+ return np;
}
static Node *
diff --git a/cc1/lex.c b/cc1/lex.c
@@ -13,13 +13,10 @@ static FILE *yyin;
const char *filename;
unsigned linenum;
-uint8_t yytoken, yyntoken;;
-union yystype yylval;
+uint8_t yytoken;
+struct yystype yylval;
char yytext[IDENTSIZ + 1];
-static union yystype yynlval;
-static char yybuf[IDENTSIZ + 1];
-
static uint8_t
integer(char *s, char base)
{
@@ -50,10 +47,10 @@ type:
sym = install("", NS_IDEN);
sym->type = tp;
- v = strtol(yybuf, NULL, base);
+ v = strtol(yytext, NULL, base);
if (tp == inttype)
sym->u.i = v;
- yynlval.sym = sym;
+ yylval.sym = sym;
return CONSTANT;
}
@@ -75,7 +72,7 @@ number(void)
ungetc(ch, yyin);
}
- for (bp = yybuf ; bp < &yybuf[IDENTSIZ]; *bp++ = ch) {
+ for (bp = yytext ; bp < &yytext[IDENTSIZ]; *bp++ = ch) {
ch = getc(yyin);
switch (base) {
case 8:
@@ -94,11 +91,11 @@ number(void)
}
end:
- if (bp == &yybuf[IDENTSIZ])
- error("identifier too long %s", yybuf);
+ if (bp == &yytext[IDENTSIZ])
+ error("identifier too long %s", yytext);
*bp = '\0';
ungetc(ch, yyin);
- return integer(yybuf, base);
+ return integer(yytext, base);
}
static char *
@@ -150,7 +147,7 @@ character(void)
sym = install("", NS_IDEN);
sym->u.i = c;
sym->type = inttype;
- yynlval.sym = sym;
+ yylval.sym = sym;
return CONSTANT;
}
@@ -185,7 +182,7 @@ end_string:
sym = install("", NS_IDEN);
sym->u.s = xstrdup(buf);
sym->type = mktype(chartype, PTR, 0);
- yynlval.sym = sym;
+ yylval.sym = sym;
return STRING;
}
@@ -248,23 +245,21 @@ iden(void)
{
register char *bp;
register int c;
- Symbol *sym;
+ register Symbol *sym;
- for (bp = yybuf; bp < &yybuf[IDENTSIZ]; *bp++ = c) {
+ for (bp = yytext; bp < &yytext[IDENTSIZ]; *bp++ = c) {
if (!isalnum(c = getc(yyin)) && c != '_')
break;
}
- if (bp == &yybuf[IDENTSIZ])
- error("identifier too long %s", yybuf);
+ if (bp == &yytext[IDENTSIZ])
+ error("identifier too long %s", yytext);
*bp = '\0';
ungetc(c, yyin);
- sym = lookup(yybuf, NS_IDEN);
- if (!sym || sym->token == IDEN) {
- yynlval.sym = sym;
+ sym = yylval.sym = lookup(yytext, NS_IDEN);
+ if (!sym || sym->token == IDEN)
return IDEN;
- }
- yynlval.token = sym->u.token;
+ yylval.token = sym->u.token;
return sym->token;
}
@@ -274,8 +269,8 @@ follow(int expect, int ifyes, int ifno)
register int c = getc(yyin);
if (c == expect) {
- yybuf[1] = c;
- yybuf[2] = 0;
+ yytext[1] = c;
+ yytext[2] = 0;
return ifyes;
}
ungetc(c, yyin);
@@ -287,14 +282,14 @@ minus(void)
{
register int c = getc(yyin);
- yybuf[1] = c;
- yybuf[2] = '\0';
+ yytext[1] = c;
+ yytext[2] = '\0';
switch (c) {
case '-': return DEC;
case '>': return INDIR;
case '=': return SUB_EQ;
default:
- yybuf[1] = '\0';
+ yytext[1] = '\0';
ungetc(c, yyin);
return '-';
}
@@ -305,13 +300,13 @@ plus(void)
{
register int c = getc(yyin);
- yybuf[1] = c;
- yybuf[2] = '\0';
+ yytext[1] = c;
+ yytext[2] = '\0';
switch (c) {
case '+': return INC;
case '=': return ADD_EQ;
default:
- yybuf[1] = '\0';
+ yytext[1] = '\0';
ungetc(c, yyin);
return '+';
}
@@ -322,15 +317,15 @@ relational(uint8_t op, uint8_t equal, uint8_t shift, uint8_t assig)
{
register int c = getc(yyin);
- yybuf[1] = c;
- yybuf[2] = '\0';
+ yytext[1] = c;
+ yytext[2] = '\0';
if (c == '=')
return equal;
if (c == op)
return follow('=', assig, shift);
ungetc(c, yyin);
- yybuf[1] = '\0';
+ yytext[1] = '\0';
return op;
}
@@ -339,15 +334,15 @@ logic(uint8_t op, uint8_t equal, uint8_t logic)
{
register int c = getc(yyin);
- yybuf[1] = c;
- yybuf[2] = '\0';
+ yytext[1] = c;
+ yytext[2] = '\0';
if (c == '=')
return equal;
if (c == op)
return logic;
ungetc(c, yyin);
- yybuf[1] = '\0';
+ yytext[1] = '\0';
return op;
}
@@ -356,8 +351,8 @@ operator(void)
{
register uint8_t c = getc(yyin);
- yybuf[0] = c;
- yybuf[1] = '\0';
+ yytext[0] = c;
+ yytext[1] = '\0';
switch (c) {
case '<': return relational('<', LE, SHL, SHL_EQ);
case '>': return relational('>', GE, SHR, SHR_EQ);
@@ -374,40 +369,43 @@ operator(void)
}
}
-uint8_t
-next(void)
+static int
+skipspaces(void)
{
- static int c;
- strcpy(yytext, yybuf);
- yylval = yynlval;
- if ((yytoken = yyntoken) == EOFTOK)
- goto ret;
+ register int c;
while (isspace(c = getc(yyin))) {
if (c == '\n')
++linenum;
}
+ return c;
+}
+
+uint8_t
+next(void)
+{
+ register int c;
+
+ ungetc(c = skipspaces(), yyin);
if (c == EOF) {
- strcpy(yybuf, "EOF");
- yyntoken = EOFTOK;
+ strcpy(yytext, "EOF");
+ yytoken = EOFTOK;
goto ret;
+ } else if (isalpha(c) || c == '_') {
+ yytoken = iden();
+ } else if (isdigit(c)) {
+ yytoken = number();
+ } else if (c == '"') {
+ yytoken = string();
+ } else if (c == '\'') {
+ yytoken = character();
+ } else {
+ yytoken = operator();
}
-
- ungetc(c, yyin);
- if (isalpha(c) || c == '_')
- yyntoken = iden();
- else if (isdigit(c))
- yyntoken = number();
- else if (c == '"')
- yyntoken = string();
- else if (c == '\'')
- yyntoken = character();
- else
- yyntoken = operator();
-
-ret: return yytoken;
+ret:
+ return yytoken;
}
void
@@ -418,6 +416,16 @@ expect(register uint8_t tok)
next();
}
+uint8_t
+ahead(void)
+{
+ register int c;
+
+ ungetc(c = skipspaces(), yyin);
+
+ return c;
+}
+
void
open_file(register const char *file)
{
@@ -432,5 +440,5 @@ open_file(register const char *file)
filename = file;
}
linenum = 1;
- next(); /* prefetch first token */
}
+