OSDN Git Service

- Fixed: Inside an ACS library, you could not use a normal #define to specify
authorRandy Heit <rheit@zdoom.fake>
Thu, 3 Aug 2006 03:45:26 +0000 (03:45 +0000)
committerRandy Heit <rheit@zdoom.fake>
Thu, 3 Aug 2006 03:45:26 +0000 (03:45 +0000)
  the size of an array. Now #defines are fully processed inside an import but
  are forgotten when the import is popped if they weren't created with
  #libdefine.

SVN r280 (trunk)

Makefile
parse.c
symbol.c
symbol.h
token.c
token.h

index 3bb2acc..62e92e9 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -16,9 +16,9 @@ EXENAME = acc
 endif\r
 endif\r
 \r
-CFLAGS = -Os -Wall -W -march=pentium -mtune=athlon-4 -fomit-frame-pointer\r
+CFLAGS = -Os -Wall -W -fomit-frame-pointer\r
 LDFLAGS = -s\r
-VERNUM = 137\r
+VERNUM = 142\r
 \r
 OBJS = \\r
        acc.o     \\r
diff --git a/parse.c b/parse.c
index 06c7a14..045ecce 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -1169,23 +1169,22 @@ static void OuterDefine(boolean force)
        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
index d61f4f9..aaa0cfd 100644 (file)
--- a/symbol.c
+++ b/symbol.c
@@ -40,6 +40,8 @@ static symbolNode_t *Find(char *name, symbolNode_t *root);
 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
@@ -450,6 +452,98 @@ static void FreeNodes(symbolNode_t *root)
 \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
index 1fc786d..bac169e 100644 (file)
--- a/symbol.h
+++ b/symbol.h
@@ -64,6 +64,7 @@ typedef struct
 typedef struct\r
 {\r
        int value;\r
+       int fileDepth;\r
 } symConstant_t;\r
 \r
 typedef struct\r
@@ -120,6 +121,7 @@ symbolNode_t *SY_InsertGlobal(char *name, symbolType_t type);
 symbolNode_t *SY_InsertGlobalUnique(char *name, symbolType_t type);\r
 void SY_FreeLocals(void);\r
 void SY_FreeGlobals(void);\r
+void SY_FreeConstants(int depth);\r
 void SY_ClearShared(void);\r
 \r
 // PUBLIC DATA DECLARATIONS ------------------------------------------------\r
diff --git a/token.c b/token.c
index e0b3590..0864a92 100644 (file)
--- a/token.c
+++ b/token.c
@@ -382,6 +382,7 @@ static int PopNestedSource(enum ImportModes *prevMode)
 \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
@@ -420,6 +421,17 @@ void TK_CloseSource(void)
 \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
diff --git a/token.h b/token.h
index 122c58a..ec9eba4 100644 (file)
--- a/token.h
+++ b/token.h
@@ -136,6 +136,7 @@ void TK_OpenSource(char *fileName);
 void TK_Include(char *fileName);\r
 void TK_Import(char *fileName, enum ImportModes prevMode);\r
 void TK_CloseSource(void);\r
+int TK_GetDepth(void);\r
 tokenType_t TK_NextToken(void);\r
 int TK_NextCharacter(void);\r
 boolean TK_NextTokenMustBe(tokenType_t token, error_t error);\r