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
extern char *filename;
extern unsigned int line_number;
extern unsigned char mode_bits;
-extern struct symrec_s *locallabel_base;
#endif
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;
}
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
extern objfmt *nasm_parser_objfmt;
extern sectionhead nasm_parser_sections;
extern section *nasm_parser_cur_section;
+extern char *nasm_parser_locallabel_base;
%}
| 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 */
/* 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); }
extern objfmt *nasm_parser_objfmt;
extern sectionhead nasm_parser_sections;
extern section *nasm_parser_cur_section;
+extern char *nasm_parser_locallabel_base;
%}
| 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 */
/* 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); }
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;
/* 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;
extern char *filename;
extern unsigned int line_number;
extern unsigned char mode_bits;
-extern struct symrec_s *locallabel_base;
#endif
extern char *filename;
extern unsigned int line_number;
extern unsigned char mode_bits;
-extern struct symrec_s *locallabel_base;
#endif
extern objfmt *nasm_parser_objfmt;
extern sectionhead nasm_parser_sections;
extern section *nasm_parser_cur_section;
+extern char *nasm_parser_locallabel_base;
%}
| 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 */
/* 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); }
extern objfmt *nasm_parser_objfmt;
extern sectionhead nasm_parser_sections;
extern section *nasm_parser_cur_section;
+extern char *nasm_parser_locallabel_base;
%}
| 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 */
/* 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); }
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;
/* 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;
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;
}
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