Mercurial > hg-old > index.cgi
annotate src/lwasm.c @ 55:8e32696380f3
added expression evaluation and checking function
author | lost |
---|---|
date | Sun, 04 Jan 2009 21:42:54 +0000 |
parents | b9856da2674a |
children | 035b95a3690f |
rev | line source |
---|---|
0 | 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 |
55 | 3 Copyright © 2009 William Astle |
4
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 |
26 | 20 |
21 Contains random functions used by the assembler | |
4
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
22 */ |
0 | 23 |
26 | 24 #define __lwasm_c_seen__ |
25 | |
26 #include <stdarg.h> | |
0 | 27 #include <stdlib.h> |
26 | 28 #include <stdio.h> |
29 | |
0 | 30 #include "lwasm.h" |
26 | 31 #include "util.h" |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
32 #include "expr.h" |
0 | 33 |
38 | 34 int debug_level = 0; |
35 | |
26 | 36 int register_error(asmstate_t *as, lwasm_line_t *l, int pass, const char *fmt, ...) |
0 | 37 { |
26 | 38 lwasm_error_t *e; |
39 va_list args; | |
40 char errbuff[1024]; | |
41 int r; | |
0 | 42 |
26 | 43 if (as -> passnum != pass) |
44 return; | |
45 | |
46 va_start(args, fmt); | |
0 | 47 |
26 | 48 e = lwasm_alloc(sizeof(lwasm_error_t)); |
49 | |
50 e -> next = l -> err; | |
51 l -> err = e; | |
0 | 52 |
53 as -> errorcount++; | |
54 | |
26 | 55 r = vsnprintf(errbuff, 1024, fmt, args); |
56 e -> mess = lwasm_strdup(errbuff); | |
0 | 57 |
26 | 58 va_end(args); |
0 | 59 |
26 | 60 return r; |
0 | 61 } |
27
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
62 |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
63 void lwasm_emit(asmstate_t *as, lwasm_line_t *l, int b) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
64 { |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
65 as -> addr += 1; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
66 |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
67 if (as -> passnum == 1) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
68 return; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
69 |
42 | 70 |
71 if (l -> codelen >= l -> codesize) | |
72 { | |
73 l -> bytes = realloc(l -> bytes, l -> codesize + 16); | |
74 l -> codesize += 16; | |
75 } | |
76 l -> bytes[l -> codelen] = b & 0xff; | |
77 l -> codelen += 1; | |
27
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
78 } |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
79 |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
80 void lwasm_emitop(asmstate_t *as, lwasm_line_t *l, int o) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
81 { |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
82 if (o >= 0x100) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
83 lwasm_emit(as, l, o >> 8); |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
84 lwasm_emit(as, l, o & 0xff); |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
85 } |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
86 |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
87 int lwasm_lookupreg2(const char *reglist, char **str) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
88 { |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
89 int rval = 0; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
90 |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
91 while (*reglist) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
92 { |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
93 if (toupper(**str) == *reglist) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
94 { |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
95 // first char matches |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
96 if (reglist[1] == ' ' && !isalpha(*(*str + 1))) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
97 break; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
98 if (toupper(*(*str + 1)) == reglist[1]) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
99 break; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
100 } |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
101 reglist += 2; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
102 rval++; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
103 } |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
104 if (!*reglist) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
105 return -1; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
106 if (reglist[1] == ' ') |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
107 (*str)++; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
108 else |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
109 (*str) += 2; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
110 return rval; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
111 } |
32 | 112 |
113 int lwasm_lookupreg3(const char *rlist, const char **str) | |
114 { | |
115 int rval = 0; | |
116 int f = 0; | |
117 const char *reglist = rlist; | |
118 | |
119 while (*reglist) | |
120 { | |
121 if (toupper(**str) == *reglist) | |
122 { | |
123 // first char matches | |
124 if (reglist[1] == ' ') | |
125 { | |
126 f = 1; | |
127 break; | |
128 } | |
129 if (toupper(*(*str + 1)) == reglist[1]) | |
130 { | |
131 // second char matches | |
132 if (reglist[2] == ' ') | |
133 { | |
134 f = 1; | |
135 break; | |
136 } | |
137 if (toupper(*(*str + 2)) == reglist[2]) | |
138 { | |
139 f = 1; | |
140 break; | |
141 } | |
142 } | |
143 } | |
144 reglist += 3; | |
145 rval++; | |
146 } | |
147 if (f == 0) | |
148 return -1; | |
149 | |
150 | |
151 reglist = rval * 3 + rlist; | |
152 if (reglist[1] == ' ') | |
153 (*str) += 1; | |
154 else if (reglist[2] == ' ') | |
155 (*str) += 2; | |
156 else | |
157 (*str)+=3; | |
158 return rval; | |
159 } | |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
160 |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
161 struct symstateinfo |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
162 { |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
163 asmstate_t *as; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
164 lwasm_line_t *l; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
165 }; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
166 |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
167 int lwasm_expr_lookup_symbol(char *sym, void *state, int *val) |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
168 { |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
169 lwasm_symbol_ent_t *se; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
170 struct symstateinfo *st; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
171 |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
172 st = state; |
52 | 173 debug_message(3, "lwasm_expr_lookup_symbol(): find '%s' (context=%d)", sym, st -> as -> context); |
174 | |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
175 // look for local symbol first then global symbol |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
176 se = lwasm_find_symbol(st -> as, sym, st -> as -> context); |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
177 if (!se) |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
178 se = lwasm_find_symbol(st -> as, sym, -1); |
52 | 179 debug_message(3, "lwasm_expr_lookup_symbol(): got '%p'", se); |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
180 if (!se) |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
181 return -1; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
182 *val = se -> value; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
183 return 0; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
184 } |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
185 |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
186 lwasm_expr_stack_t *lwasm_evaluate_expr(asmstate_t *as, lwasm_line_t *l, const char *inp, const char **outp) |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
187 { |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
188 struct symstateinfo st; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
189 |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
190 st.as = as; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
191 st.l = l; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
192 |
38 | 193 debug_message(2, "Evaluate expression: %s", inp); |
194 | |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
195 return(lwasm_expr_eval(inp, outp, lwasm_expr_lookup_symbol, &st)); |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
196 } |
38 | 197 |
55 | 198 int lwasm_expr_result(asmstate_t *as, lwasm_line_t *l, char **inp, int flag, int *val) |
199 { | |
200 lwasm_expr_stack_t *s; | |
201 char *ep; | |
202 int rval; | |
203 | |
204 s = lwasm_evaluate_expr(as, l, *inp, &ep); | |
205 if (!s) | |
206 { | |
207 register_error(as, l, 1, "Bad expression"); | |
208 *val = 0; | |
209 return -1; | |
210 } | |
211 *inp = ep; | |
212 | |
213 if (flag & EXPR_PASS1CONST && as -> passnum == 1 && !lwasm_expr_is_constant(s)) | |
214 { | |
215 register_error(as, l, 1, "Illegal incomplete reference (pass 1)"); | |
216 *val = 0; | |
217 lwasm_expr_stack_free(s); | |
218 return -1; | |
219 } | |
220 if (flag & EXPR_PASS2CONST && as -> passnum == 2 && !lwasm_expr_is_constant(s)) | |
221 { | |
222 register_error(as, l, 2, "Incomplete reference (pass 2)"); | |
223 *val = 0; | |
224 lwasm_expr_stack_free(s); | |
225 return -1; | |
226 } | |
227 *val = lwasm_expr_get_value(s); | |
228 lwasm_expr_stack_free(s); | |
229 | |
230 if (flag & EXPR_BYTE && as -> passnum == 2 && (*val < -128 || *val > 255)) | |
231 { | |
232 register_error(as, l, 2, "Byte overflow"); | |
233 *val &= 0xff; | |
234 return -1; | |
235 } | |
236 if (flag & EXPR_BYTE) | |
237 { | |
238 *val &= 0xff; | |
239 } | |
240 | |
241 return 0; | |
242 } | |
243 | |
38 | 244 void debug_message(int level, const char *fmt, ...) |
245 { | |
246 va_list args; | |
247 | |
248 va_start(args, fmt); | |
249 if (debug_level >= level) | |
250 { | |
39 | 251 if (level > 0) |
252 fprintf(stderr, "DEBUG %d: ", level); | |
38 | 253 vfprintf(stderr, fmt, args); |
254 fputc('\n', stderr); | |
255 } | |
256 va_end(args); | |
257 } |