Implementing variants on pointer assignment - assigning arrays and array

pointers to pointers to the array element type.


git-svn-id: http://picoc.googlecode.com/svn/trunk@272 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2009-04-27 12:19:36 +00:00
parent b6e61dd8ab
commit 5f09200360

View file

@ -219,6 +219,46 @@ void ExpressionPushFP(struct ParseState *Parser, struct ExpressionStack **StackT
} }
#endif #endif
/* assign to a pointer, leaving a value on the expression stack */
struct Value *ExpressionAssignToPointer(struct ParseState *Parser, struct Value *ToValue, struct Value *FromValue, int MakeValue)
{
struct ValueType *PointedToType = ToValue->Typ->FromType;
struct Value *ValueLoc = NULL;
struct Value *DerefVal = NULL;
int DerefOffset;
if (FromValue->Typ == ToValue->Typ)
ToValue->Val->Pointer = FromValue->Val->Pointer; /* plain old pointer assignment */
else if (FromValue->Typ->Base == TypeArray && PointedToType == FromValue->Typ->FromType)
{
/* the form is: blah *x = array of blah */
ToValue->Val->Pointer.Segment = FromValue;
ToValue->Val->Pointer.Offset = 0;
DerefVal = FromValue;
}
else if (FromValue->Typ->Base == TypePointer && FromValue->Typ->FromType->Base == TypeArray && PointedToType == FromValue->Typ->FromType->FromType)
{
/* the form is: blah *x = pointer to array of blah */
struct ValueType *DerefType;
VariableDereferencePointer(Parser, FromValue, &DerefVal, &DerefOffset, &DerefType);
ToValue->Val->Pointer.Segment = DerefVal;
ToValue->Val->Pointer.Offset = DerefOffset;
}
else
ProgramFail(Parser, "can't assign from a %t to a %t", FromValue->Typ, ToValue->Typ);
if (MakeValue)
{
/* put a copy of the pointer on the stack */
ValueLoc = VariableAllocValueFromType(Parser, ToValue->Typ, TRUE, NULL);
ValueLoc->Val->Pointer = ToValue->Val->Pointer;
}
return ValueLoc;
}
/* evaluate a prefix operator */ /* evaluate a prefix operator */
void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack **StackTop, enum LexToken Op, struct Value *TopValue) void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack **StackTop, enum LexToken Op, struct Value *TopValue)
{ {
@ -240,6 +280,7 @@ void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack
ProgramFail(Parser, "can't get the address of this"); ProgramFail(Parser, "can't get the address of this");
TempLValue = TopValue->LValueFrom; TempLValue = TopValue->LValueFrom;
assert(TempLValue != NULL);
Result = VariableAllocValueFromType(Parser, TypeGetMatching(Parser, TopValue->Typ, TypePointer, 0, StrEmpty), FALSE, NULL); Result = VariableAllocValueFromType(Parser, TypeGetMatching(Parser, TopValue->Typ, TypePointer, 0, StrEmpty), FALSE, NULL);
Result->Val->Pointer.Segment = TempLValue; Result->Val->Pointer.Segment = TempLValue;
if (Result->LValueFrom != NULL) if (Result->LValueFrom != NULL)
@ -575,11 +616,17 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
if (!BottomValue->IsLValue) if (!BottomValue->IsLValue)
ProgramFail(Parser, "can't assign to this"); ProgramFail(Parser, "can't assign to this");
if (BottomValue->Typ != TopValue->Typ) if (BottomValue->Typ->Base == TypePointer)
ProgramFail(Parser, "can't assign from a %t to a %t", TopValue->Typ, BottomValue->Typ); ExpressionStackPushValueNode(Parser, StackTop, ExpressionAssignToPointer(Parser, BottomValue, TopValue, TRUE)); /* pointer assignment */
else
{
/* assign anything else */
if (BottomValue->Typ != TopValue->Typ)
ProgramFail(Parser, "can't assign from a %t to a %t", TopValue->Typ, BottomValue->Typ);
memcpy((void *)BottomValue->Val, (void *)TopValue->Val, TypeSizeValue(TopValue)); // XXX - need to handle arrays memcpy((void *)BottomValue->Val, (void *)TopValue->Val, TypeSizeValue(TopValue)); // XXX - need to handle arrays
ExpressionStackPushValue(Parser, StackTop, TopValue); ExpressionStackPushValue(Parser, StackTop, TopValue);
}
} }
else else
ProgramFail(Parser, "invalid operation"); ProgramFail(Parser, "invalid operation");