diff --git a/lex.c b/lex.c index d83c874..806c89c 100644 --- a/lex.c +++ b/lex.c @@ -208,7 +208,7 @@ enum LexToken LexGetStringConstant(struct LexState *Lexer, struct Value *Value) for (EscBufPos = EscBuf, Lexer->Pos = StartPos; Lexer->Pos != EndPos;) *EscBufPos++ = LexUnEscapeCharacter(&Lexer->Pos, EndPos); - ArrayValue = VariableAllocValueAndData(NULL, sizeof(struct ArrayValue), FALSE, TRUE); + ArrayValue = VariableAllocValueAndData(NULL, sizeof(struct ArrayValue), FALSE, NULL, TRUE); ArrayValue->Typ = CharArrayType; ArrayValue->Val->Array.Size = EscBufPos - EscBuf + 1; ArrayValue->Val->Array.Data = TableStrRegister2(EscBuf, EscBufPos - EscBuf); @@ -451,6 +451,7 @@ enum LexToken LexGetToken(struct ParseState *Parser, struct Value **Value, int I LexValue.ValOnHeap = FALSE; LexValue.ValOnStack = FALSE; LexValue.IsLValue = FALSE; + LexValue.LValueFrom = NULL; *Value = &LexValue; } diff --git a/parse.c b/parse.c index 46949ed..f705da8 100644 --- a/parse.c +++ b/parse.c @@ -20,7 +20,7 @@ void ParseFunctionCall(struct ParseState *Parser, struct Value **Result, const c if (FuncValue->Typ->Base != TypeFunction) ProgramFail(Parser, "not a function - can't call"); - *Result = VariableAllocValueFromType(Parser, FuncValue->Val->FuncDef.ReturnType, FALSE); + *Result = VariableAllocValueFromType(Parser, FuncValue->Val->FuncDef.ReturnType, FALSE, NULL); HeapPushStackFrame(); ParamArray = HeapAllocStack(sizeof(struct Value *) * FuncValue->Val->FuncDef.NumParams); if (ParamArray == NULL) @@ -114,7 +114,7 @@ int ParseValue(struct ParseState *Parser, struct Value **Result) IntValue = ParseIntExpression(Parser); if (Parser->Mode == RunModeRun) { - *Result = VariableAllocValueFromType(Parser, &IntType, FALSE); + *Result = VariableAllocValueFromType(Parser, &IntType, FALSE, NULL); switch(Token) { case TokenMinus: (*Result)->Val->Integer = -IntValue; break; @@ -151,7 +151,7 @@ int ParseValue(struct ParseState *Parser, struct Value **Result) VType = (*Result)->Typ; VariableStackPop(Parser, *Result); - *Result = VariableAllocValueFromType(Parser, TypeGetMatching(Parser, VType, TypePointer, 0, StrEmpty), FALSE); + *Result = VariableAllocValueFromType(Parser, TypeGetMatching(Parser, VType, TypePointer, 0, StrEmpty), FALSE, NULL); // XXX - need to rethink how to deal with lvalues - I need the original lvalue, not a copy of it for the segment (*Result)->Val->Pointer.Segment = LocalLValue; (*Result)->Val->Pointer.Data.Offset = 0; @@ -212,7 +212,7 @@ int ParseValue(struct ParseState *Parser, struct Value **Result) ProgramFail(Parser, "illegal array index"); VariableStackPop(Parser, *Result); - *Result = VariableAllocValueFromExistingData(Parser, (*Result)->Typ->FromType, (union AnyValue *)((*Result)->Val->Array.Data + TypeSize((*Result)->Typ->FromType, 0) * IntValue), (*Result)->IsLValue); + *Result = VariableAllocValueFromExistingData(Parser, (*Result)->Typ->FromType, (union AnyValue *)((*Result)->Val->Array.Data + TypeSize((*Result)->Typ->FromType, 0) * IntValue), (*Result)->IsLValue, (*Result)->LValueFrom); } } } @@ -230,7 +230,7 @@ int ParseValue(struct ParseState *Parser, struct Value **Result) #ifndef NO_FP struct Value *ParsePushFP(struct ParseState *Parser, double NewFP) { - struct Value *Val = VariableAllocValueFromType(Parser, &FPType, FALSE); + struct Value *Val = VariableAllocValueFromType(Parser, &FPType, FALSE, NULL); Val->Val->FP = NewFP; return Val; } @@ -238,7 +238,7 @@ struct Value *ParsePushFP(struct ParseState *Parser, double NewFP) struct Value *ParsePushInt(struct ParseState *Parser, int NewInt) { - struct Value *Val = VariableAllocValueFromType(Parser, &IntType, FALSE); + struct Value *Val = VariableAllocValueFromType(Parser, &IntType, FALSE, NULL); Val->Val->Integer = NewInt; return Val; } @@ -284,7 +284,7 @@ int ParseExpression(struct ParseState *Parser, struct Value **Result) ProgramFail(Parser, "structure doesn't have a member called '%s'", Ident->Val->Identifier); VariableStackPop(Parser, TotalValue); - TotalValue = VariableAllocValueFromExistingData(Parser, CurrentValue->Typ, TotalValueData + CurrentValue->Val->Integer, TRUE); + TotalValue = VariableAllocValueFromExistingData(Parser, CurrentValue->Typ, TotalValueData + CurrentValue->Val->Integer, TRUE, CurrentValue->LValueFrom); } continue; } @@ -494,7 +494,7 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueTyp if (ParamCount > PARAMETER_MAX) ProgramFail(Parser, "too many parameters"); - FuncValue = VariableAllocValueAndData(Parser, sizeof(struct FuncDef) + sizeof(struct ValueType *) * ParamCount + sizeof(const char *) * ParamCount, FALSE, TRUE); + FuncValue = VariableAllocValueAndData(Parser, sizeof(struct FuncDef) + sizeof(struct ValueType *) * ParamCount + sizeof(const char *) * ParamCount, FALSE, NULL, TRUE); FuncValue->Typ = &FunctionType; FuncValue->Val->FuncDef.ReturnType = ReturnType; FuncValue->Val->FuncDef.NumParams = ParamCount; @@ -542,7 +542,7 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueTyp void ParseMacroDefinition(struct ParseState *Parser) { struct Value *MacroName; - struct Value *MacroValue = VariableAllocValueAndData(Parser, sizeof(struct ParseState), FALSE, TRUE); + struct Value *MacroValue = VariableAllocValueAndData(Parser, sizeof(struct ParseState), FALSE, NULL, TRUE); if (LexGetToken(Parser, &MacroName, TRUE) != TokenIdentifier) ProgramFail(Parser, "identifier expected"); @@ -780,7 +780,7 @@ int ParseStatement(struct ParseState *Parser) if (LexGetToken(Parser, NULL, FALSE) == TokenOpenBracket) ParseFunctionDefinition(Parser, Typ, Identifier, FALSE); else - VariableDefine(Parser, Identifier, VariableAllocValueFromType(Parser, Typ, TRUE)); + VariableDefine(Parser, Identifier, VariableAllocValueFromType(Parser, Typ, TRUE, NULL)); } break; diff --git a/picoc.h b/picoc.h index b3e1b66..f28d47b 100644 --- a/picoc.h +++ b/picoc.h @@ -155,6 +155,7 @@ 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 ValOnStack; /* the AnyValue is on the stack along with this Value */ char IsLValue; /* is modifiable and is allocated somewhere we can usefully modify it */ @@ -273,10 +274,10 @@ void HeapFree(void *Mem); void VariableInit(); void *VariableAlloc(struct ParseState *Parser, int Size, int OnHeap); void VariableStackPop(struct ParseState *Parser, struct Value *Var); -struct Value *VariableAllocValueAndData(struct ParseState *Parser, int DataSize, int IsLValue, int OnHeap); +struct Value *VariableAllocValueAndData(struct ParseState *Parser, int DataSize, int IsLValue, struct Value *LValueFrom, int OnHeap); struct Value *VariableAllocValueAndCopy(struct ParseState *Parser, struct Value *FromValue, int OnHeap); -struct Value *VariableAllocValueFromType(struct ParseState *Parser, struct ValueType *Typ, int IsLValue); -struct Value *VariableAllocValueFromExistingData(struct ParseState *Parser, struct ValueType *Typ, union AnyValue *FromValue, int IsLValue); +struct Value *VariableAllocValueFromType(struct ParseState *Parser, struct ValueType *Typ, int IsLValue, struct Value *LValueFrom); +struct Value *VariableAllocValueFromExistingData(struct ParseState *Parser, struct ValueType *Typ, union AnyValue *FromValue, int IsLValue, struct Value *LValueFrom); struct Value *VariableAllocValueShared(struct ParseState *Parser, struct Value *FromValue); void VariableDefine(struct ParseState *Parser, char *Ident, struct Value *InitValue); int VariableDefined(const char *Ident); diff --git a/type.c b/type.c index 7e058c3..d7a81f8 100644 --- a/type.c +++ b/type.c @@ -141,7 +141,7 @@ void TypeParseStruct(struct ParseState *Parser, struct ValueType **Typ, int IsSt if (MemberType == NULL || MemberIdentifier == NULL) ProgramFail(Parser, "invalid type in struct"); - MemberValue = VariableAllocValueAndData(Parser, sizeof(int), FALSE, TRUE); + MemberValue = VariableAllocValueAndData(Parser, sizeof(int), FALSE, NULL, TRUE); MemberValue->Typ = MemberType; if (IsStruct) { /* allocate this member's location in the struct */ diff --git a/variable.c b/variable.c index e519932..c27ca5c 100644 --- a/variable.c +++ b/variable.c @@ -37,22 +37,23 @@ void *VariableAlloc(struct ParseState *Parser, int Size, int OnHeap) } /* allocate a value either on the heap or the stack using space dependent on what type we want */ -struct Value *VariableAllocValueAndData(struct ParseState *Parser, int DataSize, int IsLValue, int OnHeap) +struct Value *VariableAllocValueAndData(struct ParseState *Parser, int DataSize, int IsLValue, struct Value *LValueFrom, int OnHeap) { struct Value *NewValue = VariableAlloc(Parser, sizeof(struct Value) + DataSize, OnHeap); NewValue->Val = (union AnyValue *)((void *)NewValue + sizeof(struct Value)); NewValue->ValOnHeap = OnHeap; NewValue->ValOnStack = !OnHeap; NewValue->IsLValue = IsLValue; + NewValue->LValueFrom = LValueFrom; return NewValue; } /* allocate a value given its type */ -struct Value *VariableAllocValueFromType(struct ParseState *Parser, struct ValueType *Typ, int IsLValue) +struct Value *VariableAllocValueFromType(struct ParseState *Parser, struct ValueType *Typ, int IsLValue, struct Value *LValueFrom) { int Size = TypeSize(Typ, Typ->ArraySize); - struct Value *NewValue = VariableAllocValueAndData(Parser, Size, IsLValue, FALSE); + struct Value *NewValue = VariableAllocValueAndData(Parser, Size, IsLValue, LValueFrom, FALSE); assert(Size > 0 || Typ == &VoidType); NewValue->Typ = Typ; if (Typ->Base == TypeArray) @@ -68,14 +69,14 @@ struct Value *VariableAllocValueFromType(struct ParseState *Parser, struct Value struct Value *VariableAllocValueAndCopy(struct ParseState *Parser, struct Value *FromValue, int OnHeap) { int CopySize = TypeSizeValue(FromValue); - struct Value *NewValue = VariableAllocValueAndData(Parser, CopySize, FromValue->IsLValue, OnHeap); + struct Value *NewValue = VariableAllocValueAndData(Parser, CopySize, FromValue->IsLValue, FromValue->LValueFrom, OnHeap); NewValue->Typ = FromValue->Typ; memcpy(NewValue->Val, FromValue->Val, CopySize); return NewValue; } /* allocate a value either on the heap or the stack from an existing AnyValue and type */ -struct Value *VariableAllocValueFromExistingData(struct ParseState *Parser, struct ValueType *Typ, union AnyValue *FromValue, int IsLValue) +struct Value *VariableAllocValueFromExistingData(struct ParseState *Parser, struct ValueType *Typ, union AnyValue *FromValue, int IsLValue, struct Value *LValueFrom) { struct Value *NewValue = VariableAlloc(Parser, sizeof(struct Value), FALSE); NewValue->Typ = Typ; @@ -83,6 +84,7 @@ struct Value *VariableAllocValueFromExistingData(struct ParseState *Parser, stru NewValue->ValOnHeap = FALSE; NewValue->ValOnStack = FALSE; NewValue->IsLValue = IsLValue; + NewValue->LValueFrom = LValueFrom; return NewValue; } @@ -90,7 +92,7 @@ struct Value *VariableAllocValueFromExistingData(struct ParseState *Parser, stru /* allocate a value either on the heap or the stack from an existing Value, sharing the value */ struct Value *VariableAllocValueShared(struct ParseState *Parser, struct Value *FromValue) { - return VariableAllocValueFromExistingData(Parser, FromValue->Typ, FromValue->Val, FromValue->IsLValue); + return VariableAllocValueFromExistingData(Parser, FromValue->Typ, FromValue->Val, FromValue->IsLValue, FromValue->LValueFrom); } /* define a variable */