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:
parent
a414de85e5
commit
ce80c66e8f
1
TODO
1
TODO
|
@ -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
1
lex.c
|
@ -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
16
parse.c
|
@ -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:
|
||||
|
@ -468,6 +466,18 @@ int ParseStatement(struct ParseState *Parser)
|
|||
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;
|
||||
|
|
4
picoc.h
4
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,
|
||||
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
19
table.c
|
@ -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)
|
||||
{
|
||||
|
|
38
variable.c
38
variable.c
|
@ -20,20 +20,9 @@ void VariableInit()
|
|||
TopStackFrame = NULL;
|
||||
}
|
||||
|
||||
/* deallocate the global table and the string literal table */
|
||||
void VariableTableCleanup(struct Table *HashTable)
|
||||
/* deallocate the contents of a variable */
|
||||
void VariableFree(struct Value *Val)
|
||||
{
|
||||
struct TableEntry *Entry;
|
||||
struct TableEntry *NextEntry;
|
||||
struct Value *Val;
|
||||
int Count;
|
||||
|
||||
for (Count = 0; Count < HashTable->Size; Count++)
|
||||
{
|
||||
for (Entry = HashTable->HashTable[Count]; Entry != NULL; Entry = NextEntry)
|
||||
{
|
||||
NextEntry = Entry->Next;
|
||||
Val = Entry->p.v.Val;
|
||||
if (Val->ValOnHeap)
|
||||
{
|
||||
/* free function bodies */
|
||||
|
@ -47,6 +36,21 @@ void VariableTableCleanup(struct Table *HashTable)
|
|||
/* 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;
|
||||
int Count;
|
||||
|
||||
for (Count = 0; Count < HashTable->Size; Count++)
|
||||
{
|
||||
for (Entry = HashTable->HashTable[Count]; Entry != NULL; Entry = NextEntry)
|
||||
{
|
||||
NextEntry = Entry->Next;
|
||||
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);
|
||||
|
|
Loading…
Reference in a new issue