Mercurial > hg-old > index.cgi
comparison 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 |
comparison
equal
deleted
inserted
replaced
344:0215a0fbf61b | 345:7416c3f9c321 |
---|---|
57 { | 57 { |
58 sym = NULL; | 58 sym = NULL; |
59 line = input_readline(as); | 59 line = input_readline(as); |
60 if (!line) | 60 if (!line) |
61 break; | 61 break; |
62 if (line[0] == 1 && line[1] == 1) | |
63 { | |
64 // special internal directive | |
65 // these DO NOT appear in the output anywhere | |
66 // they are generated by the parser to pass information | |
67 // forward | |
68 for (p1 = line + 2; *p1 && !isspace(*p1); p1++) | |
69 /* do nothing */ ; | |
70 *p1++ = '\0'; | |
71 if (!strcmp(line + 2, "SETCONTEXT")) | |
72 { | |
73 as -> context = strtol(p1, NULL, 10); | |
74 } | |
75 lw_free(line); | |
76 continue; | |
77 } | |
62 printf("%s\n", line); | 78 printf("%s\n", line); |
63 | 79 |
64 cl = lw_alloc(sizeof(line_t)); | 80 cl = lw_alloc(sizeof(line_t)); |
65 cl -> next = NULL; | 81 cl -> next = NULL; |
66 cl -> prev = as -> line_tail; | 82 cl -> prev = as -> line_tail; |
82 lw_expr_simplify(cl -> addr); | 98 lw_expr_simplify(cl -> addr); |
83 } | 99 } |
84 as -> line_tail = cl; | 100 as -> line_tail = cl; |
85 | 101 |
86 // blank lines don't count for anything | 102 // blank lines don't count for anything |
103 // except a local symbol context break | |
87 if (!*line) | 104 if (!*line) |
88 { | 105 { |
106 as -> context = lwasm_next_context(as); | |
89 goto nextline; | 107 goto nextline; |
90 } | 108 } |
91 | 109 |
92 // skip comments | 110 // skip comments |
111 // commends do not create a context break | |
93 if (*line == '*' || *line == ';' || *line == '#') | 112 if (*line == '*' || *line == ';' || *line == '#') |
94 goto nextline; | 113 goto nextline; |
95 | 114 |
96 p1 = line; | 115 p1 = line; |
97 if (isdigit(*p1)) | 116 if (isdigit(*p1)) |
103 p1 = line; | 122 p1 = line; |
104 else if (*p1 && isspace(*p1)) | 123 else if (*p1 && isspace(*p1)) |
105 p1++; | 124 p1++; |
106 } | 125 } |
107 | 126 |
127 // blank line - context break | |
108 if (!*p1) | 128 if (!*p1) |
109 goto nextline; | 129 { |
110 | 130 as -> context = lwasm_next_context(as); |
131 goto nextline; | |
132 } | |
133 | |
134 // comment - no context break | |
111 if (*p1 == '*' || *p1 == ';' || *p1 == '#') | 135 if (*p1 == '*' || *p1 == ';' || *p1 == '#') |
112 goto nextline; | 136 goto nextline; |
113 | 137 |
114 if (isspace(*p1)) | 138 if (isspace(*p1)) |
115 { | 139 { |
118 stspace = 1; | 142 stspace = 1; |
119 } | 143 } |
120 else | 144 else |
121 stspace = 0; | 145 stspace = 0; |
122 | 146 |
123 if (*p1 == '*' || *p1 == ';' || *p1 == '#' || !*p1) | 147 if (*p1 == '*' || *p1 == ';' || *p1 == '#') |
124 goto nextline; | 148 goto nextline; |
149 if (!*p1) | |
150 { | |
151 // nothing but whitespace - context break | |
152 as -> context = lwasm_next_context(as); | |
153 goto nextline; | |
154 } | |
125 | 155 |
126 // find the end of the first token | 156 // find the end of the first token |
127 for (tok = p1; *p1 && !isspace(*p1) && *p1 != ':'; p1++) | 157 for (tok = p1; *p1 && !isspace(*p1) && *p1 != ':'; p1++) |
128 /* do nothing */ ; | 158 /* do nothing */ ; |
129 | 159 |
154 for (opnum = 0; instab[opnum].opcode; opnum++) | 184 for (opnum = 0; instab[opnum].opcode; opnum++) |
155 { | 185 { |
156 if (!strcasecmp(instab[opnum].opcode, sym)) | 186 if (!strcasecmp(instab[opnum].opcode, sym)) |
157 break; | 187 break; |
158 } | 188 } |
159 lw_free(sym); | |
160 | 189 |
161 // p1 points to the start of the operand | 190 // p1 points to the start of the operand |
162 | 191 |
192 // if we're inside a macro definition and not at ENDM, | |
193 // add the line to the macro definition and continue | |
194 if (as -> inmacro && !(instab[opnum].flags & lwasm_insn_endm)) | |
195 { | |
196 add_macro_line(as, line); | |
197 goto linedone; | |
198 } | |
199 | |
200 // if skipping a condition and the operation code doesn't | |
201 // operate within a condition (not a conditional) | |
202 // do nothing | |
203 if (as -> skipcond && !(instab[opnum].flags & lwasm_insn_cond)) | |
204 goto linedone; | |
205 | |
163 if (instab[opnum].opcode == NULL) | 206 if (instab[opnum].opcode == NULL) |
164 { | 207 { |
165 cl -> insn = -1; | 208 cl -> insn = -1; |
166 if (*tok != ';' && *tok != '*') | 209 if (*tok != ';' && *tok != '*') |
167 { | 210 { |
168 // bad opcode; check for macro here | 211 // bad opcode; check for macro here |
169 lwasm_register_error(as, cl, "Bad opcode"); | 212 if (expand_macro(as, cl, &p1, sym) != 0) |
213 { | |
214 // macro expansion failed | |
215 lwasm_register_error(as, cl, "Bad opcode"); | |
216 } | |
170 } | 217 } |
171 } | 218 } |
172 else | 219 else |
173 { | 220 { |
174 cl -> insn = opnum; | 221 cl -> insn = opnum; |
175 // call parse function | 222 // no parse func means operand doesn't matter |
176 | 223 if (instab[opnum].parse) |
177 if (*p1 && !isspace(*p1)) | |
178 { | 224 { |
179 // flag bad operand error | 225 // call parse function |
180 lwasm_register_error(as, cl, "Bad operand (%s)", p1); | 226 (instab[opnum].parse)(as, cl, &p1); |
227 | |
228 if (*p1 && !isspace(*p1)) | |
229 { | |
230 // flag bad operand error | |
231 lwasm_register_error(as, cl, "Bad operand (%s)", p1); | |
232 } | |
181 } | 233 } |
182 } | 234 } |
183 } | 235 } |
184 | 236 |
185 if (cl -> sym && cl -> symset == 0) | 237 linedone: |
186 { | 238 lw_free(sym); |
187 printf("Register symbol %s:", sym); | 239 |
240 if (!as -> skipcond && !as -> inmacro) | |
241 { | |
242 if (cl -> sym && cl -> symset == 0) | |
243 { | |
244 printf("Register symbol %s:", sym); | |
245 lw_expr_print(cl -> addr); | |
246 printf("\n"); | |
247 | |
248 // register symbol at line address | |
249 if (!register_symbol(as, cl, cl -> sym, cl -> addr, symbol_flag_none)) | |
250 { | |
251 // symbol error | |
252 lwasm_register_error(as, cl, "Bad symbol '%s'", cl -> sym); | |
253 } | |
254 } | |
255 | |
188 lw_expr_print(cl -> addr); | 256 lw_expr_print(cl -> addr); |
189 printf("\n"); | 257 printf("\n"); |
190 | 258 } |
191 // register symbol at line address | |
192 if (!register_symbol(as, cl, cl -> sym, cl -> addr, symbol_flag_none)) | |
193 { | |
194 // symbol error | |
195 lwasm_register_error(as, cl, "Bad symbol '%s'", cl -> sym); | |
196 } | |
197 } | |
198 | |
199 lw_expr_print(cl -> addr); | |
200 printf("\n"); | |
201 // now parse the line | |
202 | 259 |
203 nextline: | 260 nextline: |
204 lw_free(line); | 261 lw_free(line); |
205 } | 262 } |
206 } | 263 } |