diff --git a/TODO b/TODO index 1ae8e68..3d9229f 100644 --- a/TODO +++ b/TODO @@ -1,13 +1,15 @@ TODO -* move stdio functions into an implementation-specific file -* make sure everything compiles without much library support -* make printf() honour memory constraints * pointers +* test character array pointers and dereferencing * operator precedence -* enum +* '->' +* make printf() honour memory constraints * interactive mode * casts +* enum +* '+=' / '-=' for pointers +* pointer arithmetic * change heap to use a single consistent freelist node struct * periodic heap cleanup * fix type comparison to take into account array size @@ -15,8 +17,7 @@ TODO * expression and auto-cast support for all types * octal/hex character constants * fix #include -* eliminate host puts use -* move all system specific includes to a single file +* assignment on declaration Need test/debug: * all break/continue variations diff --git a/parse.c b/parse.c index 6f76868..46949ed 100644 --- a/parse.c +++ b/parse.c @@ -5,11 +5,6 @@ int ParseArguments(struct ParseState *Parser, int RunIt); int ParseStatementMaybeRun(struct ParseState *Parser, int Condition); -/* initialise the parser */ -void ParseInit() -{ -} - /* do a function call */ void ParseFunctionCall(struct ParseState *Parser, struct Value **Result, const char *FuncName) { @@ -157,6 +152,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); + // 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; break; @@ -292,23 +288,69 @@ int ParseExpression(struct ParseState *Parser, struct Value **Result) } continue; } - case TokenAssign: case TokenAddAssign: case TokenSubtractAssign: + case TokenAssign: LexGetToken(Parser, NULL, TRUE); + + if (!ParseExpression(Parser, &CurrentValue)) + ProgramFail(Parser, "expression expected"); + + if (Parser->Mode == RunModeRun) + { /* do the assignment */ + if (!TotalValue->IsLValue) + ProgramFail(Parser, "can't assign to this"); + + if (CurrentValue->Typ != TotalValue->Typ) + ProgramFail(Parser, "can't assign incompatible types"); + + if (TotalValue->Typ->Base != TypeArray) + memcpy(TotalValue->Val, CurrentValue->Val, TotalValue->Typ->Sizeof); + else + { /* array assignment */ + if (TotalValue->Val->Array.Size != CurrentValue->Val->Array.Size) + ProgramFail(Parser, "incompatible array sizes in assignment"); + + //memcpy(TotalValue->Val->Array.Data, CurrentValue->Val->Array.Data, CurrentValue->Typ->Sizeof * CurrentValue->Val->Array.Size); + } + VariableStackPop(Parser, CurrentValue); + *Result = TotalValue; + } + return TRUE; + + case TokenAddAssign: case TokenSubtractAssign: + LexGetToken(Parser, NULL, TRUE); + if (!ParseExpression(Parser, &CurrentValue)) ProgramFail(Parser, "expression expected"); if (Parser->Mode == RunModeRun) - { - if (CurrentValue->Typ->Base != TypeInt || !TotalValue->IsLValue || TotalValue->Typ->Base != TypeInt) + { /* do the assignment */ + if (!TotalValue->IsLValue) ProgramFail(Parser, "can't assign"); - switch (Token) + if (CurrentValue->Typ->Base == TypeInt && TotalValue->Typ->Base == TypeInt) { - case TokenAddAssign: TotalValue->Val->Integer += CurrentValue->Val->Integer; break; - case TokenSubtractAssign: TotalValue->Val->Integer -= CurrentValue->Val->Integer; break; - default: TotalValue->Val->Integer = CurrentValue->Val->Integer; break; + switch (Token) + { + case TokenAddAssign: TotalValue->Val->Integer += CurrentValue->Val->Integer; break; + case TokenSubtractAssign: TotalValue->Val->Integer -= CurrentValue->Val->Integer; break; + default: break; + } + VariableStackPop(Parser, CurrentValue); } - VariableStackPop(Parser, CurrentValue); +#ifndef NO_FP + else if (CurrentValue->Typ->Base == TypeFP && TotalValue->Typ->Base == TypeFP) + { + switch (Token) + { + case TokenAddAssign: TotalValue->Val->FP += CurrentValue->Val->FP; break; + case TokenSubtractAssign: TotalValue->Val->FP -= CurrentValue->Val->FP; break; + default: break; + } + VariableStackPop(Parser, CurrentValue); + } +#endif + else + ProgramFail(Parser, "can't operate and assign these types"); } // fallthrough diff --git a/picoc.c b/picoc.c index 4b0fe06..8a3c189 100644 --- a/picoc.c +++ b/picoc.c @@ -11,7 +11,6 @@ void Initialise() TypeInit(); LibraryInit(&GlobalTable, "c library", &CLibrary); LibraryInit(&GlobalTable, "platform library", &PlatformLibrary); - ParseInit(); } /* platform-dependent code for running programs is in this file */ diff --git a/picoc.h b/picoc.h index d23396b..b3e1b66 100644 --- a/picoc.h +++ b/picoc.h @@ -247,7 +247,6 @@ void LexInitParser(struct ParseState *Parser, void *TokenSource, const char *Fil enum LexToken LexGetToken(struct ParseState *Parser, struct Value **Value, int IncPos); /* parse.c */ -void ParseInit(void); int ParseExpression(struct ParseState *Parser, struct Value **Result); int ParseIntExpression(struct ParseState *Parser); int ParseStatement(struct ParseState *Parser); diff --git a/tests/10_pointer.c b/tests/10_pointer.c index 0fadf3e..765029d 100644 --- a/tests/10_pointer.c +++ b/tests/10_pointer.c @@ -1,5 +1,6 @@ int a; int *b; +int c; a = 42; b = &a;