# HG changeset patch # User lost@l-w.ca # Date 1279934597 21600 # Node ID 502fbc37ff4edfc0b4c64383fc0ac98d85394f1e # Parent 7bcc50e828ff5e3416471ed5463d88735f5cdf68 Symbol table is now sorted in lwasm diff -r 7bcc50e828ff -r 502fbc37ff4e lwasm/symbol.c --- a/lwasm/symbol.c Fri Jul 23 18:58:20 2010 -0600 +++ b/lwasm/symbol.c Fri Jul 23 19:23:17 2010 -0600 @@ -31,14 +31,61 @@ #include "lwasm.h" +struct symtabe *symbol_findprev(asmstate_t *as, struct symtabe *se) +{ + struct symtabe *se1, *se2; + int i; + + for (se2 = NULL, se1 = as -> symtab.head; se1; se1 = se1 -> next) + { + debug_message(as, 200, "Sorting; looking at symbol %s (%p) for %s", se1 -> symbol, se1, se -> symbol); + /* compare se with se1 */ + i = strcasecmp(se -> symbol, se1 -> symbol); + + /* if the symbol sorts before se1, we just need to return */ + if (i < 0) + return se2; + + if (i == 0) + { + /* symbol name matches; compare other things */ + + /*if next version is greater than this one, return */ + if (se -> version > se1 -> version) + return se2; + /* if next context is great than this one, return */ + if (se -> context > se1 -> context) + return se2; + + /* if section name is greater, return */ + /* if se has no section but se1 does, we go first */ + if (se -> section == NULL && se1 -> section != NULL) + return se2; + if (se -> section != NULL && se -> section != NULL) + { + /* compare section names and if se < se1, return */ + i = strcasecmp(se -> section -> name, se1 -> section -> name); + if (i < 0) + return se2; + } + } + + se2 = se1; + } + return se2; +} + struct symtabe *register_symbol(asmstate_t *as, line_t *cl, char *sym, lw_expr_t val, int flags) { struct symtabe *se; + struct symtabe *sprev; int islocal = 0; int context = -1; int version = -1; char *cp; + debug_message(as, 200, "Register symbol %s (%02X), %s", sym, flags, lw_expr_print(val)); + if (!(flags & symbol_flag_nocheck)) { if (*sym < 0x80 && !strchr(SSYMCHARS, *sym)) @@ -75,6 +122,7 @@ // first, look up symbol to see if it is already defined for (se = as -> symtab.head; se; se = se -> next) { + debug_message(as, 300, "Symbol add lookup: %p, %p", se, se -> next); if (!strcmp(sym, se -> symbol)) { if (se -> context != context) @@ -104,16 +152,27 @@ // symplify the symbol expression - replaces "SET" symbols with // symbol table entries lwasm_reduce_expr(as, val); - + se = lw_alloc(sizeof(struct symtabe)); - se -> next = as -> symtab.head; - as -> symtab.head = se; se -> context = context; se -> version = version; se -> flags = flags; se -> value = lw_expr_copy(val); se -> symbol = lw_strdup(sym); se -> section = cl -> csect; + sprev = symbol_findprev(as, se); + if (!sprev) + { + debug_message(as, 200, "Adding symbol at head of symbol table"); + se -> next = as -> symtab.head; + as -> symtab.head = se; + } + else + { + debug_message(as, 200, "Adding symbol in middle of symbol table"); + se -> next = sprev -> next; + sprev -> next = se; + } return se; }