]> cloudbase.mooo.com Git - z180-stamp.git/blame - avr/eval_arg.c
Detect ZRESET polarity
[z180-stamp.git] / avr / eval_arg.c
CommitLineData
fcd2239e
L
1/*
2 * (C) Copyright 2016 Leo C. <erbl259-lmu@yahoo.de>
3 *
4 * SPDX-License-Identifier: GPL-2.0
5 */
6
7#include "eval_arg.h"
8#include "common.h"
9#include <stdlib.h>
10#include <ctype.h>
11#include <setjmp.h>
12#include "print-utils.h"
13#include "command.h" /* jump_buf */
14
15static jmp_buf eval_jbuf;
16static char ch;
17static char *start_p;
18static char *bp;
19
20
21static long expr(void);
22
23static void print_error_pos(void)
24{
25 printf_P(PSTR("Arg: '%s'\n"
26 " "), start_p);
27 print_blanks(bp - start_p);
28 my_puts_P(PSTR("^syntax error!\n"));
29}
30
31static void error (void)
32{
33 --bp;
34 longjmp (eval_jbuf, 1);
35}
36
37static void next(void)
38{
39 do
40 ch = *bp++;
a11e60da 41 while (isspace(ch));
fcd2239e
L
42}
43
44static long number (void)
45{
46 int base = 16;
47 char *end_p;
48 long n;
49
50 if (ch == '$') { /* FIXME: should be '#' */
51 next();
52 base = 10;
53 }
54 if (!isdigit(ch) && !(base == 16 && isxdigit(ch)))
55 error ();
56
57 n = strtoul(bp - 1, &end_p, base);
58
59 if (end_p == bp - 1)
60 error();
61 bp = end_p;
62 next();
63
64 return n;
65}
66
67static long factor (void)
68{
69 long f;
70
71 if (ch == '(')
72 {
73 next();
74 f = expr();
75 if (ch == ')')
76 next();
77 else
78 error ();
a11e60da
L
79 } else {
80 char sign = ch;
81 if (sign == '+' || sign == '-') {
82 next();
83 }
84 f = number();
85 if (sign == '-')
86 f = -f;
fcd2239e 87 }
fcd2239e
L
88 return f;
89}
90
91static long term (void)
92{
93 long t = factor();
94
95 for (;;)
96 switch (ch) {
97 case '*':
98 next();
99 t *= factor();
100 break;
101 case '/':
102 next();
103 t /= factor();
104 break;
105 case '%':
106 next();
107 t %= factor();
108 break;
109 default:
110 return t;
111 }
112}
113
114
115static long expr(void)
116{
a11e60da 117 long e = term ();
fcd2239e
L
118
119 while (ch == '+' || ch == '-') {
120 char op = ch;
121 next();
122 if (op == '-')
123 e -= term ();
124 else
125 e += term ();
126 }
127 return e;
128}
129
130long eval_arg(char *arg, char **end_ptr)
131{
132 long val;
133
134 start_p = arg;
135 bp = arg;
136 next();
137 if (setjmp (eval_jbuf) != 0) {
138 if (!end_ptr) {
139 print_error_pos();
140 longjmp(cmd_jbuf, 1);
141 }
142 val = -1;
143 } else {
144 val = expr ();
145 --bp;
146 }
147
148 if (!end_ptr) {
149 if (*bp != '\0') {
150 print_error_pos();
151 longjmp(cmd_jbuf, 1);
152 }
153 } else
154 *end_ptr = bp;
155
156 return val;
157}