Mercurial > hg-old > index.cgi
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 } |