comparison src/macro.c @ 0:57495da01900

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