Changed the way that arrays are represented to a simpler one without

the extra level of indirection.
Fixed various array-related problems, including array assignment
which is issue #49.


git-svn-id: http://picoc.googlecode.com/svn/trunk@373 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2009-11-04 02:02:37 +00:00
parent 7c1bca8f41
commit e75518e139
6 changed files with 19 additions and 21 deletions

View file

@ -222,7 +222,8 @@ void GenericPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct
} }
if (FormatType != NULL) if (FormatType != NULL)
{ /* we have to format something */ {
/* we have to format something */
if (ArgCount >= NumArgs) if (ArgCount >= NumArgs)
PrintStr("XXX", Stream); /* not enough parameters for format */ PrintStr("XXX", Stream); /* not enough parameters for format */
else else
@ -244,7 +245,7 @@ void GenericPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct
if (NextArg->Typ->Base == TypePointer) if (NextArg->Typ->Base == TypePointer)
Str = NextArg->Val->NativePointer; Str = NextArg->Val->NativePointer;
else else
Str = NextArg->Val->ArrayData; Str = &NextArg->Val->ArrayMem[0];
if (Str == NULL) if (Str == NULL)
PrintStr("NULL", Stream); PrintStr("NULL", Stream);
@ -303,7 +304,7 @@ void LibSPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Val
void LibGets(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void LibGets(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{ {
struct Value *CharArray = (struct Value *)(Param[0]->Val->NativePointer); struct Value *CharArray = (struct Value *)(Param[0]->Val->NativePointer);
char *ReadBuffer = CharArray->Val->ArrayData; char *ReadBuffer = &CharArray->Val->ArrayMem[0];
char *Result; char *Result;
ReturnValue->Val->NativePointer = NULL; ReturnValue->Val->NativePointer = NULL;

View file

@ -286,15 +286,16 @@ void ExpressionAssignToPointer(struct ParseState *Parser, struct Value *ToValue,
{ {
struct ValueType *PointedToType = ToValue->Typ->FromType; struct ValueType *PointedToType = ToValue->Typ->FromType;
if (FromValue->Typ == ToValue->Typ || FromValue->Typ == VoidPtrType || ToValue->Typ == VoidPtrType) if (FromValue->Typ == ToValue->Typ || FromValue->Typ == VoidPtrType || (ToValue->Typ == VoidPtrType && FromValue->Typ->Base == TypePointer))
ToValue->Val->NativePointer = FromValue->Val->NativePointer; /* plain old pointer assignment */ ToValue->Val->NativePointer = FromValue->Val->NativePointer; /* plain old pointer assignment */
else if (FromValue->Typ->Base == TypeArray && PointedToType == FromValue->Typ->FromType) else if (FromValue->Typ->Base == TypeArray && (PointedToType == FromValue->Typ->FromType || ToValue->Typ == VoidPtrType))
{ {
/* the form is: blah *x = array of blah */ /* the form is: blah *x = array of blah */
ToValue->Val->NativePointer = FromValue->Val->ArrayData; ToValue->Val->NativePointer = (void *)&FromValue->Val->ArrayMem[0];
} }
else if (FromValue->Typ->Base == TypePointer && FromValue->Typ->FromType->Base == TypeArray && PointedToType == FromValue->Typ->FromType->FromType) else if (FromValue->Typ->Base == TypePointer && FromValue->Typ->FromType->Base == TypeArray &&
(PointedToType == FromValue->Typ->FromType->FromType || ToValue->Typ == VoidPtrType) )
{ {
/* the form is: blah *x = pointer to array of blah */ /* the form is: blah *x = pointer to array of blah */
ToValue->Val->NativePointer = VariableDereferencePointer(Parser, FromValue, NULL, NULL, NULL, NULL); ToValue->Val->NativePointer = VariableDereferencePointer(Parser, FromValue, NULL, NULL, NULL, NULL);
@ -349,7 +350,7 @@ void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue, struct
if (DestValue->Typ->ArraySize != SourceValue->Typ->ArraySize) if (DestValue->Typ->ArraySize != SourceValue->Typ->ArraySize)
AssignFail(Parser, "from an array of size %d to one of size %d", NULL, NULL, DestValue->Typ->ArraySize, SourceValue->Typ->ArraySize, FuncName, ParamNo); AssignFail(Parser, "from an array of size %d to one of size %d", NULL, NULL, DestValue->Typ->ArraySize, SourceValue->Typ->ArraySize, FuncName, ParamNo);
memcpy((void *)DestValue->Val->ArrayData, (void *)SourceValue->Val->ArrayData, DestValue->Typ->ArraySize); memcpy((void *)DestValue->Val, (void *)SourceValue->Val, TypeSizeValue(DestValue));
break; break;
case TypeStruct: case TypeStruct:
@ -557,7 +558,7 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
/* make the array element result */ /* make the array element result */
switch (BottomValue->Typ->Base) switch (BottomValue->Typ->Base)
{ {
case TypeArray: Result = VariableAllocValueFromExistingData(Parser, BottomValue->Typ->FromType, (union AnyValue *)((char *)BottomValue->Val->ArrayData + TypeSize(BottomValue->Typ->FromType, 0, TRUE) * ArrayIndex), BottomValue->IsLValue, BottomValue->LValueFrom); break; case TypeArray: Result = VariableAllocValueFromExistingData(Parser, BottomValue->Typ->FromType, (union AnyValue *)(&BottomValue->Val->ArrayMem[0] + TypeSize(BottomValue->Typ->FromType, 0, TRUE) * ArrayIndex), BottomValue->IsLValue, BottomValue->LValueFrom); break;
case TypePointer: Result = VariableAllocValueFromExistingData(Parser, BottomValue->Typ->FromType, (union AnyValue *)((char *)BottomValue->Val->NativePointer + TypeSize(BottomValue->Typ->FromType, 0, TRUE) * ArrayIndex), BottomValue->IsLValue, BottomValue->LValueFrom); break; case TypePointer: Result = VariableAllocValueFromExistingData(Parser, BottomValue->Typ->FromType, (union AnyValue *)((char *)BottomValue->Val->NativePointer + TypeSize(BottomValue->Typ->FromType, 0, TRUE) * ArrayIndex), BottomValue->IsLValue, BottomValue->LValueFrom); break;
default: ProgramFail(Parser, "this %t is not an array", BottomValue->Typ); default: ProgramFail(Parser, "this %t is not an array", BottomValue->Typ);
} }

4
lex.c
View file

@ -306,9 +306,9 @@ enum LexToken LexGetStringConstant(struct LexState *Lexer, struct Value *Value)
if (ArrayValue == NULL) if (ArrayValue == NULL)
{ {
/* create and store this string literal */ /* create and store this string literal */
ArrayValue = VariableAllocValueAndData(NULL, sizeof(void *), FALSE, NULL, TRUE); ArrayValue = VariableAllocValueAndData(NULL, 0, FALSE, NULL, TRUE);
ArrayValue->Typ = CharArrayType; ArrayValue->Typ = CharArrayType;
ArrayValue->Val->ArrayData = RegString; ArrayValue->Val = (union AnyValue *)RegString;
VariableStringLiteralDefine(RegString, ArrayValue); VariableStringLiteralDefine(RegString, ArrayValue);
} }

View file

@ -166,7 +166,7 @@ union AnyValue
unsigned short UnsignedShortInteger; unsigned short UnsignedShortInteger;
unsigned int UnsignedInteger; unsigned int UnsignedInteger;
char *Identifier; char *Identifier;
void *ArrayData; char ArrayMem[2]; /* placeholder for where the data starts, doesn't point to it */
struct ParseState Parser; struct ParseState Parser;
struct ValueType *Typ; struct ValueType *Typ;
struct FuncDef FuncDef; struct FuncDef FuncDef;

8
type.c
View file

@ -52,7 +52,7 @@ struct ValueType *TypeGetMatching(struct ParseState *Parser, struct ValueType *P
switch (Base) switch (Base)
{ {
case TypePointer: Sizeof = sizeof(void *); break; case TypePointer: Sizeof = sizeof(void *); break;
case TypeArray: Sizeof = sizeof(void *) + ArraySize * ParentType->Sizeof; break; case TypeArray: Sizeof = ArraySize * ParentType->Sizeof; break;
case TypeEnum: Sizeof = sizeof(int); break; case TypeEnum: Sizeof = sizeof(int); break;
default: Sizeof = 0; break; /* structs and unions will get bigger when we add members to them */ default: Sizeof = 0; break; /* structs and unions will get bigger when we add members to them */
} }
@ -64,7 +64,7 @@ struct ValueType *TypeGetMatching(struct ParseState *Parser, struct ValueType *P
int TypeStackSizeValue(struct Value *Val) int TypeStackSizeValue(struct Value *Val)
{ {
if (Val != NULL && Val->ValOnStack) if (Val != NULL && Val->ValOnStack)
return TypeSizeValue(Val); /* XXX - doesn't handle passing system-memory arrays by value correctly */ return TypeSizeValue(Val);
else else
return 0; return 0;
} }
@ -77,7 +77,7 @@ int TypeSizeValue(struct Value *Val)
else if (Val->Typ->Base != TypeArray) else if (Val->Typ->Base != TypeArray)
return Val->Typ->Sizeof; return Val->Typ->Sizeof;
else else
return sizeof(void *) + Val->Typ->FromType->Sizeof * Val->Typ->ArraySize; return Val->Typ->FromType->Sizeof * Val->Typ->ArraySize;
} }
/* memory used by a variable given its type and array size */ /* memory used by a variable given its type and array size */
@ -88,7 +88,7 @@ int TypeSize(struct ValueType *Typ, int ArraySize, int Compact)
else if (Typ->Base != TypeArray) else if (Typ->Base != TypeArray)
return Typ->Sizeof; return Typ->Sizeof;
else else
return sizeof(void *) + Typ->FromType->Sizeof * ArraySize; return Typ->FromType->Sizeof * ArraySize;
} }
/* memory used by the base (non-array) type of a type. This is used for alignment. */ /* memory used by the base (non-array) type of a type. This is used for alignment. */

View file

@ -105,8 +105,6 @@ struct Value *VariableAllocValueFromType(struct ParseState *Parser, struct Value
struct Value *NewValue = VariableAllocValueAndData(Parser, Size, IsLValue, LValueFrom, OnHeap); struct Value *NewValue = VariableAllocValueAndData(Parser, Size, IsLValue, LValueFrom, OnHeap);
assert(Size > 0 || Typ == &VoidType); assert(Size > 0 || Typ == &VoidType);
NewValue->Typ = Typ; NewValue->Typ = Typ;
if (Typ->Base == TypeArray)
NewValue->Val->ArrayData = (void *)((char *)NewValue->Val + sizeof(void *));
return NewValue; return NewValue;
} }
@ -187,12 +185,10 @@ void VariableGet(struct ParseState *Parser, const char *Ident, struct Value **LV
/* define a global variable shared with a platform global. Ident will be registered */ /* define a global variable shared with a platform global. Ident will be registered */
void VariableDefinePlatformVar(struct ParseState *Parser, char *Ident, struct ValueType *Typ, union AnyValue *FromValue, int IsWritable) void VariableDefinePlatformVar(struct ParseState *Parser, char *Ident, struct ValueType *Typ, union AnyValue *FromValue, int IsWritable)
{ {
struct Value *SomeValue = VariableAllocValueAndData(NULL, (Typ->Base == TypeArray) ? sizeof(void *) : 0, IsWritable, NULL, TRUE); struct Value *SomeValue = VariableAllocValueAndData(NULL, 0, IsWritable, NULL, TRUE);
SomeValue->Typ = Typ; SomeValue->Typ = Typ;
if (Typ->Base != TypeArray) if (Typ->Base != TypeArray)
SomeValue->Val = FromValue; SomeValue->Val = FromValue;
else
SomeValue->Val->ArrayData = FromValue;
if (!TableSet((TopStackFrame == NULL) ? &GlobalTable : &TopStackFrame->LocalTable, TableStrRegister(Ident), SomeValue)) if (!TableSet((TopStackFrame == NULL) ? &GlobalTable : &TopStackFrame->LocalTable, TableStrRegister(Ident), SomeValue))
ProgramFail(Parser, "'%s' is already defined", Ident); ProgramFail(Parser, "'%s' is already defined", Ident);