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
|
* 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
1
lex.c
|
@ -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
16
parse.c
|
@ -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;
|
||||||
|
|
4
picoc.h
4
picoc.h
|
@ -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
19
table.c
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
42
variable.c
42
variable.c
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue