1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-09 06:29:38 +00:00

Changed the expression parser to return the lvalue flag as part of the

ExprDesc structure, not as separate value.
WARNING: The current code does compile but does not work correctly, because
the lvalue flag is part of ExprDesc.Flags and not masked out in several tests
throughout the code.


git-svn-id: svn://svn.cc65.org/cc65/trunk@3046 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2004-05-25 20:59:38 +00:00
parent c885a814c7
commit 878e4f1352
15 changed files with 984 additions and 918 deletions

View File

@ -6,7 +6,7 @@
/* */
/* */
/* */
/* (C) 2002-2003 Ullrich von Bassewitz */
/* (C) 2002-2004 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
@ -34,13 +34,14 @@
/* cc65 */
#include "assignment.h"
#include "codegen.h"
#include "datatype.h"
#include "error.h"
#include "expr.h"
#include "scanner.h"
#include "typecmp.h"
#include "typeconv.h"
#include "assignment.h"
@ -50,19 +51,26 @@
int Assignment (ExprDesc* lval)
void Assignment (ExprDesc* lval)
/* Parse an assignment */
{
int k;
ExprDesc lval2;
type* ltype = lval->Type;
/* We must have an lvalue for an assignment */
if (ED_IsRVal (lval)) {
Error ("Invalid lvalue in assignment");
}
/* Check for assignment to const */
if (IsQualConst (ltype)) {
Error ("Assignment to const");
}
/* Skip the '=' token */
NextToken ();
/* cc65 does not have full support for handling structs by value. Since
* assigning structs is one of the more useful operations from this
* family, allow it here.
@ -87,12 +95,12 @@ int Assignment (ExprDesc* lval)
if (UseReg) {
PushAddr (lval);
} else {
ExprLoad (0, 0, lval);
ExprLoad (CF_NONE, lval);
g_push (CF_PTR | CF_UNSIGNED, 0);
}
/* Get the expression on the right of the '=' into the primary */
k = hie1 (&lval2);
hie1 (&lval2);
/* Check for equality of the structs */
if (TypeCmp (ltype, lval2.Type) < TC_STRICT_COMPATIBLE) {
@ -100,14 +108,14 @@ int Assignment (ExprDesc* lval)
}
/* Check if the right hand side is an lvalue */
if (k) {
if (ED_IsLVal (&lval2)) {
/* We have an lvalue. Do we copy using the primary? */
if (UseReg) {
/* Just use the replacement type */
lval2.Type = stype;
/* Load the value into the primary */
ExprLoad (CF_FORCECHAR, k, &lval2);
ExprLoad (CF_FORCECHAR, &lval2);
/* Store it into the new location */
Store (lval, stype);
@ -115,7 +123,8 @@ int Assignment (ExprDesc* lval)
} else {
/* We will use memcpy. Push the address of the rhs */
ExprLoad (0, 0, &lval2);
ED_MakeRVal (&lval2);
ExprLoad (CF_NONE, &lval2);
/* Push the address (or whatever is in ax in case of errors) */
g_push (CF_PTR | CF_UNSIGNED, 0);
@ -148,17 +157,17 @@ int Assignment (ExprDesc* lval)
} else {
/* Get the address on stack if needed */
PushAddr (lval);
/* Get the address on stack if needed */
PushAddr (lval);
/* Read the expression on the right side of the '=' */
k = hie1 (&lval2);
/* Read the expression on the right side of the '=' */
hie1 (&lval2);
/* Do type conversion if necessary */
k = TypeConversion (&lval2, k, ltype);
/* Do type conversion if necessary */
TypeConversion (&lval2, ltype);
/* If necessary, load the value into the primary register */
ExprLoad (CF_NONE, k, &lval2);
/* If necessary, load the value into the primary register */
ExprLoad (CF_NONE, &lval2);
/* Generate a store instruction */
Store (lval, 0);
@ -166,8 +175,7 @@ int Assignment (ExprDesc* lval)
}
/* Value is still in primary and not an lvalue */
lval->Flags = E_MEXPR;
return 0;
lval->Flags = E_MEXPR | E_RVAL;
}

View File

@ -6,7 +6,7 @@
/* */
/* */
/* */
/* (C) 2002-2003 Ullrich von Bassewitz */
/* (C) 2002-2004 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
@ -49,7 +49,7 @@
int Assignment (ExprDesc* lval);
void Assignment (ExprDesc* lval);
/* Parse an assignment */

View File

@ -460,6 +460,20 @@ static unsigned OptPtrStore1 (CodeSeg* S)
* subop
* ldy yyy
* sta (ptr1),y
*
* In case a/x is loaded from the register bank before the pushax, we can even
* use the register bank instead of ptr1.
*/
/*
* jsr pushax
* ldy xxx
* jsr ldauidx
* ldx #$00
* lda (zp),y
* subop
* ldy yyy
* sta (zp),y
* jsr staspidx
*/
{
unsigned Changes = 0;
@ -490,30 +504,64 @@ static unsigned OptPtrStore1 (CodeSeg* S)
CE_IsCallTo (L[4+K], "staspidx") &&
!CE_HasLabel (L[4+K])) {
const char* RegBank = 0;
const char* ZPLoc = "ptr1";
CodeEntry* X;
/* Create and insert the stores */
X = NewCodeEntry (OP65_STA, AM65_ZP, "ptr1", 0, L[0]->LI);
CS_InsertEntry (S, X, I+1);
X = NewCodeEntry (OP65_STX, AM65_ZP, "ptr1+1", 0, L[0]->LI);
CS_InsertEntry (S, X, I+2);
/* Get the preceeding two instructions and check them. We check
* for:
* lda regbank+n
* ldx regbank+n+1
*/
if (I > 1) {
CodeEntry* P[2];
P[0] = CS_GetEntry (S, I-2);
P[1] = CS_GetEntry (S, I-1);
if (P[0]->OPC == OP65_LDA &&
P[0]->AM == AM65_ZP &&
P[1]->OPC == OP65_LDX &&
P[1]->AM == AM65_ZP &&
!CE_HasLabel (P[1]) &&
strncmp (P[0]->Arg, "regbank+", 8) == 0) {
/* Insert the load from ptr1 */
unsigned Len = strlen (P[0]->Arg);
if (strncmp (P[0]->Arg, P[1]->Arg, Len) == 0 &&
P[1]->Arg[Len+0] == '+' &&
P[1]->Arg[Len+1] == '1' &&
P[1]->Arg[Len+2] == '\0') {
/* Ok, found. Use the name of the register bank */
RegBank = ZPLoc = P[0]->Arg;
}
}
}
/* Insert the load via the zp pointer */
X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[3]->LI);
CS_InsertEntry (S, X, I+5);
X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "ptr1", 0, L[2]->LI);
CS_InsertEntry (S, X, I+6);
CS_InsertEntry (S, X, I+3);
X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, ZPLoc, 0, L[2]->LI);
CS_InsertEntry (S, X, I+4);
/* Insert the store through ptr1 */
X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, "ptr1", 0, L[3]->LI);
CS_InsertEntry (S, X, I+8+K);
/* Insert the store through the zp pointer */
X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, ZPLoc, 0, L[3]->LI);
CS_InsertEntry (S, X, I+6+K);
/* Delete the old code */
CS_DelEntry (S, I+9+K); /* jsr spaspidx */
CS_DelEntry (S, I+4); /* jsr ldauidx */
CS_DelEntry (S, I+7+K); /* jsr spaspidx */
CS_DelEntry (S, I+2); /* jsr ldauidx */
CS_DelEntry (S, I); /* jsr pushax */
/* Create and insert the stores into the zp pointer if needed */
if (RegBank == 0) {
X = NewCodeEntry (OP65_STA, AM65_ZP, "ptr1", 0, L[0]->LI);
CS_InsertEntry (S, X, I);
X = NewCodeEntry (OP65_STX, AM65_ZP, "ptr1+1", 0, L[0]->LI);
CS_InsertEntry (S, X, I+1);
}
/* Remember, we had changes */
++Changes;

