# Adventures of a Programmer: Parser Writing Peril XXI

## Constants

Before we can go on to the wild world of chaotic character-concatenations also known as strings we shall not ignore the small but rich village of constants.

The two most used constants in mathematics are $\pi = \frac{C}{d} = 4\arctan 1 = |\sqrt{6\zeta\left(2\right)}|$, $i^2 = -1$ and $e = \lim_{n\to\infty} \left( 1 + \frac{1}{n} \right)^n = \lim_{n\to\infty} \frac{n}{\sqrt[n]{n!}}$. Two of them are mere constants but $i$ is almost always found in multiples.

There are different ways to handle constants syntactically:

• As a reserved word e.g.: “Pi” in GP/PARI by Henri Cohen and François Dress
• With a prefix e.g.: “%pi” in Maxima, based on Macsyma by William Schelter which was itself based on something governmentally influenced
• With a postfix e.g.: “pi#” (but it also allows “pi”) in Mathomatic™ written by the late George John Gesslein II

It is slightly different with $i$. Singular ones are hard to find, they often come in more than just a single one. This might lead one to come up with the idea of prefixing $i$ with a real number, for example 12.34e56i like in Octave for example. Now, what is ideal to be implemented in Little?
If we inspect the short list above a bit closer we see that the programs that lean more on the side of symbolic computation have an affix and those that tend to do more numerical computations have none. GP/PARI, although mainly numerical offers some basic symbolic functions, too. They have $i$ without an affix and define it as a constant with the value $0 + 1i$; an extra operation is necessary to get more of it.
Octave on the other side defines whole imaginary numbers and marks them as such with the suffix “i”, so 0i is equivalent to 0. It also makes the input equal to the output:

octave:1> 123i
ans =    0 + 123i
octave:2> 0i
ans = 0


Little is more or less purely numerical and the way Octave handles it seems fit for us, too. If the parser itself handles it we can save us some headache but have to define Imaginary exactly.

In my last post the definitions for several kinds of number representation have been given. We can put them all together now.

; Imaginary number
imaginary = number "i"
; General number
number    = hex-sequence / dec-sequence / bin-sequence

hex-sequence     = *1sign hex-indicator hex-significand
hex-exponent
hex-exponent     = hex-exponent-indicator *1sign 1*digit
hex-significand  = (*hex-digit "." 1*hex-digit) /
(1*hex-digit ".") /
(1*hex-digit)
hex-indicator          = "0" ("x" /%x58 ) ; 0[xX]
hex-exponent-indicator = "p" / %x50 ; [Pp]
hex-digit     = digit / hexl-owercase / hex-uppercase ; [0-9a-fA-F]
hex-uppercase = %x41-46 ; [A-F] ABNF is case insensitive
hex-lowercase = "a" / "b" / "c" / "d" / "e" / "f"

; Decimal number
dec-sequence     = *1sign dec-significand decimal-exponent
dec-significand  = (*digit "." 1*digit) /
(1*digit ".") /
(1*digit)
; Binary number
bin-sequence     = *1sign bin-indicator bin-significand
decimal-exponent
decimal-exponent = bin-exponent-indicator *1sign 1*digit
bin-significand  = (*bin-digit "." 1*bin-digit) /
(1*bin-digit ".") /
(1*bin-digit)
bin-indicator          = "0" ("b" /%x42 ) ; 0[bB]
bin-exponent-indicator = "e" / %x45 ; [Ee]
bin-digit     = "0" / "1"
digit         = "0" / "1" / "2" / "3" / "4" /
"5" / "6" / "7" / "8" / "9"
sign          = "+" / "-"


I think that was that about defining the term Number.
My next post in this series shall be about strings. Really! Promised! 😉