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