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