annotate src/macro.c @ 55:8e32696380f3

added expression evaluation and checking function
author lost
date Sun, 04 Jan 2009 21:42:54 +0000
parents 34568fab6058
children 035b95a3690f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
1 /*
4
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
2 macro.c
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
3 Copyright © 2008 William Astle
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
4
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
5 This file is part of LWASM.
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
6
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
7 LWASM is free software: you can redistribute it and/or modify it under the
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
8 terms of the GNU General Public License as published by the Free Software
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
9 Foundation, either version 3 of the License, or (at your option) any later
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
10 version.
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
11
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
12 This program is distributed in the hope that it will be useful, but WITHOUT
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
15 more details.
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
16
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
17 You should have received a copy of the GNU General Public License along with
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
18 this program. If not, see <http://www.gnu.org/licenses/>.
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
19
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
20 Contains stuff associated with macro processing
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
21 */
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
22
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
23 #include <ctype.h>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
24 #include <stdlib.h>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
25 #include <string.h>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
26 #include "lwasm.h"
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
27
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
28 extern void resolve_insn(asmstate_t *as, sourceline_t *cl);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
29
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
30 void pseudo_macro(asmstate_t *as, sourceline_t *cl, char **optr)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
31 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
32 macrotab_t *m;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
33
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
34 if (as -> inmacro)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
35 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
36 errorp1(ERR_MACRO);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
37 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
38 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
39 as -> inmacro = 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
40 if (as -> passnum != 1)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
41 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
42
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
43 for (m = as -> macros; m; m = m -> next)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
44 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
45 if (!strcmp(m -> name, cl -> symstr))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
46 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
47 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
48 if (m)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
49 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
50 errorp1(ERR_DUPSYM);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
51 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
52 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
53 m = calloc(sizeof(macrotab_t), 1);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
54 m -> name = strdup(cl -> symstr);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
55 m -> next = as -> macros;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
56 as -> macros = m;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
57 cl -> hassym = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
58 while (**optr && !isspace(**optr))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
59 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
60 cl -> macrodef = 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
61 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
62
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
63 void pseudo_endm(asmstate_t *as, sourceline_t *cl, char **optr)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
64 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
65 if (!as -> inmacro)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
66 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
67 errorp1(ERR_ENDM);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
68 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
69 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
70
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
71 as -> inmacro = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
72 cl -> macrodef = 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
73 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
74
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
75 int add_macro_line(asmstate_t *as, sourceline_t *cl, char *optr)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
76 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
77 macroline_t *l;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
78
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
79 if (!as -> inmacro)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
80 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
81
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
82 if (as -> passnum == 2)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
83 return 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
84
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
85 l = calloc(sizeof(macroline_t), 1);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
86 l -> linetext = strdup(optr);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
87 if (as -> macros -> linetail)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
88 as -> macros -> linetail -> next = l;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
89 as -> macros -> linetail = l;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
90 if (!(as -> macros -> linehead))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
91 as -> macros -> linehead = l;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
92 return 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
93 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
94
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
95 void macro_add_to_buff(char **buff, int *loc, int *len, char c)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
96 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
97 if (*loc == *len)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
98 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
99 *buff = realloc(*buff, *len + 32);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
100 *len += 32;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
101 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
102 (*buff)[(*loc)++] = c;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
103 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
104
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
105 // this is just like a regular operation function
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
106 /*
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
107 macro args are references by "\n" where 1 <= n <= 9
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
108 or by "\{n}"; a \ can be included by writing \\
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
109 */
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
110 void expand_macro(asmstate_t *as, sourceline_t *cl, char **optr)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
111 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
112 char **args = NULL;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
113 int nargs = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
114 int c;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
115 sourceline_t *nl;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
116 int nline = 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
117 macrotab_t *m;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
118 macroline_t *ml;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
119 char *buff = NULL;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
120 int bufflen = 0, buffloc;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
121
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
122 m = cl -> macro;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
123
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
124 // step the first: parse arguments
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
125 while (**optr && !isspace(**optr))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
126 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
127 c = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
128 while ((*optr)[c] && !isspace((*optr)[c]) && (*optr)[c] != ',')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
129 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
130 c++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
131 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
132 args = realloc(args, sizeof(char *) * (nargs + 1));
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
133 args[nargs] = malloc(c + 1);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
134 strncpy(args[nargs], *optr, c);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
135 args[nargs][c] = '\0';
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
136 nargs++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
137 *optr += c;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
138 if (**optr == ',')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
139 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
140 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
141
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
142 // step the second: iterate over the lines and expand arguments and add
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
143 // them after "cl"
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
144 for (ml = m -> linehead; ml; ml = ml -> next)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
145 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
146 nl = calloc(sizeof(sourceline_t), 1);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
147
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
148 nl -> lineno = nline++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
149 nl -> sourcefile = m -> name;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
150 nl -> opcode = -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
151 nl -> addrmode = -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
152 nl -> addr = as -> addr;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
153 nl -> dpval = as -> dpval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
154 nl -> prev = cl;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
155 if (!(cl -> next))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
156 as -> source_tail = nl;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
157 nl -> next = cl -> next;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
158 cl -> next = nl;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
159
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
160 buffloc = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
161 c = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
162 while (ml -> linetext[c])
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
163 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
164 int ch;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
165 ch = ml -> linetext[c++];
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
166 if (ch == '{')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
167 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
168 int v = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
169 again:
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
170 ch = ml -> linetext[c++];
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
171 if (!ch)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
172 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
173 c--;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
174 continue;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
175 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
176 if (ch >= '0' && ch <= '9')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
177 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
178 v = v * 10 + (ch - '0');
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
179 goto again;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
180 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
181 if (ch == '}')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
182 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
183 v--;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
184 if (v < nargs)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
185 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
186 char *t;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
187 for (t = args[v]; *t; t++)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
188 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
189 macro_add_to_buff(&buff, &buffloc, &bufflen, *t);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
190 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
191 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
192 continue;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
193 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
194 else
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
195 continue;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
196 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
197 else if (ch == '\\' && ml -> linetext[c])
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
198 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
199 ch = ml -> linetext[c++];
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
200 if (ch >= '1' && ch <= '9')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
201 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
202 ch -= '1';
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
203 if (ch < nargs)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
204 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
205 char *t;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
206 for (t = args[ch]; *t; t++)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
207 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
208 macro_add_to_buff(&buff, &buffloc, &bufflen, *t);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
209 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
210 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
211 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
212 else
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
213 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
214 c--;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
215 macro_add_to_buff(&buff, &buffloc, &bufflen, '\\');
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
216 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
217 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
218 else
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
219 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
220 macro_add_to_buff(&buff, &buffloc, &bufflen, ch);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
221 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
222 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
223 macro_add_to_buff(&buff, &buffloc, &bufflen, 0);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
224 nl -> line = strdup(buff);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
225
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
226 resolve_insn(as, nl);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
227 cl = nl;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
228 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
229 if (buff)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
230 free(buff);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
231 }