fixed switch - preparation for new types
This commit is contained in:
119
tcc.c
119
tcc.c
@ -443,6 +443,10 @@ TokenSym *tok_alloc(char *str, int len)
|
|||||||
return ts;
|
return ts;
|
||||||
pts = &(ts->hash_next);
|
pts = &(ts->hash_next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tok_ident >= SYM_FIRST_ANOM)
|
||||||
|
error("memory full");
|
||||||
|
|
||||||
/* expand token table if needed */
|
/* expand token table if needed */
|
||||||
i = tok_ident - TOK_IDENT;
|
i = tok_ident - TOK_IDENT;
|
||||||
if ((i % TOK_ALLOC_INCR) == 0) {
|
if ((i % TOK_ALLOC_INCR) == 0) {
|
||||||
@ -451,8 +455,9 @@ TokenSym *tok_alloc(char *str, int len)
|
|||||||
error("memory full");
|
error("memory full");
|
||||||
table_ident = ptable;
|
table_ident = ptable;
|
||||||
}
|
}
|
||||||
|
|
||||||
ts = malloc(sizeof(TokenSym) + len);
|
ts = malloc(sizeof(TokenSym) + len);
|
||||||
if (!ts || tok_ident >= SYM_FIRST_ANOM)
|
if (!ts)
|
||||||
error("memory full");
|
error("memory full");
|
||||||
table_ident[i] = ts;
|
table_ident[i] = ts;
|
||||||
ts->tok = tok_ident++;
|
ts->tok = tok_ident++;
|
||||||
@ -1468,7 +1473,7 @@ void macro_subst(int **tok_str, int *tok_len,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* return next token with macro substitution */
|
/* return next token with macro substitution */
|
||||||
void next()
|
void next(void)
|
||||||
{
|
{
|
||||||
int len, *ptr;
|
int len, *ptr;
|
||||||
Sym *nested_list;
|
Sym *nested_list;
|
||||||
@ -2413,46 +2418,87 @@ int struct_decl(int u)
|
|||||||
*/
|
*/
|
||||||
int ist(void)
|
int ist(void)
|
||||||
{
|
{
|
||||||
int t;
|
int t, u;
|
||||||
Sym *s;
|
Sym *s;
|
||||||
|
|
||||||
t = 0;
|
t = 0;
|
||||||
while(1) {
|
while(1) {
|
||||||
if (tok == TOK_ENUM) {
|
switch(tok) {
|
||||||
t |= struct_decl(VT_ENUM);
|
/* basic types */
|
||||||
} else if (tok == TOK_STRUCT || tok == TOK_UNION) {
|
case TOK_CHAR:
|
||||||
t |= struct_decl(VT_STRUCT);
|
u = VT_BYTE;
|
||||||
} else {
|
basic_type:
|
||||||
if (tok == TOK_CHAR) {
|
|
||||||
t |= VT_BYTE;
|
|
||||||
} else if (tok == TOK_VOID) {
|
|
||||||
t |= VT_VOID;
|
|
||||||
} else if (tok == TOK_SHORT) {
|
|
||||||
t |= VT_SHORT;
|
|
||||||
} else if (tok == TOK_INT |
|
|
||||||
(tok >= TOK_CONST & tok <= TOK_INLINE)) {
|
|
||||||
/* ignored types */
|
|
||||||
} else if (tok == TOK_FLOAT || tok == TOK_DOUBLE) {
|
|
||||||
/* We allow that to compile standard headers */
|
|
||||||
// warning("floats not supported");
|
|
||||||
} else if (tok == TOK_EXTERN) {
|
|
||||||
t |= VT_EXTERN;
|
|
||||||
} else if (tok == TOK_STATIC) {
|
|
||||||
t |= VT_STATIC;
|
|
||||||
} else if (tok == TOK_UNSIGNED) {
|
|
||||||
t |= VT_UNSIGNED;
|
|
||||||
} else if (tok == TOK_TYPEDEF) {
|
|
||||||
t |= VT_TYPEDEF;
|
|
||||||
} else {
|
|
||||||
s = sym_find(tok);
|
|
||||||
if (!s || !(s->t & VT_TYPEDEF))
|
|
||||||
break;
|
|
||||||
t |= (s->t & ~VT_TYPEDEF);
|
|
||||||
}
|
|
||||||
next();
|
next();
|
||||||
|
basic_type1:
|
||||||
|
if ((t & VT_BTYPE) != 0)
|
||||||
|
error("too many basic types %x", t);
|
||||||
|
t |= u;
|
||||||
|
break;
|
||||||
|
case TOK_VOID:
|
||||||
|
u = VT_VOID;
|
||||||
|
goto basic_type;
|
||||||
|
case TOK_SHORT:
|
||||||
|
u = VT_SHORT;
|
||||||
|
goto basic_type;
|
||||||
|
case TOK_INT:
|
||||||
|
next();
|
||||||
|
break;
|
||||||
|
case TOK_LONG:
|
||||||
|
/* XXX: add long type */
|
||||||
|
u = VT_INT;
|
||||||
|
goto basic_type;
|
||||||
|
case TOK_FLOAT:
|
||||||
|
case TOK_DOUBLE:
|
||||||
|
/* XXX: add float types */
|
||||||
|
u = VT_INT;
|
||||||
|
goto basic_type;
|
||||||
|
case TOK_ENUM:
|
||||||
|
u = struct_decl(VT_ENUM);
|
||||||
|
goto basic_type1;
|
||||||
|
case TOK_STRUCT:
|
||||||
|
case TOK_UNION:
|
||||||
|
u = struct_decl(VT_STRUCT);
|
||||||
|
goto basic_type1;
|
||||||
|
|
||||||
|
/* type modifiers */
|
||||||
|
case TOK_CONST:
|
||||||
|
case TOK_VOLATILE:
|
||||||
|
case TOK_REGISTER:
|
||||||
|
case TOK_SIGNED:
|
||||||
|
case TOK_AUTO:
|
||||||
|
case TOK_INLINE:
|
||||||
|
case TOK_RESTRICT:
|
||||||
|
next();
|
||||||
|
break;
|
||||||
|
case TOK_UNSIGNED:
|
||||||
|
t |= VT_UNSIGNED;
|
||||||
|
next();
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* storage */
|
||||||
|
case TOK_EXTERN:
|
||||||
|
t |= VT_EXTERN;
|
||||||
|
next();
|
||||||
|
break;
|
||||||
|
case TOK_STATIC:
|
||||||
|
t |= VT_STATIC;
|
||||||
|
next();
|
||||||
|
break;
|
||||||
|
case TOK_TYPEDEF:
|
||||||
|
t |= VT_TYPEDEF;
|
||||||
|
next();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
s = sym_find(tok);
|
||||||
|
if (!s || !(s->t & VT_TYPEDEF))
|
||||||
|
goto the_end;
|
||||||
|
t |= (s->t & ~VT_TYPEDEF);
|
||||||
|
next();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
t |= 2;
|
t |= 2;
|
||||||
}
|
}
|
||||||
|
the_end:
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3268,7 +3314,7 @@ void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg)
|
|||||||
case_reg = gv();
|
case_reg = gv();
|
||||||
skip(')');
|
skip(')');
|
||||||
a = 0;
|
a = 0;
|
||||||
b = 0;
|
b = gjmp(0); /* jump to first case */
|
||||||
c = 0;
|
c = 0;
|
||||||
block(&a, csym, &b, &c, case_reg);
|
block(&a, csym, &b, &c, case_reg);
|
||||||
/* if no default, jmp after switch */
|
/* if no default, jmp after switch */
|
||||||
@ -3284,12 +3330,15 @@ void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg)
|
|||||||
a = expr_const();
|
a = expr_const();
|
||||||
if (!case_sym)
|
if (!case_sym)
|
||||||
expect("switch");
|
expect("switch");
|
||||||
|
/* since a case is like a label, we must skip it with a jmp */
|
||||||
|
b = gjmp(0);
|
||||||
gsym(*case_sym);
|
gsym(*case_sym);
|
||||||
vset(case_reg, 0);
|
vset(case_reg, 0);
|
||||||
vpush();
|
vpush();
|
||||||
vset(VT_CONST, a);
|
vset(VT_CONST, a);
|
||||||
gen_op(TOK_EQ);
|
gen_op(TOK_EQ);
|
||||||
*case_sym = gtst(1, 0);
|
*case_sym = gtst(1, 0);
|
||||||
|
gsym(b);
|
||||||
skip(':');
|
skip(':');
|
||||||
block(bsym, csym, case_sym, def_sym, case_reg);
|
block(bsym, csym, case_sym, def_sym, case_reg);
|
||||||
} else
|
} else
|
||||||
|
|||||||
Reference in New Issue
Block a user