Added the ability to declare unsized arrays which can then have a sized

value assigned to them. Part of #142


git-svn-id: http://picoc.googlecode.com/svn/trunk@577 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2012-09-03 10:14:06 +00:00
parent a106391d2e
commit 10714186eb
4 changed files with 58 additions and 15 deletions

View file

@ -390,6 +390,20 @@ void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue, struct
break;
case TypeArray:
if (SourceValue->Typ->Base == TypeArray && DestValue->Typ->FromType == DestValue->Typ->FromType && DestValue->Typ->ArraySize == 0)
{
/* destination array is unsized - need to resize the destination array to the same size as the source array */
DestValue->Typ = SourceValue->Typ;
VariableRealloc(Parser, DestValue, TypeSizeValue(DestValue, FALSE));
if (DestValue->LValueFrom != NULL)
{
/* copy the resized value back to the LValue */
DestValue->LValueFrom->Val = DestValue->Val;
DestValue->LValueFrom->AnyValOnHeap = DestValue->AnyValOnHeap;
}
}
if (DestValue->Typ != SourceValue->Typ)
AssignFail(Parser, "%t from %t", DestValue->Typ, SourceValue->Typ, 0, 0, FuncName, ParamNo);

View file

@ -208,8 +208,9 @@ struct Value
struct ValueType *Typ; /* the type of this value */
union AnyValue *Val; /* pointer to the AnyValue which holds the actual content */
struct Value *LValueFrom; /* if an LValue, this is a Value our LValue is contained within (or NULL) */
char ValOnHeap; /* the AnyValue is on the heap (but this Value is on the stack) */
char ValOnHeap; /* this Value is on the heap */
char ValOnStack; /* the AnyValue is on the stack along with this Value */
char AnyValOnHeap; /* the AnyValue is separately allocated from the Value on the heap */
char IsLValue; /* is modifiable and is allocated somewhere we can usefully modify it */
};
@ -422,6 +423,7 @@ struct Value *VariableAllocValueShared(struct ParseState *Parser, struct Value *
struct Value *VariableDefine(struct ParseState *Parser, char *Ident, struct Value *InitValue, struct ValueType *Typ, int MakeWritable);
struct Value *VariableDefineButIgnoreIdentical(struct ParseState *Parser, char *Ident, struct ValueType *Typ, int IsStatic, int *FirstVisit);
int VariableDefined(const char *Ident);
void VariableRealloc(struct ParseState *Parser, struct Value *FromValue, int NewSize);
void VariableGet(struct ParseState *Parser, const char *Ident, struct Value **LVal);
void VariableDefinePlatformVar(struct ParseState *Parser, char *Ident, struct ValueType *Typ, union AnyValue *FromValue, int IsWritable);
void VariableStackFrameAdd(struct ParseState *Parser, const char *FuncName, int NumParams);

30
type.c
View file

@ -455,16 +455,26 @@ struct ValueType *TypeParseBack(struct ParseState *Parser, struct ValueType *Fro
if (Token == TokenLeftSquareBracket)
{
/* add another array bound */
enum RunMode OldMode = Parser->Mode;
int ArraySize;
Parser->Mode = RunModeRun;
ArraySize = ExpressionParseInt(Parser);
Parser->Mode = OldMode;
if (LexGetToken(Parser, NULL, TRUE) != TokenRightSquareBracket)
ProgramFail(Parser, "']' expected");
return TypeGetMatching(Parser, TypeParseBack(Parser, FromType), TypeArray, ArraySize, StrEmpty, TRUE);
if (LexGetToken(Parser, NULL, FALSE) == TokenRightSquareBracket)
{
/* an unsized array */
LexGetToken(Parser, NULL, TRUE);
return TypeGetMatching(Parser, TypeParseBack(Parser, FromType), TypeArray, 0, StrEmpty, TRUE);
}
else
{
/* get a numeric array size */
enum RunMode OldMode = Parser->Mode;
int ArraySize;
Parser->Mode = RunModeRun;
ArraySize = ExpressionParseInt(Parser);
Parser->Mode = OldMode;
if (LexGetToken(Parser, NULL, TRUE) != TokenRightSquareBracket)
ProgramFail(Parser, "']' expected");
return TypeGetMatching(Parser, TypeParseBack(Parser, FromType), TypeArray, ArraySize, StrEmpty, TRUE);
}
}
else
{

View file

@ -29,7 +29,7 @@ void VariableInit()
/* deallocate the contents of a variable */
void VariableFree(struct Value *Val)
{
if (Val->ValOnHeap)
if (Val->ValOnHeap || Val->AnyValOnHeap)
{
/* free function bodies */
if (Val->Typ == &FunctionType && Val->Val->FuncDef.Intrinsic == NULL && Val->Val->FuncDef.Body.Pos != NULL)
@ -39,9 +39,14 @@ void VariableFree(struct Value *Val)
if (Val->Typ == &MacroType)
HeapFreeMem((void *)Val->Val->MacroDef.Body.Pos);
/* free the value */
HeapFreeMem(Val);
/* free the AnyValue */
if (Val->AnyValOnHeap)
HeapFreeMem(Val->Val);
}
/* free the value */
if (Val->ValOnHeap)
HeapFreeMem(Val);
}
/* deallocate the global table and the string literal table */
@ -97,6 +102,7 @@ struct Value *VariableAllocValueAndData(struct ParseState *Parser, int DataSize,
struct Value *NewValue = VariableAlloc(Parser, MEM_ALIGN(sizeof(struct Value)) + DataSize, OnHeap);
NewValue->Val = (union AnyValue *)((char *)NewValue + MEM_ALIGN(sizeof(struct Value)));
NewValue->ValOnHeap = OnHeap;
NewValue->AnyValOnHeap = FALSE;
NewValue->ValOnStack = !OnHeap;
NewValue->IsLValue = IsLValue;
NewValue->LValueFrom = LValueFrom;
@ -109,7 +115,7 @@ struct Value *VariableAllocValueFromType(struct ParseState *Parser, struct Value
{
int Size = TypeSize(Typ, Typ->ArraySize, FALSE);
struct Value *NewValue = VariableAllocValueAndData(Parser, Size, IsLValue, LValueFrom, OnHeap);
assert(Size > 0 || Typ == &VoidType);
assert(Size >= 0 || Typ == &VoidType);
NewValue->Typ = Typ;
return NewValue;
@ -139,6 +145,7 @@ struct Value *VariableAllocValueFromExistingData(struct ParseState *Parser, stru
NewValue->Typ = Typ;
NewValue->Val = FromValue;
NewValue->ValOnHeap = FALSE;
NewValue->AnyValOnHeap = FALSE;
NewValue->ValOnStack = FALSE;
NewValue->IsLValue = IsLValue;
NewValue->LValueFrom = LValueFrom;
@ -152,6 +159,16 @@ struct Value *VariableAllocValueShared(struct ParseState *Parser, struct Value *
return VariableAllocValueFromExistingData(Parser, FromValue->Typ, FromValue->Val, FromValue->IsLValue, FromValue->IsLValue ? FromValue : NULL);
}
/* reallocate a variable so its data has a new size */
void VariableRealloc(struct ParseState *Parser, struct Value *FromValue, int NewSize)
{
if (FromValue->AnyValOnHeap)
VariableFree(FromValue->Val);
FromValue->Val = VariableAlloc(Parser, NewSize, TRUE);
FromValue->AnyValOnHeap = TRUE;
}
/* define a variable. Ident must be registered */
struct Value *VariableDefine(struct ParseState *Parser, char *Ident, struct Value *InitValue, struct ValueType *Typ, int MakeWritable)
{