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:
parent
188eb93d43
commit
1ab28fcfb7
1
TODO
1
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
|
||||
|
|
15
expression.c
15
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;
|
||||
|
|
1
lex.c
1
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 },
|
||||
|
|
43
parse.c
43
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;
|
||||
|
|
2
picoc.h
2
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
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue