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