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:
parent
c885a814c7
commit
878e4f1352
15 changed files with 984 additions and 918 deletions
|
@ -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);
|
||||
|
@ -152,13 +161,13 @@ int Assignment (ExprDesc* lval)
|
|||
PushAddr (lval);
|
||||
|
||||
/* Read the expression on the right side of the '=' */
|
||||
k = hie1 (&lval2);
|
||||
hie1 (&lval2);
|
||||
|
||||
/* Do type conversion if necessary */
|
||||
k = TypeConversion (&lval2, k, ltype);
|
||||
TypeConversion (&lval2, ltype);
|
||||
|
||||
/* If necessary, load the value into the primary register */
|
||||
ExprLoad (CF_NONE, k, &lval2);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
1303
src/cc65/expr.c
1303
src/cc65/expr.c
File diff suppressed because it is too large
Load diff
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
@ -52,6 +52,7 @@
|
|||
|
||||
|
||||
typedef enum token_t {
|
||||
TOK_INVALID,
|
||||
TOK_CEOF,
|
||||
|
||||
TOK_AUTO,
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
|
@ -201,11 +196,12 @@ int TypeConversion (ExprDesc* Expr, int k, type* NewType)
|
|||
* 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)) {
|
||||
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");
|
||||
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,13 +281,13 @@ 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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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,13 +49,13 @@
|
|||
|
||||
|
||||
|
||||
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.
|
||||
*/
|
||||
|
|
Loading…
Add table
Reference in a new issue