1 /***********************************************************************
2 *
3 * AVRA - Assembler for the Atmel AVR microcontroller series
4 *
5 * Copyright (C) 1998-2020 The AVRA Authors
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; see the file COPYING. If not, write to
19 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
21 *
22 *
23 * Authors of AVRA can be reached at:
24 * email: jonah@omegav.ntnu.no, tobiw@suprafluid.com
25 * www: https://github.com/Ro5bert/avra
26 */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <ctype.h>
32
33 #include "misc.h"
34 #include "avra.h"
35 #include "device.h"
36
37 #define IS_UNARY(x) ((x == '!') || (x == '-') || (x == '~'))
38 #define IS_OPERATOR(x) ((x == '+') || (x == '-') || (x == '*') || (x == '/') || (x == '%') || (x == '<') || (x == '>') || (x == '=') || (x == '!') || (x == '&') || (x == '^') || (x == '|'))
39 #define IS_2ND_OPERATOR(x) ((x == '<') || (x == '>') || (x == '=') || (x == '&') || (x == '|'))
40
41 enum {
42 OPERATOR_ERROR = 0,
43 OPERATOR_MUL,
44 OPERATOR_DIV,
45 OPERATOR_MOD,
46 OPERATOR_ADD,
47 OPERATOR_SUB,
48 OPERATOR_SHIFT_LEFT,
49 OPERATOR_SHIFT_RIGHT,
50 OPERATOR_LESS_THAN,
51 OPERATOR_LESS_OR_EQUAL,
52 OPERATOR_GREATER_THAN,
53 OPERATOR_GREATER_OR_EQUAL,
54 OPERATOR_EQUAL,
55 OPERATOR_NOT_EQUAL,
56 OPERATOR_BITWISE_AND,
57 OPERATOR_BITWISE_XOR,
58 OPERATOR_BITWISE_OR,
59 OPERATOR_LOGICAL_AND,
60 OPERATOR_LOGICAL_OR
61 };
62
63 enum {
64 FUNCTION_LOW = 0,
65 FUNCTION_BYTE1,
66 FUNCTION_HIGH,
67 FUNCTION_BYTE2,
68 FUNCTION_BYTE3,
69 FUNCTION_BYTE4,
70 FUNCTION_LWRD,
71 FUNCTION_HWRD,
72 FUNCTION_PAGE,
73 FUNCTION_EXP2,
74 FUNCTION_LOG2,
75 FUNCTION_COUNT
76 };
77
78 struct element {
79 struct element *next;
80 int data;
81 };
82
83 char *function_list[] = {
84 /* allow whitespace between function name
85 * and opening brace... */
86 "low",
87 "byte1",
88 "high",
89 "byte2",
90 "byte3",
91 "byte4",
92 "lwrd",
93 "hwrd",
94 "page",
95 "exp2",
96 "log2"
97 };
98
99 int
log_2(int value)100 log_2(int value)
101 {
102 int i = 0;
103 while (value >>= 1)
104 i++;
105 return (i);
106 }
107
108 int
get_operator(char * op)109 get_operator(char *op)
110 {
111 switch (op[0]) {
112 case '*':
113 return (OPERATOR_MUL);
114 case '/':
115 return (OPERATOR_DIV);
116 case '%':
117 return (OPERATOR_MOD);
118 case '+':
119 return (OPERATOR_ADD);
120 case '-':
121 return (OPERATOR_SUB);
122 case '<':
123 switch (op[1]) {
124 case '<':
125 return (OPERATOR_SHIFT_LEFT);
126 case '=':
127 return (OPERATOR_LESS_OR_EQUAL);
128 default:
129 return (OPERATOR_LESS_THAN);
130 }
131 case '>':
132 switch (op[1]) {
133 case '>':
134 return (OPERATOR_SHIFT_RIGHT);
135 case '=':
136 return (OPERATOR_GREATER_OR_EQUAL);
137 default:
138 return (OPERATOR_GREATER_THAN);
139 }
140 case '=':
141 if (op[1] == '=')
142 return (OPERATOR_EQUAL);
143 case '!':
144 if (op[1] == '=')
145 return (OPERATOR_NOT_EQUAL);
146 case '&':
147 if (op[1] == '&')
148 return (OPERATOR_LOGICAL_AND);
149 else
150 return (OPERATOR_BITWISE_AND);
151 case '^':
152 return (OPERATOR_BITWISE_XOR);
153 case '|':
154 if (op[1] == '|')
155 return (OPERATOR_LOGICAL_OR);
156 else
157 return (OPERATOR_BITWISE_OR);
158 }
159 return (OPERATOR_ERROR);
160 }
161
162
163
164
165 int
test_operator_at_precedence(int operator,int precedence)166 test_operator_at_precedence(int operator, int precedence)
167 {
168 switch (precedence) {
169 case 13:
170 return ((operator == OPERATOR_MUL) || (operator == OPERATOR_DIV)
171 || (operator == OPERATOR_MOD));
172 case 12:
173 return ((operator == OPERATOR_ADD) || (operator == OPERATOR_SUB));
174 case 11:
175 return ((operator == OPERATOR_SHIFT_LEFT) || (operator == OPERATOR_SHIFT_RIGHT));
176 case 10:
177 return ((operator == OPERATOR_LESS_THAN) || (operator == OPERATOR_LESS_OR_EQUAL)
178 || (operator == OPERATOR_GREATER_THAN) || (operator == OPERATOR_GREATER_OR_EQUAL));
179 case 9:
180 return ((operator == OPERATOR_EQUAL) || (operator == OPERATOR_NOT_EQUAL));
181 case 8:
182 return (operator == OPERATOR_BITWISE_AND);
183 case 7:
184 return (operator == OPERATOR_BITWISE_XOR);
185 case 6:
186 return (operator == OPERATOR_BITWISE_OR);
187 case 5:
188 return (operator == OPERATOR_LOGICAL_AND);
189 default: /* Makes the compiler shut up */
190 case 4:
191 return (operator == OPERATOR_LOGICAL_OR);
192 }
193 }
194
195
196 int
calc(struct prog_info * pi,int left,int operator,int right)197 calc(struct prog_info *pi, int left, int operator, int right) /* TODO: Sjekk litt resultater */
198 {
199 switch (operator) {
200 case OPERATOR_MUL:
201 return (left * right);
202 case OPERATOR_DIV:
203 if (right == 0) {
204 print_msg(pi, MSGTYPE_ERROR, "Division by zero");
205 return (0);
206 }
207 return (left / right);
208 case OPERATOR_MOD:
209 if (right == 0) {
210 print_msg(pi, MSGTYPE_ERROR, "Division by zero (modulus operator)");
211 return (0);
212 }
213 return (left % right);
214 case OPERATOR_ADD:
215 return (left + right);
216 case OPERATOR_SUB:
217 return (left - right);
218 case OPERATOR_SHIFT_LEFT:
219 return (left << right);
220 case OPERATOR_SHIFT_RIGHT:
221 return ((unsigned)left >> right);
222 case OPERATOR_LESS_THAN:
223 return (left < right);
224 case OPERATOR_LESS_OR_EQUAL:
225 return (left <= right);
226 case OPERATOR_GREATER_THAN:
227 return (left > right);
228 case OPERATOR_GREATER_OR_EQUAL:
229 return (left >= right);
230 case OPERATOR_EQUAL:
231 return (left == right);
232 case OPERATOR_NOT_EQUAL:
233 return (left != right);
234 case OPERATOR_BITWISE_AND:
235 return (left & right);
236 case OPERATOR_BITWISE_XOR:
237 return (left ^ right);
238 case OPERATOR_BITWISE_OR:
239 return (left | right);
240 case OPERATOR_LOGICAL_AND:
241 return (left && right);
242 default: /* Make the compiler shut up */
243 case OPERATOR_LOGICAL_OR:
244 return (left || right);
245 }
246 }
247
248 /* If found, return the ID of the internal function */
249 int
get_function(char * function)250 get_function(char *function)
251 {
252 int i;
253
254 for (i = 0; i < FUNCTION_COUNT; i++) {
255 if (!nocase_strncmp(function, function_list[i], strlen(function_list[i]))) {
256 /* some more checks to allow whitespace between function name
257 * and opening brace... */
258 char *tmp = function + strlen(function_list[i]);
259 while (*tmp <= ' ')
260 tmp++;
261 if (*tmp != '(')
262 continue;
263
264 return (i);
265 }
266 }
267 return (-1);
268 }
269
270 unsigned int
do_function(int function,int value)271 do_function(int function, int value)
272 {
273 switch (function) {
274 case FUNCTION_LOW:
275 case FUNCTION_BYTE1:
276 return (value & 0xFF);
277 case FUNCTION_HIGH:
278 case FUNCTION_BYTE2:
279 return ((value >> 8) & 0xff);
280 case FUNCTION_BYTE3:
281 return ((value >> 16) & 0xff);
282 case FUNCTION_BYTE4:
283 return ((value >> 24) & 0xff);
284 case FUNCTION_LWRD:
285 return (value & 0xffff);
286 case FUNCTION_HWRD:
287 return ((value >> 16) & 0xffff);
288 case FUNCTION_PAGE:
289 return ((value >> 16) & 0xff);
290 case FUNCTION_EXP2:
291 return (1 << value);
292 case FUNCTION_LOG2:
293 return (log_2(value));
294 default:
295 return (0);
296 }
297 }
298
299
300 int
get_symbol(struct prog_info * pi,char * label_name,int * data)301 get_symbol(struct prog_info *pi, char *label_name, int *data)
302 {
303 struct label *label;
304 struct macro_call *macro_call;
305
306 if (get_constant(pi,label_name,data)) return (True);
307 if (get_variable(pi,label_name,data)) return (True);
308
309 for (macro_call = pi->macro_call; macro_call; macro_call = macro_call->prev_on_stack) {
310 for (label = pi->macro_call->first_label; label; label = label->next)
311 if (!nocase_strcmp(label->name, label_name)) {
312 if (data)
313 *data = label->value;
314 return (True);
315 }
316 }
317
318 if (get_label(pi,label_name,data)) return (True);
319 return (False);
320 }
321
322
323 int
par_length(char * data)324 par_length(char *data)
325 {
326 int i = 0, b_count = 1;
327
328 for (;;) {
329 if (data[i] == ')') {
330 b_count--;
331 if (!b_count)
332 return (i);
333 } else if (data[i] == '(')
334 b_count++;
335 else if (data[i] == '\0')
336 return (-1);
337 i++;
338 }
339 }
340
341 int
get_expr(struct prog_info * pi,char * data,int * value)342 get_expr(struct prog_info *pi, char *data, int *value)
343 {
344 /* Definition */
345 int ok, end, i, count, first_flag, length, function;
346 char unary, *label;
347 struct element *element, *first_element = NULL, *temp_element;
348 struct element **last_element = &first_element;
349
350 /* Initialisation */
351 first_flag = True;
352 ok = True;
353 end = False;
354 count = 0;
355 unary = 0;
356 /* the expression parser loop */
357 for (i = 0; ; i++) {
358 /* horizontal space is just skipped */
359 if (IS_HOR_SPACE(data[i]));
360 /* test for clean or premature end */
361 else if (IS_END_OR_COMMENT(data[i])) {
362 if ((count % 2) != 1)
363 print_msg(pi, MSGTYPE_ERROR, "Missing value in expression");
364 else
365 end = True;
366 break;
367 } else if (first_flag && IS_UNARY(data[i])) {
368 unary = data[i];
369 first_flag = False;
370 } else if ((count % 2) == 1) {
371 if (!IS_OPERATOR(data[i])) {
372 print_msg(pi, MSGTYPE_ERROR, "Illegal operator '%c'", data[i]);
373 break;
374 }
375 element = malloc(sizeof(struct element));
376 if (!element) {
377 print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
378 ok = False;
379 break;
380 }
381 element->next = NULL;
382 element->data = get_operator(&data[i]);
383 if (element->data == OPERATOR_ERROR) {
384 if (IS_2ND_OPERATOR(data[i + 1]))
385 print_msg(pi, MSGTYPE_ERROR, "Unknown operator %c%c", data[i], data[i + 1]);
386 else
387 print_msg(pi, MSGTYPE_ERROR, "Unknown operator %c", data[i]);
388 break;
389 }
390 *last_element = element;
391 last_element = &element->next;
392 if (IS_2ND_OPERATOR(data[i + 1]))
393 i++;
394 count++;
395 first_flag = True;
396 unary = 0;
397 } else {
398 element = malloc(sizeof(struct element));
399 if (!element) {
400 print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
401 ok = False;
402 break;
403 }
404 element->next = NULL;
405 length = 0;
406 if (isdigit(data[i])) {
407 if (tolower(data[i + 1]) == 'x') {
408 i += 2;
409 while (isxdigit(data[i + length])) length++; /* TODO: Sjekk overflow */
410 element->data = atox_n(&data[i], length);
411 } else if (tolower(data[i + 1]) == 'b') {
412 i += 2;
413 element->data = 0;
414 while ((data[i + length] == '1') || (data[i + length] == '0')) {
415 element->data <<= 1;
416 element->data |= data[i + length++] - '0'; /* TODO: Sjekk overflow */
417 }
418 } else {
419 while (isdigit(data[i + length])) length++;
420 element->data = atoi_n(&data[i], length); /* TODO: Sjekk overflow */
421 }
422 } else if (data[i] == '$') {
423 i++;
424 while (isxdigit(data[i + length])) length++;
425 element->data = atox_n(&data[i], length); /* TODO: Sjekk overflow */
426 } else if (data[i] == '\'') {
427 i++;
428 if (data[i+1] != '\'') {
429 print_msg(pi, MSGTYPE_ERROR, "Not a correct character ! Use 'A' !");
430 break;
431 }
432 element->data = data[i];
433 length = 2;
434 } else if (data[i] == '(') {
435 i++;
436 length = par_length(&data[i]);
437 if (length == -1) {
438 print_msg(pi, MSGTYPE_ERROR, "Missing ')'");
439 break;
440 }
441 data[i + length++] = '\0';
442 ok = get_expr(pi, &data[i], &element->data);
443 if (!ok)
444 break;
445 }
446 /* test for internal function */
447 else if ((function = get_function(&data[i])) != -1) {
448 while (data[i] != '(')
449 i++;
450 i++;
451 length = par_length(&data[i]);
452 if (length == -1) {
453 print_msg(pi, MSGTYPE_ERROR, "Missing ')'");
454 break;
455 }
456 data[i + length++] = '\0';
457 ok = get_expr(pi, &data[i], &element->data);
458 if (!ok)
459 break;
460 element->data = do_function(function, element->data);
461 } else if (!nocase_strncmp(&data[i], "defined(", 8)) {
462 i += 8;
463 length = par_length(&data[i]);
464 if (length == -1) {
465 print_msg(pi, MSGTYPE_ERROR, "Missing ')'");
466 break;
467 }
468 data[i + length++] = '\0';
469 if (get_symbol(pi, &data[i], NULL))
470 element->data = 1;
471 else
472 element->data = 0;
473 } else if (!nocase_strncmp(&data[i], "supported(", 10)) {
474 i += 10;
475 length = par_length(&data[i]);
476 if (length == -1) {
477 print_msg(pi, MSGTYPE_ERROR, "Missing ')'");
478 break;
479 }
480 data[i + length++] = '\0';
481 element->data=is_supported(pi, &data[i]);
482 if (element->data<0) {
483 if (toupper(data[i])=='X') {
484 if (pi->device->flag&DF_NO_XREG) element->data = 0;
485 else element->data = 1;
486 } else if (toupper(data[i])=='Y') {
487 if (pi->device->flag&DF_NO_YREG) element->data = 0;
488 else element->data = 1;
489 } else if (toupper(data[i])=='Z')
490 element->data = 1;
491 else {
492 print_msg(pi, MSGTYPE_ERROR, "Unknown mnemonic: %s",&data[i]);
493 element->data = 0;
494 }
495 }
496 } else {
497 while (IS_LABEL(data[i + length])) length++;
498 if ((length == 2) && !nocase_strncmp(&data[i], "PC", 2))
499 element->data = pi->cseg->addr;
500 else {
501 label = malloc(length + 1);
502 if (!label) {
503 print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
504 ok = False;
505 break;
506 }
507 strncpy(label, &data[i], length);
508 label[length] = '\0';
509 if (get_symbol(pi, label, &element->data))
510 free(label);
511 else {
512 print_msg(pi, MSGTYPE_ERROR, "Found no label/variable/constant named %s", label);
513 free(label);
514 break;
515 }
516 }
517 }
518 /* now the expression has been evaluated */
519 i += length - 1;
520 switch (unary) { /* TODO: F� den til � takle flere unary p� rad. */
521 case '-':
522 element->data = -element->data;
523 break;
524 case '!':
525 element->data = !element->data;
526 break;
527 case '~':
528 element->data = ~element->data;
529 }
530 *last_element = element;
531 last_element = &element->next;
532 count++;
533 first_flag = False;
534 }
535 }
536 if (end) {
537 for (i = 13; (i >= 4) && (count != 1); i--) {
538 for (element = first_element; element->next;) {
539 if (test_operator_at_precedence(element->next->data, i)) { /* TODO: Vurder en hi_i for kjapphet */
540 element->data = calc(pi, element->data, element->next->data, element->next->next->data);
541 temp_element = element->next->next->next;
542 free(element->next->next);
543 free(element->next);
544 count -= 2;
545 element->next = temp_element;
546 } else
547 element = element->next->next;
548 }
549 }
550 *value = first_element->data;
551 }
552 for (element = first_element; element;) {
553 temp_element = element;
554 element = element->next;
555 free(temp_element);
556 }
557 return (ok);
558 }
559
560
561 /* end of expr.c */
562
563