1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-25 13:29:41 +00:00

Added license information preproc.h

git-svn-id: svn://svn.cc65.org/cc65/trunk@3135 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2004-06-29 20:26:27 +00:00
parent b2b7006939
commit daf8e0d1e6
9 changed files with 304 additions and 70 deletions

View File

@ -57,6 +57,7 @@
/* Predefined type strings */
type type_schar[] = { T_SCHAR, T_END };
type type_uchar[] = { T_UCHAR, T_END };
type type_int[] = { T_INT, T_END };
type type_uint[] = { T_UINT, T_END };
@ -777,3 +778,23 @@ type* GetElementType (type* T)
type* IntPromotion (type* T)
/* Apply the integer promotions to T and return the result. The returned type
* string may be T if there is no need to change it.
*/
{
/* We must have an int to apply int promotions */
PRECONDITION (IsClassInt (T));
/* An integer can represent all values from either signed or unsigned char,
* so convert chars to int and leave all other types alone.
*/
if (IsTypeChar (T)) {
return type_int;
} else {
return T;
}
}

View File

@ -161,6 +161,7 @@ typedef unsigned short type;
#define SIZEOF_PTR 2
/* Predefined type strings */
extern type type_schar[];
extern type type_uchar[];
extern type type_int[];
extern type type_uint[];
@ -490,6 +491,11 @@ long GetElementCount (const type* T);
type* GetElementType (type* T);
/* Return the element type of the given array type. */
type* IntPromotion (type* T);
/* Apply the integer promotions to T and return the result. The returned type
* string may be T if there is no need to change it.
*/
/* End of datatype.h */

View File

