Mercurial > hg > index.cgi
comparison lwasm/struct.c @ 0:2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
author | lost@l-w.ca |
---|---|
date | Wed, 19 Jan 2011 22:27:17 -0700 |
parents | |
children | 7317fbe024af |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:2c24602be78f |
---|---|
1 /* | |
2 struct.c | |
3 Copyright © 2010 William Astle | |
4 | |
5 This file is part of LWASM. | |
6 | |
7 LWASM is free software: you can redistribute it and/or modify it under the | |
8 terms of the GNU General Public License as published by the Free Software | |
9 Foundation, either version 3 of the License, or (at your option) any later | |
10 version. | |
11 | |
12 This program is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
15 more details. | |
16 | |
17 You should have received a copy of the GNU General Public License along with | |
18 this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | |
20 Contains stuff associated with structure processing | |
21 */ | |
22 | |
23 #include <string.h> | |
24 | |
25 #include <lw_alloc.h> | |
26 #include <lw_string.h> | |
27 | |
28 #include "lwasm.h" | |
29 #include "instab.h" | |
30 | |
31 PARSEFUNC(pseudo_parse_struct) | |
32 { | |
33 structtab_t *s; | |
34 | |
35 if (as -> instruct) | |
36 { | |
37 lwasm_register_error(as, l, "Attempt to define a structure inside a structure"); | |
38 return; | |
39 } | |
40 | |
41 if (l -> sym == NULL) | |
42 { | |
43 lwasm_register_error(as, l, "Structure definition with no effect - no symbol"); | |
44 return; | |
45 } | |
46 | |
47 for (s = as -> structs; s; s = s -> next) | |
48 { | |
49 if (!strcmp(s -> name, l -> sym)) | |
50 break; | |
51 } | |
52 | |
53 if (s) | |
54 { | |
55 lwasm_register_error(as, l, "Duplicate structure definition"); | |
56 return; | |
57 } | |
58 | |
59 as -> instruct = 1; | |
60 | |
61 s = lw_alloc(sizeof(structtab_t)); | |
62 s -> name = lw_strdup(l -> sym); | |
63 s -> next = as -> structs; | |
64 s -> fields = NULL; | |
65 s -> size = 0; | |
66 as -> structs = s; | |
67 as -> cstruct = s; | |
68 | |
69 skip_operand(p); | |
70 | |
71 l -> len = 0; | |
72 l -> symset = 1; | |
73 } | |
74 | |
75 void pseudo_endstruct_aux(asmstate_t *as, line_t *l, structtab_field_t *e, const char *prefix, int *coff) | |
76 { | |
77 char *symname = NULL; | |
78 lw_expr_t te1, te2; | |
79 | |
80 while (e) | |
81 { | |
82 if (e -> name) | |
83 0 == asprintf(&symname, "%s.%s", prefix, e -> name); | |
84 else | |
85 0 == asprintf(&symname, "%s.____%d", prefix, *coff); | |
86 | |
87 // register the symbol | |
88 te1 = lw_expr_build(lw_expr_type_int, *coff); | |
89 te2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_plus, te1, l -> addr); | |
90 register_symbol(as, l, symname, te2, symbol_flag_nocheck); | |
91 lw_expr_destroy(te2); | |
92 lw_expr_destroy(te1); | |
93 | |
94 if (e -> substruct) | |
95 { | |
96 char *t; | |
97 0 == asprintf(&t, "sizeof{%s}", symname); | |
98 te1 = lw_expr_build(lw_expr_type_int, e -> substruct -> size); | |
99 register_symbol(as, l, t, te1, symbol_flag_nocheck); | |
100 lw_expr_destroy(te1); | |
101 lw_free(t); | |
102 pseudo_endstruct_aux(as, l, e -> substruct -> fields, symname, coff); | |
103 } | |
104 else | |
105 { | |
106 *coff += e -> size; | |
107 } | |
108 e = e -> next; | |
109 } | |
110 } | |
111 | |
112 | |
113 PARSEFUNC(pseudo_parse_endstruct) | |
114 { | |
115 char *t; | |
116 int coff = 0; | |
117 lw_expr_t te; | |
118 | |
119 if (as -> instruct == 0) | |
120 { | |
121 lwasm_register_warning(as, l, "endstruct without struct"); | |
122 skip_operand(p); | |
123 return; | |
124 } | |
125 | |
126 0 == asprintf(&t, "sizeof{%s}", as -> cstruct -> name); | |
127 te = lw_expr_build(lw_expr_type_int, as -> cstruct -> size); | |
128 register_symbol(as, l, t, te, symbol_flag_nocheck); | |
129 lw_expr_destroy(te); | |
130 lw_free(t); | |
131 | |
132 l -> soff = as -> cstruct -> size; | |
133 as -> instruct = 0; | |
134 | |
135 skip_operand(p); | |
136 | |
137 pseudo_endstruct_aux(as, l, as -> cstruct -> fields, as -> cstruct -> name, &coff); | |
138 | |
139 l -> len = 0; | |
140 } | |
141 | |
142 void register_struct_entry(asmstate_t *as, line_t *l, int size, structtab_t *ss) | |
143 { | |
144 structtab_field_t *e, *e2; | |
145 | |
146 l -> soff = as -> cstruct -> size; | |
147 e = lw_alloc(sizeof(structtab_field_t)); | |
148 e -> next = NULL; | |
149 e -> size = size; | |
150 if (l -> sym) | |
151 e -> name = lw_strdup(l -> sym); | |
152 else | |
153 e -> name = NULL; | |
154 e -> substruct = ss; | |
155 if (as -> cstruct -> fields) | |
156 { | |
157 for (e2 = as -> cstruct -> fields; e2 -> next; e2 = e2 -> next) | |
158 /* do nothing */ ; | |
159 e2 -> next = e; | |
160 } | |
161 else | |
162 { | |
163 as -> cstruct -> fields = e; | |
164 } | |
165 as -> cstruct -> size += size; | |
166 } | |
167 | |
168 int expand_struct(asmstate_t *as, line_t *l, char **p, char *opc) | |
169 { | |
170 structtab_t *s; | |
171 char *t; | |
172 lw_expr_t te; | |
173 int addr = 0; | |
174 | |
175 debug_message(as, 200, "Checking for structure expansion: %s", opc); | |
176 | |
177 for (s = as -> structs; s; s = s -> next) | |
178 { | |
179 if (!strcmp(opc, s -> name)) | |
180 break; | |
181 } | |
182 | |
183 if (!s) | |
184 return -1; | |
185 | |
186 debug_message(as, 10, "Expanding structure: %s", opc); | |
187 | |
188 if (!(l -> sym)) | |
189 { | |
190 lwasm_register_error(as, l, "Cannot declare a structure without a symbol name."); | |
191 return; | |
192 } | |
193 | |
194 l -> len = s -> size; | |
195 | |
196 if (as -> instruct) | |
197 0 == asprintf(&t, "sizeof(%s.%s}", as -> cstruct -> name, l -> sym); | |
198 else | |
199 0 == asprintf(&t, "sizeof{%s}", l -> sym); | |
200 te = lw_expr_build(lw_expr_type_int, s -> size); | |
201 register_symbol(as, l, t, te, symbol_flag_nocheck); | |
202 lw_expr_destroy(te); | |
203 lw_free(t); | |
204 | |
205 if (as -> instruct) | |
206 0 == asprintf(&t, "%s.%s", as -> cstruct -> name, l -> sym); | |
207 else | |
208 t = lw_strdup(l -> sym); | |
209 pseudo_endstruct_aux(as, l, s -> fields, t, &addr); | |
210 lw_free(t); | |
211 l -> symset = 1; | |
212 if (as -> instruct) | |
213 register_struct_entry(as, l, s -> size, s); | |
214 return 0; | |
215 } | |
216 |