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