1 /************************************************************************
2 * This program is Copyright (C) 1986-1996 by Jonathan Payne. JOVE is *
3 * provided to you without charge, and with no warranty. You may give *
4 * away copies of JOVE, including sources, provided that this notice is *
5 * included in all the files. *
6 ************************************************************************/
7
8 #include "jove.h"
9 #include "jctype.h"
10
11 int arg_state = AS_NONE,
12 arg_count;
13
14 void
negate_arg()15 negate_arg()
16 {
17 if (arg_count < 0) {
18 arg_count = -arg_count;
19 if (arg_count < 0)
20 complain("arg count overflow");
21 } else {
22 arg_count = -arg_count;
23 }
24 }
25
26 private void
gather_argument(ns,nc)27 gather_argument(ns, nc)
28 int
29 ns, /* new state */
30 nc; /* new count */
31 {
32 for (;;) {
33 ZXchar c;
34 bool neg = NO;
35
36 if (arg_count < 0) {
37 neg = YES;
38 negate_arg();
39 }
40 if (ns != arg_state) {
41 /* First time in this state */
42 arg_state = ns;
43 arg_count = nc; /* ignore previous value (but remember sign) */
44 } else {
45 /* Continuing in this state. */
46 int t = arg_count;
47
48 switch (ns) {
49 case AS_NUMERIC:
50 t = t*10 + nc; /* add a digit to previous value */
51 break;
52 case AS_NEGSIGN:
53 neg = !neg; /* change previous sign */
54 break;
55 case AS_TIMES:
56 t *= nc; /* multiply by factor */
57 break;
58 }
59 if (t < arg_count)
60 complain("arg count overflow");
61 arg_count = t;
62 }
63 if (neg)
64 negate_arg();
65
66 /* Treat a following digit as AS_NUMERIC.
67 * If in AS_TIMES, accept a '-'.
68 */
69 c = waitchar();
70 if (jisdigit(c)) {
71 ns = AS_NUMERIC;
72 nc = c - '0';
73 } else if (arg_state==AS_TIMES && c=='-') {
74 ns = AS_NEGSIGN; /* forget multiplication */
75 nc = -1;
76 } else {
77 Ungetc(c);
78 break;
79 }
80 }
81 this_cmd = ARG_CMD;
82 }
83
84 void
TimesFour()85 TimesFour()
86 {
87 gather_argument(AS_TIMES, 4);
88 }
89
90 void
Digit()91 Digit()
92 {
93 if (LastKeyStruck == '-')
94 gather_argument(AS_NEGSIGN, -1);
95 else if (jisdigit(LastKeyStruck))
96 gather_argument(AS_NUMERIC, LastKeyStruck - '0');
97 else
98 complain((char *)NULL);
99 }
100
101 void
Digit0()102 Digit0()
103 {
104 gather_argument(AS_NUMERIC, 0);
105 }
106
107 void
Digit1()108 Digit1()
109 {
110 gather_argument(AS_NUMERIC, 1);
111 }
112
113 void
Digit2()114 Digit2()
115 {
116 gather_argument(AS_NUMERIC, 2);
117 }
118
119 void
Digit3()120 Digit3()
121 {
122 gather_argument(AS_NUMERIC, 3);
123 }
124
125 void
Digit4()126 Digit4()
127 {
128 gather_argument(AS_NUMERIC, 4);
129 }
130
131 void
Digit5()132 Digit5()
133 {
134 gather_argument(AS_NUMERIC, 5);
135 }
136
137 void
Digit6()138 Digit6()
139 {
140 gather_argument(AS_NUMERIC, 6);
141 }
142
143 void
Digit7()144 Digit7()
145 {
146 gather_argument(AS_NUMERIC, 7);
147 }
148
149 void
Digit8()150 Digit8()
151 {
152 gather_argument(AS_NUMERIC, 8);
153 }
154
155 void
Digit9()156 Digit9()
157 {
158 gather_argument(AS_NUMERIC, 9);
159 }
160
161 void
DigitMinus()162 DigitMinus()
163 {
164 gather_argument(AS_NEGSIGN, -1);
165 }
166