int value;\r
symbolNode_t *sym;\r
\r
- // Don't define inside an import\r
+ MS_Message(MSG_DEBUG, "---- OuterDefine %s----\n",\r
+ force ? "(forced) " : "");\r
+ TK_NextTokenMustBe(TK_IDENTIFIER, ERR_INVALID_IDENTIFIER);\r
+ sym = SY_InsertGlobalUnique(tk_String, SY_CONSTANT);\r
+ TK_NextToken();\r
+ value = EvalConstExpression();\r
+ MS_Message(MSG_DEBUG, "Constant value: %d\n", value);\r
+ sym->info.constant.value = value;\r
+ // Defines inside an import are deleted when the import is popped.\r
if(ImportMode != IMPORT_Importing || force)\r
{\r
- MS_Message(MSG_DEBUG, "---- OuterDefine %s----\n",\r
- force ? "(forced) " : "");\r
- TK_NextTokenMustBe(TK_IDENTIFIER, ERR_INVALID_IDENTIFIER);\r
- sym = SY_InsertGlobalUnique(tk_String, SY_CONSTANT);\r
- TK_NextToken();\r
- value = EvalConstExpression();\r
- MS_Message(MSG_DEBUG, "Constant value: %d\n", value);\r
- sym->info.constant.value = value;\r
+ sym->info.constant.fileDepth = 0;\r
}\r
else\r
{\r
- TK_NextToken();\r
- TK_NextToken();\r
- EvalConstExpression();\r
+ sym->info.constant.fileDepth = TK_GetDepth();\r
}\r
}\r
\r
static symbolNode_t *Insert(char *name, symbolType_t type,\r
symbolNode_t **root);\r
static void FreeNodes(symbolNode_t *root);\r
+static void FreeNodesAtDepth(symbolNode_t **root, int depth);\r
+static void DeleteNode(symbolNode_t *node, symbolNode_t **parent_p);\r
static void ClearShared(symbolNode_t *root);\r
\r
// EXTERNAL DATA DECLARATIONS ----------------------------------------------\r
\r
//==========================================================================\r
//\r
+// SY_FreeConstants\r
+//\r
+//==========================================================================\r
+\r
+void SY_FreeConstants(int depth)\r
+{\r
+ MS_Message(MSG_DEBUG, "Freeing constants for depth %d\n", depth);\r
+ FreeNodesAtDepth(&GlobalRoot, depth);\r
+}\r
+\r
+//==========================================================================\r
+//\r
+// FreeNodesAtDepth\r
+//\r
+// Like FreeNodes, but it only frees the nodes of type SY_CONSTANT that are\r
+// marked at the specified depth. The other nodes are relinked to maintain a\r
+// proper binary tree.\r
+//\r
+//==========================================================================\r
+\r
+static void FreeNodesAtDepth(symbolNode_t **root, int depth)\r
+{\r
+ symbolNode_t *node = *root;\r
+\r
+ if(node == NULL)\r
+ {\r
+ return;\r
+ }\r
+ FreeNodesAtDepth(&node->left, depth);\r
+ FreeNodesAtDepth(&node->right, depth);\r
+ if(node->type == SY_CONSTANT && node->info.constant.fileDepth == depth)\r
+ {\r
+ MS_Message(MSG_DEBUG, "Deleting constant %s\n", node->name);\r
+ DeleteNode(node, root);\r
+ }\r
+}\r
+\r
+//==========================================================================\r
+//\r
+// DeleteNode\r
+//\r
+//==========================================================================\r
+\r
+static void DeleteNode(symbolNode_t *node, symbolNode_t **parent_p)\r
+{\r
+ symbolNode_t **temp;\r
+\r
+ if(node->left == NULL)\r
+ {\r
+ *parent_p = node->right;\r
+ free(node->name);\r
+ free(node);\r
+ }\r
+ else if(node->right == NULL)\r
+ {\r
+ *parent_p = node->left;\r
+ free(node->name);\r
+ free(node);\r
+ }\r
+ else\r
+ {\r
+ // "Randomly" pick the in-order successor or predecessor to take\r
+ // the place of the deleted node.\r
+ if(rand() & 1)\r
+ {\r
+ // predecessor\r
+ temp = &node->left;\r
+ while((*temp)->right != NULL)\r
+ {\r
+ temp = &(*temp)->right;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ // successor\r
+ temp = &node->right;\r
+ while((*temp)->left != NULL)\r
+ {\r
+ temp = &(*temp)->left;\r
+ }\r
+ }\r
+ node->name = (*temp)->name;\r
+ node->type = (*temp)->type;\r
+ node->unused = (*temp)->unused;\r
+ node->imported = (*temp)->imported;\r
+ node->info = (*temp)->info;\r
+ DeleteNode(*temp, temp);\r
+ }\r
+}\r
+\r
+//==========================================================================\r
+//\r
// SY_ClearShared\r
//\r
//==========================================================================\r
\r
MS_Message(MSG_DEBUG, "*Leaving %s\n", tk_SourceName);\r
free(FileStart);\r
+ SY_FreeConstants(NestDepth);\r
tk_IncludedLines += tk_Line;\r
info = &OpenFiles[--NestDepth];\r
tk_SourceName = info->name;\r
\r
//==========================================================================\r
//\r
+// TK_GetDepth\r
+//\r
+//==========================================================================\r
+\r
+int TK_GetDepth(void)\r
+{\r
+ return NestDepth;\r
+}\r
+\r
+//==========================================================================\r
+//\r
// TK_NextToken\r
//\r
//==========================================================================\r