diff --git a/TODO b/TODO index 114a668..c7553ad 100644 --- a/TODO +++ b/TODO @@ -13,10 +13,8 @@ Bugs: Implement: * operator precedence -* '->' * pointer arithmetic * casts -* enum * fix #include * char access/char array access/char * access diff --git a/expression.c b/expression.c index f1329d3..7f5a5a7 100644 --- a/expression.c +++ b/expression.c @@ -192,6 +192,7 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result) if (Parser->Mode == RunModeRun) { void *TotalValueData = (void *)TotalValue->Val; + struct Value *TotalLValueFrom = TotalValue->LValueFrom; if (TotalValue->Typ->Base != TypeStruct && TotalValue->Typ->Base != TypeUnion) ProgramFail(Parser, "can't use '.' on something that's not a struct or union"); @@ -200,7 +201,37 @@ int ExpressionParse(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->LValueFrom); + TotalValue = VariableAllocValueFromExistingData(Parser, CurrentValue->Typ, TotalValueData + CurrentValue->Val->Integer, TRUE, TotalLValueFrom); + } + continue; + } + case TokenArrow: + { + struct Value *Ident; + + LexGetToken(Parser, NULL, TRUE); + if (LexGetToken(Parser, &Ident, TRUE) != TokenIdentifier) + ProgramFail(Parser, "need an structure or union member after '->'"); + + if (Parser->Mode == RunModeRun) + { + void *TotalValueData; + struct Value *DerefValue; + + if (TotalValue->Typ->Base != TypePointer) + ProgramFail(Parser, "can't dereference this non-pointer"); + + DerefValue = TotalValue->Val->Pointer.Segment; + TotalValueData = (void *)DerefValue->Val; + + if (DerefValue->Typ->Base != TypeStruct && DerefValue->Typ->Base != TypeUnion) + ProgramFail(Parser, "can't use '->' on something that's not a struct or union"); + + if (!TableGet(DerefValue->Typ->Members, Ident->Val->Identifier, &CurrentValue)) + 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, DerefValue); } continue; } diff --git a/tests/10_pointer.c b/tests/10_pointer.c index 8ee808e..4206356 100644 --- a/tests/10_pointer.c +++ b/tests/10_pointer.c @@ -21,6 +21,12 @@ printf("bolshevic.a = %d\n", bolshevic.a); printf("bolshevic.b = %d\n", bolshevic.b); printf("bolshevic.c = %d\n", bolshevic.c); +struct ziggy *tsar = &bolshevic; + +printf("tsar->a = %d\n", tsar->a); +printf("tsar->b = %d\n", tsar->b); +printf("tsar->c = %d\n", tsar->c); + /* b = &(bolshevic.b); printf("bolshevic.b = %d\n", *b); diff --git a/tests/10_pointer.expect b/tests/10_pointer.expect index 2d2516b..97116c0 100644 --- a/tests/10_pointer.expect +++ b/tests/10_pointer.expect @@ -2,3 +2,6 @@ a = 42 bolshevic.a = 12 bolshevic.b = 34 bolshevic.c = 56 +tsar->a = 12 +tsar->b = 34 +tsar->c = 56