]> granicus.if.org Git - yasm/commitdiff
Used ternary search tree instead of linked list to store symbol table.
authorPeter Johnson <peter@tortall.net>
Mon, 24 Sep 2001 06:40:27 +0000 (06:40 -0000)
committerPeter Johnson <peter@tortall.net>
Mon, 24 Sep 2001 06:40:27 +0000 (06:40 -0000)
Cleaned up function naming too.
Removed locallabel_base from global.h, moving it into the parser-specific code.
Made sym_table private to symrec.c.

svn path=/trunk/yasm/; revision=220

13 files changed:
libyasm/linemgr.h
libyasm/symrec.c
libyasm/symrec.h
modules/parsers/nasm/bison.y.in
modules/parsers/nasm/nasm-bison.y
modules/parsers/nasm/token.l.in
src/globals.h
src/linemgr.h
src/parsers/nasm/bison.y.in
src/parsers/nasm/nasm-bison.y
src/parsers/nasm/token.l.in
src/symrec.c
src/symrec.h

index a836dfd983264b5cde28c397b4804a20fc8b9903..1d6716e02e2fd152cd2b110005c0bdc76e4af2ee 100644 (file)
@@ -25,6 +25,5 @@
 extern char *filename;
 extern unsigned int line_number;
 extern unsigned char mode_bits;
-extern struct symrec_s *locallabel_base;
 
 #endif
index 8de9f81ee409bae0d97362527ddaffd0b36680a1..779e03a1c525188000503c7341b60416acf1e23e 100644 (file)
 RCSID("$IdPath$");
 
 /* private functions */
-static symtab *symtab_get(char *);
-static symtab *symtab_new(char *, SymType);
-static symtab *symtab_get_or_new(char *, SymType);
-static void symtab_insert(symtab *);
+static symrec *symrec_get_or_new(char *, SymType);
 
-/* The symbol table: a chain of `symtab'. */
-symtab *sym_table = (symtab *)NULL;
+/* The symbol table: a ternary tree. */
+static ternary_tree sym_table = (ternary_tree)NULL;
 
-/* insert a symtab into the global sym_table */
-void
-symtab_insert(symtab *tab)
-{
-    tab->next = (symtab *)sym_table;
-    sym_table = tab;
-}
-
-/* find a symtab in the global sym_table */
-symtab *
-symtab_get(char *name)
+/* create a new symrec */
+static symrec *
+symrec_get_or_new(char *name, SymType type)
 {
-    symtab *tab;
+    symrec *rec, *rec2;
 
-    for (tab = sym_table; tab != NULL; tab = tab->next) {
-       if (strcmp(tab->rec.name, name) == 0) {
-           return tab;
-       }
-    }
-    return NULL;
-}
+    rec = malloc(sizeof(symrec));
+    if (!rec)
+       Fatal(FATAL_NOMEM);
 
