Took a first stab at implementing new/delete. Needs a bit more thought on how to handle dangling references to deallocated storage.

git-svn-id: http://picoc.googlecode.com/svn/trunk@211 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2009-03-16 04:25:58 +00:00
parent 188eb93d43
commit 1ab28fcfb7
5 changed files with 53 additions and 9 deletions

1
TODO
View file

@ -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

View file

@ -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;

1
lex.c
View file

@ -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 },

43
parse.c
View file

@ -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;

View file

@ -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
};