# Original Parser

## version 1 by Ron Newcomb

**Chapter - TryNumber**

[|TryNumber| takes word number |wordnum| and tries to parse it as an (unsigned)

decimal number or the name of a small number, returning

(a) $-1000$ if it is not a number

(b) the number, if it has between 1 and 4 digits

(c) 10000 if it has 5 or more digits.

(The danger of allowing 5 digits is that Z-machine integers are only 16 bits

long, and anyway this routine isn't meant to be perfect: it only really needs

to be good enough to handle numeric descriptors such as those in TAKE 31 COINS

or DROP FOUR DAGGERS. In particular, it is not the way I7 ``[number]'' tokens

are parsed.)]

To decide what number is the number typed in by the player at (Nth - a number) (this is TryNumber):

save the parser's current word position;

now the parser's current word position is the Nth;

let the num be the next word as digits; [ is it a word like "twenty"? ]

restore the parser's current word position;

if the num is at least 1, decide on the num;

now num is 0; [ otherwise it's in numeric form like "365", so read them a 'letter' at a time, toting them up. ]

let the typed number be the player's input buffer advanced to the Nth word's position of the player's parsed command - 1;

repeat with ith running from 1 to the Nth word's length of the player's parsed command:

let the digit's value be the ith letter of the typed number as a numeric digit;

if the digit's value < 0 or the digit's value > 9, [ then it isn't a numeric digit, so ] decide on -1000;

if num >= 1000, [then we're about to make a five-digit number, a total >= 10,000, so cap it: ] decide on 10000;

now num is (num multiplied by 10) plus the digit's value;

decide on the num.

[ TryNumber wordnum i j c num len mul tot d digit;

i = wn; wn = wordnum; j = NextWord(); wn = i;

j = NumberWord(j); ! Test for verbal forms ONE to THIRTY

if (j >= 1) return j;

#Ifdef TARGET_ZCODE;

i = wordnum*4+1; j = parse->i; num = j+buffer; len = parse->(i-1);

#Ifnot; ! TARGET_GLULX

i = wordnum*3; j = parse-->i; num = j+buffer; len = parse-->(i-1);

#Endif; ! TARGET_

if (len >= 4) mul=1000;

if (len == 3) mul=100;

if (len == 2) mul=10;

if (len == 1) mul=1;

tot = 0; c = 0; len = len-1;

for (c=0 : c<=len : c++) {

digit=num->c;

if (digit == '0') { d = 0; jump digok; }

if (digit == '1') { d = 1; jump digok; }

if (digit == '2') { d = 2; jump digok; }

if (digit == '3') { d = 3; jump digok; }

if (digit == '4') { d = 4; jump digok; }

if (digit == '5') { d = 5; jump digok; }

if (digit == '6') { d = 6; jump digok; }

if (digit == '7') { d = 7; jump digok; }

if (digit == '8') { d = 8; jump digok; }

if (digit == '9') { d = 9; jump digok; }

return -1000;

.digok;

tot = tot+mul*d; mul = mul/10;

}

if (len > 3) tot=10000;

return tot;

]