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

View File

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

View File

@@ -460,6 +460,20 @@ static unsigned OptPtrStore1 (CodeSeg* S)
* subop * subop
* ldy yyy * ldy yyy
* sta (ptr1),y * 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; unsigned Changes = 0;
@@ -490,30 +504,64 @@ static unsigned OptPtrStore1 (CodeSeg* S)
CE_IsCallTo (L[4+K], "staspidx") && CE_IsCallTo (L[4+K], "staspidx") &&
!CE_HasLabel (L[4+K])) { !CE_HasLabel (L[4+K])) {
const char* RegBank = 0;
const char* ZPLoc = "ptr1";
CodeEntry* X; 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); /* Get the preceeding two instructions and check them. We check
CS_InsertEntry (S, X, I+2); * 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); X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[3]->LI);
CS_InsertEntry (S, X, I+5); CS_InsertEntry (S, X, I+3);
X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "ptr1", 0, L[2]->LI); X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, ZPLoc, 0, L[2]->LI);
CS_InsertEntry (S, X, I+6); CS_InsertEntry (S, X, I+4);
/* Insert the store through ptr1 */ /* Insert the store through the zp pointer */
X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, "ptr1", 0, L[3]->LI); X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, ZPLoc, 0, L[3]->LI);
CS_InsertEntry (S, X, I+8+K); CS_InsertEntry (S, X, I+6+K);
/* Delete the old code */ /* Delete the old code */
CS_DelEntry (S, I+9+K); /* jsr spaspidx */ CS_DelEntry (S, I+7+K); /* jsr spaspidx */
CS_DelEntry (S, I+4); /* jsr ldauidx */ CS_DelEntry (S, I+2); /* jsr ldauidx */
CS_DelEntry (S, I); /* jsr pushax */ 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 */ /* Remember, we had changes */
++Changes; ++Changes;

View File

@@ -1224,7 +1224,7 @@ static unsigned ParseScalarInit (type* T)
/* Get the expression and convert it to the target type */ /* Get the expression and convert it to the target type */
ConstExpr (&ED); ConstExpr (&ED);
TypeConversion (&ED, 0, T); TypeConversion (&ED, T);
/* Output the data */ /* Output the data */
DefineData (&ED); DefineData (&ED);
@@ -1251,7 +1251,7 @@ static unsigned ParsePointerInit (type* T)
/* Make the const value the correct size */ /* Make the const value the correct size */
ED.ConstVal &= 0xFFFF; ED.ConstVal &= 0xFFFF;
} }
TypeConversion (&ED, 0, T); TypeConversion (&ED, T);
/* Output the data */ /* Output the data */
DefineData (&ED); 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. * 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 /* 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, a diagnostic will be printed, and the value is replaced by
* a constant one to make sure there are no internal errors that result * a constant one to make sure there are no internal errors that result
@@ -42,7 +42,7 @@ void CheckBoolExpr (ExprDesc* lval);
* if not. * 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 */ /* Put the result of an expression into the primary register */
void Store (ExprDesc* lval, const type* StoreType); void Store (ExprDesc* lval, const type* StoreType);
@@ -51,17 +51,17 @@ void Store (ExprDesc* lval, const type* StoreType);
* is NULL, use lval->Type instead. * is NULL, use lval->Type instead.
*/ */
int hie0 (ExprDesc *lval); void hie0 (ExprDesc *lval);
/* Parse comma operator. */ /* 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 /* 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 * 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 * result is not constant, ExprLoad is called to bring the value into the
* primary register and 1 is returned. * 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. */ /* Expression parser; func is either hie0 or hie1. */
void expression1 (ExprDesc* lval); void expression1 (ExprDesc* lval);
@@ -69,8 +69,8 @@ void expression1 (ExprDesc* lval);
* the primary register * the primary register
*/ */
void expression (ExprDesc* lval); void expression0 (ExprDesc* lval);
/* Evaluate an expression and put it into the primary register */ /* Evaluate an expression via hie0 and put it into the primary register */
void ConstExpr (ExprDesc* lval); void ConstExpr (ExprDesc* lval);
/* Get a constant value */ /* Get a constant value */
@@ -81,10 +81,10 @@ void ConstIntExpr (ExprDesc* Val);
void intexpr (ExprDesc* lval); void intexpr (ExprDesc* lval);
/* Get an integer expression */ /* Get an integer expression */
int hie10 (ExprDesc* lval); void hie10 (ExprDesc* lval);
/* Handle ++, --, !, unary - etc. */ /* Handle ++, --, !, unary - etc. */
int hie1 (ExprDesc* lval); void hie1 (ExprDesc* lval);
/* Parse first level of expression hierarchy. */ /* Parse first level of expression hierarchy. */
void DefineData (ExprDesc* lval); void DefineData (ExprDesc* lval);

