/* deallocate any memory */ void ParseCleanup(Picoc *pc) { while (pc->CleanupTokenList != NULL) { struct CleanupTokenNode *Next = pc->CleanupTokenList->Next; HeapFreeMem(pc, pc->CleanupTokenList->Tokens); if (pc->CleanupTokenList->SourceText != NULL) HeapFreeMem(pc, (void *)pc->CleanupTokenList->SourceText); HeapFreeMem(pc, pc->CleanupTokenList); pc->CleanupTokenList = Next; } }
/* deallocate any memory */ void ParseCleanup() { while (CleanupTokenList != NULL) { struct CleanupTokenNode *Next = CleanupTokenList->Next; HeapFreeMem(CleanupTokenList->Tokens); if (CleanupTokenList->SourceText != NULL) HeapFreeMem((void *)CleanupTokenList->SourceText); HeapFreeMem(CleanupTokenList); CleanupTokenList = Next; } }
/* indicate that we've completed up to this point in the interactive input and free expired tokens */ void LexInteractiveClear(struct ParseState *Parser) { while (InteractiveHead != NULL) { struct TokenLine *NextLine = InteractiveHead->Next; HeapFreeMem(InteractiveHead->Tokens); HeapFreeMem(InteractiveHead); InteractiveHead = NextLine; } if (Parser != NULL) Parser->Pos = NULL; InteractiveTail = NULL; }
/* indicate that we've completed up to this point in the interactive input and free expired tokens */ void LexInteractiveClear(Picoc *pc, struct ParseState *Parser) { while (pc->InteractiveHead != NULL) { struct TokenLine *NextLine = pc->InteractiveHead->Next; HeapFreeMem(pc, pc->InteractiveHead->Tokens); HeapFreeMem(pc, pc->InteractiveHead); pc->InteractiveHead = NextLine; } if (Parser != NULL) Parser->Pos = NULL; pc->InteractiveTail = 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 && Val->Val->FuncDef.Body.Pos != NULL) HeapFreeMem((void *)Val->Val->FuncDef.Body.Pos); /* free macro bodies */ if (Val->Typ == &MacroType) HeapFreeMem((void *)Val->Val->MacroDef.Body.Pos); /* free the value */ HeapFreeMem(Val); } }
/* deallocate heap-allocated types */ void TypeCleanupNode(Picoc *pc, struct ValueType *Typ){ struct ValueType *SubType; struct ValueType *NextSubType; /* clean up and free all the sub-nodes */ for (SubType = Typ->DerivedTypeList; SubType; SubType = NextSubType){ NextSubType = SubType->Next; TypeCleanupNode(pc, SubType); if (SubType->OnHeap){ /* if it's a struct or union deallocate all the member values */ if (SubType->Members != NULL){ VariableTableCleanup(pc, SubType->Members); HeapFreeMem(pc, SubType->Members); } /* free this node */ HeapFreeMem(pc, SubType); } } }
/* indicate that we've completed up to this point in the interactive input and free expired tokens */ void LexInteractiveCompleted(struct ParseState *Parser) { while (InteractiveHead != NULL && !(Parser->Pos >= &InteractiveHead->Tokens[0] && Parser->Pos < &InteractiveHead->Tokens[InteractiveHead->NumBytes])) { /* this token line is no longer needed - free it */ struct TokenLine *NextLine = InteractiveHead->Next; HeapFreeMem(InteractiveHead->Tokens); HeapFreeMem(InteractiveHead); InteractiveHead = NextLine; if (InteractiveHead == NULL) { /* we've emptied the list */ Parser->Pos = NULL; InteractiveTail = NULL; } } }
/* clean up space used by the include system */ void IncludeCleanup(Picoc *pc){ struct IncludeLibrary *ThisInclude = pc->IncludeLibList; struct IncludeLibrary *NextInclude; while (ThisInclude != NULL){ NextInclude = ThisInclude->NextLib; HeapFreeMem(pc, ThisInclude); ThisInclude = NextInclude; } pc->IncludeLibList = NULL; }
/* free all the strings */ void TableStrFree(Picoc *pc){ struct TableEntry *Entry; struct TableEntry *NextEntry; int Count; for (Count = 0; Count < pc->StringTable.Size; Count++){ for (Entry = pc->StringTable.HashTable[Count]; Entry != NULL; Entry = NextEntry){ NextEntry = Entry->Next; HeapFreeMem(pc, Entry); } } }
/* free the contents of the breakpoint table */ void DebugCleanup(Picoc *pc) { struct TableEntry *Entry; struct TableEntry *NextEntry; int Count; for (Count = 0; Count < pc->BreakpointTable.Size; Count++) { for (Entry = pc->BreakpointHashTable[Count]; Entry != NULL; Entry = NextEntry) { NextEntry = Entry->Next; HeapFreeMem(pc, Entry); } } }
/* remove an entry from the table */ struct Value *TableDelete(Picoc *pc, 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 TableEntry *DeleteEntry = *EntryPtr; struct Value *Val = DeleteEntry->p.v.Val; *EntryPtr = DeleteEntry->Next; HeapFreeMem(pc, DeleteEntry); return Val; } } return NULL; }
/* clean up space used by the include system */ void IncludeCleanup() { struct IncludeLibrary *ThisInclude = IncludeLibList; struct IncludeLibrary *NextInclude; while (ThisInclude != NULL) { NextInclude = ThisInclude->NextLib; HeapFreeMem(ThisInclude); ThisInclude = NextInclude; } IncludeLibList = NULL; }
/* 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 */ HeapFreeMem(Entry); } } }
/* add a library */ void LibraryAdd(Picoc *pc, struct Table *GlobalTable, const char *LibraryName, struct LibraryFunction *FuncList) { struct ParseState Parser; int Count; char *Identifier; struct ValueType *ReturnType; struct Value *NewValue; void *Tokens; char *IntrinsicName = TableStrRegister(pc, "c library"); /* read all the library definitions */ for (Count = 0; FuncList[Count].Prototype != NULL; Count++) { Tokens = LexAnalyse(pc, IntrinsicName, FuncList[Count].Prototype, strlen((char *)FuncList[Count].Prototype), NULL); LexInitParser(&Parser, pc, FuncList[Count].Prototype, Tokens, IntrinsicName, TRUE, FALSE); TypeParse(&Parser, &ReturnType, &Identifier, NULL); NewValue = ParseFunctionDefinition(&Parser, ReturnType, Identifier); NewValue->Val->FuncDef.Intrinsic = FuncList[Count].Func; HeapFreeMem(pc, Tokens); } }
/* delete a breakpoint from the hash table */ int DebugClearBreakpoint(struct ParseState *Parser) { struct TableEntry **EntryPtr; int HashValue = BREAKPOINT_HASH(Parser) % BreakpointTable.Size; for (EntryPtr = &BreakpointHashTable[HashValue]; *EntryPtr != NULL; EntryPtr = &(*EntryPtr)->Next) { struct TableEntry *DeleteEntry = *EntryPtr; if (DeleteEntry->p.b.FileName == Parser->FileName && DeleteEntry->p.b.Line == Parser->Line && DeleteEntry->p.b.CharacterPos == Parser->CharacterPos) { *EntryPtr = DeleteEntry->Next; HeapFreeMem(DeleteEntry); BreakpointCount--; return TRUE; } } return FALSE; }
/* quick scan a source file for definitions */ void PicocParse(Picoc *pc, const char *FileName, const char *Source, int SourceLen, int RunIt, int CleanupNow, int CleanupSource, int EnableDebugger) { struct ParseState Parser; enum ParseResult Ok; struct CleanupTokenNode *NewCleanupNode; char *RegFileName = TableStrRegister(pc, FileName); void *Tokens = LexAnalyse(pc, RegFileName, Source, SourceLen, NULL); /* allocate a cleanup node so we can clean up the tokens later */ if (!CleanupNow) { NewCleanupNode = (struct CleanupTokenNode *) HeapCallocMem(pc, sizeof(struct CleanupTokenNode)); if (NewCleanupNode == NULL) ProgramFailNoParser(pc, "out of memory"); NewCleanupNode->Tokens = Tokens; if (CleanupSource) NewCleanupNode->SourceText = Source; else NewCleanupNode->SourceText = NULL; NewCleanupNode->Next = pc->CleanupTokenList; pc->CleanupTokenList = NewCleanupNode; } /* do the parsing */ LexInitParser(&Parser, pc, Source, Tokens, RegFileName, RunIt, EnableDebugger); do { Ok = ParseStatement(&Parser, TRUE); } while (Ok == ParseResultOk); if (Ok == ParseResultError) ProgramFail(&Parser, "parse error"); /* clean up */ if (CleanupNow) HeapFreeMem(pc, Tokens); }
/* quick scan a source file for definitions */ void PicocParse(const char *FileName, const char *Source, int SourceLen, int RunIt, int CleanupNow, int CleanupSource) { // printf("in PicocParse function after IncludeFile %s\n",FileName); struct ParseState Parser; enum ParseResult Ok; struct CleanupTokenNode *NewCleanupNode; void *Tokens = LexAnalyse(FileName, Source, SourceLen, NULL); /* allocate a cleanup node so we can clean up the tokens later */ if (!CleanupNow) { NewCleanupNode = HeapAllocMem(sizeof(struct CleanupTokenNode)); if (NewCleanupNode == NULL) ProgramFail(NULL, "out of memory"); NewCleanupNode->Tokens = Tokens; if (CleanupSource) NewCleanupNode->SourceText = Source; else NewCleanupNode->SourceText = NULL; NewCleanupNode->Next = CleanupTokenList; CleanupTokenList = NewCleanupNode; } /* do the parsing */ LexInitParser(&Parser, Source, Tokens, FileName, RunIt); do { Ok = ParseStatement(&Parser, TRUE); } while (Ok == ParseResultOk); if (Ok == ParseResultError) ProgramFail(&Parser, "parse error"); /* clean up */ if (CleanupNow) HeapFreeMem(Tokens); }
/* free and/or pop the top value off the stack. Var must be the top value on the stack! */ void VariableStackPop(struct ParseState *Parser, struct Value *Var) { int Success; #ifdef DEBUG_HEAP if (Var->ValOnStack) printf("popping %ld at 0x%lx\n", (unsigned long)(sizeof(struct Value) + TypeSizeValue(Var, FALSE)), (unsigned long)Var); #endif if (Var->ValOnHeap) { if (Var->Val != NULL) HeapFreeMem(Var->Val); Success = HeapPopStack(Var, sizeof(struct Value)); /* free from heap */ } else if (Var->ValOnStack) Success = HeapPopStack(Var, sizeof(struct Value) + TypeSizeValue(Var, FALSE)); /* free from stack */ else Success = HeapPopStack(Var, sizeof(struct Value)); /* value isn't our problem */ if (!Success) ProgramFail(Parser, "stack underrun"); }