-/* call a function with each symrec.  stop early if 0 returned */
-void
-sym_foreach(int (*mapfunc) (symrec *))
-{
-    symtab *tab;
+    rec2 = ternary_insert(&sym_table, name, rec, 0);
 
-    for (tab = sym_table; tab != NULL; tab = tab->next) {
-       if (mapfunc(&(tab->rec)) == 0) {
-           return;
-       }
+    if (rec2 != rec) {
+       free(rec);
+       return rec2;
     }
-}
 
-/* create a new symtab */
-symtab *
-symtab_new(char *name, SymType type)
-{
-    symtab *tab;
-    tab = malloc(sizeof(symtab));
-    if (tab == NULL)
-       return NULL;
-    tab->rec.name = malloc(strlen(name) + 1);
-    if (tab->rec.name == NULL) {
-       free(tab);
-       return NULL;
-    }
-    strcpy(tab->rec.name, name);
-    tab->rec.type = type;
-    tab->rec.value = 0;
-    tab->rec.line = line_number;
-    tab->rec.status = SYM_NOSTATUS;
-    symtab_insert(tab);
-    return tab;
+    rec->name = strdup(name);
+    if (!rec->name)
+       Fatal(FATAL_NOMEM);
+    rec->type = type;
+    rec->value = 0;
+    rec->line = line_number;
+    rec->status = SYM_NOSTATUS;
+
+    return rec;
 }
 
-symtab *
-symtab_get_or_new(char *name, SymType type)
+/* call a function with each symrec.  stop early if 0 returned */
+void
+symrec_foreach(int (*func) (char *name, symrec *rec))
 {
-    symtab *tab;
-
-    tab = symtab_get(name);
-    if (tab == NULL) {
-       tab = symtab_new(name, type);
-       if (tab == NULL) {
-           Fatal(FATAL_NOMEM);
-       }
-    }
-    return tab;
 }
 
 symrec *
-sym_use_get(char *name, SymType type)
+symrec_use(char *name, SymType type)
 {
-    symtab *tab;
+    symrec *rec;
 
-    tab = symtab_get_or_new(name, type);
-    tab->rec.status |= SYM_USED;
-    return &(tab->rec);
+    rec = symrec_get_or_new(name, type);
+    rec->status |= SYM_USED;
+    return rec;
 }
 
 symrec *
-sym_def_get(char *name, SymType type)
+symrec_define(char *name, SymType type)
 {
-    symtab *tab;
+    symrec *rec;
 
-    tab = symtab_get_or_new(name, type);
-    if (tab->rec.status & SYM_DECLARED)
+    rec = symrec_get_or_new(name, type);
+    if (rec->status & SYM_DECLARED)
        Error(_("duplicate definition of `%s'; previously defined on line %d"),
-             tab->rec.name, tab->rec.line);
-    tab->rec.status |= SYM_DECLARED;
-    return &(tab->rec);
+             name, rec->line);
+    rec->line = line_number;   /* set line number of definition */
+    rec->status |= SYM_DECLARED;
+    return rec;
 }
index a31fe7e211789b9afe478ac2764db9aad67fd7b1..936c67284435ddda931208d8315ba771ee2e903c 100644 (file)
@@ -38,19 +38,12 @@ typedef struct symrec_s {
     char *name;
     SymType type;
     SymStatus status;
-    int line;
+    int line;                  /* line symbol was first declared or used on */
     double value;
 } symrec;
 
-typedef struct symtab_s {
-    symrec rec;
-    struct symtab_s *next;
-} symtab;
-
-extern symtab *sym_table;
-
-symrec *sym_use_get(char *, SymType);
-symrec *sym_def_get(char *, SymType);
-void sym_foreach(int (*)(symrec *));
+symrec *symrec_use(char *name, SymType type);
+symrec *symrec_define(char *name, SymType type);
+void symrec_foreach(int (*func) (char *name, symrec *rec));
 
 #endif
index d3eee5ac7b6864a92d755e785ae698e4c1f156b1..25cd0dee805824470056c33200a50cd932715569 100644 (file)
@@ -56,6 +56,7 @@ void nasm_parser_error(char *);
 extern objfmt *nasm_parser_objfmt;
 extern sectionhead nasm_parser_sections;
 extern section *nasm_parser_cur_section;
+extern char *nasm_parser_locallabel_base;
 
 %}
 
@@ -176,9 +177,12 @@ label: label_id        { $1->value = 0; } /* TODO: add pointer to bytecode */
     | label_id ':'  { $1->value = 0; } /* TODO: add pointer to bytecode */
 ;
 
-label_id: ID       { $$ = locallabel_base = sym_def_get($1.name, SYM_LABEL); }
-    | SPECIAL_ID    { $$ = sym_def_get($1.name, SYM_LABEL); }
-    | LOCAL_ID     { $$ = sym_def_get($1.name, SYM_LABEL); }
+label_id: ID       {
+       $$ = symrec_define($1.name, SYM_LABEL);
+       nasm_parser_locallabel_base = strdup($1.name);
+    }
+    | SPECIAL_ID    { $$ = symrec_define($1.name, SYM_LABEL); }
+    | LOCAL_ID     { $$ = symrec_define($1.name, SYM_LABEL); }
 ;
 
 /* directives */
