comparison lwasm/symbol.c @ 406:502fbc37ff4e

Symbol table is now sorted in lwasm
author lost@l-w.ca
date Fri, 23 Jul 2010 19:23:17 -0600
parents 7bcc50e828ff
children cac204676434
comparison
equal deleted inserted replaced
405:7bcc50e828ff 406:502fbc37ff4e
29 #include <lw_expr.h> 29 #include <lw_expr.h>
30 #include <lw_string.h> 30 #include <lw_string.h>
31 31
32 #include "lwasm.h" 32 #include "lwasm.h"
33 33
34 struct symtabe *symbol_findprev(asmstate_t *as, struct symtabe *se)
35 {
36 struct symtabe *se1, *se2;
37 int i;
38
39 for (se2 = NULL, se1 = as -> symtab.head; se1; se1 = se1 -> next)
40 {
41 debug_message(as, 200, "Sorting; looking at symbol %s (%p) for %s", se1 -> symbol, se1, se -> symbol);
42 /* compare se with se1 */
43 i = strcasecmp(se -> symbol, se1 -> symbol);
44
45 /* if the symbol sorts before se1, we just need to return */
46 if (i < 0)
47 return se2;
48
49 if (i == 0)
50 {
51 /* symbol name matches; compare other things */
52
53 /*if next version is greater than this one, return */
54 if (se -> version > se1 -> version)
55 return se2;
56 /* if next context is great than this one, return */
57 if (se -> context > se1 -> context)
58 return se2;
59
60 /* if section name is greater, return */
61 /* if se has no section but se1 does, we go first */
62 if (se -> section == NULL && se1 -> section != NULL)
63 return se2;
64 if (se -> section != NULL && se -> section != NULL)
65 {
66 /* compare section names and if se < se1, return */
67 i = strcasecmp(se -> section -> name, se1 -> section -> name);
68 if (i < 0)
69 return se2;
70 }
71 }
72
73 se2 = se1;
74 }
75 return se2;
76 }
77
34 struct symtabe *register_symbol(asmstate_t *as, line_t *cl, char *sym, lw_expr_t val, int flags) 78 struct symtabe *register_symbol(asmstate_t *as, line_t *cl, char *sym, lw_expr_t val, int flags)
35 { 79 {
36 struct symtabe *se; 80 struct symtabe *se;
81 struct symtabe *sprev;
37 int islocal = 0; 82 int islocal = 0;
38 int context = -1; 83 int context = -1;
39 int version = -1; 84 int version = -1;
40 char *cp; 85 char *cp;
41 86
87 debug_message(as, 200, "Register symbol %s (%02X), %s", sym, flags, lw_expr_print(val));
88
42 if (!(flags & symbol_flag_nocheck)) 89 if (!(flags & symbol_flag_nocheck))
43 { 90 {
44 if (*sym < 0x80 && !strchr(SSYMCHARS, *sym)) 91 if (*sym < 0x80 && !strchr(SSYMCHARS, *sym))
45 { 92 {
46 lwasm_register_error(as, cl, "Bad symbol (%s)", sym); 93 lwasm_register_error(as, cl, "Bad symbol (%s)", sym);
73 context = cl -> context; 120 context = cl -> context;
74 121
75 // first, look up symbol to see if it is already defined 122 // first, look up symbol to see if it is already defined
76 for (se = as -> symtab.head; se; se = se -> next) 123 for (se = as -> symtab.head; se; se = se -> next)
77 { 124 {
125 debug_message(as, 300, "Symbol add lookup: %p, %p", se, se -> next);
78 if (!strcmp(sym, se -> symbol)) 126 if (!strcmp(sym, se -> symbol))
79 { 127 {
80 if (se -> context != context) 128 if (se -> context != context)
81 continue; 129 continue;
82 if ((flags & symbol_flag_set) && (se -> flags & symbol_flag_set)) 130 if ((flags & symbol_flag_set) && (se -> flags & symbol_flag_set))
102 } 150 }
103 151
104 // symplify the symbol expression - replaces "SET" symbols with 152 // symplify the symbol expression - replaces "SET" symbols with
105 // symbol table entries 153 // symbol table entries
106 lwasm_reduce_expr(as, val); 154 lwasm_reduce_expr(as, val);
107 155
108 se = lw_alloc(sizeof(struct symtabe)); 156 se = lw_alloc(sizeof(struct symtabe));
109 se -> next = as -> symtab.head;
110 as -> symtab.head = se;
111 se -> context = context; 157 se -> context = context;
112 se -> version = version; 158 se -> version = version;
113 se -> flags = flags; 159 se -> flags = flags;
114 se -> value = lw_expr_copy(val); 160 se -> value = lw_expr_copy(val);
115 se -> symbol = lw_strdup(sym); 161 se -> symbol = lw_strdup(sym);
116 se -> section = cl -> csect; 162 se -> section = cl -> csect;
163 sprev = symbol_findprev(as, se);
164 if (!sprev)
165 {
166 debug_message(as, 200, "Adding symbol at head of symbol table");
167 se -> next = as -> symtab.head;
168 as -> symtab.head = se;
169 }
170 else
171 {
172 debug_message(as, 200, "Adding symbol in middle of symbol table");
173 se -> next = sprev -> next;
174 sprev -> next = se;
175 }
117 return se; 176 return se;
118 } 177 }
119 178
120 // for "SET" symbols, always returns the LAST definition of the 179 // for "SET" symbols, always returns the LAST definition of the
121 // symbol. This works because the lwasm_reduce_expr() call in 180 // symbol. This works because the lwasm_reduce_expr() call in