Mercurial > hg-old > index.cgi
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 |