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