1 /* evaluation of integer expressions */
7 #define SCHAR "icpPvmnu" /* scale indicators */
9 static int defunit
= 0; /* default scale indicator */
10 static int abspos
= 0; /* absolute position like |1i */
12 static int readunit(int c
, int n
)
18 return n
* SC_IN
* 50 / 127;
20 return n
* SC_IN
/ 72;
26 return n
* n_s
* SC_IN
/ 72;
28 return n
* n_s
* SC_IN
/ 144;
35 static int evalnum(char **_s
)
38 int n
= 0; /* the result */
39 int mag
= 0; /* n should be divided by mag */
40 while (isdigit(*s
) || *s
== '.') {
47 n
= n
* 10 + *s
++ - '0';
53 n
= readunit(*s
&& strchr(SCHAR
, *s
) ? *s
++ : defunit
, n
);
55 return n
/ (mag
> 0 ? mag
: 1);
58 static int evaljmp(char **s
, int c
)
67 static int evalisnum(char **s
)
69 return **s
== '.' || isdigit(**s
);
72 static int evalexpr(char **s
);
73 static int evalatom(char **s
);
75 static int evalatom(char **s
)
85 return abspos
+ evalatom(s
);
86 if (!evaljmp(s
, '(')) {
94 static int evalexpr(char **s
)
96 int ret
= evalatom(s
);
100 else if (!evaljmp(s
, '-'))
102 else if (!evaljmp(s
, '/'))
104 else if (!evaljmp(s
, '*'))
106 else if (!evaljmp(s
, '%'))
108 else if (!evaljmp(s
, '<'))
109 ret
= !evaljmp(s
, '=') ? ret
<= evalatom(s
) : ret
< evalatom(s
);
110 else if (!evaljmp(s
, '>'))
111 ret
= !evaljmp(s
, '=') ? ret
>= evalatom(s
) : ret
> evalatom(s
);
112 else if (!evaljmp(s
, '=') + !evaljmp(s
, '='))
113 ret
= ret
== evalatom(s
);
114 else if (!evaljmp(s
, '&'))
115 ret
= ret
&& evalatom(s
);
116 else if (!evaljmp(s
, ':'))
117 ret
= ret
|| evalatom(s
);
124 /* evaluate *s and update s to point to the last character read */
125 int eval_up(char **s
, int unit
)
131 abspos
= n_lb
- f_hpos();
135 /* evaluate s relative to its previous value */
136 int eval_re(char *s
, int orig
, int unit
)
139 int rel
= 0; /* n should be added to orig */
140 if (*s
== '+' || *s
== '-') {
141 rel
= *s
== '+' ? 1 : -1;
144 n
= eval_up(&s
, unit
);
146 return rel
> 0 ? orig
+ n
: orig
- n
;
151 int eval(char *s
, int unit
)
153 return eval_up(&s
, unit
);