@@ -375,8 +379,7 @@ target: expr            { $$.val = $1; $$.op_sel = JR_NONE; }
 /* expression trees */
 expr_no_string: INTNUM         { $$ = expr_new_ident(EXPR_NUM, ExprNum($1)); }
     | explabel                 {
-       $$ = expr_new_ident(EXPR_SYM,
-                           ExprSym(sym_use_get($1.name, SYM_LABEL)));
+       $$ = expr_new_ident(EXPR_SYM, ExprSym(symrec_use($1.name, SYM_LABEL)));
     }
     /*| expr '||' expr         { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/
     | expr '|' expr            { $$ = expr_new_tree($1, EXPR_OR, $3); }
index d3eee5ac7b6864a92d755e785ae698e4c1f156b1..25cd0dee805824470056c33200a50cd932715569 100644 (file)
@@ -56,6 +56,7 @@ void nasm_parser_error(char *);
 extern objfmt *nasm_parser_objfmt;
 extern sectionhead nasm_parser_sections;
 extern section *nasm_parser_cur_section;
+extern char *nasm_parser_locallabel_base;
 
 %}
 
@@ -176,9 +177,12 @@ label: label_id        { $1->value = 0; } /* TODO: add pointer to bytecode */
     | label_id ':'  { $1->value = 0; } /* TODO: add pointer to bytecode */
 ;
 
-label_id: ID       { $$ = locallabel_base = sym_def_get($1.name, SYM_LABEL); }
-    | SPECIAL_ID    { $$ = sym_def_get($1.name, SYM_LABEL); }
-    | LOCAL_ID     { $$ = sym_def_get($1.name, SYM_LABEL); }
+label_id: ID       {
+       $$ = symrec_define($1.name, SYM_LABEL);
+       nasm_parser_locallabel_base = strdup($1.name);
+    }
+    | SPECIAL_ID    { $$ = symrec_define($1.name, SYM_LABEL); }
+    | LOCAL_ID     { $$ = symrec_define($1.name, SYM_LABEL); }
 ;
 
 /* directives */
@@ -375,8 +379,7 @@ target: expr            { $$.val = $1; $$.op_sel = JR_NONE; }
 /* expression trees */
 expr_no_string: INTNUM         { $$ = expr_new_ident(EXPR_NUM, ExprNum($1)); }
     | explabel                 {
-       $$ = expr_new_ident(EXPR_SYM,
-                           ExprSym(sym_use_get($1.name, SYM_LABEL)));
+       $$ = expr_new_ident(EXPR_SYM, ExprSym(symrec_use($1.name, SYM_LABEL)));
     }
     /*| expr '||' expr         { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/
     | expr '|' expr            { $$ = expr_new_tree($1, EXPR_OR, $3); }
index ab87ebf9533a8c7269e545770584edd554767091..47a6fdb7f5b6fc355bd44cf552c3dd36e90612b5 100644 (file)
@@ -62,7 +62,7 @@ static char *strbuf = (char *)NULL;
 static size_t strbuf_size = 0;
 
 /* last "base" label for local (.) labels */
-symrec *locallabel_base = (symrec *)NULL;
+char *nasm_parser_locallabel_base = (char *)NULL;
 
 /* current line number */
 int line_number;
