fixed int to unsigned conversions, declarations, pp-list initialization

This commit is contained in:
eck 1990-07-13 10:18:27 +00:00
parent 63fe4e0a18
commit 7f5abdd670
8 changed files with 132 additions and 113 deletions

View file

@ -342,10 +342,11 @@ garbage:
}
#endif NOPP
ptok->tk_symb = (
idef->id_reserved ? idef->id_reserved
: idef->id_def && idef->id_def->df_sc == TYPEDEF ?
TYPE_IDENTIFIER
: IDENTIFIER
idef->id_reserved
? idef->id_reserved
: idef->id_def && idef->id_def->df_sc == TYPEDEF
? TYPE_IDENTIFIER
: IDENTIFIER
);
return IDENTIFIER;
}

View file

@ -56,6 +56,14 @@ conversion(from_type, to_type)
C_cii();
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(to_size);
if (to_cnvtype == T_UNSIGNED) C_ciu();

View file

@ -67,28 +67,43 @@ declaration
short typedef yepp;
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;)
/* Reads a non-empty decl_specifiers and fills the struct
decspecs *ds.
*/
:
[
other_specifier(ds)+
[%if (DOT != IDENTIFIER || AHEAD == IDENTIFIER)
/* the thin ice in R.M. 11.1 */
single_type_specifier(ds) other_specifier(ds)*
|
empty
]
[ %if (AHEAD == IDENTIFIER) /* like: register i; */
normal_specifier(ds)
|
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);}
;
/* 3.5.1 & 3.5.2 (partially) & 3.5.3 (partially) */
other_specifier(register struct decspecs *ds;)
normal_specifier(register struct decspecs *ds;)
:
[ AUTO | STATIC | EXTERN | TYPEDEF | REGISTER ]
{ if (ds->ds_sc_given)
@ -96,18 +111,6 @@ other_specifier(register struct decspecs *ds;)
ds->ds_sc_given = 1;
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.
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 */
type_specifier(struct type **tpp;)
/* Used in struct/union declarations and in casts; only the
@ -146,9 +164,20 @@ type_specifier(struct type **tpp;)
{*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;):
%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
{
@ -283,7 +312,7 @@ declarator(register struct declarator *dc;)
|
formal_list(&fm)
|
empty
/* empty */
]
')'
{ add_decl_unary(dc, FUNCTION, 0, (arith)0, fm, pl);
@ -308,6 +337,7 @@ arrayer(arith *sizep;)
{ struct expr *expr; }
:
'['
{ *sizep = (arith)-1; }
[
constant_expression(&expr)
{
@ -315,10 +345,7 @@ arrayer(arith *sizep;)
*sizep = expr->VL_VALUE;
free_expression(expr);
}
|
empty
{ *sizep = (arith)-1; }
]
]?
']'
;
@ -358,7 +385,7 @@ enum_specifier(register struct type **tpp;)
enumerator_pack(*tpp, &l)
|
{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);
else apply_struct(fund, idf, tpp);
}
empty
/* empty */
]
]
;
@ -533,7 +560,7 @@ abstract_declarator(register struct declarator *dc;)
[
parameter_type_list(&pl)
|
empty
/* empty */
]
')'
{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;)
:
[%if (AHEAD == ')' || first_of_parameter_type_list(AHEAD))
empty
/* empty */
|
'(' abstract_declarator(dc) ')'
]
@ -663,7 +690,7 @@ primary_parameter_declarator(register struct declarator *dc;)
:
[%if (AHEAD == ')' || first_of_parameter_type_list(AHEAD)
&& (AHEAD != IDENTIFIER))
empty
/* empty */
|
identifier(&dc->dc_idf)
|

View file

@ -71,62 +71,42 @@ do_decspecs(ds)
ds->ds_notypegiven = 1;
tp = int_type;
}
switch (ds->ds_size) {
case 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_size) {
register int ds_isshort = (ds->ds_size == SHORT);
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);
}

View file

@ -9,6 +9,7 @@ struct decspecs {
struct decspecs *next;
struct type *ds_type; /* single type */
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; /* storage class, given or implied */
int ds_size; /* LONG, SHORT or 0 */

View file

@ -175,21 +175,14 @@ deleted, is now a debug-flag
register char *new = text;
if (++inc_total > inc_max) {
char **n = (char **)
Malloc((10+inc_max)*sizeof(char *));
for (i = 0; i < inc_max; i++) {
n[i] = inctable[i];
}
free((char *) inctable);
inctable = n;
inc_max += 10;
inctable = (char **)
Realloc(inctable,(inc_max+=10)*sizeof(char *));
}
i = inc_pos++;
while (new) {
for (i = inc_pos++; i<= inc_total ; i++) {
char *tmp = inctable[i];
inctable[i++] = new;
inctable[i] = new;
new = tmp;
}
}

View file

@ -91,18 +91,26 @@ struct tokenname tkidf[] = { /* names of the identifier tokens */
{UNSIGNED, "unsigned"},
{VOLATILE, "volatile"},
{WHILE, "while"},
{VOID, "void"},
{CHAR, "char"},
{INT, "int"},
{FLOAT, "float"},
{DOUBLE, "double"},
{0, ""}
};
#ifdef ____
struct tokenname tkfunny[] = { /* internal keywords */
{CHAR, "char"},
{INT, "int"},
{FLOAT, "float"},
{DOUBLE, "double"},
/* The following may be removed after testing:
{Q_VOID, "void"},
{Q_CHAR, "char"},
{Q_INT, "int"},
{Q_FLOAT, "float"},
{Q_DOUBLE, "double"},
*/
{LNGDBL, "long double"},
{ULONG, "unsigned long"},
{VOID, "void"},
{ARRAY, "array"},
{FUNCTION, "function"},

View file

@ -249,13 +249,14 @@ idf2type(idf, tpp)
struct idf *idf;
struct type **tpp;
{
/* Decoding a typedef-ed identifier: if the size is yet
unknown we have to make copy of the type descriptor to
prevent garbage at the initialisation of arrays with
unknown size.
/* Decoding a typedef-ed identifier or basic type: if the
size is yet unknown we have to make copy of the type
descriptor to prevent garbage at the initialisation of
arrays with unknown size.
*/
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) {
*tpp = new_type();
**tpp = *tp;