diff --git a/TODO b/TODO index 51ed909..56709f1 100644 --- a/TODO +++ b/TODO @@ -26,6 +26,7 @@ Improvements: Need test/debug: * all break/continue variations * getchar()/gets() tests +* new/delete heap allocation Also: * Remove Var parameter from HeapPopStack() once we're certain it all works diff --git a/expression.c b/expression.c index 4dd681e..4613cec 100644 --- a/expression.c +++ b/expression.c @@ -18,6 +18,7 @@ int ExpressionParseValue(struct ParseState *Parser, struct Value **Result) enum LexToken Token = LexGetToken(Parser, &LexValue, TRUE); struct Value *LocalLValue = NULL; struct ValueType *VType; + char *Identifier; int Success = TRUE; switch (Token) @@ -133,6 +134,20 @@ int ExpressionParseValue(struct ParseState *Parser, struct Value **Result) } } break; + + case TokenNew: + TypeParse(Parser, &VType, &Identifier); + if (Identifier != StrEmpty) + ProgramFail(Parser, "identifier not expected here"); + + if (Parser->Mode == RunModeRun) + { /* create an object of this type on the heap and a pointer to it on the stack */ + LocalLValue = VariableAllocValueFromType(Parser, VType, TRUE, NULL); + *Result = VariableAllocValueFromType(Parser, TypeGetMatching(Parser, VType, TypePointer, 0, StrEmpty), FALSE, NULL); + (*Result)->Val->Pointer.Segment = LocalLValue; + (*Result)->Val->Pointer.Offset = 0; + } + break; default: *Parser = PreState; diff --git a/lex.c b/lex.c index 3aa85d2..6df74fc 100644 --- a/lex.c +++ b/lex.c @@ -52,6 +52,7 @@ static struct ReservedWord ReservedWords[] = { "if", TokenIf, NULL }, { "int", TokenIntType, NULL }, { "long", TokenLongType, NULL }, + { "new", TokenNew, NULL }, { "return", TokenReturn, NULL }, // { "short", TokenShortType, NULL }, { "signed", TokenSignedType, NULL }, diff --git a/parse.c b/parse.c index 5893a50..6a253c7 100644 --- a/parse.c +++ b/parse.c @@ -472,16 +472,43 @@ int ParseStatement(struct ParseState *Parser) break; case TokenDelete: - if (LexGetToken(Parser, &LexerValue, TRUE) != TokenIdentifier) - ProgramFail(Parser, "identifier expected"); - - CValue = TableDelete(&GlobalTable, LexerValue->Val->Identifier); - - if (CValue == NULL) - ProgramFail(Parser, "'%s' is not defined", LexerValue->Val->Identifier); + { + /* first try to parse this as "delete a pointer from an expression" */ + struct ParseState PreExpression = *Parser; + int WasPointer = FALSE; - VariableFree(CValue); + if (ExpressionParse(Parser, &CValue)) + { /* found an expression */ + if (Parser->Mode == RunModeRun) + { + if (TopStackFrame->ReturnValue->Typ->Base == TypePointer) + { /* this was a pointer to something - delete the object we're pointing to */ + // XXX - now I'm having second thoughts about this + WasPointer = TRUE; + } + + VariableStackPop(Parser, CValue); + } + } + + if (!WasPointer) + { /* go back and try it as a function or variable name to delete */ + *Parser = PreExpression; + if (LexGetToken(Parser, &LexerValue, TRUE) != TokenIdentifier) + ProgramFail(Parser, "identifier expected"); + + if (Parser->Mode == RunModeRun) + { /* delete this variable or function */ + CValue = TableDelete(&GlobalTable, LexerValue->Val->Identifier); + + if (CValue == NULL) + ProgramFail(Parser, "'%s' is not defined", LexerValue->Val->Identifier); + + VariableFree(CValue); + } + } break; + } default: *Parser = PreState; diff --git a/picoc.h b/picoc.h index f6c8a05..faaad7b 100644 --- a/picoc.h +++ b/picoc.h @@ -54,7 +54,7 @@ enum LexToken TokenIntType, TokenCharType, TokenFloatType, TokenDoubleType, TokenVoidType, TokenEnumType, TokenLongType, TokenSignedType, TokenShortType, TokenStructType, TokenUnionType, TokenUnsignedType, TokenTypedef, TokenContinue, TokenDo, TokenElse, TokenFor, TokenIf, TokenWhile, TokenBreak, TokenSwitch, TokenCase, TokenDefault, TokenReturn, - TokenHashDefine, TokenHashInclude, TokenDelete, + TokenHashDefine, TokenHashInclude, TokenNew, TokenDelete, TokenNone, TokenEOF, TokenEndOfLine, TokenEndOfFunction };