comparison lwasm/parse.c @ 254:c7a41b4c89b3 2.x

Added struct support to LWASM
author lost
date Sat, 19 Dec 2009 06:38:43 +0000
parents c537a3a723fc
children 6363b9ebf825
comparison
equal deleted inserted replaced
253:c537a3a723fc 254:c7a41b4c89b3
186 186
187 // second condition above 187 // second condition above
188 if (as -> skipcond && instab[opnum].iscond == 0) 188 if (as -> skipcond && instab[opnum].iscond == 0)
189 goto done_line; 189 goto done_line;
190 190
191 // we've registered the symbol as needed 191 if (as -> instruct && as -> passnum == 1)
192 // now we need to check for a macro call IFF we don't collide with 192 {
193 // an operation code; otherwise, call the operation function 193 structtab_t *s = NULL;
194 if (instab[opnum].opcode) 194 struct struct_sym_e *e, *e2;
195 { 195
196 if (instab[opnum].fn && !(as -> no6309 && instab[opnum].is6309)) 196 // look for a structure if not an acceptable opcode
197 if (!instab[opnum].opcode)
198 {
199 for (s = as -> structs; s; s = s -> next)
200 {
201 if (s == as -> cstruct)
202 continue;
203 if (!strcmp(opc, s -> name))
204 goto isok;
205 }
206 }
207 // check for a "reservation opcode"
208 if (instab[opnum].opcode && instab[opnum].isreserve)
197 { 209 {
198 (instab[opnum].fn)(as, l, &p2, opnum); 210 (instab[opnum].fn)(as, l, &p2, opnum);
199 211
200 // if we didn't end on a "space" character or EOL, throw error 212 // if we didn't end on a "space" character or EOL, throw error
201 if (p2 && *p2 && !isspace(*p2) && !(l -> err) && as -> passnum == 1) 213 if (p2 && *p2 && !isspace(*p2) && !(l -> err) && as -> passnum == 1)
202 register_error(as, l, 1, "Bad operand: %s (%d)", p2, as -> passnum); 214 register_error(as, l, 1, "Bad operand: %s (%d)", p2, as -> passnum);
215
216 if (as -> instruct == 0)
217 goto done_line;
218
219 goto isok;
220 }
221 // carp if not valid
222 register_error(as, l, 1, "Only other structs and rmb allowed in struct");
223 l -> badop = 1;
224 goto done_line;
225
226 isok:
227 for (e2 = as -> cstruct -> fields; e2 && e2 -> next; e2 = e2 -> next)
228 /* do nothing */ ;
229 e = lwasm_alloc(sizeof(struct struct_sym_e));
230 e -> next = NULL;
231 e -> substruct = s;
232 if (sym)
233 e -> name = lwasm_strdup(sym);
234 else
235 e -> name = NULL;
236 if (s)
237 e -> size = s -> size;
238 else
239 e -> size = l -> nocodelen;
240 if (e2)
241 e2 -> next = e;
242 else
243 as -> cstruct -> fields = e;
244 as -> cstruct -> size += e -> size;
245 }
246
247 // we've registered the symbol as needed
248 // now we need to check for a macro call IFF we don't collide with
249 // an operation code; otherwise, call the operation function
250 if (instab[opnum].opcode)
251 {
252 if (instab[opnum].fn && !(as -> no6309 && instab[opnum].is6309))
253 {
254 (instab[opnum].fn)(as, l, &p2, opnum);
255
256 // if we didn't end on a "space" character or EOL, throw error
257 if (p2 && *p2 && !isspace(*p2) && !(l -> err) && as -> passnum == 1)
258 register_error(as, l, 1, "Bad operand: %s (%d)", p2, as -> passnum);
203 } 259 }
204 else 260 else
205 { 261 {
206 // carp about unimplemented operation 262 // carp about unimplemented operation
207 if (instab[opnum].is6309) 263 if (instab[opnum].is6309)
213 else 269 else
214 { 270 {
215 if (expand_macro(as, l, &p2, opc) == 0) 271 if (expand_macro(as, l, &p2, opc) == 0)
216 goto done_line; 272 goto done_line;
217 273
274 if (expand_struct(as, l, &p2, opc) == 0)
275 goto done_line;
276
218 // carp about an unknown operation code and note that fact for 277 // carp about an unknown operation code and note that fact for
219 // pass 2 in case a macro appears later with the same name! 278 // pass 2 in case a macro appears later with the same name!
220 register_error(as, l, 1, "Uknown operation code: %s", opc); 279 register_error(as, l, 1, "Uknown operation code: %s", opc);
221 l -> badop = 1; 280 l -> badop = 1;
222 } 281 }
223 282
224 done_line: 283 done_line:
225 if (!(as -> skipcond || as -> inmacro)) 284 if (!(as -> skipcond || as -> inmacro))
226 { 285 {
227 // register symbol if the operation didn't 286 // register symbol if the operation didn't
228 if (sym && instab[opnum].setsym == 0) 287 if (sym && instab[opnum].setsym == 0 && as -> instruct == 0)
229 { 288 {
230 if (as -> passnum == 1) 289 if (as -> passnum == 1)
231 { 290 {
232 debug_message(1, "Registering symbol '%s' at %04X", sym, l -> codeaddr); 291 debug_message(1, "Registering symbol '%s' at %04X", sym, l -> codeaddr);
233 if (lwasm_register_symbol(as, l, sym, l -> codeaddr, SYMBOL_NORM) < 0) 292 if (lwasm_register_symbol(as, l, sym, l -> codeaddr, SYMBOL_NORM) < 0)