Mercurial > hg-old > index.cgi
annotate lwasm/symbol.c @ 388:8991eb507d2d
Added missing arg-nonnull.h ??? file to repo
author | lost@l-w.ca |
---|---|
date | Wed, 14 Jul 2010 20:17:57 -0600 |
parents | d99322ef6f21 |
children | fbb7bfed8076 |
rev | line source |
---|---|
342 | 1 /* |
2 symbol.c | |
3 | |
4 Copyright © 2010 William Astle | |
5 | |
6 This file is part of LWTOOLS. | |
7 | |
8 LWTOOLS is free software: you can redistribute it and/or modify it under the | |
9 terms of the GNU General Public License as published by the Free Software | |
10 Foundation, either version 3 of the License, or (at your option) any later | |
11 version. | |
12 | |
13 This program is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
16 more details. | |
17 | |
18 You should have received a copy of the GNU General Public License along with | |
19 this program. If not, see <http://www.gnu.org/licenses/>. | |
20 */ | |
21 | |
22 #include <config.h> | |
23 | |
24 #include <stdlib.h> | |
25 #include <string.h> | |
26 | |
27 #include <lw_alloc.h> | |
28 #include <lw_expr.h> | |
370 | 29 #include <lw_string.h> |
342 | 30 |
31 #include "lwasm.h" | |
32 | |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
33 struct symtabe *register_symbol(asmstate_t *as, line_t *cl, char *sym, lw_expr_t val, int flags) |
342 | 34 { |
35 struct symtabe *se; | |
36 int islocal = 0; | |
37 int context = -1; | |
38 int version = -1; | |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
39 char *cp; |
342 | 40 |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
41 if (*sym < 0x80 && !strchr(SSYMCHARS, *sym)) |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
42 { |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
43 lwasm_register_error(as, cl, "Bad symbol (%s)", sym); |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
44 return NULL; |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
45 } |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
46 |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
47 if ((*sym == '$' || *sym == '@') && (sym[1] >= '0' && sym[1] <= '9')) |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
48 { |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
49 lwasm_register_error(as, cl, "Bad symbol (%s)", sym); |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
50 return NULL; |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
51 } |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
52 |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
53 for (cp = sym; *cp; cp++) |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
54 { |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
55 if (*cp == '@' || *cp == '?') |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
56 islocal = 1; |
360
7d91ab7ac7d6
Indexed stage 2; set line structure to track pragmas in effect for that line
lost@starbug
parents:
346
diff
changeset
|
57 if (*cp == '$' && !(CURPRAGMA(cl, PRAGMA_DOLLARNOTLOCAL))) |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
58 islocal = 1; |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
59 |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
60 // bad symbol |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
61 if (*cp < 0x80 && !strchr(SYMCHARS, *cp)) |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
62 { |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
63 lwasm_register_error(as, cl, "Bad symbol (%s)", sym); |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
64 return NULL; |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
65 } |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
66 } |
342 | 67 |
68 if (islocal) | |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
69 context = cl -> context; |
342 | 70 |
71 // first, look up symbol to see if it is already defined | |
72 for (se = as -> symtab.head; se; se = se -> next) | |
73 { | |
74 if (!strcmp(sym, se -> symbol)) | |
75 { | |
76 if (se -> context != context) | |
77 continue; | |
78 if ((flags & symbol_flag_set) && (se -> flags & symbol_flag_set)) | |
79 { | |
80 if (version < se -> version) | |
81 version = se -> version; | |
82 continue; | |
83 } | |
84 break; | |
85 } | |
86 } | |
87 if (se) | |
88 { | |
89 // multiply defined symbol | |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
90 lwasm_register_error(as, cl, "Multiply defined symbol (%s)", sym); |
342 | 91 return NULL; |
92 } | |
93 | |
94 if (flags & symbol_flag_set) | |
95 { | |
96 version++; | |
97 } | |
98 | |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
99 // symplify the symbol expression - replaces "SET" symbols with |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
100 // symbol table entries |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
101 lwasm_reduce_expr(as, val); |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
102 |
342 | 103 se = lw_alloc(sizeof(struct symtabe)); |
104 se -> next = as -> symtab.head; | |
105 as -> symtab.head = se; | |
106 se -> context = context; | |
107 se -> version = version; | |
108 se -> flags = flags; | |
109 se -> value = lw_expr_copy(val); | |
370 | 110 se -> symbol = lw_strdup(sym); |
374 | 111 se -> section = cl -> csect; |
342 | 112 return se; |
113 } | |
114 | |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
115 // for "SET" symbols, always returns the LAST definition of the |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
116 // symbol. This works because the lwasm_reduce_expr() call in |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
117 // register_symbol will ensure there are no lingering "var" references |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
118 // to the set symbol anywhere in the symbol table; they will all be |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
119 // converted to direct references |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
120 // NOTE: this means that for a forward reference to a SET symbol, |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
121 // the LAST definition will be the one used. |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
122 // This arrangement also ensures that any reference to the symbol |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
123 // itself inside a "set" definition will refer to the previous version |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
124 // of the symbol. |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
125 struct symtabe * lookup_symbol(asmstate_t *as, line_t *cl, char *sym) |
342 | 126 { |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
127 int local = 0; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
128 struct symtabe *s, *s2; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
129 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
130 // check if this is a local symbol |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
131 if (strchr(sym, '@') || strchr(sym, '?')) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
132 local = 1; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
133 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
134 if (cl && !CURPRAGMA(cl, PRAGMA_DOLLARNOTLOCAL) && strchr(sym, '$')) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
135 local = 1; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
136 if (!cl && !(as -> pragmas & PRAGMA_DOLLARNOTLOCAL) && strchr(sym, '$')) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
137 local = 1; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
138 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
139 // cannot look up local symbol in global context!!!!! |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
140 if (!cl && local) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
141 return NULL; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
142 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
143 for (s = as -> symtab.head, s2 = NULL; s; s = s -> next) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
144 { |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
145 if (!strcmp(sym, s -> symbol)) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
146 { |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
147 if (local && s -> context != cl -> context) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
148 continue; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
149 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
150 if (s -> flags & symbol_flag_set) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
151 { |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
152 // look for highest version of symbol |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
153 if (s -> version > s2 -> version) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
154 s2 = s; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
155 continue; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
156 } |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
157 break; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
158 } |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
159 } |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
160 if (!s && s2) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
161 s = s2; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
162 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
163 return s; |
342 | 164 } |