annotate src/lwasm.c @ 8:f1df096aa76f 1.1

Tagged 1.1 bugfix release
author lost
date Sun, 04 Jan 2009 05:46:07 +0000
parents 34568fab6058
children 05d4115b4860
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
1 /*
4
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
2 lwasm.c
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
3 Copyright © 2008 William Astle
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
4
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
5 This file is part of LWASM.
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
6
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
7 LWASM is free software: you can redistribute it and/or modify it under the
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
8 terms of the GNU General Public License as published by the Free Software
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
9 Foundation, either version 3 of the License, or (at your option) any later
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
10 version.
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
11
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
12 This program is distributed in the hope that it will be useful, but WITHOUT
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
15 more details.
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
16
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
17 You should have received a copy of the GNU General Public License along with
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
18 this program. If not, see <http://www.gnu.org/licenses/>.
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
19
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
20 Contains the main code for lwasm
34568fab6058 Fixed package to include all required files; also added copyright preamble to all source files
lost
parents: 0
diff changeset
21 */
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
22
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
23 #include <ctype.h>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
24 #include <errno.h>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
25 #include <stdio.h>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
26 #include <stdlib.h>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
27 #include <string.h>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
28 #define __lwasm_c_seen__
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
29 #include "instab.h"
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
30 #include "lwasm.h"
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
31
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
32 void lwasm_read_file(asmstate_t *as, char *fname);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
33 extern int add_macro_line(asmstate_t *as, sourceline_t *cl, char *optr);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
34 extern void expand_macro(asmstate_t *as, sourceline_t *cl, char **optr);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
35
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
36 #define debug(mess, ...) do { if (as->debug) { fprintf(stderr, "DEBUG: "); fprintf(stderr, (mess), ## __VA_ARGS__); } } while (0)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
37
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
38 void register_error(asmstate_t *as, sourceline_t *cl, int errcode)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
39 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
40 errortab_t *e;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
41
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
42 e = malloc(sizeof(errortab_t));
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
43
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
44 e -> errnum = errcode;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
45 e -> line = cl;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
46 e -> next = cl -> errors;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
47 cl -> errors = e;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
48
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
49 as -> errorcount++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
50 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
51
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
52 int eval_expr(asmstate_t *as, sourceline_t *cl, char **optr, int *val);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
53
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
54 int eval_min(int v1, int v2, int v3, int v4)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
55 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
56 if (v2 < v1)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
57 v1 = v2;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
58 if (v3 < v1)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
59 v1 = v3;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
60 if (v4 < v1)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
61 v1 = v4;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
62 return v1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
63 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
64
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
65 int eval_max(int v1, int v2, int v3, int v4)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
66 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
67 if (v2 > v1)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
68 v1 = v2;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
69 if (v3 > v1)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
70 v1 = v3;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
71 if (v4 > v1)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
72 v1 = v4;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
73 return v1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
74 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
75
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
76 int lookupreg3(const char *rlist, char **str)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
77 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
78 int rval = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
79 int f = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
80 const char *reglist = rlist;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
81
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
82 while (*reglist)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
83 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
84 if (toupper(**str) == *reglist)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
85 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
86 // first char matches
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
87 if (reglist[1] == ' ')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
88 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
89 f = 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
90 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
91 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
92 if (toupper(*(*str + 1)) == reglist[1])
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
93 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
94 // second char matches
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
95 if (reglist[2] == ' ')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
96 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
97 f = 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
98 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
99 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
100 if (toupper(*(*str + 2)) == reglist[2])
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
101 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
102 f = 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
103 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
104 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
105 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
106 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
107 reglist += 3;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
108 rval++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
109 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
110 if (f == 0)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
111 return -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
112
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
113
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
114 reglist = rval * 3 + rlist;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
115 if (reglist[1] == ' ')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
116 (*str) += 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
117 else if (reglist[2] == ' ')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
118 (*str) += 2;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
119 else
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
120 (*str)+=3;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
121 return rval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
122 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
123
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
124
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
125 int lookupreg(const char *reglist, char **str)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
126 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
127 int rval = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
128 while (*reglist)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
129 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
130 if (toupper(**str) == *reglist)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
131 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
132 // first char matches
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
133 if (reglist[1] == ' ' && !isalpha(*(*str + 1)))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
134 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
135 if (toupper(*(*str + 1)) == reglist[1])
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
136 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
137 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
138 reglist += 2;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
139 rval++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
140 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
141 if (!*reglist)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
142 return -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
143 if (reglist[1] == ' ')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
144 (*str)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
145 else
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
146 (*str)+=2;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
147 return rval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
148 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
149
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
150 void addcodebyte(asmstate_t *as, sourceline_t *cl, int cb)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
151 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
152 cl -> len += 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
153 if (as -> passnum != 2)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
154 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
155
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
156 if (cl -> numcodebytes >= cl -> codesize)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
157 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
158 cl -> codebytes = realloc(cl -> codebytes, cl -> codesize + 32);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
159 cl -> codesize += 32;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
160 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
161 debug("EMIT: %02x\n", cb & 0xff);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
162 cl -> codebytes[cl -> numcodebytes++] = cb & 0xFF;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
163 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
164
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
165 // parse a symble out of the line and return a pointer
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
166 // to a static pointer
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
167 // return NULL if not a symbol or a bad symbol
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
168 char *parse_symbol(asmstate_t *as, char **ptr)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
169 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
170 static char *symptr = NULL;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
171 char *tptr = *ptr;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
172 int sl = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
173
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
174 // symbol can start with _,a-z,A-Z
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
175
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
176 if (!strchr(SYMCHAR_START, **ptr))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
177 return NULL;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
178
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
179 while (*tptr && !isspace(*tptr) && strchr(SYMCHAR, *tptr))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
180 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
181 tptr++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
182 sl++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
183 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
184
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
185 symptr = realloc(symptr, sl + 1);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
186 tptr = symptr;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
187 while (sl)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
188 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
189 *tptr++ = *(*ptr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
190 sl--;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
191 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
192 *tptr = '\0';
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
193 return symptr;
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 // resolve an instruction
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
197 void resolve_insn(asmstate_t *as, sourceline_t *cl)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
198 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
199 char *optr;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
200 char opbuf[MAX_OP_LEN + 1];
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
201 char *symbol = NULL;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
202 int c;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
203
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
204 cl -> code_symloc = as -> addr;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
205
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
206 cl -> addrset = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
207 cl -> isequ = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
208 cl -> len = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
209 cl -> undef = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
210
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
211 // only parse line on first pass
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
212 if (as -> passnum == 1)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
213 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
214 optr = cl -> line;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
215 if (!*optr || *optr == '*' || *optr == ';')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
216 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
217 cl -> opcode = -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
218 cl -> remainder = cl -> line;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
219 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
220 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
221
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
222 if (!isspace(*optr))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
223 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
224 symbol = parse_symbol(as, &optr);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
225 if (*optr && !isspace(*optr) && !(as -> inmacro))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
226 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
227 errorp1(ERR_BADSYM);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
228 while (*optr && !isspace(*optr))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
229 optr++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
230 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
231 if (symbol)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
232 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
233 cl -> symstr = strdup(symbol);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
234 cl -> hassym = 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
235 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
236 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
237
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
238 while (isspace(*optr))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
239 optr++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
240
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
241 // parse opcode
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
242 if (*optr && *optr != ';')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
243 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
244 c = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
245 while (c < MAX_OP_LEN && *optr && !isspace(*optr))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
246 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
247 opbuf[c++] = *optr++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
248 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
249 opbuf[c] = '\0';
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
250 if (*optr && !isspace(*optr) && !(as -> inmacro))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
251 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
252 errorp1(ERR_BADOP);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
253 cl -> opcode = -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
254 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
255 else
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
256 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
257 cl -> opcstr = strdup(opbuf);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
258 for (c = 0; instab[c].opcode; c++)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
259 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
260 if (!strcasecmp(opbuf, instab[c].opcode))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
261 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
262 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
263 if (!instab[c].opcode && opbuf[0] == '*')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
264 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
265 cl -> opcode = -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
266 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
267 else if (!instab[c].opcode && !(as -> inmacro))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
268 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
269 cl -> opcode = -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
270
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
271 // look up macro
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
272 if (as -> macros)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
273 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
274 macrotab_t *m;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
275
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
276 for (m = as -> macros; m; m = m -> next)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
277 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
278 if (!strcmp(m -> name, opbuf))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
279 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
280 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
281 if (m)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
282 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
283 // we have a macro here
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
284 cl -> macro = m;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
285 while (*optr && isspace(*optr))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
286 optr++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
287 expand_macro(as, cl, &optr);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
288 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
289 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
290 else
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
291 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
292 errorp1(ERR_BADOP);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
293 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
294 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
295 else
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
296 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
297 errorp1(ERR_BADOP);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
298 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
299 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
300 else
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
301 cl -> opcode = c;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
302 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
303 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
304 else
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
305 cl -> opcode = -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
306
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
307 if (as -> inmacro && cl -> opcode >= 0 && instab[cl -> opcode].specialnum != SPECIAL_ENDM)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
308 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
309 add_macro_line(as, cl, cl -> line);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
310 cl -> opcode = -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
311 cl -> remainder = cl -> line;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
312 cl -> opcstr = NULL;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
313 cl -> operstr = NULL;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
314 cl -> symstr = NULL;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
315 cl -> hassym = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
316 cl -> macrodef = 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
317 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
318 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
319 // parse operand
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
320 while (*optr && isspace(*optr))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
321 optr++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
322
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
323 cl -> operstr = optr;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
324 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
325 else
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
326 optr = cl -> operstr;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
327
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
328 if (as -> skipcond)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
329 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
330 // if skipping a condition, need to skip a macro
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
331 if (cl -> opcode >= 0)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
332 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
333 if (instab[cl -> opcode].specialnum == SPECIAL_MACRO)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
334 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
335 as -> skipmacro = 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
336 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
337 else if (instab[cl -> opcode].specialnum == SPECIAL_ENDM)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
338 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
339 as -> skipmacro = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
340 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
341 else if (instab[cl -> opcode].specialnum == SPECIAL_COND && !(as -> skipmacro))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
342 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
343 as -> skipcount++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
344 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
345 else if (instab[cl -> opcode].specialnum == SPECIAL_ENDC && !(as -> skipmacro))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
346 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
347 as -> skipcount--;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
348 if (as -> skipcount <= 0)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
349 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
350 as -> skipcond = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
351 as -> noelse = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
352 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
353 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
354 else if (instab[cl -> opcode].specialnum == SPECIAL_ELSE && !(as -> skipmacro))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
355 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
356 if (as -> skipcount == 1)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
357 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
358 as -> skipcount = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
359 as -> skipcond = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
360 as -> noelse = 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
361 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
362 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
363 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
364 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
365 if (as -> skipcond)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
366 cl -> skipped = 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
367 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
368 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
369
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
370 // do the code thing
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
371 // on pass 1, no code is generated
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
372 // on pass 2, code is generated using the "emit()" macro
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
373 if (cl -> opcode >= 0)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
374 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
375 if (instab[cl -> opcode].opfn)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
376 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
377 (*(instab[cl -> opcode].opfn))(as, cl, &optr);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
378 if (as -> passnum == 1)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
379 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
380 if (*optr)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
381 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
382 char *t = optr;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
383 char t2;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
384
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
385 t2 = *optr;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
386 cl -> operstr = strdup(cl -> operstr);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
387 *optr = t2;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
388 while (*t && isspace(*t))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
389 t++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
390 cl -> remainder = strdup(t);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
391
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
392 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
393 cl -> remainder = optr;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
394 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
395 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
396 else
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
397 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
398 errorp1(ERR_BADOP);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
399 cl -> opcode = -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
400 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
401 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
402 // address of the symbol may have been changed by a pseudo op
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
403 // so we couldn't register it above
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
404 // that means it may turn out to be a "forward ref" in pass 1
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
405 if (cl -> hassym)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
406 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
407 register_symbol(as, cl, cl -> symstr, cl -> code_symloc, cl -> isset ? SYMFLAG_SET : SYMFLAG_NONE);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
408 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
409
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
410 as -> addr += cl -> len;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
411 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
412
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
413 void generate_code(asmstate_t *as)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
414 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
415 sourceline_t *cl;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
416
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
417 as -> addr = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
418 as -> dpval = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
419 as -> passnum = 2;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
420 for (cl = as -> source_head; cl; cl = cl -> next)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
421 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
422 resolve_insn(as, cl);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
423 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
424 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
425
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
426 void lwasm_read_file(asmstate_t *as, char *fname)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
427 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
428 FILE *f;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
429 int cline = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
430 sourceline_t *cl;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
431 size_t bufflen;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
432 char *buff = NULL;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
433 int retval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
434
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
435 as -> passnum = 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
436
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
437 f = fopen(fname, "r");
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
438 if (!f)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
439 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
440 fprintf(stderr, "Cannot open input file %s: %s\n", fname, strerror(errno));
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
441 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
442 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
443
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
444 while (!feof(f))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
445 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
446 retval = getline(&buff, &bufflen, f);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
447 debug(" read line (%s:%d): %s\n", fname, cline, buff);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
448 if (retval < 0)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
449 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
450 if (feof(f))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
451 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
452 fprintf(stderr, "Error reading '%s': %s\n", fname, strerror(errno));
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
453 exit(1);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
454 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
455 if (strchr(buff, '\n'))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
456 *strchr(buff, '\n') = '\0';
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
457 if (strchr(buff, '\r'))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
458 *strchr(buff, '\r') = '\0';
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
459 cl = calloc(sizeof(sourceline_t), 1);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
460 if (!cl)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
461 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
462 perror("Malloc");
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
463 exit(1);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
464 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
465
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
466 cl -> lineno = cline++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
467 cl -> sourcefile = fname;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
468 cl -> opcode = -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
469 cl -> addrmode = -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
470 cl -> addr = as -> addr;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
471 cl -> dpval = as -> dpval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
472 cl -> prev = as -> source_tail;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
473 if (as -> source_tail)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
474 as -> source_tail -> next = cl;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
475 as -> source_tail = cl;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
476 if (as -> source_head == NULL)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
477 as -> source_head = cl;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
478 cl -> line = strdup(buff);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
479
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
480 resolve_insn(as, cl);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
481
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
482 if (cl -> opcode >= 0 && instab[cl -> opcode].instype == INSTYPE_PSEUDO && instab[cl -> opcode].specialnum == SPECIAL_END)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
483 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
484
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
485 *buff = '\0';
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
486
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
487 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
488 if (buff)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
489 free(buff);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
490
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
491 fclose(f);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
492
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
493 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
494 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
495
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
496 /*
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
497 below this point is the expression evaluation package
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
498
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
499 Supported binary operators: + - / * %
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
500 Supported unary operators: -
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
501
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
502 <infix>: + | - | * | / | %
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
503 <unary>: -
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
504 <expr>: <term> <infix> <term>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
505 <term>: <unary> <term>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
506 <term>: ( <expr> )
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
507 <term>: <symbol>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
508 <term>: ' <char>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
509 <term>: " <char> <char>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
510 <term>: *
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
511 <term>: <number>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
512
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
513 <number>: <dec>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
514 <number>: & <dec>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
515
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
516 <number>: $ <hex>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
517 <number>: <hex> H
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
518 <number>: @ <oct>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
519 <number>: <oct> O
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
520 <number>: <oct> Q
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
521
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
522 <number>: % <bin>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
523 <number>: <bin> B
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
524
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
525 <bin>: 0 | 1
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
526 <oct>: <bin> | 2 | 3 | 4 | 5 | 6 | 7
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
527 <dec>: <oct> | 8 | 9
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
528 <hex>: <dec> | A | B | C | D | E | F
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
529
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
530 NOTE: hex values which start with a non-digit will need to be prefixed
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
531 by $ or have a 0 as the leading digit; hence: $CC or 0CCH otherwise the
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
532 assembler cannot tell the difference between CCH as a symbol or CCH as
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
533 the value $CC
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
534
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
535 */
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
536
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
537 // will throw an error and return 0 in tval if there's a problem
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
538 // -1 is problem; cl -> undef set is undefined symbol
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
539 int eval_term(asmstate_t *as, sourceline_t *cl, char **optr, int *tval)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
540 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
541 char tc;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
542 int rval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
543 int binval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
544 int octval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
545 int decval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
546 int hexval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
547 int valtype;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
548 int digval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
549 int bindone = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
550
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
551 *tval = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
552
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
553 beginagain:
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
554 tc = **optr;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
555 if (tc == '+')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
556 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
557 // unary +, ignored for symetry
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
558 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
559 goto beginagain;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
560 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
561
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
562 if (tc == '(')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
563 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
564 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
565 rval = eval_expr(as, cl, optr, tval);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
566 if (rval < 0)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
567 return rval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
568 if (**optr != ')')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
569 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
570 errorp1(ERR_BADEXPR);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
571 return -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
572 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
573 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
574 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
575 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
576
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
577 if (tc == '-')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
578 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
579 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
580 rval = eval_term(as, cl, optr, tval);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
581 if (rval < 0)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
582 return rval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
583 *tval = -*tval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
584 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
585 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
586
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
587 // current address (of current instruction, not PC)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
588 if (tc == '*')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
589 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
590 *tval = cl -> addr;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
591 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
592 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
593 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
594
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
595 if (strchr("abcdefghijklmnopqrstuvwxyz_", tolower(tc)))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
596 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
597 // evaluate a symbol
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
598 char *symbuf;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
599
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
600 symbuf = parse_symbol(as, optr);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
601 if (!symbuf)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
602 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
603 errorp1(ERR_BADSYM);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
604 *tval = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
605 return -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
606 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
607
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
608 debug(" looking up symbol: %s\n", symbuf);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
609 *tval = lookup_symbol(as, symbuf);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
610
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
611 // if not found, flag forward ref
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
612 if (*tval == -1)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
613 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
614 errorp2(ERR_UNDEF);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
615 cl -> undef = 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
616 *tval = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
617 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
618 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
619 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
620 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
621
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
622 if (tc == '%')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
623 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
624 // binary number
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
625 int v1 = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
626 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
627 while (strchr("01", **optr))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
628 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
629 v1 = v1 << 1 | ((*(*optr)++) - '0');
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
630 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
631 *tval = v1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
632 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
633 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
634 if (tc == '$')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
635 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
636 // hex number
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
637 int v1 = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
638 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
639 debug("HEX CONST: %s\n", *optr);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
640 while (**optr && strchr("01234567890ABCDEF", toupper(tc = **optr)))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
641 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
642 debug("HEX 2: %02x\n", tc);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
643 if (**optr >= 'A')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
644 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
645 v1 = v1 << 4 | (toupper((*(*optr)++)) - 'A' + 10);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
646 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
647 else
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
648 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
649 v1 = v1 << 4 | ((*(*optr)++) - '0');
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
650 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
651 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
652 *tval = v1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
653 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
654 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
655 if (tc == '@')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
656 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
657 // octal number
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
658 int v1 = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
659 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
660 while (strchr("01234567", **optr))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
661 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
662 v1 = v1 << 3 | ((*(*optr)++) - '0');
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
663 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
664 *tval = v1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
665 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
666 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
667 if (tc == '&')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
668 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
669 // decimal number
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
670 int v1 = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
671 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
672 while (strchr("0123456789", **optr))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
673 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
674 v1 = v1 * 10 + ((*(*optr)++) - '0');
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
675 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
676 *tval = v1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
677 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
678 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
679 if (tc == '\'')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
680 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
681 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
682 if (!**optr)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
683 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
684 errorp1(ERR_BADEXPR);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
685 return -2;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
686 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
687 *tval = *(*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
688 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
689 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
690 if (tc == '"')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
691 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
692 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
693 if (!**optr || !*(*optr + 1))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
694 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
695 errorp1(ERR_BADEXPR);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
696 return -2;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
697 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
698 *tval = *(*optr)++ << 8 | *(*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
699 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
700 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
701 // end of string
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
702 if (tc == '\0')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
703 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
704 // error if at EOS as we are looking for a term
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
705 errorp1(ERR_BADEXPR);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
706 return -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
707 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
708
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
709 // we have a generic number here which may be decimal, hex, binary, or octal
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
710 // based on a suffix
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
711
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
712 // possible data types are binary (1), octal (2), decimal(4), hex (8)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
713 valtype = 15;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
714 hexval = octval = decval = binval = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
715 while (1)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
716 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
717
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
718 // printf(" %c\n", **optr);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
719 if (!**optr || !strchr("ABCDEFabcdefqhoQHO0123456789", **optr))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
720 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
721 // end of string, must be decimal or the end of a bin
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
722 if (bindone == 1)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
723 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
724 *tval = binval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
725 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
726 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
727 if (valtype & 4)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
728 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
729 *tval = decval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
730 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
731 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
732 else
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
733 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
734 errorp1(ERR_BADEXPR);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
735 return -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
736 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
737 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
738 tc = toupper(*(*optr)++);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
739
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
740 if (tc == 'H')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
741 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
742 if (valtype & 8)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
743 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
744 *tval = hexval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
745 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
746 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
747 else
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
748 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
749 // syntax error
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
750 errorp1(ERR_BADEXPR);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
751 return -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
752 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
753 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
754
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
755 if (tc == 'Q' || tc == 'O')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
756 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
757 if (valtype && 2)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
758 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
759 *tval = octval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
760 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
761 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
762 else
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
763 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
764 errorp1(ERR_BADEXPR);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
765 return -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
766 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
767 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
768
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
769 digval = tc - '0';
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
770 if (digval > 9)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
771 digval -= 7;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
772
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
773 // if it's not in the range of a hex digit, error out
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
774 if (tc < '0' || (tc > '9' && tc < 'A') || tc > 'F')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
775 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
776 (*optr)--;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
777 if (valtype & 4)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
778 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
779 *tval = decval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
780 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
781 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
782 // if we're in hex/bin mode and run to the end of the number
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
783 // we must have a binary constant or an error
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
784 // if the previous character is B, then we have binary
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
785 // else we have error since hex would require a terminating H
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
786 // which would be caught above
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
787 if (valtype == 8 && toupper(*(*optr)) == 'B')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
788 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
789 *tval = binval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
790 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
791 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
792 errorp1(ERR_BADEXPR);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
793 return -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
794 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
795
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
796 // if we have any characters past the end of the B, it's not binary
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
797 if (bindone == 1)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
798 bindone = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
799 if (tc == 'B')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
800 bindone = 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
801 if (digval > 1)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
802 valtype &= 14;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
803 else if (digval > 7)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
804 valtype &= 13;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
805 else if (digval > 9)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
806 valtype &= 11;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
807
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
808 if (valtype & 8)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
809 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
810 hexval = (hexval << 4) | digval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
811 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
812 if (valtype & 4)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
813 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
814 decval = decval * 10 + digval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
815 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
816 if (valtype & 2)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
817 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
818 octval = (octval << 3) | digval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
819 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
820 if (valtype & 1 && !bindone)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
821 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
822 binval = (binval << 1) | digval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
823 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
824
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
825 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
826 // can't get here from there
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
827 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
828
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
829 // returns -1 if the expression cannot be parsed
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
830 // and returns -2 if there is an undefined symbol reference
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
831 // resulting value will be in *val; undefined symbols are parsed as
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
832 // value 0 but cl -> undef will be set.
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
833 int eval_expr(asmstate_t *as, sourceline_t *cl, char **optr, int *val)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
834 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
835 int left;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
836 int right;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
837 char oper;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
838 int rval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
839
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
840 // by default, return 0 in val
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
841 *val = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
842 cl -> undef = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
843
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
844 rval = eval_term(as, cl, optr, &left);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
845 if (rval < 0)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
846 return rval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
847
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
848 nextop:
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
849 oper = **optr;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
850
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
851 // end of expr
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
852 if (isspace(oper) || oper == ',' || oper == '\0' || oper == ']' || oper == ')')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
853 goto retleft;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
854
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
855 // unrecognized chars
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
856 if (!strchr("+-*/%", oper))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
857 goto retleft;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
858
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
859 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
860
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
861 rval = eval_term(as, cl, optr, &right);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
862 // propagate error
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
863 if (rval < 0)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
864 return rval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
865
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
866 // do the operation and put it in "left"
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
867 switch (oper)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
868 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
869 case '+':
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
870 left += right;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
871 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
872
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
873 case '-':
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
874 left -= right;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
875 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
876
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
877 case '*':
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
878 left *= right;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
879 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
880
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
881 case '/':
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
882 left /= right;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
883 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
884
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
885 case '%':
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
886 left %= right;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
887 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
888 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
889
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
890 goto nextop;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
891
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
892 retleft:
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
893 *val = left;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
894 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
895 }