View File

@ -1224,7 +1224,7 @@ static unsigned ParseScalarInit (type* T)
/* Get the expression and convert it to the target type */
ConstExpr (&ED);
TypeConversion (&ED, 0, T);
TypeConversion (&ED, T);
/* Output the data */
DefineData (&ED);
@ -1251,7 +1251,7 @@ static unsigned ParsePointerInit (type* T)
/* Make the const value the correct size */
ED.ConstVal &= 0xFFFF;
}
TypeConversion (&ED, 0, T);
TypeConversion (&ED, T);
/* Output the data */
DefineData (&ED);

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ void PushAddr (ExprDesc* lval);
* must be saved if it's not constant, before evaluating the rhs.
*/
void ConstSubExpr (int (*F) (ExprDesc*), ExprDesc* Expr);
void ConstSubExpr (void (*F) (ExprDesc*), ExprDesc* Expr);
/* Will evaluate an expression via the given function. If the result is not
* a constant, a diagnostic will be printed, and the value is replaced by
* a constant one to make sure there are no internal errors that result
@ -42,7 +42,7 @@ void CheckBoolExpr (ExprDesc* lval);
* if not.
*/
void ExprLoad (unsigned flags, int k, ExprDesc *lval);
void ExprLoad (unsigned flags, ExprDesc *lval);
/* Put the result of an expression into the primary register */
void Store (ExprDesc* lval, const type* StoreType);
@ -51,17 +51,17 @@ void Store (ExprDesc* lval, const type* StoreType);
* is NULL, use lval->Type instead.
*/
int hie0 (ExprDesc *lval);
void hie0 (ExprDesc *lval);
/* Parse comma operator. */
int evalexpr (unsigned flags, int (*f) (ExprDesc*), ExprDesc* lval);
int evalexpr (unsigned flags, void (*f) (ExprDesc*), ExprDesc* lval);
/* 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
* result is not constant, ExprLoad is called to bring the value into the
* primary register and 1 is returned.
*/
int expr (int (*func) (ExprDesc*), ExprDesc *lval);
void expr (void (*Func) (ExprDesc*), ExprDesc *Expr);
/* Expression parser; func is either hie0 or hie1. */
void expression1 (ExprDesc* lval);
@ -69,8 +69,8 @@ void expression1 (ExprDesc* lval);
* the primary register
*/
void expression (ExprDesc* lval);
/* Evaluate an expression and put it into the primary register */
void expression0 (ExprDesc* lval);
/* Evaluate an expression via hie0 and put it into the primary register */
void ConstExpr (ExprDesc* lval);
/* Get a constant value */
@ -81,10 +81,10 @@ void ConstIntExpr (ExprDesc* Val);
void intexpr (ExprDesc* lval);
/* Get an integer expression */
int hie10 (ExprDesc* lval);
void hie10 (ExprDesc* lval);
/* Handle ++, --, !, unary - etc. */
int hie1 (ExprDesc* lval);
void hie1 (ExprDesc* lval);
/* Parse first level of expression hierarchy. */
void DefineData (ExprDesc* lval);

