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

Added struct support to LWASM
author lost
date Sat, 19 Dec 2009 06:38:43 +0000
parents
children
comparison
equal deleted inserted replaced
253:c537a3a723fc 254:c7a41b4c89b3
1 /*
2 struct.c
3 Copyright © 2009 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 definition.
21
22 Structures have their own name space. Macros will shadow structures so it's
23 a good idea to make sure no structures are name the same as macros.
24 */
25
26 #include <config.h>
27
28 #include <ctype.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include "lwasm.h"
32 #include "instab.h"
33 #include "util.h"
34
35 OPFUNC(pseudo_struct)
36 {
37 structtab_t *m;
38
39 // actually define a structure
40 if (as -> instruct)
41 {
42 register_error(as, l, 1, "Attempt to define a structure inside a structure");
43 return;
44 }
45
46 as -> instruct = 1;
47
48 // don't actually do anything if not pass 1
49 if (as -> passnum != 1)
50 return;
51
52
53 if (!l -> sym)
54 {
55 register_error(as, l, 1, "Structure definition with no effect - no symbol");
56 return;
57 }
58
59 // search for macro by same name...
60 for (m = as -> structs; m; m = m -> next)
61 {
62 if (!strcmp(m -> name, l -> sym))
63 break;
64 }
65 if (m)
66 {
67 register_error(as, l, 1, "Duplicate structure definition");
68 return;
69 }
70
71 m = lwasm_alloc(sizeof(structtab_t));
72 m -> name = lwasm_strdup(l -> sym);
73 m -> next = as -> structs;
74 m -> fields = NULL;
75 m -> size = 0;
76 as -> structs = m;
77 as -> cstruct = m;
78
79 while (**p && !isspace(**p))
80 (*p)++;
81 }
82
83
84
85 pseudo_endstruct_aux(asmstate_t *as, lwasm_line_t *l, struct struct_sym_e *e, const char *prefix, int *coff)
86 {
87 char *symname = NULL;
88
89 while (e)
90 {
91 if (e -> name)
92 0 == asprintf(&symname, "%s.%s", prefix, e -> name);
93 else
94 0 == asprintf(&symname, "%s.___%d", prefix, *coff);
95
96 // register symbol "symname" as global at coff
97 lwasm_register_symbol(as, l, symname, *coff, SYMBOL_NOCHECK);
98
99 if (e -> substruct)
100 {
101 char * t;
102 0 == asprintf(&t, "sizeof{%s}", symname);
103 lwasm_register_symbol(as, l, t, e -> substruct -> size, SYMBOL_NOCHECK);
104 lwasm_free(t);
105 pseudo_endstruct_aux(as, l, e -> substruct -> fields, symname, coff);
106 }
107 else
108 {
109 *coff += e -> size;
110 }
111
112 lwasm_free(symname);
113 e = e -> next;
114 }
115 }
116
117 OPFUNC(pseudo_endstruct)
118 {
119 int coff = 0;
120 char *t;
121
122 as -> instruct = 0;
123
124 if (as -> passnum != 1)
125 return;
126
127 // now register the global symbols for the structure
128 // this is a recursive process
129 0 == asprintf(&t, "sizeof{%s}", as -> cstruct -> name);
130 lwasm_register_symbol(as, l, t, as -> cstruct -> size, SYMBOL_NOCHECK);
131 lwasm_free(t);
132
133 pseudo_endstruct_aux(as, l, as -> cstruct -> fields, as -> cstruct -> name, &coff);
134 }
135
136
137 int expand_struct(asmstate_t *as, lwasm_line_t *l, char **p, char *opc)
138 {
139 structtab_t *s;
140 int addr;
141 char *t;
142
143 if (as -> passnum != 1)
144 return 0;
145
146 for (s = as -> structs; s; s = s -> next)
147 {
148 if (!strcmp(opc, s -> name))
149 break;
150 }
151 if (!s)
152 return -1;
153
154 if (!(l -> sym))
155 {
156 register_error(as, l, 1, "Cannot declare a structure without a symbol name.");
157 return;
158 }
159
160 l -> nocodelen = s -> size;
161
162 addr = as -> addr;
163 as -> addr += s -> size;
164
165 // now register the global symbols for the structure
166 // this is a recursive process
167 0 == asprintf(&t, "sizeof{%s}", l -> sym);
168 lwasm_register_symbol(as, l, t, s -> size, SYMBOL_NOCHECK);
169 lwasm_free(t);
170
171 pseudo_endstruct_aux(as, l, s -> fields, l -> sym, &addr);
172
173 return 0;
174 }