Mercurial > hg-old > index.cgi
annotate lwasm/pass1.c @ 344:0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
author | lost@starbug |
---|---|
date | Thu, 25 Mar 2010 22:06:50 -0600 |
parents | 7b4123dce741 |
children | 7416c3f9c321 |
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; | |
62 printf("%s\n", line); | |
337 | 63 |
64 cl = lw_alloc(sizeof(line_t)); | |
65 cl -> next = NULL; | |
66 cl -> prev = as -> line_tail; | |
67 cl -> len = -1; | |
68 cl -> insn = -1; | |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
69 cl -> err = NULL; |
337 | 70 if (!as -> line_tail) |
71 { | |
72 as -> line_head = cl; | |
73 cl -> addr = lw_expr_build(lw_expr_type_int, 0); | |
74 } | |
75 else | |
76 { | |
77 lw_expr_t te; | |
78 as -> line_tail -> next = cl; | |
79 te = lw_expr_build(lw_expr_type_special, lwasm_expr_linelen, cl -> prev); | |
80 cl -> addr = lw_expr_build(lw_expr_type_oper, lw_expr_oper_plus, cl -> prev -> addr, te); | |
81 lw_expr_destroy(te); | |
82 lw_expr_simplify(cl -> addr); | |
83 } | |
84 as -> line_tail = cl; | |
85 | |
340 | 86 // blank lines don't count for anything |
87 if (!*line) | |
88 { | |
89 goto nextline; | |
90 } | |
91 | |
92 // skip comments | |
93 if (*line == '*' || *line == ';' || *line == '#') | |
94 goto nextline; | |
95 | |
96 p1 = line; | |
97 if (isdigit(*p1)) | |
98 { | |
99 // skip line number | |
100 while (*p1 && isdigit(*p1)) | |
101 p1++; | |
102 if (!*p1 && !isspace(*p1)) | |
103 p1 = line; | |
104 else if (*p1 && isspace(*p1)) | |
105 p1++; | |
106 } | |
107 | |
108 if (!*p1) | |
109 goto nextline; | |
110 | |
111 if (*p1 == '*' || *p1 == ';' || *p1 == '#') | |
112 goto nextline; | |
113 | |
114 if (isspace(*p1)) | |
115 { | |
116 for (; *p1 && isspace(*p1); p1++) | |
117 /* do nothing */ ; | |
118 stspace = 1; | |
119 } | |
120 else | |
121 stspace = 0; | |
122 | |
123 if (*p1 == '*' || *p1 == ';' || *p1 == '#' || !*p1) | |
124 goto nextline; | |
125 | |
342 | 126 // find the end of the first token |
340 | 127 for (tok = p1; *p1 && !isspace(*p1) && *p1 != ':'; p1++) |
128 /* do nothing */ ; | |
129 | |
130 if (*p1 == ':' || stspace == 0) | |
131 { | |
132 // have a symbol here | |
133 sym = lw_strndup(tok, p1 - tok); | |
134 if (*p1 == ':') | |
135 p1++; | |
136 for (; *p1 && isspace(*p1); p1++) | |
137 /* do nothing */ ; | |
138 | |
139 for (tok = p1; *p1 && !isspace(*p1); p1++) | |
140 /* do nothing */ ; | |
141 } | |
142 | |
143 cl -> sym = sym; | |
144 cl -> symset = 0; | |
145 | |
146 // tok points to the opcode for the line or NUL if none | |
147 if (*tok) | |
148 { | |
149 // look up operation code | |
150 sym = lw_strndup(tok, p1 - tok); | |
151 for (; *p1 && isspace(p1); p1++) | |
152 /* do nothing */ ; | |
153 | |
154 for (opnum = 0; instab[opnum].opcode; opnum++) | |
155 { | |
156 if (!strcasecmp(instab[opnum].opcode, sym)) | |
157 break; | |
158 } | |
159 lw_free(sym); | |
160 | |
161 // p1 points to the start of the operand | |
162 | |
163 if (instab[opnum].opcode == NULL) | |
164 { | |
165 cl -> insn = -1; | |
166 if (*tok != ';' && *tok != '*') | |
167 { | |
168 // bad opcode; check for macro here | |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
169 lwasm_register_error(as, cl, "Bad opcode"); |
340 | 170 } |
171 } | |
172 else | |
173 { | |
174 cl -> insn = opnum; | |
175 // call parse function | |
176 | |
177 if (*p1 && !isspace(*p1)) | |
178 { | |
179 // flag bad operand error | |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
180 lwasm_register_error(as, cl, "Bad operand (%s)", p1); |
340 | 181 } |
182 } | |
183 } | |
184 | |
185 if (cl -> sym && cl -> symset == 0) | |
186 { | |
342 | 187 printf("Register symbol %s:", sym); |
188 lw_expr_print(cl -> addr); | |
189 printf("\n"); | |
190 | |
340 | 191 // register symbol at line address |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
192 if (!register_symbol(as, cl, cl -> sym, cl -> addr, symbol_flag_none)) |
342 | 193 { |
194 // symbol error | |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
195 lwasm_register_error(as, cl, "Bad symbol '%s'", cl -> sym); |
342 | 196 } |
340 | 197 } |
198 | |
337 | 199 lw_expr_print(cl -> addr); |
200 printf("\n"); | |
201 // now parse the line | |
202 | |
340 | 203 nextline: |
332 | 204 lw_free(line); |
205 } | |
206 } |