From a96324456a01237c445608d2bbddc7a8f60ec4f6 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 3 Aug 2006 03:45:26 +0000 Subject: [PATCH] - Fixed: Inside an ACS library, you could not use a normal #define to specify 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 | 4 +-- parse.c | 23 +++++++------- symbol.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ symbol.h | 2 ++ token.c | 12 ++++++++ token.h | 1 + 6 files changed, 122 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index 3bb2acc..62e92e9 100644 --- a/Makefile +++ b/Makefile @@ -16,9 +16,9 @@ EXENAME = acc endif endif -CFLAGS = -Os -Wall -W -march=pentium -mtune=athlon-4 -fomit-frame-pointer +CFLAGS = -Os -Wall -W -fomit-frame-pointer LDFLAGS = -s -VERNUM = 137 +VERNUM = 142 OBJS = \ acc.o \ diff --git a/parse.c b/parse.c index 06c7a14..045ecce 100644 --- a/parse.c +++ b/parse.c @@ -1169,23 +1169,22 @@ static void OuterDefine(boolean force) int value; symbolNode_t *sym; - // Don't define inside an import + MS_Message(MSG_DEBUG, "---- OuterDefine %s----\n", + force ? "(forced) " : ""); + TK_NextTokenMustBe(TK_IDENTIFIER, ERR_INVALID_IDENTIFIER); + sym = SY_InsertGlobalUnique(tk_String, SY_CONSTANT); + TK_NextToken(); + value = EvalConstExpression(); + MS_Message(MSG_DEBUG, "Constant value: %d\n", value); + sym->info.constant.value = value; + // Defines inside an import are deleted when the import is popped. if(ImportMode != IMPORT_Importing || force) { - MS_Message(MSG_DEBUG, "---- OuterDefine %s----\n", - force ? "(forced) " : ""); - TK_NextTokenMustBe(TK_IDENTIFIER, ERR_INVALID_IDENTIFIER); - sym = SY_InsertGlobalUnique(tk_String, SY_CONSTANT); - TK_NextToken(); - value = EvalConstExpression(); - MS_Message(MSG_DEBUG, "Constant value: %d\n", value); - sym->info.constant.value = value; + sym->info.constant.fileDepth = 0; } else { - TK_NextToken(); - TK_NextToken(); - EvalConstExpression(); + sym->info.constant.fileDepth = TK_GetDepth(); } } diff --git a/symbol.c b/symbol.c index d61f4f9..aaa0cfd 100644 --- 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, symbolNode_t **root); static void FreeNodes(symbolNode_t *root); +static void FreeNodesAtDepth(symbolNode_t **root, int depth); +static void DeleteNode(symbolNode_t *node, symbolNode_t **parent_p); static void ClearShared(symbolNode_t *root); // EXTERNAL DATA DECLARATIONS ---------------------------------------------- @@ -448,6 +450,98 @@ static void FreeNodes(symbolNode_t *root) free(root); } +//========================================================================== +// +// SY_FreeConstants +// +//========================================================================== + +void SY_FreeConstants(int depth) +{ + MS_Message(MSG_DEBUG, "Freeing constants for depth %d\n", depth); + FreeNodesAtDepth(&GlobalRoot, depth); +} + +//========================================================================== +// +// FreeNodesAtDepth +// +// Like FreeNodes, but it only frees the nodes of type SY_CONSTANT that are +// marked at the specified depth. The other nodes are relinked to maintain a +// proper binary tree. +// +//========================================================================== + +static void FreeNodesAtDepth(symbolNode_t **root, int depth) +{ + symbolNode_t *node = *root; + + if(node == NULL) + { + return; + } + FreeNodesAtDepth(&node->left, depth); + FreeNodesAtDepth(&node->right, depth); + if(node->type == SY_CONSTANT && node->info.constant.fileDepth == depth) + { + MS_Message(MSG_DEBUG, "Deleting constant %s\n", node->name); + DeleteNode(node, root); + } +} + +//========================================================================== +// +// DeleteNode +// +//========================================================================== + +static void DeleteNode(symbolNode_t *node, symbolNode_t **parent_p) +{ + symbolNode_t **temp; + + if(node->left == NULL) + { + *parent_p = node->right; + free(node->name); + free(node); + } + else if(node->right == NULL) + { + *parent_p = node->left; + free(node->name); + free(node); + } + else + { + // "Randomly" pick the in-order successor or predecessor to take + // the place of the deleted node. + if(rand() & 1) + { + // predecessor + temp = &node->left; + while((*temp)->right != NULL) + { + temp = &(*temp)->right; + } + } + else + { + // successor + temp = &node->right; + while((*temp)->left != NULL) + { + temp = &(*temp)->left; + } + } + node->name = (*temp)->name; + node->type = (*temp)->type; + node->unused = (*temp)->unused; + node->imported = (*temp)->imported; + node->info = (*temp)->info; + DeleteNode(*temp, temp); + } +} + //========================================================================== // // SY_ClearShared diff --git a/symbol.h b/symbol.h index 1fc786d..bac169e 100644 --- a/symbol.h +++ b/symbol.h @@ -64,6 +64,7 @@ typedef struct typedef struct { int value; + int fileDepth; } symConstant_t; typedef struct @@ -120,6 +121,7 @@ symbolNode_t *SY_InsertGlobal(char *name, symbolType_t type); symbolNode_t *SY_InsertGlobalUnique(char *name, symbolType_t type); void SY_FreeLocals(void); void SY_FreeGlobals(void); +void SY_FreeConstants(int depth); void SY_ClearShared(void); // PUBLIC DATA DECLARATIONS ------------------------------------------------ diff --git a/token.c b/token.c index e0b3590..0864a92 100644 --- a/token.c +++ b/token.c @@ -382,6 +382,7 @@ static int PopNestedSource(enum ImportModes *prevMode) MS_Message(MSG_DEBUG, "*Leaving %s\n", tk_SourceName); free(FileStart); + SY_FreeConstants(NestDepth); tk_IncludedLines += tk_Line; info = &OpenFiles[--NestDepth]; tk_SourceName = info->name; @@ -418,6 +419,17 @@ void TK_CloseSource(void) } } +//========================================================================== +// +// TK_GetDepth +// +//========================================================================== + +int TK_GetDepth(void) +{ + return NestDepth; +} + //========================================================================== // // TK_NextToken diff --git a/token.h b/token.h index 122c58a..ec9eba4 100644 --- a/token.h +++ b/token.h @@ -136,6 +136,7 @@ void TK_OpenSource(char *fileName); void TK_Include(char *fileName); void TK_Import(char *fileName, enum ImportModes prevMode); void TK_CloseSource(void); +int TK_GetDepth(void); tokenType_t TK_NextToken(void); int TK_NextCharacter(void); boolean TK_NextTokenMustBe(tokenType_t token, error_t error);