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((unsigned char) *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((unsigned char) **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 nonzero(int n
)
97 errdie("neatroff: divide by zero\n");
101 static int evalexpr(char **s
)
103 int ret
= evalatom(s
);
105 if (!evaljmp(s
, '+'))
107 else if (!evaljmp(s
, '-'))
109 else if (!evaljmp(s
, '/'))
110 ret
/= nonzero(evalatom(s
));
111 else if (!evaljmp(s
, '*'))
113 else if (!evaljmp(s
, '%'))
114 ret
%= nonzero(evalatom(s
));
115 else if (!evaljmp(s
, '<'))
116 ret
= !evaljmp(s
, '=') ? ret
<= evalatom(s
) : ret
< evalatom(s
);
117 else if (!evaljmp(s
, '>'))
118 ret
= !evaljmp(s
, '=') ? ret
>= evalatom(s
) : ret
> evalatom(s
);
119 else if (!evaljmp(s
, '=') + !evaljmp(s
, '='))
120 ret
= ret
== evalatom(s
);
121 else if (!evaljmp(s
, '&'))
122 ret
= ret
> 0 && evalatom(s
) > 0;
123 else if (!evaljmp(s
, ':'))
124 ret
= ret
> 0 || evalatom(s
) > 0;
131 /* evaluate *s and update s to point to the last character read */
132 int eval_up(char **s
, int unit
)
138 abspos
= n_lb
- f_hpos();
142 /* evaluate s relative to its previous value */
143 int eval_re(char *s
, int orig
, int unit
)
146 int rel
= 0; /* n should be added to orig */
147 if (*s
== '+' || *s
== '-') {
148 rel
= *s
== '+' ? 1 : -1;
151 n
= eval_up(&s
, unit
);
153 return rel
> 0 ? orig
+ n
: orig
- n
;
158 int eval(char *s
, int unit
)
160 return eval_up(&s
, unit
);