Changed dereferencing to handle arrays correctly.

git-svn-id: http://picoc.googlecode.com/svn/trunk@269 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2009-04-26 03:26:04 +00:00
parent c805b3fdec
commit 4ea76ea5b3
5 changed files with 38 additions and 16 deletions

View file

@ -191,6 +191,16 @@ void ExpressionStackPushLValue(struct ParseState *Parser, struct ExpressionStack
ExpressionStackPushValueNode(Parser, StackTop, ValueLoc);
}
void ExpressionStackPushDereference(struct ParseState *Parser, struct ExpressionStack **StackTop, struct Value *DereferenceValue)
{
struct Value *DerefVal;
int Offset;
struct ValueType *DerefType;
void *DerefDataLoc = VariableDereferencePointer(Parser, DereferenceValue, &DerefVal, &Offset, &DerefType);
struct Value *ValueLoc = VariableAllocValueFromExistingData(Parser, DerefType, (union AnyValue *)DerefDataLoc, DerefVal->IsLValue, DerefVal);
ExpressionStackPushValueNode(Parser, StackTop, ValueLoc);
}
void ExpressionPushInt(struct ParseState *Parser, struct ExpressionStack **StackTop, int IntValue)
{
debugf("ExpressionPushInt()\n");
@ -239,8 +249,7 @@ void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack
break;
case TokenAsterisk:
VariableCheckPointer(Parser, TopValue);
ExpressionStackPushLValue(Parser, StackTop, TopValue->Val->Pointer.Segment, TopValue->Val->Pointer.Offset);
ExpressionStackPushDereference(Parser, StackTop, TopValue);
break;
case TokenSizeof:
@ -640,21 +649,19 @@ void ExpressionGetStructElement(struct ParseState *Parser, struct ExpressionStac
struct Value *ParamVal = (*StackTop)->p.Val;
struct Value *StructVal = ParamVal;
int StructOffset = 0;
struct ValueType *StructType = ParamVal->Typ;
void *DerefDataLoc = (void *)ParamVal->Val;
struct Value *MemberValue;
struct Value *Result;
/* if we're doing '->' dereference the struct pointer first */
if (Token == TokenArrow)
{
/* dereference the struct pointer first */
VariableCheckPointer(Parser, ParamVal);
StructVal = ParamVal->Val->Pointer.Segment;
StructOffset = ParamVal->Val->Pointer.Offset;
}
DerefDataLoc = VariableDereferencePointer(Parser, ParamVal, &StructVal, &StructOffset, &StructType);
if (StructVal->Typ->Base != TypeStruct && StructVal->Typ->Base != TypeUnion)
if (StructType->Base != TypeStruct && StructType->Base != TypeUnion)
ProgramFail(Parser, "can't use '%s' on something that's not a struct or union %s : it's a %t", (Token == TokenDot) ? "." : "->", (Token == TokenArrow) ? "pointer" : "", ParamVal->Typ);
if (!TableGet(StructVal->Typ->Members, Ident->Val->Identifier, &MemberValue))
if (!TableGet(StructType->Members, Ident->Val->Identifier, &MemberValue))
ProgramFail(Parser, "doesn't have a member called '%s'", Ident->Val->Identifier);
/* pop the value - assume it'll still be there until we're done */
@ -662,7 +669,7 @@ void ExpressionGetStructElement(struct ParseState *Parser, struct ExpressionStac
*StackTop = (*StackTop)->Next;
/* make the result value for this member only */
Result = VariableAllocValueFromExistingData(Parser, MemberValue->Typ, (void *)StructVal->Val + StructOffset + MemberValue->Val->Integer, TRUE, StructVal->LValueFrom);
Result = VariableAllocValueFromExistingData(Parser, MemberValue->Typ, DerefDataLoc + MemberValue->Val->Integer, TRUE, StructVal->LValueFrom);
ExpressionStackPushValueNode(Parser, StackTop, Result);
}
}

1
lex.c
View file

@ -56,7 +56,6 @@ static struct ReservedWord ReservedWords[] =
{ "long", TokenLongType, NULL },
{ "new", TokenNew, NULL },
{ "return", TokenReturn, NULL },
// { "short", TokenShortType, NULL },
{ "signed", TokenSignedType, NULL },
{ "sizeof", TokenSizeof, NULL },
{ "struct", TokenStructType, NULL },

View file

@ -330,7 +330,7 @@ void VariableStackFrameAdd(struct ParseState *Parser, int NumParams);
void VariableStackFramePop(struct ParseState *Parser);
struct Value *VariableStringLiteralGet(char *Ident);
void VariableStringLiteralDefine(char *Ident, struct Value *Val);
void VariableCheckPointer(struct ParseState *Parser, struct Value *PointerValue);
void *VariableDereferencePointer(struct ParseState *Parser, struct Value *PointerValue, struct Value **DerefVal, int *DerefOffset, struct ValueType **DerefType);
/* clibrary.c */
void LibraryInit(struct Table *GlobalTable, const char *LibraryName, struct LibraryFunction (*FuncList)[]);

View file

@ -1,3 +1,6 @@
int x = 'a';
char y = x;
char *a = "hello";
printf("%s\n", a);

View file

@ -261,8 +261,8 @@ void VariableStringLiteralDefine(char *Ident, struct Value *Val)
TableSet(&StringLiteralTable, Ident, Val);
}
/* check a pointer for validity */
void VariableCheckPointer(struct ParseState *Parser, struct Value *PointerValue)
/* check a pointer for validity and dereference it for use */
void *VariableDereferencePointer(struct ParseState *Parser, struct Value *PointerValue, struct Value **DerefVal, int *DerefOffset, struct ValueType **DerefType)
{
struct Value *PointedToValue = PointerValue->Val->Pointer.Segment;
@ -274,5 +274,18 @@ void VariableCheckPointer(struct ParseState *Parser, struct Value *PointerValue)
if (PointerValue->Val->Pointer.Offset < 0 || PointerValue->Val->Pointer.Offset > TypeLastAccessibleOffset(PointedToValue))
ProgramFail(Parser, "attempt to access invalid pointer");
/* pass back the optional dereferenced pointer, offset and type */
if (DerefVal != NULL)
{
*DerefVal = PointedToValue;
*DerefOffset = PointerValue->Val->Pointer.Offset;
*DerefType = PointerValue->Typ->FromType;
}
/* return a pointer to the data */
if (PointedToValue->Typ->Base == TypeArray)
return PointedToValue->Val->Array.Data + PointerValue->Val->Pointer.Offset;
else
return (void *)PointedToValue->Val + PointerValue->Val->Pointer.Offset;
}