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:
parent
c805b3fdec
commit
4ea76ea5b3
29
expression.c
29
expression.c
|
@ -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
1
lex.c
|
@ -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 },
|
||||
|
|
2
picoc.h
2
picoc.h
|
@ -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)[]);
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
int x = 'a';
|
||||
char y = x;
|
||||
|
||||
char *a = "hello";
|
||||
|
||||
printf("%s\n", a);
|
||||
|
|
19
variable.c
19
variable.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue