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 #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;
} }

View file

@ -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();

View file

@ -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)
| |

View file

@ -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);
} }

View file

@ -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 */

View file

@ -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;
} }
} }

View file

@ -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"},

View file

@ -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;