@ -68,17 +68,6 @@ static GenDesc GenOASGN = { TOK_OR_ASSIGN, GEN_NOPUSH, g_or };
/*****************************************************************************/
/* Function forwards */
/*****************************************************************************/
void hie0 (ExprDesc *lval);
/* Parse comma operator. */
/*****************************************************************************/
/* Helper functions */
/*****************************************************************************/
@ -97,7 +86,7 @@ static unsigned GlobalModeFlags (unsigned Flags)
}
}
void ExprWithCheck (void (*Func) (ExprDesc*), ExprDesc *Expr)
/* Call an expression function with checks. */
@ -2277,7 +2266,7 @@ static void parsesub (ExprDesc* Expr)
static void hie8 (ExprDesc* Expr)
void hie8 (ExprDesc* Expr)
/* Process + and - binary operators. */
{
hie9 (Expr);
@ -2293,16 +2282,191 @@ static void hie8 (ExprDesc* Expr)
static void hie7 (ExprDesc* Expr)
/* Parse << and >>. */
/* Parse the << and >> operators. */
{
static const GenDesc hie7_ops [] = {
{ TOK_SHL, GEN_NOPUSH, g_asl },
{ TOK_SHR, GEN_NOPUSH, g_asr },
{ TOK_INVALID, 0, 0 }
};
int UsedGen;
ExprDesc Expr2;
CodeMark Mark1;
CodeMark Mark2;
token_t Tok; /* The operator token */
unsigned ltype, rtype, flags;
int rconst; /* Operand is a constant */
hie_internal (hie7_ops, Expr, hie8, &UsedGen);
/* Evaluate the lhs */
ExprWithCheck (hie8, Expr);
while (CurTok.Tok == TOK_SHL || CurTok.Tok == TOK_SHR) {
/* All operators that call this function expect an int on the lhs */
if (!IsClassInt (Expr->Type)) {
Error ("Integer expression expected");
ED_MakeConstAbsInt (Expr, 1);
}
/* Remember the operator token, then skip it */
Tok = CurTok.Tok;
NextToken ();
/* Get the lhs on stack */
Mark1 = GetCodePos ();
ltype = TypeOf (Expr->Type);
if (ED_IsConstAbs (Expr)) {
/* Constant value */
Mark2 = GetCodePos ();
g_push (ltype | CF_CONST, Expr->IVal);
} else {
/* Value not constant */
LoadExpr (CF_NONE, Expr);
Mark2 = GetCodePos ();
g_push (ltype, 0);
}
/* Get the right hand side */
ExprWithCheck (hie8, &Expr2);
/* Check the type of the rhs */
if (!IsClassInt (Expr2.Type)) {
Error ("Integer expression expected");
ED_MakeConstAbsInt (&Expr2, 1);
}
/* Check for a constant right side expression */
rconst = ED_IsConstAbs (&Expr2);
if (!rconst) {
/* Not constant, load into the primary */
LoadExpr (CF_NONE, &Expr2);
} else {
/* If the right hand side is constant, we can check a lot of
* things:
*/
/* If the shift count is zero, nothing happens */
if (Expr2.IVal == 0) {
/* Result is already in Expr, remove the generated code */
RemoveCode (Mark1);
pop (ltype);
/* Done */
goto Next;
}
/* If the left hand side is a constant, the result is constant */
if (ED_IsConstAbs (Expr)) {
/* Evaluate the result */
Expr->IVal = kcalc (Tok, Expr->IVal, Expr2.IVal);
/* Both operands are constant, remove the generated code */
RemoveCode (Mark1);
pop (ltype);
/* Done */
goto Next;
}
/* If we're shifting to the left, and the shift count is larger
* or equal than the bit count of the integer type, the result
* is zero.
*/
if (Tok == TOK_SHL && Expr2.IVal >= (long) SizeOf (Expr->Type) * 8) {
/* Set the result */
ED_MakeConstAbs (Expr, 0, Expr->Type);
/* Result is zero, remove the generated code */
RemoveCode (Mark1);
pop (ltype);
/* Done */
goto Next;
}
/* If we're shifting an integer or unsigned to the right, the
* lhs has a const address, and the shift count is larger than 8,
* we can load just the high byte as a char with the correct
* signedness, and reduce the shift count by 8. If the remaining
* shift count is zero, we're done.
*/
if (Tok == TOK_SHR &&
IsTypeInt (Expr->Type) &&
ED_IsLVal (Expr) &&
(ED_IsLocConst (Expr) || ED_IsLocStack (Expr)) &&
Expr2.IVal >= 8) {
type* OldType;
/* Increase the address by one and decrease the shift count */
++Expr->IVal;
Expr2.IVal -= 8;
/* Replace the type of the expression temporarily by the
* corresponding char type.
*/
OldType = Expr->Type;
if (IsSignUnsigned (Expr->Type)) {
Expr->Type = type_uchar;
} else {
Expr->Type = type_schar;
}
/* Remove the generated load code */
RemoveCode (Mark1);
pop (ltype);
/* Generate again code for the load */
LoadExpr (CF_NONE, Expr);
/* Reset the type */
Expr->Type = OldType;
/* If the shift count is now zero, we're done */
if (Expr2.IVal == 0) {
/* Be sure to mark the value as in the primary */
goto Loaded;
}
/* Otherwise generate code to push the value */
Mark2 = GetCodePos ();
g_push (ltype, 0);
}
}
/* If the right hand side is a constant, remove the push of the
* primary register.
*/
rtype = TypeOf (Expr2.Type);
flags = 0;
if (rconst) {
flags |= CF_CONST;
rtype |= CF_CONST;
RemoveCode (Mark2);
pop (ltype);
ltype |= CF_REG; /* Value is in register */
}
/* Determine the type of the operation result. */
flags |= g_typeadjust (ltype, rtype);
/* Generate code */
switch (Tok) {
case TOK_SHL: g_asl (flags, Expr2.IVal); break;
case TOK_SHR: g_asr (flags, Expr2.IVal); break;
default: break;
}
Loaded:
/* We have a rvalue in the primary now */
ED_MakeRValExpr (Expr);
Next:
/* Get the type of the result */
Expr->Type = promoteint (Expr->Type, Expr2.Type);
}
}

View File

@ -39,9 +39,6 @@ void Store (ExprDesc* Expr, const type* StoreType);
* is NULL, use lval->Type instead.
*/
void hie0 (ExprDesc* Expr);
/* Parse comma operator. */
int evalexpr (unsigned flags, void (*Func) (ExprDesc*), ExprDesc* Expr);
/* Will evaluate an expression via the given function. If the result is a
* constant, 0 is returned and the value is put in the lval struct. If the
@ -76,9 +73,15 @@ void ConstAbsIntExpr (void (*Func) (ExprDesc*), ExprDesc* Expr);
void hie10 (ExprDesc* lval);
/* Handle ++, --, !, unary - etc. */
void hie8 (ExprDesc* Expr);
/* Process + and - binary operators. */
void hie1 (ExprDesc* lval);
/* Parse first level of expression hierarchy. */
void hie0 (ExprDesc* Expr);
/* Parse comma operator. */
void DefineData (ExprDesc* lval);
/* Output a data definition for the given expression */

View File

@ -192,7 +192,7 @@ ExprDesc* ED_MakeLValExpr (ExprDesc* Expr)
Expr->Flags |= (E_LOC_EXPR | E_RTYPE_LVAL);
Expr->Name = 0;
Expr->IVal = 0; /* No offset */
Expr->FVal = 0.0;
Expr->FVal = 0.0;
return Expr;
}
@ -209,16 +209,6 @@ int ED_IsConst (const ExprDesc* Expr)
int ED_IsConstAbs (const ExprDesc* Expr)
/* Return true if the expression denotes a constant absolute value. This can be
* a numeric constant, cast to any type.
*/
{
return (Expr->Flags & (E_MASK_LOC|E_MASK_RTYPE)) == (E_LOC_ABS|E_RTYPE_RVAL);
}
int ED_IsConstAbsInt (const ExprDesc* Expr)
/* Return true if the expression is a constant (numeric) integer. */
{

View File

@ -307,10 +307,18 @@ int ED_IsConst (const ExprDesc* Expr);
* similar.
*/
int ED_IsConstAbs (const ExprDesc* Expr);
#if defined(HAVE_INLINE)
INLINE int ED_IsConstAbs (const ExprDesc* Expr)
/* Return true if the expression denotes a constant absolute value. This can be
* a numeric constant, cast to any type.
*/
{
return (Expr->Flags & (E_MASK_LOC|E_MASK_RTYPE)) == (E_LOC_ABS|E_RTYPE_RVAL);
}
#else
# define ED_IsConstAbs(E) \
(((E)->Flags & (E_MASK_LOC|E_MASK_RTYPE)) == (E_LOC_ABS|E_RTYPE_RVAL))
#endif
int ED_IsConstAbsInt (const ExprDesc* Expr);
/* Return true if the expression is a constant (numeric) integer. */

View File

@ -1,6 +1,9 @@
/* C pre-processor functions */
/*
* C pre-processor functions.
* Portions of this code are copyright (C) 1989 John R. Dunning.
* See copyleft.jrd for license information.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

View File

@ -1,8 +1,35 @@
/*
* preproc.h
*
* Ullrich von Bassewitz, 07.06.1998
*/
/*****************************************************************************/
/* */
/* preproc.h */
/* */
/* C preprocessor */
/* */
/* */
/* */
/* (C) 1998-2004 Ullrich von Bassewitz */
/* Römerstraße 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be */
/* appreciated but is not required. */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/* */
/*****************************************************************************/
@ -17,7 +44,7 @@
/* Set when the pp calls expr() recursively */
/* Set when the preprocessor calls ConstExpr() recursively */
extern unsigned char Preprocessing;

View File

@ -195,6 +195,12 @@ void TypeConversion (ExprDesc* Expr, type* NewType)
Error ("Illegal type");
}
/* If both types are equal, no conversion is needed */
if (TypeCmp (Expr->Type, NewType) >= TC_EQUAL) {
/* We're already done */
return;
}
/* Check for conversion problems */
if (IsClassInt (NewType)) {
@ -202,10 +208,16 @@ void TypeConversion (ExprDesc* Expr, type* NewType)
if (IsClassPtr (Expr->Type)) {
/* Pointer -> int conversion */
Warning ("Converting pointer to integer without a cast");
} else if (!IsClassInt (Expr->Type)) {
} else if (!IsClassInt (Expr->Type) && !IsClassFloat (Expr->Type)) {
Error ("Incompatible types");
}
} else if (IsClassFloat (NewType)) {
if (!IsClassFloat (Expr->Type) && !IsClassInt (Expr->Type)) {
Error ("Incompatible types");
}
} else if (IsClassPtr (NewType)) {
/* Handle conversions to pointer type */
@ -213,40 +225,40 @@ void TypeConversion (ExprDesc* Expr, type* NewType)
/* Pointer to pointer assignment is valid, if:
* - both point to the same types, or
* - the rhs pointer is a void pointer, or
* - the lhs pointer is a void pointer.
* - the lhs pointer is a void pointer.
*/
if (!IsTypeVoid (Indirect (NewType)) && !IsTypeVoid (Indirect (Expr->Type))) {
/* Compare the types */
switch (TypeCmp (NewType, Expr->Type)) {
if (!IsTypeVoid (Indirect (NewType)) && !IsTypeVoid (Indirect (Expr->Type))) {
/* Compare the types */
switch (TypeCmp (NewType, Expr->Type)) {
case TC_INCOMPATIBLE:
Error ("Incompatible pointer types");
break;
case TC_INCOMPATIBLE:
Error ("Incompatible pointer types");
break;
case TC_QUAL_DIFF:
Error ("Pointer types differ in type qualifiers");
break;
case TC_QUAL_DIFF:
Error ("Pointer types differ in type qualifiers");
break;
default:
/* Ok */
break;
}
}
default:
/* Ok */
break;
}
}
} else if (IsClassInt (Expr->Type)) {
/* Int to pointer assignment is valid only for constant zero */
if (!ED_IsConstAbsInt (Expr) || Expr->IVal != 0) {
Warning ("Converting integer to pointer without a cast");
}
} else if (IsTypeFuncPtr (NewType) && IsTypeFunc(Expr->Type)) {
/* Assignment of function to function pointer is allowed, provided
* that both functions have the same parameter list.
*/
if (TypeCmp (Indirect (NewType), Expr->Type) < TC_EQUAL) {
Error ("Incompatible types");
}
} else if (IsTypeFuncPtr (NewType) && IsTypeFunc(Expr->Type)) {
/* Assignment of function to function pointer is allowed, provided
* that both functions have the same parameter list.
*/
if (TypeCmp (Indirect (NewType), Expr->Type) < TC_EQUAL) {
Error ("Incompatible types");
}
} else {
Error ("Incompatible types");
}
Error ("Incompatible types");
}
} else {