annotate src/lwasm.c @ 13:05d4115b4860

Started work on new expression evaluator system and major code re-work for next release
author lost
date Wed, 22 Oct 2008 04:51:16 +0000
parents 34568fab6058
children d2e86babd958
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
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
427 /*
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
428 below this point is the expression evaluation package
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
429
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
430 Supported binary operators: + - / * %
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
431 Supported unary operators: -
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
432
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
433 <infix>: + | - | * | / | %
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
434 <unary>: -
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
435 <expr>: <term> <infix> <term>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
436 <term>: <unary> <term>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
437 <term>: ( <expr> )
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
438 <term>: <symbol>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
439 <term>: ' <char>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
440 <term>: " <char> <char>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
441 <term>: *
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
442 <term>: <number>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
443
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
444 <number>: <dec>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
445 <number>: & <dec>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
446
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
447 <number>: $ <hex>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
448 <number>: <hex> H
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
449 <number>: @ <oct>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
450 <number>: <oct> O
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
451 <number>: <oct> Q
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
452
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
453 <number>: % <bin>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
454 <number>: <bin> B
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
455
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
456 <bin>: 0 | 1
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
457 <oct>: <bin> | 2 | 3 | 4 | 5 | 6 | 7
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
458 <dec>: <oct> | 8 | 9
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
459 <hex>: <dec> | A | B | C | D | E | F
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
460
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
461 NOTE: hex values which start with a non-digit will need to be prefixed
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
462 by $ or have a 0 as the leading digit; hence: $CC or 0CCH otherwise the
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
463 assembler cannot tell the difference between CCH as a symbol or CCH as
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
464 the value $CC
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
465
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
466 */
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
467
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
468 // will throw an error and return 0 in tval if there's a problem
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
469 // -1 is problem; cl -> undef set is undefined symbol
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
470 int eval_term(asmstate_t *as, sourceline_t *cl, char **optr, int *tval)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
471 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
472 char tc;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
473 int rval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
474 int binval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
475 int octval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
476 int decval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
477 int hexval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
478 int valtype;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
479 int digval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
480 int bindone = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
481
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
482 *tval = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
483
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
484 beginagain:
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
485 tc = **optr;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
486 if (tc == '+')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
487 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
488 // unary +, ignored for symetry
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
489 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
490 goto beginagain;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
491 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
492
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
493 if (tc == '(')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
494 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
495 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
496 rval = eval_expr(as, cl, optr, tval);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
497 if (rval < 0)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
498 return rval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
499 if (**optr != ')')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
500 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
501 errorp1(ERR_BADEXPR);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
502 return -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
503 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
504 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
505 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
506 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
507
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
508 if (tc == '-')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
509 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
510 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
511 rval = eval_term(as, cl, optr, tval);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
512 if (rval < 0)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
513 return rval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
514 *tval = -*tval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
515 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
516 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
517
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
518 // current address (of current instruction, not PC)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
519 if (tc == '*')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
520 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
521 *tval = cl -> addr;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
522 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
523 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
524 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
525
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
526 if (strchr("abcdefghijklmnopqrstuvwxyz_", tolower(tc)))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
527 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
528 // evaluate a symbol
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
529 char *symbuf;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
530
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
531 symbuf = parse_symbol(as, optr);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
532 if (!symbuf)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
533 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
534 errorp1(ERR_BADSYM);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
535 *tval = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
536 return -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
537 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
538
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
539 debug(" looking up symbol: %s\n", symbuf);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
540 *tval = lookup_symbol(as, symbuf);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
541
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
542 // if not found, flag forward ref
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
543 if (*tval == -1)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
544 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
545 errorp2(ERR_UNDEF);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
546 cl -> undef = 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
547 *tval = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
548 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
549 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
550 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
551 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
552
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
553 if (tc == '%')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
554 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
555 // binary number
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
556 int v1 = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
557 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
558 while (strchr("01", **optr))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
559 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
560 v1 = v1 << 1 | ((*(*optr)++) - '0');
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
561 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
562 *tval = v1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
563 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
564 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
565 if (tc == '$')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
566 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
567 // hex number
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
568 int v1 = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
569 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
570 debug("HEX CONST: %s\n", *optr);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
571 while (**optr && strchr("01234567890ABCDEF", toupper(tc = **optr)))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
572 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
573 debug("HEX 2: %02x\n", tc);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
574 if (**optr >= 'A')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
575 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
576 v1 = v1 << 4 | (toupper((*(*optr)++)) - 'A' + 10);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
577 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
578 else
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
579 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
580 v1 = v1 << 4 | ((*(*optr)++) - '0');
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
581 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
582 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
583 *tval = v1;
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 if (tc == '@')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
587 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
588 // octal number
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
589 int v1 = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
590 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
591 while (strchr("01234567", **optr))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
592 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
593 v1 = v1 << 3 | ((*(*optr)++) - '0');
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
594 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
595 *tval = v1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
596 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
597 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
598 if (tc == '&')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
599 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
600 // decimal number
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
601 int v1 = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
602 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
603 while (strchr("0123456789", **optr))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
604 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
605 v1 = v1 * 10 + ((*(*optr)++) - '0');
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
606 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
607 *tval = v1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
608 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
609 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
610 if (tc == '\'')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
611 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
612 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
613 if (!**optr)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
614 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
615 errorp1(ERR_BADEXPR);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
616 return -2;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
617 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
618 *tval = *(*optr)++;
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 if (tc == '"')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
622 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
623 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
624 if (!**optr || !*(*optr + 1))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
625 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
626 errorp1(ERR_BADEXPR);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
627 return -2;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
628 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
629 *tval = *(*optr)++ << 8 | *(*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
630 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
631 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
632 // end of string
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
633 if (tc == '\0')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
634 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
635 // error if at EOS as we are looking for a term
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
636 errorp1(ERR_BADEXPR);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
637 return -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
638 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
639
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
640 // we have a generic number here which may be decimal, hex, binary, or octal
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
641 // based on a suffix
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
642
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
643 // possible data types are binary (1), octal (2), decimal(4), hex (8)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
644 valtype = 15;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
645 hexval = octval = decval = binval = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
646 while (1)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
647 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
648
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
649 // printf(" %c\n", **optr);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
650 if (!**optr || !strchr("ABCDEFabcdefqhoQHO0123456789", **optr))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
651 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
652 // end of string, must be decimal or the end of a bin
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
653 if (bindone == 1)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
654 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
655 *tval = binval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
656 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
657 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
658 if (valtype & 4)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
659 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
660 *tval = decval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
661 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
662 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
663 else
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
664 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
665 errorp1(ERR_BADEXPR);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
666 return -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
667 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
668 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
669 tc = toupper(*(*optr)++);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
670
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
671 if (tc == 'H')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
672 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
673 if (valtype & 8)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
674 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
675 *tval = hexval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
676 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
677 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
678 else
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
679 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
680 // syntax error
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
681 errorp1(ERR_BADEXPR);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
682 return -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
683 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
684 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
685
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
686 if (tc == 'Q' || tc == 'O')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
687 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
688 if (valtype && 2)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
689 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
690 *tval = octval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
691 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
692 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
693 else
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 -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
697 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
698 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
699
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
700 digval = tc - '0';
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
701 if (digval > 9)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
702 digval -= 7;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
703
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
704 // if it's not in the range of a hex digit, error out
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
705 if (tc < '0' || (tc > '9' && tc < 'A') || tc > 'F')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
706 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
707 (*optr)--;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
708 if (valtype & 4)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
709 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
710 *tval = decval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
711 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
712 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
713 // if we're in hex/bin mode and run to the end of the number
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
714 // we must have a binary constant or an error
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
715 // if the previous character is B, then we have binary
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
716 // else we have error since hex would require a terminating H
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
717 // which would be caught above
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
718 if (valtype == 8 && toupper(*(*optr)) == 'B')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
719 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
720 *tval = binval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
721 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
722 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
723 errorp1(ERR_BADEXPR);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
724 return -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
725 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
726
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
727 // if we have any characters past the end of the B, it's not binary
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
728 if (bindone == 1)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
729 bindone = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
730 if (tc == 'B')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
731 bindone = 1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
732 if (digval > 1)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
733 valtype &= 14;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
734 else if (digval > 7)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
735 valtype &= 13;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
736 else if (digval > 9)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
737 valtype &= 11;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
738
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
739 if (valtype & 8)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
740 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
741 hexval = (hexval << 4) | digval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
742 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
743 if (valtype & 4)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
744 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
745 decval = decval * 10 + digval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
746 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
747 if (valtype & 2)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
748 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
749 octval = (octval << 3) | digval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
750 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
751 if (valtype & 1 && !bindone)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
752 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
753 binval = (binval << 1) | digval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
754 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
755
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
756 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
757 // can't get here from there
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
758 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
759
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
760 // returns -1 if the expression cannot be parsed
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
761 // and returns -2 if there is an undefined symbol reference
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
762 // resulting value will be in *val; undefined symbols are parsed as
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
763 // value 0 but cl -> undef will be set.
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
764 int eval_expr(asmstate_t *as, sourceline_t *cl, char **optr, int *val)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
765 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
766 int left;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
767 int right;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
768 char oper;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
769 int rval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
770
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
771 // by default, return 0 in val
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
772 *val = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
773 cl -> undef = 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
774
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
775 rval = eval_term(as, cl, optr, &left);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
776 if (rval < 0)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
777 return rval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
778
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
779 nextop:
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
780 oper = **optr;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
781
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
782 // end of expr
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
783 if (isspace(oper) || oper == ',' || oper == '\0' || oper == ']' || oper == ')')
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
784 goto retleft;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
785
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
786 // unrecognized chars
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
787 if (!strchr("+-*/%", oper))
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
788 goto retleft;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
789
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
790 (*optr)++;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
791
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
792 rval = eval_term(as, cl, optr, &right);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
793 // propagate error
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
794 if (rval < 0)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
795 return rval;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
796
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
797 // do the operation and put it in "left"
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
798 switch (oper)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
799 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
800 case '+':
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
801 left += right;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
802 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
803
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
804 case '-':
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
805 left -= right;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
806 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
807
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
808 case '*':
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
809 left *= right;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
810 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
811
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
812 case '/':
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
813 left /= right;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
814 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
815
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
816 case '%':
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
817 left %= right;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
818 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
819 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
820
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
821 goto nextop;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
822
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
823 retleft:
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
824 *val = left;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
825 return 0;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
826 }