fixed int to unsigned conversions, declarations, pp-list initialization
This commit is contained in:
parent
63fe4e0a18
commit
7f5abdd670
8 changed files with 132 additions and 113 deletions
|
@ -342,10 +342,11 @@ garbage:
|
||||||
}
|
}
|
||||||
#endif NOPP
|
#endif NOPP
|
||||||
ptok->tk_symb = (
|
ptok->tk_symb = (
|
||||||
idef->id_reserved ? idef->id_reserved
|
idef->id_reserved
|
||||||
: idef->id_def && idef->id_def->df_sc == TYPEDEF ?
|
? idef->id_reserved
|
||||||
TYPE_IDENTIFIER
|
: idef->id_def && idef->id_def->df_sc == TYPEDEF
|
||||||
: IDENTIFIER
|
? TYPE_IDENTIFIER
|
||||||
|
: IDENTIFIER
|
||||||
);
|
);
|
||||||
return IDENTIFIER;
|
return IDENTIFIER;
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,14 @@ conversion(from_type, to_type)
|
||||||
C_cii();
|
C_cii();
|
||||||
from_size = word_size;
|
from_size = word_size;
|
||||||
}
|
}
|
||||||
|
/* 3.2.1.2 */
|
||||||
|
if (to_cnvtype == T_UNSIGNED
|
||||||
|
&& (int)from_size < (int)to_size) {
|
||||||
|
C_loc(from_size);
|
||||||
|
C_loc(to_size);
|
||||||
|
C_cii();
|
||||||
|
from_size = to_size;
|
||||||
|
}
|
||||||
C_loc(from_size);
|
C_loc(from_size);
|
||||||
C_loc(to_size);
|
C_loc(to_size);
|
||||||
if (to_cnvtype == T_UNSIGNED) C_ciu();
|
if (to_cnvtype == T_UNSIGNED) C_ciu();
|
||||||
|
|
|
@ -67,28 +67,43 @@ declaration
|
||||||
short typedef yepp;
|
short typedef yepp;
|
||||||
makes all hope of writing a specific grammar for typedefs illusory.
|
makes all hope of writing a specific grammar for typedefs illusory.
|
||||||
*/
|
*/
|
||||||
|
/* We do not accept the whole of the grammar, since when we see
|
||||||
|
something like 'unsigned plain' (where plain is a typedef) is
|
||||||
|
illegal if 'plain' is a typedef. Therefore, we assume that
|
||||||
|
'plain' is the identifier of a declarator. Unfortunately, this
|
||||||
|
causes declarations like 'unsigned plain x;' to be rejected on the
|
||||||
|
grounds of syntax, even though it is syntactically right. This may
|
||||||
|
cause a lot of extra messages.
|
||||||
|
To do this, decl_specifiers is divided into:
|
||||||
|
1: normal specifiers == storage class specifiers + type_qualifiers
|
||||||
|
2: special specifiers == short + long + signed + unsigned
|
||||||
|
3: basic types == void + char + int + float + double
|
||||||
|
4: single type specifiers == struct or union specifiers
|
||||||
|
+ enum specifiers + typedef names
|
||||||
|
|
||||||
|
*/
|
||||||
decl_specifiers /* non-empty */ (register struct decspecs *ds;)
|
decl_specifiers /* non-empty */ (register struct decspecs *ds;)
|
||||||
/* Reads a non-empty decl_specifiers and fills the struct
|
/* Reads a non-empty decl_specifiers and fills the struct
|
||||||
decspecs *ds.
|
decspecs *ds.
|
||||||
*/
|
*/
|
||||||
:
|
:
|
||||||
[
|
[ %if (AHEAD == IDENTIFIER) /* like: register i; */
|
||||||
other_specifier(ds)+
|
normal_specifier(ds)
|
||||||
[%if (DOT != IDENTIFIER || AHEAD == IDENTIFIER)
|
|
||||||
/* the thin ice in R.M. 11.1 */
|
|
||||||
single_type_specifier(ds) other_specifier(ds)*
|
|
||||||
|
|
|
||||||
empty
|
|
||||||
]
|
|
||||||
|
|
|
|
||||||
single_type_specifier(ds) other_specifier(ds)*
|
normal_specifier(ds)*
|
||||||
|
[ special_specifier(ds)
|
||||||
|
| basic_type(ds)
|
||||||
|
| single_type_specifier(ds)
|
||||||
|
]
|
||||||
|
[ normal_specifier(ds)
|
||||||
|
| special_specifier(ds)
|
||||||
|
| basic_type(ds)
|
||||||
|
]*
|
||||||
]
|
]
|
||||||
{do_decspecs(ds);}
|
{do_decspecs(ds);}
|
||||||
;
|
;
|
||||||
|
|
||||||
/* 3.5.1 & 3.5.2 (partially) & 3.5.3 (partially) */
|
normal_specifier(register struct decspecs *ds;)
|
||||||
other_specifier(register struct decspecs *ds;)
|
|
||||||
:
|
:
|
||||||
[ AUTO | STATIC | EXTERN | TYPEDEF | REGISTER ]
|
[ AUTO | STATIC | EXTERN | TYPEDEF | REGISTER ]
|
||||||
{ if (ds->ds_sc_given)
|
{ if (ds->ds_sc_given)
|
||||||
|
@ -96,18 +111,6 @@ other_specifier(register struct decspecs *ds;)
|
||||||
ds->ds_sc_given = 1;
|
ds->ds_sc_given = 1;
|
||||||
ds->ds_sc = DOT;
|
ds->ds_sc = DOT;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
[ SHORT | LONG ]
|
|
||||||
{ if (ds->ds_size)
|
|
||||||
error("repeated size specifier");
|
|
||||||
ds->ds_size = DOT;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
[ SIGNED | UNSIGNED ]
|
|
||||||
{ if (ds->ds_unsigned != 0)
|
|
||||||
error("repeated sign specifier");
|
|
||||||
ds->ds_unsigned = DOT;
|
|
||||||
}
|
|
||||||
|
|
|
|
||||||
/* This qualifier applies to the top type.
|
/* This qualifier applies to the top type.
|
||||||
E.g. volatile float * is a pointer to volatile float.
|
E.g. volatile float * is a pointer to volatile float.
|
||||||
|
@ -129,6 +132,21 @@ other_specifier(register struct decspecs *ds;)
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
special_specifier(register struct decspecs *ds;)
|
||||||
|
:
|
||||||
|
[ SHORT | LONG ]
|
||||||
|
{ if (ds->ds_size)
|
||||||
|
error("repeated size specifier");
|
||||||
|
ds->ds_size = DOT;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
[ SIGNED | UNSIGNED ]
|
||||||
|
{ if (ds->ds_unsigned != 0)
|
||||||
|
error("repeated sign specifier");
|
||||||
|
ds->ds_unsigned = DOT;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
/* 3.5.2 */
|
/* 3.5.2 */
|
||||||
type_specifier(struct type **tpp;)
|
type_specifier(struct type **tpp;)
|
||||||
/* Used in struct/union declarations and in casts; only the
|
/* Used in struct/union declarations and in casts; only the
|
||||||
|
@ -146,9 +164,20 @@ type_specifier(struct type **tpp;)
|
||||||
{*tpp = Ds.ds_type;}
|
{*tpp = Ds.ds_type;}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
basic_type(register struct decspecs *ds;):
|
||||||
|
[ VOID | CHAR | INT | FLOAT | DOUBLE ]
|
||||||
|
{
|
||||||
|
idf2type(dot.tk_idf, &ds->ds_type);
|
||||||
|
ds->ds_typedef = 0;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
single_type_specifier(register struct decspecs *ds;):
|
single_type_specifier(register struct decspecs *ds;):
|
||||||
%default TYPE_IDENTIFIER /* this includes INT, CHAR, etc. */
|
%default TYPE_IDENTIFIER /* this includes INT, CHAR, etc. */
|
||||||
{idf2type(dot.tk_idf, &ds->ds_type);}
|
{
|
||||||
|
idf2type(dot.tk_idf, &ds->ds_type);
|
||||||
|
ds->ds_typedef = 1;
|
||||||
|
}
|
||||||
|
|
|
|
||||||
IDENTIFIER
|
IDENTIFIER
|
||||||
{
|
{
|
||||||
|
@ -283,7 +312,7 @@ declarator(register struct declarator *dc;)
|
||||||
|
|
|
|
||||||
formal_list(&fm)
|
formal_list(&fm)
|
||||||
|
|
|
|
||||||
empty
|
/* empty */
|
||||||
]
|
]
|
||||||
')'
|
')'
|
||||||
{ add_decl_unary(dc, FUNCTION, 0, (arith)0, fm, pl);
|
{ add_decl_unary(dc, FUNCTION, 0, (arith)0, fm, pl);
|
||||||
|
@ -308,6 +337,7 @@ arrayer(arith *sizep;)
|
||||||
{ struct expr *expr; }
|
{ struct expr *expr; }
|
||||||
:
|
:
|
||||||
'['
|
'['
|
||||||
|
{ *sizep = (arith)-1; }
|
||||||
[
|
[
|
||||||
constant_expression(&expr)
|
constant_expression(&expr)
|
||||||
{
|
{
|
||||||
|
@ -315,10 +345,7 @@ arrayer(arith *sizep;)
|
||||||
*sizep = expr->VL_VALUE;
|
*sizep = expr->VL_VALUE;
|
||||||
free_expression(expr);
|
free_expression(expr);
|
||||||
}
|
}
|
||||||
|
|
]?
|
||||||
empty
|
|
||||||
{ *sizep = (arith)-1; }
|
|
||||||
]
|
|
||||||
']'
|
']'
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -358,7 +385,7 @@ enum_specifier(register struct type **tpp;)
|
||||||
enumerator_pack(*tpp, &l)
|
enumerator_pack(*tpp, &l)
|
||||||
|
|
|
|
||||||
{apply_struct(ENUM, idf, tpp);}
|
{apply_struct(ENUM, idf, tpp);}
|
||||||
empty
|
/* empty */
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
;
|
;
|
||||||
|
@ -433,7 +460,7 @@ struct_or_union_specifier(register struct type **tpp;)
|
||||||
if (DOT == ';') declare_struct(fund, idf, tpp);
|
if (DOT == ';') declare_struct(fund, idf, tpp);
|
||||||
else apply_struct(fund, idf, tpp);
|
else apply_struct(fund, idf, tpp);
|
||||||
}
|
}
|
||||||
empty
|
/* empty */
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
;
|
;
|
||||||
|
@ -533,7 +560,7 @@ abstract_declarator(register struct declarator *dc;)
|
||||||
[
|
[
|
||||||
parameter_type_list(&pl)
|
parameter_type_list(&pl)
|
||||||
|
|
|
|
||||||
empty
|
/* empty */
|
||||||
]
|
]
|
||||||
')'
|
')'
|
||||||
{add_decl_unary(dc, FUNCTION, 0, (arith)0, NO_PARAMS, pl);}
|
{add_decl_unary(dc, FUNCTION, 0, (arith)0, NO_PARAMS, pl);}
|
||||||
|
@ -551,7 +578,7 @@ abstract_declarator(register struct declarator *dc;)
|
||||||
primary_abstract_declarator(struct declarator *dc;)
|
primary_abstract_declarator(struct declarator *dc;)
|
||||||
:
|
:
|
||||||
[%if (AHEAD == ')' || first_of_parameter_type_list(AHEAD))
|
[%if (AHEAD == ')' || first_of_parameter_type_list(AHEAD))
|
||||||
empty
|
/* empty */
|
||||||
|
|
|
|
||||||
'(' abstract_declarator(dc) ')'
|
'(' abstract_declarator(dc) ')'
|
||||||
]
|
]
|
||||||
|
@ -663,7 +690,7 @@ primary_parameter_declarator(register struct declarator *dc;)
|
||||||
:
|
:
|
||||||
[%if (AHEAD == ')' || first_of_parameter_type_list(AHEAD)
|
[%if (AHEAD == ')' || first_of_parameter_type_list(AHEAD)
|
||||||
&& (AHEAD != IDENTIFIER))
|
&& (AHEAD != IDENTIFIER))
|
||||||
empty
|
/* empty */
|
||||||
|
|
|
|
||||||
identifier(&dc->dc_idf)
|
identifier(&dc->dc_idf)
|
||||||
|
|
|
|
||||||
|
|
|
@ -71,62 +71,42 @@ do_decspecs(ds)
|
||||||
ds->ds_notypegiven = 1;
|
ds->ds_notypegiven = 1;
|
||||||
tp = int_type;
|
tp = int_type;
|
||||||
}
|
}
|
||||||
switch (ds->ds_size) {
|
if (ds->ds_size) {
|
||||||
case SHORT:
|
register int ds_isshort = (ds->ds_size == SHORT);
|
||||||
if (tp == int_type)
|
|
||||||
tp = short_type;
|
|
||||||
else
|
|
||||||
error("short with illegal type");
|
|
||||||
break;
|
|
||||||
case LONG:
|
|
||||||
if (tp == int_type)
|
|
||||||
tp = long_type;
|
|
||||||
else
|
|
||||||
if (tp == double_type)
|
|
||||||
tp = lngdbl_type;
|
|
||||||
else
|
|
||||||
error("long with illegal type");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (ds->ds_unsigned == UNSIGNED) {
|
|
||||||
switch (tp->tp_fund) {
|
|
||||||
case CHAR:
|
|
||||||
tp = uchar_type;
|
|
||||||
break;
|
|
||||||
case SHORT:
|
|
||||||
tp = ushort_type;
|
|
||||||
break;
|
|
||||||
case INT:
|
|
||||||
tp = uint_type;
|
|
||||||
break;
|
|
||||||
case LONG:
|
|
||||||
tp = ulong_type;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
error("unsigned with illegal type");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ds->ds_unsigned == SIGNED) {
|
|
||||||
switch (tp->tp_fund) {
|
|
||||||
case CHAR:
|
|
||||||
tp = schar_type;
|
|
||||||
break;
|
|
||||||
case SHORT:
|
|
||||||
tp = short_type;
|
|
||||||
break;
|
|
||||||
case INT:
|
|
||||||
tp = int_type;
|
|
||||||
break;
|
|
||||||
case LONG:
|
|
||||||
tp = long_type;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
error("signed with illegal type");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (ds->ds_typedef) goto SIZE_ERROR; /* yes */
|
||||||
|
if (tp == int_type) {
|
||||||
|
if (ds_isshort) tp = short_type;
|
||||||
|
else tp = long_type;
|
||||||
|
} else if (tp == double_type && !ds_isshort ) {
|
||||||
|
tp = lngdbl_type;
|
||||||
|
} else {
|
||||||
|
SIZE_ERROR:
|
||||||
|
error("%s with illegal type",symbol2str(ds->ds_size));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ds->ds_unsigned) {
|
||||||
|
register int ds_isunsigned = (ds->ds_unsigned == UNSIGNED);
|
||||||
|
|
||||||
|
if (ds->ds_typedef) goto SIGN_ERROR; /* yes */
|
||||||
|
/*
|
||||||
|
* All integral types are signed by default (char too),
|
||||||
|
* so the case that ds->ds_unsigned == SIGNED can be ignored.
|
||||||
|
*/
|
||||||
|
if (tp == schar_type) {
|
||||||
|
if (ds_isunsigned) tp = uchar_type;
|
||||||
|
} else if (tp == short_type) {
|
||||||
|
if (ds_isunsigned) tp = ushort_type;
|
||||||
|
} else if (tp == int_type) {
|
||||||
|
if (ds_isunsigned) tp = uint_type;
|
||||||
|
} else if (tp == long_type) {
|
||||||
|
if (ds_isunsigned) tp = ulong_type;
|
||||||
|
} else {
|
||||||
|
SIGN_ERROR:
|
||||||
|
error("%s with illegal type"
|
||||||
|
, symbol2str(ds->ds_unsigned));
|
||||||
|
}
|
||||||
|
}
|
||||||
ds->ds_type = qualifier_type(tp, ds->ds_typequal);
|
ds->ds_type = qualifier_type(tp, ds->ds_typequal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ struct decspecs {
|
||||||
struct decspecs *next;
|
struct decspecs *next;
|
||||||
struct type *ds_type; /* single type */
|
struct type *ds_type; /* single type */
|
||||||
int ds_notypegiven; /* set if type not given explicitly */
|
int ds_notypegiven; /* set if type not given explicitly */
|
||||||
|
int ds_typedef; /* 1 if type was a user typedef */
|
||||||
int ds_sc_given; /* 1 if the st. class is explicitly given */
|
int ds_sc_given; /* 1 if the st. class is explicitly given */
|
||||||
int ds_sc; /* storage class, given or implied */
|
int ds_sc; /* storage class, given or implied */
|
||||||
int ds_size; /* LONG, SHORT or 0 */
|
int ds_size; /* LONG, SHORT or 0 */
|
||||||
|
|
|
@ -175,21 +175,14 @@ deleted, is now a debug-flag
|
||||||
register char *new = text;
|
register char *new = text;
|
||||||
|
|
||||||
if (++inc_total > inc_max) {
|
if (++inc_total > inc_max) {
|
||||||
char **n = (char **)
|
inctable = (char **)
|
||||||
Malloc((10+inc_max)*sizeof(char *));
|
Realloc(inctable,(inc_max+=10)*sizeof(char *));
|
||||||
for (i = 0; i < inc_max; i++) {
|
|
||||||
n[i] = inctable[i];
|
|
||||||
}
|
|
||||||
free((char *) inctable);
|
|
||||||
inctable = n;
|
|
||||||
inc_max += 10;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i = inc_pos++;
|
for (i = inc_pos++; i<= inc_total ; i++) {
|
||||||
while (new) {
|
|
||||||
char *tmp = inctable[i];
|
char *tmp = inctable[i];
|
||||||
|
|
||||||
inctable[i++] = new;
|
inctable[i] = new;
|
||||||
new = tmp;
|
new = tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,18 +91,26 @@ struct tokenname tkidf[] = { /* names of the identifier tokens */
|
||||||
{UNSIGNED, "unsigned"},
|
{UNSIGNED, "unsigned"},
|
||||||
{VOLATILE, "volatile"},
|
{VOLATILE, "volatile"},
|
||||||
{WHILE, "while"},
|
{WHILE, "while"},
|
||||||
|
|
||||||
|
{VOID, "void"},
|
||||||
|
{CHAR, "char"},
|
||||||
|
{INT, "int"},
|
||||||
|
{FLOAT, "float"},
|
||||||
|
{DOUBLE, "double"},
|
||||||
{0, ""}
|
{0, ""}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef ____
|
#ifdef ____
|
||||||
struct tokenname tkfunny[] = { /* internal keywords */
|
struct tokenname tkfunny[] = { /* internal keywords */
|
||||||
{CHAR, "char"},
|
/* The following may be removed after testing:
|
||||||
{INT, "int"},
|
{Q_VOID, "void"},
|
||||||
{FLOAT, "float"},
|
{Q_CHAR, "char"},
|
||||||
{DOUBLE, "double"},
|
{Q_INT, "int"},
|
||||||
|
{Q_FLOAT, "float"},
|
||||||
|
{Q_DOUBLE, "double"},
|
||||||
|
*/
|
||||||
{LNGDBL, "long double"},
|
{LNGDBL, "long double"},
|
||||||
{ULONG, "unsigned long"},
|
{ULONG, "unsigned long"},
|
||||||
{VOID, "void"},
|
|
||||||
|
|
||||||
{ARRAY, "array"},
|
{ARRAY, "array"},
|
||||||
{FUNCTION, "function"},
|
{FUNCTION, "function"},
|
||||||
|
|
|
@ -249,13 +249,14 @@ idf2type(idf, tpp)
|
||||||
struct idf *idf;
|
struct idf *idf;
|
||||||
struct type **tpp;
|
struct type **tpp;
|
||||||
{
|
{
|
||||||
/* Decoding a typedef-ed identifier: if the size is yet
|
/* Decoding a typedef-ed identifier or basic type: if the
|
||||||
unknown we have to make copy of the type descriptor to
|
size is yet unknown we have to make copy of the type
|
||||||
prevent garbage at the initialisation of arrays with
|
descriptor to prevent garbage at the initialisation of
|
||||||
unknown size.
|
arrays with unknown size.
|
||||||
*/
|
*/
|
||||||
register struct type *tp = idf->id_def->df_type;
|
register struct type *tp = idf->id_def->df_type;
|
||||||
|
|
||||||
|
if (*tpp) error("multiple types in declaration");
|
||||||
if ( tp->tp_size < (arith)0 && tp->tp_fund == ARRAY) {
|
if ( tp->tp_size < (arith)0 && tp->tp_fund == ARRAY) {
|
||||||
*tpp = new_type();
|
*tpp = new_type();
|
||||||
**tpp = *tp;
|
**tpp = *tp;
|
||||||
|
|
Loading…
Reference in a new issue