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