annotate src/macro.c @ 0:57495da01900

Initial checking of LWASM
author lost
date Fri, 03 Oct 2008 02:44:20 +0000
parents
children 34568fab6058
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
1 /*
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
2 * macro.c
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
3 *
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
4 * stuff associated with macro processing
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
5 */
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
6
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
7 #include <ctype.h>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
8 #include <stdlib.h>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
9 #include <string.h>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
10 #include "lwasm.h"
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
11
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
12 extern void resolve_insn(asmstate_t *as, sourceline_t *cl);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
13
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
14 void pseudo_macro(asmstate_t *as, sourceline_t *cl, char **optr)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
15 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
16 macrotab_t *m;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
17
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
18 if (as -> inmacro)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
19 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
20 errorp1(ERR_MACRO);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
21 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
22 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
23 as -> inmacro = 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
24 if (as -> passnum != 1)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
25 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
26
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
27 for (m = as -> macros; m; m = m -> next)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
28 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
29 if (!strcmp(m -> name, cl -> symstr))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
30 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
31 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
32 if (m)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
33 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
34 errorp1(ERR_DUPSYM);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
35 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
36 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
37 m = calloc(sizeof(macrotab_t), 1);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
38 m -> name = strdup(cl -> symstr);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
39 m -> next = as -> macros;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
40 as -> macros = m;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
41 cl -> hassym = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
42 while (**optr && !isspace(**optr))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
43 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
44 cl -> macrodef = 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
45 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
46
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
47 void pseudo_endm(asmstate_t *as, sourceline_t *cl, char **optr)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
48 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
49 if (!as -> inmacro)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
50 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
51 errorp1(ERR_ENDM);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
52 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
53 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
54
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
55 as -> inmacro = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
56 cl -> macrodef = 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
57 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
58
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
59 int add_macro_line(asmstate_t *as, sourceline_t *cl, char *optr)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
60 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
61 macroline_t *l;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
62
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
63 if (!as -> inmacro)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
64 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
65
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
66 if (as -> passnum == 2)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
67 return 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
68
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
69 l = calloc(sizeof(macroline_t), 1);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
70 l -> linetext = strdup(optr);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
71 if (as -> macros -> linetail)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
72 as -> macros -> linetail -> next = l;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
73 as -> macros -> linetail = l;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
74 if (!(as -> macros -> linehead))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
75 as -> macros -> linehead = l;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
76 return 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
77 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
78
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
79 void macro_add_to_buff(char **buff, int *loc, int *len, char c)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
80 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
81 if (*loc == *len)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
82 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
83 *buff = realloc(*buff, *len + 32);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
84 *len += 32;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
85 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
86 (*buff)[(*loc)++] = c;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
87 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
88
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
89 // this is just like a regular operation function
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
90 /*
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
91 macro args are references by "\n" where 1 <= n <= 9
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
92 or by "\{n}"; a \ can be included by writing \\
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
93 */
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
94 void expand_macro(asmstate_t *as, sourceline_t *cl, char **optr)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
95 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
96 char **args = NULL;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
97 int nargs = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
98 int c;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
99 sourceline_t *nl;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
100 int nline = 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
101 macrotab_t *m;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
102 macroline_t *ml;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
103 char *buff = NULL;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
104 int bufflen = 0, buffloc;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
105
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
106 m = cl -> macro;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
107
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
108 // step the first: parse arguments
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
109 while (**optr && !isspace(**optr))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
110 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
111 c = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
112 while ((*optr)[c] && !isspace((*optr)[c]) && (*optr)[c] != ',')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
113 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
114 c++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
115 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
116 args = realloc(args, sizeof(char *) * (nargs + 1));
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
117 args[nargs] = malloc(c + 1);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
118 strncpy(args[nargs], *optr, c);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
119 args[nargs][c] = '\0';
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
120 nargs++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
121 *optr += c;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
122 if (**optr == ',')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
123 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
124 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
125
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
126 // step the second: iterate over the lines and expand arguments and add
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
127 // them after "cl"
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
128 for (ml = m -> linehead; ml; ml = ml -> next)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
129 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
130 nl = calloc(sizeof(sourceline_t), 1);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
131
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
132 nl -> lineno = nline++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
133 nl -> sourcefile = m -> name;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
134 nl -> opcode = -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
135 nl -> addrmode = -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
136 nl -> addr = as -> addr;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
137 nl -> dpval = as -> dpval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
138 nl -> prev = cl;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
139 if (!(cl -> next))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
140 as -> source_tail = nl;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
141 nl -> next = cl -> next;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
142 cl -> next = nl;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
143
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
144 buffloc = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
145 c = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
146 while (ml -> linetext[c])
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
147 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
148 int ch;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
149 ch = ml -> linetext[c++];
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
150 if (ch == '{')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
151 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
152 int v = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
153 again:
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
154 ch = ml -> linetext[c++];
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
155 if (!ch)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
156 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
157 c--;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
158 continue;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
159 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
160 if (ch >= '0' && ch <= '9')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
161 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
162 v = v * 10 + (ch - '0');
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
163 goto again;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
164 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
165 if (ch == '}')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
166 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
167 v--;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
168 if (v < nargs)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
169 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
170 char *t;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
171 for (t = args[v]; *t; t++)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
172 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
173 macro_add_to_buff(&buff, &buffloc, &bufflen, *t);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
174 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
175 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
176 continue;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
177 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
178 else
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
179 continue;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
180 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
181 else if (ch == '\\' && ml -> linetext[c])
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
182 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
183 ch = ml -> linetext[c++];
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
184 if (ch >= '1' && ch <= '9')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
185 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
186 ch -= '1';
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
187 if (ch < nargs)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
188 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
189 char *t;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
190 for (t = args[ch]; *t; t++)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
191 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
192 macro_add_to_buff(&buff, &buffloc, &bufflen, *t);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
193 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
194 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
195 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
196 else
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
197 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
198 c--;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
199 macro_add_to_buff(&buff, &buffloc, &bufflen, '\\');
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
200 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
201 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
202 else
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
203 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
204 macro_add_to_buff(&buff, &buffloc, &bufflen, ch);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
205 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
206 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
207 macro_add_to_buff(&buff, &buffloc, &bufflen, 0);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
208 nl -> line = strdup(buff);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
209
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
210 resolve_insn(as, nl);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
211 cl = nl;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
212 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
213 if (buff)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
214 free(buff);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
215 }