View File

@@ -6,9 +6,9 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2002 Ullrich von Bassewitz */ /* (C) 2002-2004 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* R<EFBFBD>merstra<EFBFBD>e 52 */
/* D-70597 Stuttgart */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* 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 */ /* 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->Type = type_int;
Expr->ConstVal = Value; Expr->ConstVal = Value;
return Expr;
} }

View File

@@ -6,9 +6,9 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2002 Ullrich von Bassewitz */ /* (C) 2002-2004 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* R<EFBFBD>merstra<EFBFBD>e 52 */
/* D-70597 Stuttgart */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
@@ -70,6 +70,9 @@
#define E_TLLAB 0x0004U /* Local label */ #define E_TLLAB 0x0004U /* Local label */
#define E_TREGISTER 0x0005U /* Register variable */ #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 */ /* Defines for the test field of the expression descriptor */
#define E_CC 0x0001U /* expr has set cond codes apropos result value */ #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 */ #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))) # define InitExprDesc(E) memset ((E), 0, sizeof (*(E)))
#endif #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 */ /* Make Expr a constant integer expression with the given value */
void PrintExprDesc (FILE* F, ExprDesc* Expr); void PrintExprDesc (FILE* F, ExprDesc* Expr);

View File

@@ -111,13 +111,13 @@ static unsigned ParseRegisterDecl (Declaration* Decl, unsigned* SC, int Reg)
} else { } else {
/* Parse the expression */ /* Parse the expression */
int k = hie1 (InitExprDesc (&lval)); hie1 (InitExprDesc (&lval));
/* Convert it to the target type */ /* Convert it to the target type */
k = TypeConversion (&lval, k, Decl->Type); TypeConversion (&lval, Decl->Type);
/* Load the value into the primary */ /* Load the value into the primary */
ExprLoad (CF_NONE, k, &lval); ExprLoad (CF_NONE, &lval);
/* Store the value into the variable */ /* Store the value into the variable */
g_putstatic (CF_REGVAR | TypeOf (Decl->Type), Reg, 0); g_putstatic (CF_REGVAR | TypeOf (Decl->Type), Reg, 0);
@@ -200,8 +200,6 @@ static unsigned ParseAutoDecl (Declaration* Decl, unsigned* SC)
} else { } else {
int k;
/* Allocate previously reserved local space */ /* Allocate previously reserved local space */
F_AllocLocalSpace (CurrentFunc); F_AllocLocalSpace (CurrentFunc);
@@ -209,17 +207,17 @@ static unsigned ParseAutoDecl (Declaration* Decl, unsigned* SC)
Flags = (Size == SIZEOF_CHAR)? CF_FORCECHAR : CF_NONE; Flags = (Size == SIZEOF_CHAR)? CF_FORCECHAR : CF_NONE;
/* Parse the expression */ /* Parse the expression */
k = hie1 (InitExprDesc (&lval)); hie1 (InitExprDesc (&lval));
/* Convert it to the target type */ /* 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. /* If the value is not const, load it into the primary.
* Otherwise pass the information to the code generator. * Otherwise pass the information to the code generator.
*/ */
if (k != 0 || lval.Flags != E_MCONST) { if (ED_IsLVal (&lval) || lval.Flags != E_MCONST) {
ExprLoad (CF_NONE, k, &lval); ExprLoad (CF_NONE, &lval);
k = 0; ED_MakeRVal (&lval);
} else { } else {
Flags |= CF_CONST; Flags |= CF_CONST;
} }
@@ -285,13 +283,13 @@ static unsigned ParseAutoDecl (Declaration* Decl, unsigned* SC)
} else { } else {
/* Parse the expression */ /* Parse the expression */
int k = hie1 (InitExprDesc (&lval)); hie1 (InitExprDesc (&lval));
/* Convert it to the target type */ /* Convert it to the target type */
k = TypeConversion (&lval, k, Decl->Type); TypeConversion (&lval, Decl->Type);
/* Load the value into the primary */ /* Load the value into the primary */
ExprLoad (CF_NONE, k, &lval); ExprLoad (CF_NONE, &lval);
/* Store the value into the variable */ /* Store the value into the variable */
g_putstatic (TypeOf (Decl->Type), SymData, 0); 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 */ /* R<>merstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
@@ -46,12 +46,13 @@
/*****************************************************************************/ /*****************************************************************************/
/* Token definitions */ /* Token definitions */
/*****************************************************************************/ /*****************************************************************************/
typedef enum token_t { typedef enum token_t {
TOK_INVALID,
TOK_CEOF, TOK_CEOF,
TOK_AUTO, TOK_AUTO,

View File

@@ -116,17 +116,17 @@ static unsigned ParseArg (type* Type, ExprDesc* Arg)
unsigned Flags = CF_FORCECHAR; unsigned Flags = CF_FORCECHAR;
/* Read the expression we're going to pass to the function */ /* 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 */ /* 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 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 */ /* Load into the primary */
ExprLoad (CF_NONE, k, Arg); ExprLoad (CF_NONE, Arg);
k = 0; ED_MakeRVal (Arg);
} else { } else {
@@ -191,7 +191,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)),
if (Arg.ConstVal == 0) { if (Arg.ConstVal == 0) {
Warning ("Call to memset has no effect"); Warning ("Call to memset has no effect");
} }
ExprLoad (CF_FORCECHAR, 0, &Arg); ExprLoad (CF_FORCECHAR, &Arg);
} }
/* Emit the actual function call */ /* Emit the actual function call */
@@ -208,7 +208,6 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)),
/* Handle the strlen function */ /* Handle the strlen function */
{ {
static type ParamType[] = { T_PTR, T_SCHAR, T_END }; static type ParamType[] = { T_PTR, T_SCHAR, T_END };
int k;
ExprDesc Param; ExprDesc Param;
unsigned CodeFlags; unsigned CodeFlags;
unsigned long ParamName; unsigned long ParamName;
@@ -217,7 +216,8 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)),
ParamType[1] = GetDefaultChar () | T_QUAL_CONST; ParamType[1] = GetDefaultChar () | T_QUAL_CONST;
/* Fetch the parameter and convert it to the type needed */ /* 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 /* Check if the parameter is a constant array of some type, or a numeric
* address cast to a pointer. * address cast to a pointer.
@@ -259,9 +259,9 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)),
if (!WriteableStrings) { if (!WriteableStrings) {
/* String literals are const */ /* String literals are const */
ExprDesc Length; ExprDesc Length;
MakeConstIntExpr (&Length, strlen (GetLiteral (Param.ConstVal))); ED_MakeConstInt (&Length, strlen (GetLiteral (Param.ConstVal)));
ResetLiteralPoolOffs (Param.ConstVal); ResetLiteralPoolOffs (Param.ConstVal);
ExprLoad (CF_NONE, 0, &Length); ExprLoad (CF_NONE, &Length);
goto ExitPoint; goto ExitPoint;
} else { } else {
CodeFlags |= CF_CONST | CF_STATIC; CodeFlags |= CF_CONST | CF_STATIC;
@@ -276,7 +276,7 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)),
} else { } else {
/* Not an array with a constant address. Load parameter into primary */ /* 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 */ /* Handle the 'return' statement */
{ {
ExprDesc Expr; ExprDesc Expr;
int k;
NextToken (); NextToken ();
if (CurTok.Tok != TOK_SEMI) { if (CurTok.Tok != TOK_SEMI) {
@@ -284,16 +283,16 @@ static void ReturnStatement (void)
} }
/* Evaluate the return expression */ /* Evaluate the return expression */
k = hie0 (InitExprDesc (&Expr)); hie0 (InitExprDesc (&Expr));
/* Ignore the return expression if the function returns void */ /* Ignore the return expression if the function returns void */
if (!F_HasVoidReturn (CurrentFunc)) { if (!F_HasVoidReturn (CurrentFunc)) {
/* Convert the return value to the type of the function result */ /* 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 */ /* Load the value into the primary */
ExprLoad (CF_NONE, k, &Expr); ExprLoad (CF_NONE, &Expr);
} }
} else if (!F_HasVoidReturn (CurrentFunc) && !F_HasOldStyleIntRet (CurrentFunc)) { } else if (!F_HasVoidReturn (CurrentFunc) && !F_HasOldStyleIntRet (CurrentFunc)) {
@@ -400,7 +399,7 @@ static void ForStatement (void)
/* Parse the initializer expression */ /* Parse the initializer expression */
if (CurTok.Tok != TOK_SEMI) { if (CurTok.Tok != TOK_SEMI) {
expression (&lval1); expression0 (&lval1);
} }
ConsumeSemi (); ConsumeSemi ();
@@ -425,7 +424,7 @@ static void ForStatement (void)
/* Parse the increment expression */ /* Parse the increment expression */
HaveIncExpr = (CurTok.Tok != TOK_RPAREN); HaveIncExpr = (CurTok.Tok != TOK_RPAREN);
if (HaveIncExpr) { if (HaveIncExpr) {
expression (&lval3); expression0 (&lval3);
} }
/* Jump to the test */ /* Jump to the test */
@@ -591,7 +590,7 @@ int Statement (int* PendingToken)
default: default:
/* Actual statement */ /* Actual statement */
expression (&lval); expression0 (&lval);
CheckSemi (PendingToken); CheckSemi (PendingToken);
} }
} }

View File

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

View File

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

View File

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