Mercurial > hg-old > index.cgi
annotate lwasm/pass1.c @ 345:7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
author | lost@starbug |
---|---|
date | Thu, 25 Mar 2010 23:17:54 -0600 |
parents | 0215a0fbf61b |
children | a82c55070624 |
rev | line source |
---|---|
332 | 1 /* |
2 pass1.c | |
3 | |
4 Copyright © 2010 William Astle | |
5 | |
6 This file is part of LWTOOLS. | |
7 | |
8 LWTOOLS is free software: you can redistribute it and/or modify it under the | |
9 terms of the GNU General Public License as published by the Free Software | |
10 Foundation, either version 3 of the License, or (at your option) any later | |
11 version. | |
12 | |
13 This program is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
16 more details. | |
17 | |
18 You should have received a copy of the GNU General Public License along with | |
19 this program. If not, see <http://www.gnu.org/licenses/>. | |
20 */ | |
21 | |
22 #include <config.h> | |
23 | |
24 #include <stdio.h> | |
25 | |
26 #include <lw_alloc.h> | |
342 | 27 #include <lw_string.h> |
332 | 28 |
29 #include "lwasm.h" | |
342 | 30 #include "instab.h" |
332 | 31 #include "input.h" |
32 | |
337 | 33 /* |
34 pass 1: parse the lines | |
340 | 35 |
36 line format: | |
37 | |
38 [<symbol>] <opcode> <operand>[ <comment>] | |
39 | |
40 If <symbol> is followed by a :, whitespace may precede the symbol | |
41 | |
42 A line may optionally start with a number which must not be preceded by | |
43 white space and must be followed by a single whitespace character. After | |
44 that whitespace character, the line is parsed as if it had no line number. | |
45 | |
337 | 46 */ |
332 | 47 void do_pass1(asmstate_t *as) |
48 { | |
49 char *line; | |
337 | 50 line_t *cl; |
340 | 51 char *p1; |
342 | 52 int stspace; |
340 | 53 char *tok, *sym; |
54 int opnum; | |
55 | |
332 | 56 for (;;) |
57 { | |
340 | 58 sym = NULL; |
332 | 59 line = input_readline(as); |
60 if (!line) | |
61 break; | |
345
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
62 if (line[0] == 1 && line[1] == 1) |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
63 { |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
64 // special internal directive |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
65 // these DO NOT appear in the output anywhere |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
66 // they are generated by the parser to pass information |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
67 // forward |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
68 for (p1 = line + 2; *p1 && !isspace(*p1); p1++) |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
69 /* do nothing */ ; |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
70 *p1++ = '\0'; |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
71 if (!strcmp(line + 2, "SETCONTEXT")) |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
72 { |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
73 as -> context = strtol(p1, NULL, 10); |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
74 } |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
75 lw_free(line); |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
76 continue; |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
77 } |
332 | 78 printf("%s\n", line); |
337 | 79 |
80 cl = lw_alloc(sizeof(line_t)); | |
81 cl -> next = NULL; | |
82 cl -> prev = as -> line_tail; | |
83 cl -> len = -1; | |
84 cl -> insn = -1; | |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
85 cl -> err = NULL; |
337 | 86 if (!as -> line_tail) |
87 { | |
88 as -> line_head = cl; | |
89 cl -> addr = lw_expr_build(lw_expr_type_int, 0); | |
90 } | |
91 else | |
92 { | |
93 lw_expr_t te; | |
94 as -> line_tail -> next = cl; | |
95 te = lw_expr_build(lw_expr_type_special, lwasm_expr_linelen, cl -> prev); | |
96 cl -> addr = lw_expr_build(lw_expr_type_oper, lw_expr_oper_plus, cl -> prev -> addr, te); | |
97 lw_expr_destroy(te); | |
98 lw_expr_simplify(cl -> addr); | |
99 } | |
100 as -> line_tail = cl; | |
101 | |
340 | 102 // blank lines don't count for anything |
345
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
103 // except a local symbol context break |
340 | 104 if (!*line) |
105 { | |
345
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
106 as -> context = lwasm_next_context(as); |
340 | 107 goto nextline; |
108 } | |
109 | |
110 // skip comments | |
345
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
111 // commends do not create a context break |
340 | 112 if (*line == '*' || *line == ';' || *line == '#') |
113 goto nextline; | |
114 | |
115 p1 = line; | |
116 if (isdigit(*p1)) | |
117 { | |
118 // skip line number | |
119 while (*p1 && isdigit(*p1)) | |
120 p1++; | |
121 if (!*p1 && !isspace(*p1)) | |
122 p1 = line; | |
123 else if (*p1 && isspace(*p1)) | |
124 p1++; | |
125 } | |
126 | |
345
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
127 // blank line - context break |
340 | 128 if (!*p1) |
345
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
129 { |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
130 as -> context = lwasm_next_context(as); |
340 | 131 goto nextline; |
345
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
132 } |
340 | 133 |
345
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
134 // comment - no context break |
340 | 135 if (*p1 == '*' || *p1 == ';' || *p1 == '#') |
136 goto nextline; | |
137 | |
138 if (isspace(*p1)) | |
139 { | |
140 for (; *p1 && isspace(*p1); p1++) | |
141 /* do nothing */ ; | |
142 stspace = 1; | |
143 } | |
144 else | |
145 stspace = 0; | |
146 | |
345
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
147 if (*p1 == '*' || *p1 == ';' || *p1 == '#') |
340 | 148 goto nextline; |
345
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
149 if (!*p1) |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
150 { |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
151 // nothing but whitespace - context break |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
152 as -> context = lwasm_next_context(as); |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
153 goto nextline; |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
154 } |
340 | 155 |
342 | 156 // find the end of the first token |
340 | 157 for (tok = p1; *p1 && !isspace(*p1) && *p1 != ':'; p1++) |
158 /* do nothing */ ; | |
159 | |
160 if (*p1 == ':' || stspace == 0) | |
161 { | |
162 // have a symbol here | |
163 sym = lw_strndup(tok, p1 - tok); | |
164 if (*p1 == ':') | |
165 p1++; | |
166 for (; *p1 && isspace(*p1); p1++) | |
167 /* do nothing */ ; | |
168 | |
169 for (tok = p1; *p1 && !isspace(*p1); p1++) | |
170 /* do nothing */ ; | |
171 } | |
172 | |
173 cl -> sym = sym; | |
174 cl -> symset = 0; | |
175 | |
176 // tok points to the opcode for the line or NUL if none | |
177 if (*tok) | |
178 { | |
179 // look up operation code | |
180 sym = lw_strndup(tok, p1 - tok); | |
181 for (; *p1 && isspace(p1); p1++) | |
182 /* do nothing */ ; | |
183 | |
184 for (opnum = 0; instab[opnum].opcode; opnum++) | |
185 { | |
186 if (!strcasecmp(instab[opnum].opcode, sym)) | |
187 break; | |
188 } | |
189 | |
190 // p1 points to the start of the operand | |
191 | |
345
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
192 // if we're inside a macro definition and not at ENDM, |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
193 // add the line to the macro definition and continue |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
194 if (as -> inmacro && !(instab[opnum].flags & lwasm_insn_endm)) |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
195 { |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
196 add_macro_line(as, line); |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
197 goto linedone; |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
198 } |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
199 |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
200 // if skipping a condition and the operation code doesn't |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
201 // operate within a condition (not a conditional) |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
202 // do nothing |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
203 if (as -> skipcond && !(instab[opnum].flags & lwasm_insn_cond)) |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
204 goto linedone; |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
205 |
340 | 206 if (instab[opnum].opcode == NULL) |
207 { | |
208 cl -> insn = -1; | |
209 if (*tok != ';' && *tok != '*') | |
210 { | |
211 // bad opcode; check for macro here | |
345
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
212 if (expand_macro(as, cl, &p1, sym) != 0) |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
213 { |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
214 // macro expansion failed |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
215 lwasm_register_error(as, cl, "Bad opcode"); |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
216 } |
340 | 217 } |
218 } | |
219 else | |
220 { | |
221 cl -> insn = opnum; | |
345
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
222 // no parse func means operand doesn't matter |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
223 if (instab[opnum].parse) |
340 | 224 { |
345
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
225 // call parse function |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
226 (instab[opnum].parse)(as, cl, &p1); |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
227 |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
228 if (*p1 && !isspace(*p1)) |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
229 { |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
230 // flag bad operand error |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
231 lwasm_register_error(as, cl, "Bad operand (%s)", p1); |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
232 } |
340 | 233 } |
234 } | |
235 } | |
345
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
236 |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
237 linedone: |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
238 lw_free(sym); |
340 | 239 |
345
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
240 if (!as -> skipcond && !as -> inmacro) |
340 | 241 { |
345
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
242 if (cl -> sym && cl -> symset == 0) |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
243 { |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
244 printf("Register symbol %s:", sym); |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
245 lw_expr_print(cl -> addr); |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
246 printf("\n"); |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
247 |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
248 // register symbol at line address |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
249 if (!register_symbol(as, cl, cl -> sym, cl -> addr, symbol_flag_none)) |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
250 { |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
251 // symbol error |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
252 lwasm_register_error(as, cl, "Bad symbol '%s'", cl -> sym); |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
253 } |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
254 } |
7416c3f9c321
Basic macro processor ported forward; added context break handling for local symbols
lost@starbug
parents:
344
diff
changeset
|
255 |
342 | 256 lw_expr_print(cl -> addr); |
257 printf("\n"); | |
340 | 258 } |
259 | |
260 nextline: | |
332 | 261 lw_free(line); |
262 } | |
263 } |