mirror of
https://github.com/mirror/tinycc.git
synced 2025-04-01 12:30:08 +08:00
added do while continue - simplify break/continue handling
This commit is contained in:
parent
704d61357c
commit
4e92bac070
93
tcc.c
93
tcc.c
@ -11,12 +11,11 @@
|
|||||||
glo : global variable index
|
glo : global variable index
|
||||||
parm : parameter variable index
|
parm : parameter variable index
|
||||||
ind : output code ptr
|
ind : output code ptr
|
||||||
lsym: loop symbol stack
|
|
||||||
rsym: return symbol
|
rsym: return symbol
|
||||||
prog: output code
|
prog: output code
|
||||||
astk: arg position stack
|
astk: arg position stack
|
||||||
*/
|
*/
|
||||||
int tok, *vac, *vat, *lsym, rsym,
|
int tok, *vac, *vat, rsym,
|
||||||
prog, ind, loc, glo, file, vt,
|
prog, ind, loc, glo, file, vt,
|
||||||
vc, *macro_stack, *macro_stack_ptr, line_num;
|
vc, *macro_stack, *macro_stack_ptr, line_num;
|
||||||
char *idtable, *idptr, *filename;
|
char *idtable, *idptr, *filename;
|
||||||
@ -87,17 +86,21 @@ char *idtable, *idptr, *filename;
|
|||||||
#define TOK_CASE 274
|
#define TOK_CASE 274
|
||||||
|
|
||||||
/* ignored types Must have contiguous values */
|
/* ignored types Must have contiguous values */
|
||||||
#define TOK_CONST 271
|
#define TOK_CONST 275
|
||||||
#define TOK_LONG 276
|
#define TOK_VOLATILE 276
|
||||||
#define TOK_REGISTER 277
|
#define TOK_LONG 277
|
||||||
#define TOK_SIGNED 278
|
#define TOK_REGISTER 278
|
||||||
|
#define TOK_SIGNED 279
|
||||||
|
|
||||||
/* unsupported types. Must have contiguous values */
|
/* unsupported types. Must have contiguous values */
|
||||||
#define TOK_FLOAT 279
|
#define TOK_FLOAT 280
|
||||||
#define TOK_DOUBLE 280
|
#define TOK_DOUBLE 281
|
||||||
#define TOK_STRUCT 281
|
#define TOK_STRUCT 282
|
||||||
#define TOK_UNION 282
|
#define TOK_UNION 283
|
||||||
#define TOK_TYPEDEF 283
|
#define TOK_TYPEDEF 284
|
||||||
|
|
||||||
|
#define TOK_DEFAULT 285
|
||||||
|
#define TOK_ENUM 286
|
||||||
|
|
||||||
#define TOK_EQ 0x94 /* warning: depend on asm code */
|
#define TOK_EQ 0x94 /* warning: depend on asm code */
|
||||||
#define TOK_NE 0x95 /* warning: depend on asm code */
|
#define TOK_NE 0x95 /* warning: depend on asm code */
|
||||||
@ -336,16 +339,21 @@ void o(c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* output a symbol and patch all calls to it */
|
/* output a symbol and patch all calls to it */
|
||||||
void gsym(t)
|
void gsym_addr(t, a)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
while (t) {
|
while (t) {
|
||||||
n = *(int *)t; /* next value */
|
n = *(int *)t; /* next value */
|
||||||
*(int *)t = ind - t - 4;
|
*(int *)t = a - t - 4;
|
||||||
t = n;
|
t = n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gsym(t)
|
||||||
|
{
|
||||||
|
gsym_addr(t, ind);
|
||||||
|
}
|
||||||
|
|
||||||
/* psym is used to put an instruction with a data field which is a
|
/* psym is used to put an instruction with a data field which is a
|
||||||
reference to a symbol. It is in fact the same as oad ! */
|
reference to a symbol. It is in fact the same as oad ! */
|
||||||
#define psym oad
|
#define psym oad
|
||||||
@ -1022,9 +1030,9 @@ void expr()
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void block()
|
void block(int *bsym, int *csym)
|
||||||
{
|
{
|
||||||
int a, c, d;
|
int a, b, c, d;
|
||||||
|
|
||||||
if (tok == TOK_IF) {
|
if (tok == TOK_IF) {
|
||||||
/* if test */
|
/* if test */
|
||||||
@ -1033,13 +1041,13 @@ void block()
|
|||||||
expr();
|
expr();
|
||||||
skip(')');
|
skip(')');
|
||||||
a = gtst(1, 0);
|
a = gtst(1, 0);
|
||||||
block();
|
block(bsym, csym);
|
||||||
c = tok;
|
c = tok;
|
||||||
if (c == TOK_ELSE) {
|
if (c == TOK_ELSE) {
|
||||||
next();
|
next();
|
||||||
d = psym(0xe9, 0); /* jmp */
|
d = psym(0xe9, 0); /* jmp */
|
||||||
gsym(a);
|
gsym(a);
|
||||||
block();
|
block(bsym, csym);
|
||||||
gsym(d); /* patch else jmp */
|
gsym(d); /* patch else jmp */
|
||||||
} else
|
} else
|
||||||
gsym(a);
|
gsym(a);
|
||||||
@ -1049,16 +1057,18 @@ void block()
|
|||||||
skip('(');
|
skip('(');
|
||||||
expr();
|
expr();
|
||||||
skip(')');
|
skip(')');
|
||||||
*++lsym = gtst(1, 0);
|
a = gtst(1, 0);
|
||||||
block();
|
b = 0;
|
||||||
|
block(&a, &b);
|
||||||
oad(0xe9, d - ind - 5); /* jmp */
|
oad(0xe9, d - ind - 5); /* jmp */
|
||||||
gsym(*lsym--);
|
gsym(a);
|
||||||
|
gsym_addr(b, d);
|
||||||
} else if (tok == '{') {
|
} else if (tok == '{') {
|
||||||
next();
|
next();
|
||||||
/* declarations */
|
/* declarations */
|
||||||
decl(VT_LOCAL);
|
decl(VT_LOCAL);
|
||||||
while (tok != '}')
|
while (tok != '}')
|
||||||
block();
|
block(bsym, csym);
|
||||||
next();
|
next();
|
||||||
} else if (tok == TOK_RETURN) {
|
} else if (tok == TOK_RETURN) {
|
||||||
next();
|
next();
|
||||||
@ -1070,7 +1080,16 @@ void block()
|
|||||||
rsym = psym(0xe9, rsym); /* jmp */
|
rsym = psym(0xe9, rsym); /* jmp */
|
||||||
} else if (tok == TOK_BREAK) {
|
} else if (tok == TOK_BREAK) {
|
||||||
/* compute jump */
|
/* compute jump */
|
||||||
*lsym = psym(0xe9, *lsym);
|
if (!bsym)
|
||||||
|
error("cannot break");
|
||||||
|
*bsym = psym(0xe9, *bsym);
|
||||||
|
next();
|
||||||
|
skip(';');
|
||||||
|
} else if (tok == TOK_CONTINUE) {
|
||||||
|
/* compute jump */
|
||||||
|
if (!csym)
|
||||||
|
error("cannot continue");
|
||||||
|
*csym = psym(0xe9, *csym);
|
||||||
next();
|
next();
|
||||||
skip(';');
|
skip(';');
|
||||||
} else
|
} else
|
||||||
@ -1085,11 +1104,11 @@ void block()
|
|||||||
d = ind;
|
d = ind;
|
||||||
c = ind;
|
c = ind;
|
||||||
a = 0;
|
a = 0;
|
||||||
|
b = 0;
|
||||||
if (tok != ';') {
|
if (tok != ';') {
|
||||||
expr();
|
expr();
|
||||||
a = gtst(1, 0);
|
a = gtst(1, 0);
|
||||||
}
|
}
|
||||||
*++lsym = a;
|
|
||||||
skip(';');
|
skip(';');
|
||||||
if (tok != ')') {
|
if (tok != ')') {
|
||||||
e = psym(0xe9, 0);
|
e = psym(0xe9, 0);
|
||||||
@ -1099,9 +1118,25 @@ void block()
|
|||||||
gsym(e);
|
gsym(e);
|
||||||
}
|
}
|
||||||
skip(')');
|
skip(')');
|
||||||
block();
|
block(&a, &b);
|
||||||
oad(0xe9, c - ind - 5); /* jmp */
|
oad(0xe9, c - ind - 5); /* jmp */
|
||||||
gsym(*lsym--);
|
gsym(a);
|
||||||
|
gsym_addr(b, c);
|
||||||
|
} else
|
||||||
|
if (tok == TOK_DO) {
|
||||||
|
next();
|
||||||
|
a = 0;
|
||||||
|
b = 0;
|
||||||
|
d = ind;
|
||||||
|
block(&a, &b);
|
||||||
|
skip(TOK_WHILE);
|
||||||
|
skip('(');
|
||||||
|
gsym(b);
|
||||||
|
expr();
|
||||||
|
c = gtst(0, 0);
|
||||||
|
gsym_addr(c, d);
|
||||||
|
skip(')');
|
||||||
|
gsym(a);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
@ -1131,7 +1166,7 @@ void decl(l)
|
|||||||
o(0xe58955); /* push %ebp, mov %esp, %ebp */
|
o(0xe58955); /* push %ebp, mov %esp, %ebp */
|
||||||
a = oad(0xec81, 0); /* sub $xxx, %esp */
|
a = oad(0xec81, 0); /* sub $xxx, %esp */
|
||||||
rsym = 0;
|
rsym = 0;
|
||||||
block();
|
block(0, 0);
|
||||||
gsym(rsym);
|
gsym(rsym);
|
||||||
o(0xc3c9); /* leave, ret */
|
o(0xc3c9); /* leave, ret */
|
||||||
*a = (-loc + 3) & -4; /* align local size to word &
|
*a = (-loc + 3) & -4; /* align local size to word &
|
||||||
@ -1207,15 +1242,13 @@ int main(int c, char **v)
|
|||||||
idptr = idtable + 53;
|
idptr = idtable + 53;
|
||||||
#else
|
#else
|
||||||
memcpy(idtable,
|
memcpy(idtable,
|
||||||
"int\0void\0char\0if\0else\0while\0break\0return\0define\0main\0for\0extern\0static\0unsigned\0goto\0do\0continue\0switch\0case\0const\0long\0register\0signed\0float\0double\0struct\0union\0typedef", 170);
|
"int\0void\0char\0if\0else\0while\0break\0return\0define\0main\0for\0extern\0static\0unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0register\0signed\0float\0double\0struct\0union\0typedef\0default\0enum", 192);
|
||||||
|
idptr = idtable + 192;
|
||||||
idptr = idtable + 170;
|
|
||||||
#endif
|
#endif
|
||||||
glo = malloc(DATA_SIZE);
|
glo = malloc(DATA_SIZE);
|
||||||
prog = malloc(TEXT_SIZE);
|
prog = malloc(TEXT_SIZE);
|
||||||
vac = malloc(VAR_TABLE_SIZE);
|
vac = malloc(VAR_TABLE_SIZE);
|
||||||
vat = malloc(VAR_TABLE_SIZE);
|
vat = malloc(VAR_TABLE_SIZE);
|
||||||
lsym = malloc(256);
|
|
||||||
macro_stack = malloc(256);
|
macro_stack = malloc(256);
|
||||||
macro_stack_ptr = macro_stack;
|
macro_stack_ptr = macro_stack;
|
||||||
ind = prog;
|
ind = prog;
|
||||||
|
Loading…
Reference in New Issue
Block a user