forked from Mirrors/tinycc
clarified function types - added extern / static - added unsigned and invalid type parsing
parent
9c1b84560e
commit
704d61357c
316
tcc.c
316
tcc.c
|
@ -19,7 +19,7 @@
|
||||||
int tok, *vac, *vat, *lsym, rsym,
|
int tok, *vac, *vat, *lsym, 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, *idlast, *filename;
|
char *idtable, *idptr, *filename;
|
||||||
|
|
||||||
/* The current value can be: */
|
/* The current value can be: */
|
||||||
#define VT_CONST 0x0002 /* constant in vc */
|
#define VT_CONST 0x0002 /* constant in vc */
|
||||||
|
@ -49,30 +49,55 @@ char *idtable, *idptr, *idlast, *filename;
|
||||||
* otherwise integer type is assumed.
|
* otherwise integer type is assumed.
|
||||||
* */
|
* */
|
||||||
|
|
||||||
#define VT_BYTE 0x00001 /* byte pointer. HARDCODED VALUE */
|
#define VT_BYTE 0x00001 /* byte pointer. HARDCODED VALUE */
|
||||||
#define VT_PTRMASK 0x00f00 /* pointer mask */
|
#define VT_PTRMASK 0x00f00 /* pointer mask */
|
||||||
#define VT_PTRINC 0x00100 /* pointer increment */
|
#define VT_PTRINC 0x00100 /* pointer increment */
|
||||||
#define VT_FUNC 0x01000 /* function type */
|
#define VT_FUNC 0x01000 /* function type */
|
||||||
#define VT_TYPE 0x01f01 /* type mask */
|
#define VT_UNSIGNED 0x02000 /* unsigned type */
|
||||||
|
#define VT_ARRAY 0x04000 /* array type (only used in parsing) */
|
||||||
#define VT_TYPEN 0xffffe0fe /* ~VT_TYPE */
|
#define VT_TYPE 0x07f01 /* type mask */
|
||||||
|
#define VT_TYPEN 0xffff80fe /* ~VT_TYPE */
|
||||||
#define VT_FUNCN -4097
|
#define VT_FUNCN -4097
|
||||||
|
|
||||||
|
#define VT_EXTERN 0x08000 /* extern definition */
|
||||||
|
#define VT_STATIC 0x10000 /* static variable */
|
||||||
|
|
||||||
/* Special infos */
|
/* Special infos */
|
||||||
#define VT_DEFINE 0x02000 /* special value for #defined symbols */
|
#define VT_DEFINE 0x80000 /* special value for #defined symbols */
|
||||||
|
|
||||||
/* token values */
|
/* token values */
|
||||||
#define TOK_INT 256
|
#define TOK_INT 256
|
||||||
#define TOK_VOID 257
|
#define TOK_VOID 257
|
||||||
#define TOK_CHAR 258
|
#define TOK_CHAR 258
|
||||||
#define TOK_IF 259
|
#define TOK_IF 259
|
||||||
#define TOK_ELSE 260
|
#define TOK_ELSE 260
|
||||||
#define TOK_WHILE 261
|
#define TOK_WHILE 261
|
||||||
#define TOK_BREAK 262
|
#define TOK_BREAK 262
|
||||||
#define TOK_RETURN 263
|
#define TOK_RETURN 263
|
||||||
#define TOK_DEFINE 264
|
#define TOK_DEFINE 264
|
||||||
#define TOK_MAIN 265
|
#define TOK_MAIN 265
|
||||||
#define TOK_FOR 266
|
#define TOK_FOR 266
|
||||||
|
#define TOK_EXTERN 267
|
||||||
|
#define TOK_STATIC 268
|
||||||
|
#define TOK_UNSIGNED 269
|
||||||
|
#define TOK_GOTO 270
|
||||||
|
#define TOK_DO 271
|
||||||
|
#define TOK_CONTINUE 272
|
||||||
|
#define TOK_SWITCH 273
|
||||||
|
#define TOK_CASE 274
|
||||||
|
|
||||||
|
/* ignored types Must have contiguous values */
|
||||||
|
#define TOK_CONST 271
|
||||||
|
#define TOK_LONG 276
|
||||||
|
#define TOK_REGISTER 277
|
||||||
|
#define TOK_SIGNED 278
|
||||||
|
|
||||||
|
/* unsupported types. Must have contiguous values */
|
||||||
|
#define TOK_FLOAT 279
|
||||||
|
#define TOK_DOUBLE 280
|
||||||
|
#define TOK_STRUCT 281
|
||||||
|
#define TOK_UNION 282
|
||||||
|
#define TOK_TYPEDEF 283
|
||||||
|
|
||||||
#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 */
|
||||||
|
@ -166,6 +191,21 @@ void test_lvalue()
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
char *get_tok_str(int v)
|
||||||
|
{
|
||||||
|
int t;
|
||||||
|
char *p;
|
||||||
|
p = idtable;
|
||||||
|
t = 256;
|
||||||
|
while (t != v) {
|
||||||
|
if (p >= idptr)
|
||||||
|
return 0;
|
||||||
|
while (*p++);
|
||||||
|
t++;
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
void next()
|
void next()
|
||||||
{
|
{
|
||||||
int c, v;
|
int c, v;
|
||||||
|
@ -226,7 +266,6 @@ void next()
|
||||||
}
|
}
|
||||||
if (isid(c)) {
|
if (isid(c)) {
|
||||||
q = idptr;
|
q = idptr;
|
||||||
idlast = q;
|
|
||||||
while(isid(c) | isnum(c)) {
|
while(isid(c) | isnum(c)) {
|
||||||
*q++ = c;
|
*q++ = c;
|
||||||
c = inp();
|
c = inp();
|
||||||
|
@ -328,6 +367,7 @@ void vset(t, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generate a value in eax from vt and vc */
|
/* generate a value in eax from vt and vc */
|
||||||
|
/* XXX: generate correct pointer for forward references to functions */
|
||||||
void gv()
|
void gv()
|
||||||
{
|
{
|
||||||
#ifndef TINY
|
#ifndef TINY
|
||||||
|
@ -402,15 +442,23 @@ int gtst(inv, t)
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return the size in bytes of a given type */
|
|
||||||
int type_size(t)
|
int type_size(t)
|
||||||
{
|
{
|
||||||
if ((t & VT_PTRMASK) > VT_PTRINC | (t & VT_TYPE) == VT_PTRINC)
|
if ((t & VT_PTRMASK) >= VT_PTRINC | (t & VT_TYPE) == 0)
|
||||||
return 4;
|
return 4;
|
||||||
else
|
else
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* return the number size in bytes of a given type */
|
||||||
|
int incr_value(t)
|
||||||
|
{
|
||||||
|
if ((t & VT_PTRMASK) >= VT_PTRINC)
|
||||||
|
return type_size(t - VT_PTRINC);
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
#define POST_ADD 0x1000
|
#define POST_ADD 0x1000
|
||||||
#define PRE_ADD 0
|
#define PRE_ADD 0
|
||||||
|
|
||||||
|
@ -422,12 +470,13 @@ void inc(a, c)
|
||||||
gv();
|
gv();
|
||||||
o(0x018bc189); /* movl %eax, %ecx ; mov (%ecx), %eax */
|
o(0x018bc189); /* movl %eax, %ecx ; mov (%ecx), %eax */
|
||||||
o(0x408d | a); /* leal x(%eax), %eax/%edx */
|
o(0x408d | a); /* leal x(%eax), %eax/%edx */
|
||||||
g((c - TOK_MID) * type_size(vt));
|
g((c - TOK_MID) * incr_value(vt));
|
||||||
o(0x0189 | a); /* mov %eax/%edx, (%ecx) */
|
o(0x0189 | a); /* mov %eax/%edx, (%ecx) */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: handle ptr sub and 'int + ptr' case (only 'ptr + int' handled) */
|
/* XXX: handle ptr sub and 'int + ptr' case (only 'ptr + int' handled) */
|
||||||
/* XXX: handle constant propagation (need to track live eax) */
|
/* XXX: handle constant propagation (need to track live eax) */
|
||||||
|
/* XXX: handle unsigned propagation */
|
||||||
void gen_op(op, l)
|
void gen_op(op, l)
|
||||||
{
|
{
|
||||||
int t;
|
int t;
|
||||||
|
@ -445,7 +494,7 @@ void gen_op(op, l)
|
||||||
o(0x59); /* pop %ecx */
|
o(0x59); /* pop %ecx */
|
||||||
if (op == '+' | op == '-') {
|
if (op == '+' | op == '-') {
|
||||||
/* XXX: incorrect for short (futur!) */
|
/* XXX: incorrect for short (futur!) */
|
||||||
if (type_size(t) == 4)
|
if (incr_value(t) == 4)
|
||||||
o(0x02e0c1); /* shl $2, %eax */
|
o(0x02e0c1); /* shl $2, %eax */
|
||||||
if (op == '-')
|
if (op == '-')
|
||||||
o(0xd8f7); /* neg %eax */
|
o(0xd8f7); /* neg %eax */
|
||||||
|
@ -461,16 +510,23 @@ void gen_op(op, l)
|
||||||
o(0xc1af0f); /* imul %ecx, %eax */
|
o(0xc1af0f); /* imul %ecx, %eax */
|
||||||
#ifndef TINY
|
#ifndef TINY
|
||||||
else if (op == TOK_SHL | op == TOK_SHR) {
|
else if (op == TOK_SHL | op == TOK_SHR) {
|
||||||
o(0xd391); /* xchg %ecx, %eax, shl/sar %cl, %eax */
|
o(0xd391); /* xchg %ecx, %eax, shl/shr/sar %cl, %eax */
|
||||||
if (op == TOK_SHL)
|
if (op == TOK_SHL)
|
||||||
o(0xe0);
|
o(0xe0);
|
||||||
|
else if (t & VT_UNSIGNED)
|
||||||
|
o(0xe8);
|
||||||
else
|
else
|
||||||
o(0xf8);
|
o(0xf8);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (op == '/' | op == '%') {
|
else if (op == '/' | op == '%') {
|
||||||
o(0x91); /* xchg %ecx, %eax */
|
o(0x91); /* xchg %ecx, %eax */
|
||||||
o(0xf9f799); /* cltd, idiv %ecx, %eax */
|
if (t & VT_UNSIGNED) {
|
||||||
|
o(0xd231); /* xor %edx, %edx */
|
||||||
|
o(0xf1f7); /* div %ecx, %eax */
|
||||||
|
} else {
|
||||||
|
o(0xf9f799); /* cltd, idiv %ecx, %eax */
|
||||||
|
}
|
||||||
if (op == '%')
|
if (op == '%')
|
||||||
o(0x92); /* xchg %edx, %eax */
|
o(0x92); /* xchg %edx, %eax */
|
||||||
} else {
|
} else {
|
||||||
|
@ -486,19 +542,33 @@ void gen_op(op, l)
|
||||||
int ist()
|
int ist()
|
||||||
{
|
{
|
||||||
int t;
|
int t;
|
||||||
|
t = 0;
|
||||||
if (tok == TOK_INT | tok == TOK_CHAR | tok == TOK_VOID) {
|
while(1) {
|
||||||
t = tok;
|
if (tok == TOK_CHAR | tok == TOK_VOID) {
|
||||||
|
t |= VT_BYTE;
|
||||||
|
} else if (tok == TOK_INT |
|
||||||
|
(tok >= TOK_CONST & tok <= TOK_SIGNED)) {
|
||||||
|
/* ignored types */
|
||||||
|
} else if (tok >= TOK_FLOAT & tok <= TOK_TYPEDEF) {
|
||||||
|
error("unsupported type");
|
||||||
|
} 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 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
next();
|
next();
|
||||||
return (t != TOK_INT) | 2;
|
t |= 2;
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read a type declaration (except basic type), and return the
|
/* Read a type declaration (except basic type), and return the
|
||||||
type. If v is true, then also put variable name in 'vc' */
|
type. If v is true, then also put variable name in 'vc' */
|
||||||
int typ(v,t)
|
int typ(int *v, int t, int *array_size_ptr)
|
||||||
{
|
{
|
||||||
int u, p, n;
|
int u, p, n;
|
||||||
|
|
||||||
|
@ -512,46 +582,80 @@ int typ(v,t)
|
||||||
/* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
|
/* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
|
||||||
if (tok == '(') {
|
if (tok == '(') {
|
||||||
next();
|
next();
|
||||||
u = typ(v, 0);
|
u = typ(v, 0, 0);
|
||||||
skip(')');
|
skip(')');
|
||||||
} else {
|
} else {
|
||||||
u = 0;
|
u = 0;
|
||||||
/* type identifier */
|
/* type identifier */
|
||||||
if (v) {
|
if (v) {
|
||||||
vc = tok;
|
*v = tok;
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* function declaration */
|
while(1) {
|
||||||
if (tok == '(') {
|
if (tok == '(') {
|
||||||
next();
|
/* function declaration */
|
||||||
p = 4;
|
next();
|
||||||
n = vc; /* must save vc there */
|
p = 4;
|
||||||
while (tok != ')') {
|
while (tok != ')') {
|
||||||
/* read param name and compute offset */
|
/* read param name and compute offset */
|
||||||
if (t = ist())
|
if (t = ist())
|
||||||
t = typ(1, t); /* XXX: should accept both arg/non arg if v == 0 */
|
t = typ(&n, t, 0); /* XXX: should accept both arg/non arg if v == 0 */
|
||||||
else {
|
else {
|
||||||
vc = tok;
|
n = tok;
|
||||||
t = 0;
|
t = 0;
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
p = p + 4;
|
p = p + 4;
|
||||||
vat[vc] = VT_LOCAL | VT_LVAL | t;
|
vat[n] = VT_LOCAL | VT_LVAL | t;
|
||||||
vac[vc] = p;
|
vac[n] = p;
|
||||||
if (tok == ',')
|
if (tok == ',')
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
next(); /* skip ')' */
|
next(); /* skip ')' */
|
||||||
vc = n;
|
if (u)
|
||||||
if (u)
|
t = u + VT_BYTE;
|
||||||
t = u + VT_BYTE;
|
else
|
||||||
else
|
t = t | VT_FUNC;
|
||||||
t = t | VT_FUNC;
|
} else if (tok == '[') {
|
||||||
|
/* array definition */
|
||||||
|
if (t & VT_ARRAY)
|
||||||
|
error("multi dimension arrays not supported");
|
||||||
|
next();
|
||||||
|
vc = 0;
|
||||||
|
if (tok != ']') {
|
||||||
|
expr();
|
||||||
|
if (array_size_ptr)
|
||||||
|
*array_size_ptr = vc;
|
||||||
|
}
|
||||||
|
if ((vt & (VT_CONST | VT_LVAL)) != VT_CONST |
|
||||||
|
(vc <= 0 & array_size_ptr != 0))
|
||||||
|
error("invalid array size");
|
||||||
|
skip(']');
|
||||||
|
t = (t + VT_PTRINC) | VT_ARRAY;
|
||||||
|
} else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* define a new external reference to a function 'v' of type 'u' */
|
||||||
|
void external_func(v, u)
|
||||||
|
{
|
||||||
|
int t, n;
|
||||||
|
t = vat[v];
|
||||||
|
if (t == 0) {
|
||||||
|
n = dlsym(0, get_tok_str(v));
|
||||||
|
if (n == 0) {
|
||||||
|
vat[v] = u | VT_CONST | VT_LVAL | VT_FORWARD;
|
||||||
|
vac[v] = 0; /* used to generate symbol list */
|
||||||
|
} else {
|
||||||
|
vat[v] = u | VT_CONST | VT_LVAL; /* int f() */
|
||||||
|
vac[v] = n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* read a number in base b */
|
/* read a number in base b */
|
||||||
int getn(c, b)
|
int getn(c, b)
|
||||||
{
|
{
|
||||||
|
@ -631,20 +735,18 @@ void unary()
|
||||||
vset(VT_CONST | VT_PTRINC | VT_BYTE, glo);
|
vset(VT_CONST | VT_PTRINC | VT_BYTE, glo);
|
||||||
while (tok == '\"') {
|
while (tok == '\"') {
|
||||||
while((n = inp()) != 34) {
|
while((n = inp()) != 34) {
|
||||||
*(char *)glo = getq(n);
|
*(char *)glo++ = getq(n);
|
||||||
glo++;
|
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
*(char *)glo = 0;
|
*(char *)glo++ = 0;
|
||||||
glo = (glo + 4) & -4; /* align heap */
|
|
||||||
} else {
|
} else {
|
||||||
t = tok;
|
t = tok;
|
||||||
next();
|
next();
|
||||||
if (t == '(') {
|
if (t == '(') {
|
||||||
/* cast ? */
|
/* cast ? */
|
||||||
if (t = ist()) {
|
if (t = ist()) {
|
||||||
ft = typ(0, t);
|
ft = typ(0, t, 0);
|
||||||
skip(')');
|
skip(')');
|
||||||
unary();
|
unary();
|
||||||
vt = (vt & VT_TYPEN) | ft;
|
vt = (vt & VT_TYPEN) | ft;
|
||||||
|
@ -700,15 +802,17 @@ void unary()
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
vset(vat[t], vac[t]);
|
if (vat[t] == 0) {
|
||||||
/* forward reference or external reference ? */
|
if (tok != '(')
|
||||||
if (vt == 0) {
|
error("undefined symbol");
|
||||||
n = dlsym(0, idlast);
|
/* for simple function calls, we tolerate undeclared
|
||||||
if (n == 0)
|
external reference */
|
||||||
vset(VT_CONST | VT_FORWARD | VT_LVAL, vac + t);
|
external_func(t, VT_FUNC); /* int() function */
|
||||||
else
|
|
||||||
vset(VT_CONST | VT_LVAL, n);
|
|
||||||
}
|
}
|
||||||
|
vset(vat[t], vac[t]);
|
||||||
|
/* if forward reference, we must point to vac[t] */
|
||||||
|
if (vt & VT_FORWARD)
|
||||||
|
vc = t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -764,18 +868,20 @@ void unary()
|
||||||
}
|
}
|
||||||
if (ft & VT_CONST) {
|
if (ft & VT_CONST) {
|
||||||
/* forward reference */
|
/* forward reference */
|
||||||
if (ft & VT_FORWARD)
|
if (ft & VT_FORWARD) {
|
||||||
*(int *)fc = psym(0xe8, *(int *)fc);
|
vac[fc] = psym(0xe8, vac[fc]);
|
||||||
else
|
} else
|
||||||
oad(0xe8, fc - ind - 5);
|
oad(0xe8, fc - ind - 5);
|
||||||
|
/* return value is variable, and take type from function proto */
|
||||||
|
vt = VT_VAR | (ft & VT_TYPE & VT_FUNCN);
|
||||||
} else {
|
} else {
|
||||||
oad(0x2494ff, t); /* call *xxx(%esp) */
|
oad(0x2494ff, t); /* call *xxx(%esp) */
|
||||||
t = t + 4;
|
t = t + 4;
|
||||||
|
/* return value is variable, int */
|
||||||
|
vt = VT_VAR;
|
||||||
}
|
}
|
||||||
if (t)
|
if (t)
|
||||||
oad(0xc481, t);
|
oad(0xc481, t);
|
||||||
/* return value is variable, int */
|
|
||||||
vt = VT_VAR;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1005,22 +1111,22 @@ void block()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 'l' is true if local declarations */
|
/* 'l' is VT_LOCAL or VT_CONST to define default storage type */
|
||||||
void decl(l)
|
void decl(l)
|
||||||
{
|
{
|
||||||
int *a, t, b;
|
int *a, t, b, s, align, v, u, n;
|
||||||
|
|
||||||
while (b = ist()) {
|
while (b = ist()) {
|
||||||
while (1) { /* iterate thru each declaration */
|
while (1) { /* iterate thru each declaration */
|
||||||
vt = typ(1, b);
|
s = 1;
|
||||||
|
t = typ(&v, b, &s);
|
||||||
if (tok == '{') {
|
if (tok == '{') {
|
||||||
/* patch forward references (XXX: does not work for
|
/* patch forward references */
|
||||||
function pointers) */
|
if (vat[v] & VT_FORWARD)
|
||||||
if (vat[vc] == 0)
|
gsym(vac[v]);
|
||||||
gsym(vac[vc]);
|
|
||||||
/* put function address */
|
/* put function address */
|
||||||
vat[vc] = VT_CONST | VT_LVAL | vt;
|
vat[v] = VT_CONST | VT_LVAL | t;
|
||||||
vac[vc] = ind;
|
vac[v] = ind;
|
||||||
loc = 0;
|
loc = 0;
|
||||||
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 */
|
||||||
|
@ -1028,17 +1134,44 @@ void decl(l)
|
||||||
block();
|
block();
|
||||||
gsym(rsym);
|
gsym(rsym);
|
||||||
o(0xc3c9); /* leave, ret */
|
o(0xc3c9); /* leave, ret */
|
||||||
*a = loc; /* save local variables */
|
*a = (-loc + 3) & -4; /* align local size to word &
|
||||||
|
save local variables */
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
/* variable */
|
if (t & VT_FUNC) {
|
||||||
vat[vc] = l | VT_LVAL | vt;
|
/* external function definition */
|
||||||
if (l == VT_LOCAL) {
|
external_func(v, t);
|
||||||
loc = loc + 4;
|
|
||||||
vac[vc] = -loc;
|
|
||||||
} else {
|
} else {
|
||||||
vac[vc] = glo;
|
/* not lvalue if array */
|
||||||
glo = glo + 4;
|
if (!(t & VT_ARRAY))
|
||||||
|
t |= VT_LVAL;
|
||||||
|
if (t & VT_EXTERN) {
|
||||||
|
/* external variable */
|
||||||
|
n = dlsym(NULL, get_tok_str(v));
|
||||||
|
if (!n)
|
||||||
|
error("unknown external variable");
|
||||||
|
vat[v] = VT_CONST | t;
|
||||||
|
vac[v] = n;
|
||||||
|
} else {
|
||||||
|
u = l;
|
||||||
|
if (t & VT_STATIC)
|
||||||
|
u = VT_CONST;
|
||||||
|
vat[v] = u | t;
|
||||||
|
if (t & VT_ARRAY)
|
||||||
|
t -= VT_PTRINC;
|
||||||
|
align = type_size(t);
|
||||||
|
s *= align;
|
||||||
|
if (u == VT_LOCAL) {
|
||||||
|
/* allocate space down on the stack */
|
||||||
|
loc = (loc - s) & -align;
|
||||||
|
vac[v] = loc;
|
||||||
|
} else {
|
||||||
|
/* allocate space up in the data space */
|
||||||
|
glo = (glo + align - 1) & -align;
|
||||||
|
vac[v] = glo;
|
||||||
|
glo += s;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (tok != ',') {
|
if (tok != ',') {
|
||||||
skip(';');
|
skip(';');
|
||||||
|
@ -1074,8 +1207,9 @@ 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", 57);
|
"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);
|
||||||
idptr = idtable + 57;
|
|
||||||
|
idptr = idtable + 170;
|
||||||
#endif
|
#endif
|
||||||
glo = malloc(DATA_SIZE);
|
glo = malloc(DATA_SIZE);
|
||||||
prog = malloc(TEXT_SIZE);
|
prog = malloc(TEXT_SIZE);
|
||||||
|
|
Loading…
Reference in New Issue