@@ -305,17 +305,17 @@ $$|$|\.\.[a-z0-9_$#@~.?]+ {
 
     /* local label (.label) */
 \.[a-z0-9_$#@~?][a-z0-9_$#@~.?]* {
-    if (!locallabel_base) {
+    if (!nasm_parser_locallabel_base) {
        Warning(_("no non-local label before `%s'"), yytext);
        yylval.syminfo.name = strdup(yytext);
        if (!yylval.syminfo.name)
            Fatal(FATAL_NOMEM);
     } else {
        yylval.syminfo.name = malloc(strlen(yytext) +
-                                    strlen(locallabel_base->name) + 1);
+                                    strlen(nasm_parser_locallabel_base) + 1);
        if (!yylval.syminfo.name)
            Fatal(FATAL_NOMEM);
-       strcpy(yylval.syminfo.name, locallabel_base->name);
+       strcpy(yylval.syminfo.name, nasm_parser_locallabel_base);
        strcat(yylval.syminfo.name, yytext);
     }
     yylval.syminfo.line = line_number;
index a836dfd983264b5cde28c397b4804a20fc8b9903..1d6716e02e2fd152cd2b110005c0bdc76e4af2ee 100644 (file)
@@ -25,6 +25,5 @@
 extern char *filename;
 extern unsigned int line_number;
 extern unsigned char mode_bits;
-extern struct symrec_s *locallabel_base;
 
 #endif
index a836dfd983264b5cde28c397b4804a20fc8b9903..1d6716e02e2fd152cd2b110005c0bdc76e4af2ee 100644 (file)
@@ -25,6 +25,5 @@
 extern char *filename;
 extern unsigned int line_number;
 extern unsigned char mode_bits;
-extern struct symrec_s *locallabel_base;
 
 #endif
index d3eee5ac7b6864a92d755e785ae698e4c1f156b1..25cd0dee805824470056c33200a50cd932715569 100644 (file)
@@ -56,6 +56,7 @@ void nasm_parser_error(char *);
 extern objfmt *nasm_parser_objfmt;
 extern sectionhead nasm_parser_sections;
 extern section *nasm_parser_cur_section;
+extern char *nasm_parser_locallabel_base;
 
 %}
 
@@ -176,9 +177,12 @@ label: label_id        { $1->value = 0; } /* TODO: add pointer to bytecode */
     | label_id ':'  { $1->value = 0; } /* TODO: add pointer to bytecode */
 ;
 
-label_id: ID       { $$ = locallabel_base = sym_def_get($1.name, SYM_LABEL); }
-    | SPECIAL_ID    { $$ = sym_def_get($1.name, SYM_LABEL); }
-    | LOCAL_ID     { $$ = sym_def_get($1.name, SYM_LABEL); }
+label_id: ID       {
+       $$ = symrec_define($1.name, SYM_LABEL);
+       nasm_parser_locallabel_base = strdup($1.name);
+    }
+    | SPECIAL_ID    { $$ = symrec_define($1.name, SYM_LABEL); }
+    | LOCAL_ID     { $$ = symrec_define($1.name, SYM_LABEL); }
 ;
 
 /* directives */
@@ -375,8 +379,7 @@ target: expr            { $$.val = $1; $$.op_sel = JR_NONE; }
 /* expression trees */
 expr_no_string: INTNUM         { $$ = expr_new_ident(EXPR_NUM, ExprNum($1)); }
     | explabel                 {
-       $$ = expr_new_ident(EXPR_SYM,
-                           ExprSym(sym_use_get($1.name, SYM_LABEL)));
+       $$ = expr_new_ident(EXPR_SYM, ExprSym(symrec_use($1.name, SYM_LABEL)));
     }
     /*| expr '||' expr         { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/
     | expr '|' expr            { $$ = expr_new_tree($1, EXPR_OR, $3); }
index d3eee5ac7b6864a92d755e785ae698e4c1f156b1..25cd0dee805824470056c33200a50cd932715569 100644 (file)
@@ -56,6 +56,7 @@ void nasm_parser_error(char *);
 extern objfmt *nasm_parser_objfmt;
 extern sectionhead nasm_parser_sections;
 extern section *nasm_parser_cur_section;
+extern char *nasm_parser_locallabel_base;
 
 %}
 
@@ -176,9 +177,12 @@ label: label_id        { $1->value = 0; } /* TODO: add pointer to bytecode */
     | label_id ':'  { $1->value = 0; } /* TODO: add pointer to bytecode */
 ;
 
-label_id: ID       { $$ = locallabel_base = sym_def_get($1.name, SYM_LABEL); }
-    | SPECIAL_ID    { $$ = sym_def_get($1.name, SYM_LABEL); }
-    | LOCAL_ID     { $$ = sym_def_get($1.name, SYM_LABEL); }
+label_id: ID       {
+       $$ = symrec_define($1.name, SYM_LABEL);
+       nasm_parser_locallabel_base = strdup($1.name);
+    }
+    | SPECIAL_ID    { $$ = symrec_define($1.name, SYM_LABEL); }
+    | LOCAL_ID     { $$ = symrec_define($1.name, SYM_LABEL); }
 ;
 
 /* directives */
@@ -375,8 +379,7 @@ target: expr            { $$.val = $1; $$.op_sel = JR_NONE; }
 /* expression trees */
 expr_no_string: INTNUM         { $$ = expr_new_ident(EXPR_NUM, ExprNum($1)); }
     | explabel                 {
-       $$ = expr_new_ident(EXPR_SYM,
-                           ExprSym(sym_use_get($1.name, SYM_LABEL)));
+       $$ = expr_new_ident(EXPR_SYM, ExprSym(symrec_use($1.name, SYM_LABEL)));
     }
     /*| expr '||' expr         { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/
     | expr '|' expr            { $$ = expr_new_tree($1, EXPR_OR, $3); }
index ab87ebf9533a8c7269e545770584edd554767091..47a6fdb7f5b6fc355bd44cf552c3dd36e90612b5 100644 (file)
@@ -62,7 +62,7 @@ static char *strbuf = (char *)NULL;
 static size_t strbuf_size = 0;
 
 /* last "base" label for local (.) labels */
-symrec *locallabel_base = (symrec *)NULL;
+char *nasm_parser_locallabel_base = (char *)NULL;
 
 /* current line number */
 int line_number;
@@ -305,17 +305,17 @@ $$|$|\.\.[a-z0-9_$#@~.?]+ {
 
     /* local label (.label) */
 \.[a-z0-9_$#@~?][a-z0-9_$#@~.?]* {
-    if (!locallabel_base) {
+    if (!nasm_parser_locallabel_base) {
        Warning(_("no non-local label before `%s'"), yytext);
        yylval.syminfo.name = strdup(yytext);
        if (!yylval.syminfo.name)
            Fatal(FATAL_NOMEM);
     } else {
        yylval.syminfo.name = malloc(strlen(yytext) +
-                                    strlen(locallabel_base->name) + 1);
+                                    strlen(nasm_parser_locallabel_base) + 1);
        if (!yylval.syminfo.name)
            Fatal(FATAL_NOMEM);
-       strcpy(yylval.syminfo.name, locallabel_base->name);
+       strcpy(yylval.syminfo.name, nasm_parser_locallabel_base);
        strcat(yylval.syminfo.name, yytext);
     }
     yylval.syminfo.line = line_number;
index 8de9f81ee409bae0d97362527ddaffd0b36680a1..779e03a1c525188000503c7341b60416acf1e23e 100644 (file)
 RCSID("$IdPath$");
 
 /* private functions */
-static symtab *symtab_get(char *);
-static symtab *symtab_new(char *, SymType);
-static symtab *symtab_get_or_new(char *, SymType);
-static void symtab_insert(symtab *);
+static symrec *symrec_get_or_new(char *, SymType);
 
-/* The symbol table: a chain of `symtab'. */
-symtab *sym_table = (symtab *)NULL;
+/* The symbol table: a ternary tree. */
+static ternary_tree sym_table = (ternary_tree)NULL;
 
-/* insert a symtab into the global sym_table */
-void
-symtab_insert(symtab *tab)
-{
-    tab->next = (symtab *)sym_table;
-    sym_table = tab;
-}
-
-/* find a symtab in the global sym_table */
-symtab *
-symtab_get(char *name)
+/* create a new symrec */
+static symrec *
+symrec_get_or_new(char *name, SymType type)
 {
-    symtab *tab;
+    symrec *rec, *rec2;
 
-    for (tab = sym_table; tab != NULL; tab = tab->next) {
-       if (strcmp(tab->rec.name, name) == 0) {
-           return tab;
-       }
-    }
-    return NULL;
-}
+    rec = malloc(sizeof(symrec));
+    if (!rec)
+       Fatal(FATAL_NOMEM);
 
-/* call a function with each symrec.  stop early if 0 returned */
-void
-sym_foreach(int (*mapfunc) (symrec *))
-{
-    symtab *tab;
+    rec2 = ternary_insert(&sym_table, name, rec, 0);
 
-    for (tab = sym_table; tab != NULL; tab = tab->next) {
-       if (mapfunc(&(tab->rec)) == 0) {
-           return;
-       }
+    if (rec2 != rec) {
+       free(rec);
+       return rec2;
     }
-}
 
-/* create a new symtab */
-symtab *
-symtab_new(char *name, SymType type)
-{
-    symtab *tab;
-    tab = malloc(sizeof(symtab));
-    if (tab == NULL)
-       return NULL;
-    tab->rec.name = malloc(strlen(name) + 1);
-    if (tab->rec.name == NULL) {
-       free(tab);
-       return NULL;
-    }
-    strcpy(tab->rec.name, name);
-    tab->rec.type = type;
-    tab->rec.value = 0;
-    tab->rec.line = line_number;
-    tab->rec.status = SYM_NOSTATUS;
-    symtab_insert(tab);
-    return tab;
+    rec->name = strdup(name);
+    if (!rec->name)
+       Fatal(FATAL_NOMEM);
+    rec->type = type;
+    rec->value = 0;
+    rec->line = line_number;
+    rec->status = SYM_NOSTATUS;
+
+    return rec;
 }
 
-symtab *
-symtab_get_or_new(char *name, SymType type)
+/* call a function with each symrec.  stop early if 0 returned */
+void
+symrec_foreach(int (*func) (char *name, symrec *rec))
 {
-    symtab *tab;
-
-    tab = symtab_get(name);
-    if (tab == NULL) {
-       tab = symtab_new(name, type);
-       if (tab == NULL) {
-           Fatal(FATAL_NOMEM);
-       }
-    }
-    return tab;
 }
 
 symrec *
-sym_use_get(char *name, SymType type)
+symrec_use(char *name, SymType type)
 {
-    symtab *tab;
+    symrec *rec;
 
-    tab = symtab_get_or_new(name, type);
-    tab->rec.status |= SYM_USED;
-    return &(tab->rec);
+    rec = symrec_get_or_new(name, type);
+    rec->status |= SYM_USED;
+    return rec;
 }
 
 symrec *
-sym_def_get(char *name, SymType type)
+symrec_define(char *name, SymType type)
 {
-    symtab *tab;
+    symrec *rec;
 
-    tab = symtab_get_or_new(name, type);
-    if (tab->rec.status & SYM_DECLARED)
+    rec = symrec_get_or_new(name, type);
+    if (rec->status & SYM_DECLARED)
        Error(_("duplicate definition of `%s'; previously defined on line %d"),
-             tab->rec.name, tab->rec.line);
-    tab->rec.status |= SYM_DECLARED;
-    return &(tab->rec);
+             name, rec->line);
+    rec->line = line_number;   /* set line number of definition */
+    rec->status |= SYM_DECLARED;
+    return rec;
 }
index a31fe7e211789b9afe478ac2764db9aad67fd7b1..936c67284435ddda931208d8315ba771ee2e903c 100644 (file)
@@ -38,19 +38,12 @@ typedef struct symrec_s {
     char *name;
     SymType type;
     SymStatus status;
-    int line;
+    int line;                  /* line symbol was first declared or used on */
     double value;
 } symrec;
 
-typedef struct symtab_s {
-    symrec rec;
-    struct symtab_s *next;
-} symtab;
-
-extern symtab *sym_table;
-
-symrec *sym_use_get(char *, SymType);
-symrec *sym_def_get(char *, SymType);
-void sym_foreach(int (*)(symrec *));
+symrec *symrec_use(char *name, SymType type);
+symrec *symrec_define(char *name, SymType type);
+void symrec_foreach(int (*func) (char *name, symrec *rec));
 
 #endif