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 * pointer arithmetic
* casts * casts
* char access/char array access/char * access * char access/char array access/char * access
* getc()/gets()/malloc()/free()
* "delete" for interactive mode to remove old functions * "delete" for interactive mode to remove old functions
Improvements: Improvements:

1
lex.c
View file

@ -38,6 +38,7 @@ static struct ReservedWord ReservedWords[] =
{ "char", TokenCharType, NULL }, { "char", TokenCharType, NULL },
{ "continue", TokenContinue, NULL }, { "continue", TokenContinue, NULL },
{ "default", TokenDefault, NULL }, { "default", TokenDefault, NULL },
{ "delete", TokenDelete, NULL },
{ "do", TokenDo, NULL }, { "do", TokenDo, NULL },
#ifndef NO_FP #ifndef NO_FP
{ "double", TokenDoubleType, NULL }, { "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) int ParseStatement(struct ParseState *Parser)
{ {
struct Value *CValue; struct Value *CValue;
struct Value *LexerValue;
int Condition; int Condition;
int CheckTrailingSemicolon = TRUE; int CheckTrailingSemicolon = TRUE;
struct ParseState PreState = *Parser; struct ParseState PreState = *Parser;
@ -373,15 +374,12 @@ int ParseStatement(struct ParseState *Parser)
#ifndef NO_HASH_INCLUDE #ifndef NO_HASH_INCLUDE
case TokenHashInclude: case TokenHashInclude:
{
struct Value *LexerValue;
if (LexGetToken(Parser, &LexerValue, TRUE) != TokenStringConstant) if (LexGetToken(Parser, &LexerValue, TRUE) != TokenStringConstant)
ProgramFail(Parser, "\"filename.h\" expected"); ProgramFail(Parser, "\"filename.h\" expected");
PlatformScanFile(LexerValue->Val->Pointer.Segment->Val->Array.Data); PlatformScanFile(LexerValue->Val->Pointer.Segment->Val->Array.Data);
CheckTrailingSemicolon = FALSE; CheckTrailingSemicolon = FALSE;
break; break;
}
#endif #endif
case TokenSwitch: case TokenSwitch:
@ -467,7 +465,19 @@ int ParseStatement(struct ParseState *Parser)
else else
ExpressionParse(Parser, &CValue); ExpressionParse(Parser, &CValue);
break; 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: default:
*Parser = PreState; *Parser = PreState;
return FALSE; return FALSE;

View file

@ -54,7 +54,7 @@ enum LexToken
TokenIntType, TokenCharType, TokenFloatType, TokenDoubleType, TokenVoidType, TokenEnumType, TokenIntType, TokenCharType, TokenFloatType, TokenDoubleType, TokenVoidType, TokenEnumType,
TokenLongType, TokenSignedType, TokenShortType, TokenStructType, TokenUnionType, TokenUnsignedType, TokenTypedef, TokenLongType, TokenSignedType, TokenShortType, TokenStructType, TokenUnionType, TokenUnsignedType, TokenTypedef,
TokenContinue, TokenDo, TokenElse, TokenFor, TokenIf, TokenWhile, TokenBreak, TokenSwitch, TokenCase, TokenDefault, TokenReturn, TokenContinue, TokenDo, TokenElse, TokenFor, TokenIf, TokenWhile, TokenBreak, TokenSwitch, TokenCase, TokenDefault, TokenReturn,
TokenHashDefine, TokenHashInclude, TokenHashDefine, TokenHashInclude, TokenDelete,
TokenNone, TokenEOF, TokenEndOfLine, TokenEndOfFunction 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); void TableInitTable(struct Table *Tbl, struct TableEntry **HashTable, int Size, int OnHeap);
int TableSet(struct Table *Tbl, char *Key, struct Value *Val); int TableSet(struct Table *Tbl, char *Key, struct Value *Val);
int TableGet(struct Table *Tbl, const 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); char *TableSetIdentifier(struct Table *Tbl, const char *Ident, int IdentLen);
void TableStrFree(); void TableStrFree();
@ -297,6 +298,7 @@ void HeapFree(void *Mem);
/* variable.c */ /* variable.c */
void VariableInit(); void VariableInit();
void VariableCleanup(); void VariableCleanup();
void VariableFree(struct Value *Val);
void VariableTableCleanup(struct Table *HashTable); void VariableTableCleanup(struct Table *HashTable);
void *VariableAlloc(struct ParseState *Parser, int Size, int OnHeap); void *VariableAlloc(struct ParseState *Parser, int Size, int OnHeap);
void VariableStackPop(struct ParseState *Parser, struct Value *Var); 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; 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 */ /* check a hash table entry for an identifier */
static struct TableEntry *TableSearchIdentifier(struct Table *Tbl, const char *Key, int Len, int *AddAt) static struct TableEntry *TableSearchIdentifier(struct Table *Tbl, const char *Key, int Len, int *AddAt)
{ {

View file

@ -20,12 +20,29 @@ void VariableInit()
TopStackFrame = NULL; 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 */ /* deallocate the global table and the string literal table */
void VariableTableCleanup(struct Table *HashTable) void VariableTableCleanup(struct Table *HashTable)
{ {
struct TableEntry *Entry; struct TableEntry *Entry;
struct TableEntry *NextEntry; struct TableEntry *NextEntry;
struct Value *Val;
int Count; int Count;
for (Count = 0; Count < HashTable->Size; 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) for (Entry = HashTable->HashTable[Count]; Entry != NULL; Entry = NextEntry)
{ {
NextEntry = Entry->Next; NextEntry = Entry->Next;
Val = Entry->p.v.Val; VariableFree(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);
}
/* free the hash table entry */ /* free the hash table entry */
HeapFree(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); 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) void VariableDefine(struct ParseState *Parser, char *Ident, struct Value *InitValue)
{ {
if (!TableSet((TopStackFrame == NULL) ? &GlobalTable : &TopStackFrame->LocalTable, Ident, VariableAllocValueAndCopy(Parser, InitValue, TopStackFrame == NULL))) if (!TableSet((TopStackFrame == NULL) ? &GlobalTable : &TopStackFrame->LocalTable, Ident, VariableAllocValueAndCopy(Parser, InitValue, TopStackFrame == NULL)))
ProgramFail(Parser, "'%s' is already defined", Ident); 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) int VariableDefined(const char *Ident)
{ {
struct Value *FoundValue; struct Value *FoundValue;
@ -161,7 +165,7 @@ int VariableDefined(const char *Ident)
return TRUE; 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) void VariableGet(struct ParseState *Parser, const char *Ident, struct Value **LVal)
{ {
if (TopStackFrame == NULL || !TableGet(&TopStackFrame->LocalTable, Ident, 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) 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); struct Value *SomeValue = VariableAllocValueAndData(NULL, (Typ->Base == TypeArray) ? sizeof(struct ArrayValue) : 0, IsWritable, NULL, TRUE);