View File

@ -6,9 +6,9 @@
/* */
/* */
/* */
/* (C) 2002 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* (C) 2002-2004 Ullrich von Bassewitz */
/* Römerstraße 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
@ -46,12 +46,13 @@
void MakeConstIntExpr (ExprDesc* Expr, long Value)
ExprDesc* ED_MakeConstInt (ExprDesc* Expr, long Value)
/* Make Expr a constant integer expression with the given value */
{
Expr->Flags = E_MCONST;
Expr->Flags = E_MCONST | E_RVAL;
Expr->Type = type_int;
Expr->ConstVal = Value;
return Expr;
}

View File

@ -6,9 +6,9 @@
/* */
/* */
/* */
/* (C) 2002 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* (C) 2002-2004 Ullrich von Bassewitz */
/* Römerstraße 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
@ -70,6 +70,9 @@
#define E_TLLAB 0x0004U /* Local label */
#define E_TREGISTER 0x0005U /* Register variable */
#define E_RVAL 0x0000U /* Expression node is a value */
#define E_LVAL 0x1000U /* Expression node is a reference */
/* Defines for the test field of the expression descriptor */
#define E_CC 0x0001U /* expr has set cond codes apropos result value */
#define E_FORCETEST 0x0002U /* if expr has NOT set CC, force a test */
@ -103,7 +106,61 @@ INLINE ExprDesc* InitExprDesc (ExprDesc* Expr)
# define InitExprDesc(E) memset ((E), 0, sizeof (*(E)))
#endif
void MakeConstIntExpr (ExprDesc* Expr, long Value);
#if defined(HAVE_INLINE)
INLINE int ED_IsLVal (const ExprDesc* Expr)
/* Return true if the expression is a reference */
{
return (Expr->Flags & E_LVAL) != 0;
}
#else
# define ED_IsLVal(Expr) (((Expr)->Flags & E_LVAL) != 0)
#endif
#if defined(HAVE_INLINE)
INLINE int ED_IsRVal (const ExprDesc* Expr)
/* Return true if the expression is a rvalue */
{
return (Expr->Flags & E_LVAL) == 0;
}
#else
# define ED_IsRVal(Expr) (((Expr)->Flags & E_LVAL) == 0)
#endif
#if defined(HAVE_INLINE)
INLINE int ED_SetValType (ExprDesc* Expr, int Ref)
/* Set the reference flag for an expression and return it (the flag) */
{
Expr->Flags = Ref? (Expr->Flags | E_LVAL) : (Expr->Flags & ~E_LVAL);
return Ref;
}
#else
/* Beware: Just one occurance of R below, since it may have side effects! */
# define ED_SetValType(E, R) \
(((E)->Flags = (R)? ((E)->Flags | E_LVAL) : ((E)->Flags & ~E_LVAL)), \
ED_IsLVal (E))
#endif
#if defined(HAVE_INLINE)
INLINE int ED_MakeLVal (ExprDesc* Expr)
/* Make the expression a lvalue and return true */
{
return ED_SetValType (Expr, 1);
}
#else
# define ED_MakeLVal(Expr) ED_SetValType (Expr, 1)
#endif
#if defined(HAVE_INLINE)
INLINE int ED_MakeRVal (ExprDesc* Expr)
/* Make the expression a rvalue and return false */
{
return ED_SetValType (Expr, 0);
}
#else
# define ED_MakeRVal(Expr) ED_SetValType (Expr, 0)
#endif
ExprDesc* ED_MakeConstInt (ExprDesc* Expr, long Value);
/* Make Expr a constant integer expression with the given value */
void PrintExprDesc (FILE* F, ExprDesc* Expr);

