Added new "delete" keyword, used for undefining variables or functions

in interactive mode.


git-svn-id: http://picoc.googlecode.com/svn/trunk@206 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2009-03-15 10:44:56 +00:00
parent a414de85e5
commit ce80c66e8f
6 changed files with 59 additions and 24 deletions

1
TODO
View file

@ -9,7 +9,6 @@ Implement:
* pointer arithmetic
* casts
* char access/char array access/char * access
* getc()/gets()/malloc()/free()
* "delete" for interactive mode to remove old functions
Improvements:

1
lex.c
View file

@ -38,6 +38,7 @@ static struct ReservedWord ReservedWords[] =
{ "char", TokenCharType, NULL },
{ "continue", TokenContinue, NULL },
{ "default", TokenDefault, NULL },
{ "delete", TokenDelete, NULL },
{ "do", TokenDo, NULL },
#ifndef NO_FP
{ "double", TokenDoubleType, NULL },

16
parse.c
View file

@ -260,6 +260,7 @@ enum RunMode ParseBlock(struct ParseState *Parser, int AbsorbOpenBrace, int Cond
int ParseStatement(struct ParseState *Parser)
{
struct Value *CValue;
struct Value *LexerValue;
int Condition;
int CheckTrailingSemicolon = TRUE;
struct ParseState PreState = *Parser;
@ -373,15 +374,12 @@ int ParseStatement(struct ParseState *Parser)
#ifndef NO_HASH_INCLUDE
case TokenHashInclude:
{
struct Value *LexerValue;
if (LexGetToken(Parser, &LexerValue, TRUE) != TokenStringConstant)
ProgramFail(Parser, "\"filename.h\" expected");
PlatformScanFile(LexerValue->Val->Pointer.Segment->Val->Array.Data);
CheckTrailingSemicolon = FALSE;
break;
}
#endif
case TokenSwitch:
@ -467,7 +465,19 @@ int ParseStatement(struct ParseState *Parser)
else
ExpressionParse(Parser, &CValue);
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);
VariableFree(CValue);
break;
default:
*Parser = PreState;
return FALSE;

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,
TokenHashDefine, TokenHashInclude, TokenDelete,
TokenNone, TokenEOF, TokenEndOfLine, TokenEndOfFunction
};
@ -248,6 +248,7 @@ char *TableStrRegister2(const char *Str, int Len);
void TableInitTable(struct Table *Tbl, struct TableEntry **HashTable, int Size, int OnHeap);
int TableSet(struct Table *Tbl, char *Key, struct Value *Val);
int TableGet(struct Table *Tbl, const char *Key, struct Value **Val);
struct Value *TableDelete(struct Table *Tbl, const char *Key);
char *TableSetIdentifier(struct Table *Tbl, const char *Ident, int IdentLen);
void TableStrFree();
@ -297,6 +298,7 @@ void HeapFree(void *Mem);
/* variable.c */
void VariableInit();
void VariableCleanup();
void VariableFree(struct Value *Val);
void VariableTableCleanup(struct Table *HashTable);
void *VariableAlloc(struct ParseState *Parser, int Size, int OnHeap);
void VariableStackPop(struct ParseState *Parser, struct Value *Var);

19
table.c
View file

@ -87,6 +87,25 @@ int TableGet(struct Table *Tbl, const char *Key, struct Value **Val)
return TRUE;
}
/* remove an entry from the table */
struct Value *TableDelete(struct Table *Tbl, const char *Key)
{
struct TableEntry **EntryPtr;
int HashValue = ((unsigned long)Key) % Tbl->Size; /* shared strings have unique addresses so we don't need to hash them */
for (EntryPtr = &Tbl->HashTable[HashValue]; *EntryPtr != NULL; EntryPtr = &(*EntryPtr)->Next)
{
if ((*EntryPtr)->p.v.Key == Key)
{
struct Value *Val = (*EntryPtr)->p.v.Val;
*EntryPtr = (*EntryPtr)->Next;
return Val;
}
}
return NULL;
}
/* check a hash table entry for an identifier */
static struct TableEntry *TableSearchIdentifier(struct Table *Tbl, const char *Key, int Len, int *AddAt)
{

View file

@ -20,12 +20,29 @@ void VariableInit()
TopStackFrame = NULL;
}
/* deallocate the contents of a variable */
void VariableFree(struct Value *Val)
{
if (Val->ValOnHeap)
{
/* free function bodies */
if (Val->Typ == &FunctionType && Val->Val->FuncDef.Intrinsic == NULL)
HeapFree((void *)Val->Val->FuncDef.Body.Pos);
/* free macro bodies */
if (Val->Typ == &MacroType)
HeapFree((void *)Val->Val->Parser.Pos);
/* free the value */
HeapFree(Val);
}
}
/* deallocate the global table and the string literal table */
void VariableTableCleanup(struct Table *HashTable)
{
struct TableEntry *Entry;
struct TableEntry *NextEntry;
struct Value *Val;
int Count;
for (Count = 0; Count < HashTable->Size; Count++)
@ -33,20 +50,7 @@ void VariableTableCleanup(struct Table *HashTable)
for (Entry = HashTable->HashTable[Count]; Entry != NULL; Entry = NextEntry)
{
NextEntry = Entry->Next;
Val = Entry->p.v.Val;
if (Val->ValOnHeap)
{
/* free function bodies */
if (Val->Typ == &FunctionType && Val->Val->FuncDef.Intrinsic == NULL)
HeapFree((void *)Val->Val->FuncDef.Body.Pos);
/* free macro bodies */
if (Val->Typ == &MacroType)
HeapFree((void *)Val->Val->Parser.Pos);
/* free the value */
HeapFree(Val);
}
VariableFree(Entry->p.v.Val);
/* free the hash table entry */
HeapFree(Entry);
@ -140,14 +144,14 @@ struct Value *VariableAllocValueShared(struct ParseState *Parser, struct Value *
return VariableAllocValueFromExistingData(Parser, FromValue->Typ, FromValue->Val, FromValue->IsLValue, FromValue->IsLValue ? FromValue : NULL);
}
/* define a variable */
/* define a variable. Ident must be registered */
void VariableDefine(struct ParseState *Parser, char *Ident, struct Value *InitValue)
{
if (!TableSet((TopStackFrame == NULL) ? &GlobalTable : &TopStackFrame->LocalTable, Ident, VariableAllocValueAndCopy(Parser, InitValue, TopStackFrame == NULL)))
ProgramFail(Parser, "'%s' is already defined", Ident);
}
/* check if a variable with a given name is defined */
/* check if a variable with a given name is defined. Ident must be registered */
int VariableDefined(const char *Ident)
{
struct Value *FoundValue;
@ -161,7 +165,7 @@ int VariableDefined(const char *Ident)
return TRUE;
}
/* get the value of a variable. must be defined */
/* get the value of a variable. must be defined. Ident must be registered */
void VariableGet(struct ParseState *Parser, const char *Ident, struct Value **LVal)
{
if (TopStackFrame == NULL || !TableGet(&TopStackFrame->LocalTable, Ident, LVal))
@ -171,7 +175,7 @@ void VariableGet(struct ParseState *Parser, const char *Ident, struct Value **LV
}
}
/* define a global variable shared with a platform global */
/* define a global variable shared with a platform global. Ident will be registered */
void VariableDefinePlatformVar(struct ParseState *Parser, char *Ident, struct ValueType *Typ, union AnyValue *FromValue, int IsWritable)
{
struct Value *SomeValue = VariableAllocValueAndData(NULL, (Typ->Base == TypeArray) ? sizeof(struct ArrayValue) : 0, IsWritable, NULL, TRUE);