View File

@ -111,13 +111,13 @@ static unsigned ParseRegisterDecl (Declaration* Decl, unsigned* SC, int Reg)
} else {
/* Parse the expression */
int k = hie1 (InitExprDesc (&lval));
hie1 (InitExprDesc (&lval));
/* Convert it to the target type */
k = TypeConversion (&lval, k, Decl->Type);
TypeConversion (&lval, Decl->Type);
/* Load the value into the primary */
ExprLoad (CF_NONE, k, &lval);
ExprLoad (CF_NONE, &lval);
/* Store the value into the variable */
g_putstatic (CF_REGVAR | TypeOf (Decl->Type), Reg, 0);
@ -200,8 +200,6 @@ static unsigned ParseAutoDecl (Declaration* Decl, unsigned* SC)
} else {
int k;
/* Allocate previously reserved local space */
F_AllocLocalSpace (CurrentFunc);
@ -209,17 +207,17 @@ static unsigned ParseAutoDecl (Declaration* Decl, unsigned* SC)
Flags = (Size == SIZEOF_CHAR)? CF_FORCECHAR : CF_NONE;
/* Parse the expression */
k = hie1 (InitExprDesc (&lval));
hie1 (InitExprDesc (&lval));
/* Convert it to the target type */
k = TypeConversion (&lval, k, Decl->Type);
TypeConversion (&lval, Decl->Type);
/* If the value is not const, load it into the primary.
* Otherwise pass the information to the code generator.
*/
if (k != 0 || lval.Flags != E_MCONST) {
ExprLoad (CF_NONE, k, &lval);
k = 0;
if (ED_IsLVal (&lval) || lval.Flags != E_MCONST) {
ExprLoad (CF_NONE, &lval);
ED_MakeRVal (&lval);
} else {
Flags |= CF_CONST;
}
@ -285,13 +283,13 @@ static unsigned ParseAutoDecl (Declaration* Decl, unsigned* SC)
} else {
/* Parse the expression */
int k = hie1 (InitExprDesc (&lval));
hie1 (InitExprDesc (&lval));
/* Convert it to the target type */
k = TypeConversion (&lval, k, Decl->Type);
TypeConversion (&lval, Decl->Type);
/* Load the value into the primary */
ExprLoad (CF_NONE, k, &lval);
ExprLoad (CF_NONE, &lval);
/* Store the value into the variable */
g_putstatic (TypeOf (Decl->Type), SymData, 0);

View File

@ -6,7 +6,7 @@
/* */
/* */
/* */
/* (C) 1998-2003 Ullrich von Bassewitz */
/* (C) 1998-2004 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
@ -46,12 +46,13 @@
/*****************************************************************************/
/* Token definitions */
/* Token definitions */
/*****************************************************************************/
typedef enum token_t {
TOK_INVALID,
TOK_CEOF,
TOK_AUTO,

View File

@ -116,17 +116,17 @@ static unsigned ParseArg (type* Type, ExprDesc* Arg)
unsigned Flags = CF_FORCECHAR;
/* Read the expression we're going to pass to the function */
int k = hie1 (InitExprDesc (Arg));
hie1 (InitExprDesc (Arg));
/* Convert this expression to the expected type */
k = TypeConversion (Arg, k, Type);
TypeConversion (Arg, Type);
/* If the value is not a constant, load it into the primary */
if (k != 0 || Arg->Flags != E_MCONST) {
if (ED_IsLVal (Arg) || Arg->Flags != E_MCONST) {
/* Load into the primary */
ExprLoad (CF_NONE, k, Arg);
k = 0;
ExprLoad (CF_NONE, Arg);
ED_MakeRVal (Arg);
} else {
@ -191,7 +191,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)),
if (Arg.ConstVal == 0) {
Warning ("Call to memset has no effect");
}
ExprLoad (CF_FORCECHAR, 0, &Arg);
ExprLoad (CF_FORCECHAR, &Arg);
}
/* Emit the actual function call */
@ -208,7 +208,6 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)),
/* Handle the strlen function */
{
static type ParamType[] = { T_PTR, T_SCHAR, T_END };
int k;
ExprDesc Param;
unsigned CodeFlags;
unsigned long ParamName;
@ -217,7 +216,8 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)),
ParamType[1] = GetDefaultChar () | T_QUAL_CONST;
/* Fetch the parameter and convert it to the type needed */
k = TypeConversion (&Param, hie1 (InitExprDesc (&Param)), ParamType);
hie1 (InitExprDesc (&Param));
TypeConversion (&Param, ParamType);
/* Check if the parameter is a constant array of some type, or a numeric
* address cast to a pointer.
@ -259,9 +259,9 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)),
if (!WriteableStrings) {
/* String literals are const */
ExprDesc Length;
MakeConstIntExpr (&Length, strlen (GetLiteral (Param.ConstVal)));
ED_MakeConstInt (&Length, strlen (GetLiteral (Param.ConstVal)));
ResetLiteralPoolOffs (Param.ConstVal);
ExprLoad (CF_NONE, 0, &Length);
ExprLoad (CF_NONE, &Length);
goto ExitPoint;
} else {
CodeFlags |= CF_CONST | CF_STATIC;
@ -276,7 +276,7 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)),
} else {
/* Not an array with a constant address. Load parameter into primary */
ExprLoad (CF_NONE, k, &Param);
ExprLoad (CF_NONE, &Param);
}

View File

@ -273,7 +273,6 @@ static void ReturnStatement (void)
/* Handle the 'return' statement */
{
ExprDesc Expr;
int k;
NextToken ();
if (CurTok.Tok != TOK_SEMI) {
@ -284,16 +283,16 @@ static void ReturnStatement (void)
}
/* Evaluate the return expression */
k = hie0 (InitExprDesc (&Expr));
hie0 (InitExprDesc (&Expr));
/* Ignore the return expression if the function returns void */
if (!F_HasVoidReturn (CurrentFunc)) {
/* Convert the return value to the type of the function result */
k = TypeConversion (&Expr, k, F_GetReturnType (CurrentFunc));
TypeConversion (&Expr, F_GetReturnType (CurrentFunc));
/* Load the value into the primary */
ExprLoad (CF_NONE, k, &Expr);
ExprLoad (CF_NONE, &Expr);
}
} else if (!F_HasVoidReturn (CurrentFunc) && !F_HasOldStyleIntRet (CurrentFunc)) {
@ -400,7 +399,7 @@ static void ForStatement (void)
/* Parse the initializer expression */
if (CurTok.Tok != TOK_SEMI) {
expression (&lval1);
expression0 (&lval1);
}
ConsumeSemi ();
@ -425,7 +424,7 @@ static void ForStatement (void)
/* Parse the increment expression */
HaveIncExpr = (CurTok.Tok != TOK_RPAREN);
if (HaveIncExpr) {
expression (&lval3);
expression0 (&lval3);
}
/* Jump to the test */
@ -591,7 +590,7 @@ int Statement (int* PendingToken)
default:
/* Actual statement */
expression (&lval);
expression0 (&lval);
CheckSemi (PendingToken);
}
}

View File

@ -57,13 +57,13 @@ unsigned Test (unsigned Label, int Invert)
unsigned Result;
/* Evaluate the expression */
int k = expr (hie0, InitExprDesc (&lval));
expr (hie0, InitExprDesc (&lval));
/* Check for a boolean expression */
CheckBoolExpr (&lval);
/* Check for a constant expression */
if (k == 0 && lval.Flags == E_MCONST) {
if (ED_IsRVal (&lval) && lval.Flags == E_MCONST) {
/* Result is constant, so we know the outcome */
Result = (lval.ConstVal != 0);
@ -77,7 +77,7 @@ unsigned Test (unsigned Label, int Invert)
}
} else {
/* Result is unknown */
Result = TESTEXPR_UNKNOWN;
@ -87,7 +87,7 @@ unsigned Test (unsigned Label, int Invert)
}
/* Load the value into the primary register */
ExprLoad (CF_FORCECHAR, k, &lval);
ExprLoad (CF_FORCECHAR, &lval);
/* Generate the jump */
if (Invert) {

View File

@ -6,7 +6,7 @@
/* */
/* */
/* */
/* (C) 2002-2003 Ullrich von Bassewitz */
/* (C) 2002-2004 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
@ -68,7 +68,7 @@ static void DoPtrConversions (ExprDesc* Expr)
static int DoConversion (ExprDesc* Expr, int k, type* NewType)
static void DoConversion (ExprDesc* Expr, type* NewType)
/* Emit code to convert the given expression to a new type. */
{
type* OldType;
@ -83,7 +83,7 @@ static int DoConversion (ExprDesc* Expr, int k, type* NewType)
* conversion void -> void.
*/
if (IsTypeVoid (NewType)) {
k = 0; /* Never an lvalue */
ED_MakeRVal (Expr); /* Never an lvalue */
goto ExitPoint;
}
@ -100,7 +100,7 @@ static int DoConversion (ExprDesc* Expr, int k, type* NewType)
NewSize = CheckedSizeOf (NewType);
/* lvalue? */
if (k != 0) {
if (ED_IsLVal (Expr)) {
/* We have an lvalue. If the new size is smaller than the new one,
* we don't need to do anything. The compiler will generate code
@ -112,14 +112,13 @@ static int DoConversion (ExprDesc* Expr, int k, type* NewType)
*/
if (NewSize > OldSize) {
/* Load the value into the primary */
ExprLoad (CF_NONE, k, Expr);
ExprLoad (CF_NONE, Expr);
/* Emit typecast code */
g_typecast (TypeOf (NewType), TypeOf (OldType));
/* Value is now in primary */
Expr->Flags = E_MEXPR;
k = 0;
/* Value is now in primary and an rvalue */
Expr->Flags = E_MEXPR | E_RVAL;
}
} else {
@ -162,14 +161,13 @@ static int DoConversion (ExprDesc* Expr, int k, type* NewType)
if (OldSize != NewSize) {
/* Load the value into the primary */
ExprLoad (CF_NONE, k, Expr);
ExprLoad (CF_NONE, Expr);
/* Emit typecast code. */
g_typecast (TypeOf (NewType) | CF_FORCECHAR, TypeOf (OldType));
/* Value is now in primary */
Expr->Flags = E_MEXPR;
k = 0;
/* Value is now a rvalie in the primary */
Expr->Flags = E_MEXPR | E_RVAL;
}
}
}
@ -177,14 +175,11 @@ static int DoConversion (ExprDesc* Expr, int k, type* NewType)
ExitPoint:
/* The expression has always the new type */
ReplaceType (Expr, NewType);
/* Done */
return k;
}
int TypeConversion (ExprDesc* Expr, int k, type* NewType)
void TypeConversion (ExprDesc* Expr, type* NewType)
/* Do an automatic conversion of the given expression to the new type. Output
* warnings or errors where this automatic conversion is suspicious or
* impossible.
@ -197,15 +192,16 @@ int TypeConversion (ExprDesc* Expr, int k, type* NewType)
/* First, do some type checking */
if (IsTypeVoid (NewType) || IsTypeVoid (Expr->Type)) {
/* If one of the sides are of type void, output a more apropriate
* error message.
*/
/* If one of the sides are of type void, output a more apropriate
* error message.
*/
Error ("Illegal type");
return k;
}
/* Handle conversions to int type */
/* Check for conversion problems */
if (IsClassInt (NewType)) {
/* Handle conversions to int type */
if (IsClassPtr (Expr->Type)) {
/* Pointer -> int conversion */
Warning ("Converting pointer to integer without a cast");
@ -213,12 +209,9 @@ int TypeConversion (ExprDesc* Expr, int k, type* NewType)
Error ("Incompatible types");
}
/* Do a conversion regardless of errors and return the result. */
return DoConversion (Expr, k, NewType);
}
} else if (IsClassPtr (NewType)) {
/* Handle conversions to pointer type */
if (IsClassPtr (NewType)) {
/* Handle conversions to pointer type */
if (IsClassPtr (Expr->Type)) {
/* Pointer to pointer assignment is valid, if:
* - both point to the same types, or
@ -258,24 +251,24 @@ int TypeConversion (ExprDesc* Expr, int k, type* NewType)
Error ("Incompatible types");
}
/* Do the conversion even in case of errors */
return DoConversion (Expr, k, NewType);
} else {
/* Invalid automatic conversion */
Error ("Incompatible types");
}
/* Invalid automatic conversion */
Error ("Incompatible types");
return DoConversion (Expr, k, NewType);
/* Do the actual conversion */
DoConversion (Expr, NewType);
}
int TypeCast (ExprDesc* Expr)
void TypeCast (ExprDesc* Expr)
/* Handle an explicit cast. The function returns true if the resulting
* expression is an lvalue and false if not.
*/
{
int k;
type NewType[MAXTYPELEN];
/* Skip the left paren */
@ -288,15 +281,15 @@ int TypeCast (ExprDesc* Expr)
ConsumeRParen ();
/* Read the expression we have to cast */
k = hie10 (Expr);
hie10 (Expr);
/* Convert functions and arrays to "pointer to" object */
DoPtrConversions (Expr);
/* Convert the value and return the result. */
return DoConversion (Expr, k, NewType);
/* Convert the value. */
DoConversion (Expr, NewType);
}

View File

@ -6,7 +6,7 @@
/* */
/* */
/* */
/* (C) 2002-2003 Ullrich von Bassewitz */
/* (C) 2002-2004 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
@ -44,18 +44,18 @@
/*****************************************************************************/
/* Code */
/* Code */
/*****************************************************************************/
int TypeConversion (ExprDesc* Expr, int k, type* NewType);
void TypeConversion (ExprDesc* Expr, type* NewType);
/* Do an automatic conversion of the given expression to the new type. Output
* warnings or errors where this automatic conversion is suspicious or
* impossible.
*/
int TypeCast (ExprDesc* Expr);
void TypeCast (ExprDesc* Expr);
/* Handle an explicit cast. The function returns true if the resulting
* expression is an lvalue and false if not.
*/