Add BOOL token_type, macros, and boolean operators
For clarity, it is valuable for the results of comparisons to show as "true" and "false" rather than "1" and "0". This change implements a BOOL type to facilitate that. Since we want logical operators to short-circuit, this change also obliges the introduction of macros, which are just like functions except their arguments are not evaluated before control is passed to the routine implementing the macro.
This commit is contained in:
parent
7e0ba7370d
commit
892fdcdb75
10 changed files with 871 additions and 688 deletions
341
doc/teapot.lyx
341
doc/teapot.lyx
|
@ -647,7 +647,7 @@ Paper
|
|||
|
||||
\begin_layout Standard
|
||||
As the last step, save your work sheet to a file: F)ile, S)ave.
|
||||
The native file format is XDR, so choose that.
|
||||
The native file format is Teapot ASCII, so choose that.
|
||||
Up to now, your sheet does not have a name, so you will be prompted for
|
||||
one:
|
||||
\end_layout
|
||||
|
@ -4872,8 +4872,26 @@ Integer Integer values are exact, their range depends on the C type long
|
|||
An example is:
|
||||
\family typewriter
|
||||
42
|
||||
\family default
|
||||
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
Boolean
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
true
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
or
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
false,
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
used for logical conditions.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
|
@ -4919,6 +4937,93 @@ Unlike other spreadsheets, the operators in teapot check the type of the
|
|||
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
x
|
||||
\series medium
|
||||
\emph on
|
||||
|
||||
\begin_inset space ~
|
||||
\end_inset
|
||||
|
||||
|
||||
\family typewriter
|
||||
\series default
|
||||
\emph default
|
||||
and
|
||||
\family default
|
||||
\series medium
|
||||
\emph on
|
||||
|
||||
\begin_inset space ~
|
||||
\end_inset
|
||||
|
||||
|
||||
\series default
|
||||
\emph default
|
||||
y evaluates to the logical conjunction of boolean values
|
||||
\emph on
|
||||
x
|
||||
\emph default
|
||||
and
|
||||
\emph on
|
||||
y
|
||||
\emph default
|
||||
.
|
||||
Note that this evaluation short-circuits: if
|
||||
\emph on
|
||||
x
|
||||
\emph default
|
||||
is false, then
|
||||
\emph on
|
||||
y
|
||||
\emph default
|
||||
is never evaluated, and so does not affect the value even if it is an error,
|
||||
for example.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
x
|
||||
\series medium
|
||||
\emph on
|
||||
|
||||
\begin_inset space ~
|
||||
\end_inset
|
||||
|
||||
|
||||
\family typewriter
|
||||
\series default
|
||||
\emph default
|
||||
or
|
||||
\family default
|
||||
\series medium
|
||||
\emph on
|
||||
|
||||
\begin_inset space ~
|
||||
\end_inset
|
||||
|
||||
|
||||
\series default
|
||||
\emph default
|
||||
y evaluates to the logical disjunction of boolean values
|
||||
\emph on
|
||||
x
|
||||
\emph default
|
||||
and
|
||||
\emph on
|
||||
y
|
||||
\emph default
|
||||
.
|
||||
As with
|
||||
\family typewriter
|
||||
and
|
||||
\family default
|
||||
, this evaluation short-circuits if
|
||||
\emph on
|
||||
x
|
||||
\emph default
|
||||
is true.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
|
||||
\series bold
|
||||
|
@ -4932,7 +5037,7 @@ x
|
|||
y
|
||||
\series default
|
||||
\emph default
|
||||
evaluates to 1 if
|
||||
evaluates to Boolean true if
|
||||
\emph on
|
||||
x
|
||||
\emph default
|
||||
|
@ -4979,7 +5084,7 @@ x
|
|||
y
|
||||
\series default
|
||||
\emph default
|
||||
evaluates to 1 if
|
||||
evaluates to true if
|
||||
\emph on
|
||||
x
|
||||
\emph default
|
||||
|
@ -5004,7 +5109,7 @@ x
|
|||
y
|
||||
\series default
|
||||
\emph default
|
||||
evaluates to 1 if
|
||||
evaluates to true if
|
||||
\emph on
|
||||
x
|
||||
\emph default
|
||||
|
@ -5029,7 +5134,7 @@ x
|
|||
y
|
||||
\series default
|
||||
\emph default
|
||||
evaluates to 1 if
|
||||
evaluates to true if
|
||||
\emph on
|
||||
x
|
||||
\emph default
|
||||
|
@ -5055,7 +5160,7 @@ x
|
|||
y
|
||||
\series default
|
||||
\emph default
|
||||
evaluates to 1 if
|
||||
evaluates to true if
|
||||
\emph on
|
||||
x
|
||||
\emph default
|
||||
|
@ -5079,7 +5184,7 @@ x
|
|||
y
|
||||
\series default
|
||||
\emph default
|
||||
evaluates to 1 if the floating point value
|
||||
evaluates to true if the floating point value
|
||||
\emph on
|
||||
x
|
||||
\emph default
|
||||
|
@ -5088,8 +5193,9 @@ x
|
|||
y
|
||||
\emph default
|
||||
.
|
||||
Almost equal means, the numbers are at most neighbours.
|
||||
It is an error to use this with any type but float.
|
||||
Almost equal means that the numbers are equal or neighbor each other in
|
||||
the floating point representation being used.
|
||||
It is an error to use this comparison with any type but float.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
|
@ -5116,6 +5222,26 @@ y
|
|||
.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
Note: a string of consecutive relational operators is interpreted as the
|
||||
conjunction of each consecutive (overlapping) pair.
|
||||
Thus
|
||||
\family typewriter
|
||||
2 <= y() <= 10
|
||||
\family default
|
||||
will evaluate to true precisely in rows 2 through 10, inclusive (it is
|
||||
shorthand for
|
||||
\family typewriter
|
||||
2 <= y() and y() <= 10
|
||||
\family default
|
||||
).
|
||||
Similarly
|
||||
\family typewriter
|
||||
@(cell1) == @(cell2) == @(cell3)
|
||||
\family default
|
||||
will return true exactly when all three cells have the same value.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
|
||||
\series bold
|
||||
|
@ -5129,7 +5255,7 @@ x
|
|||
y
|
||||
\series default
|
||||
\emph default
|
||||
evaluates to the sum if
|
||||
evaluates to the sum if
|
||||
\emph on
|
||||
x
|
||||
\emph default
|
||||
|
@ -5148,16 +5274,6 @@ y
|
|||
\emph default
|
||||
are strings, the result is the concatenated string.
|
||||
If they are locations, this operates componentwise.
|
||||
There is no dedicated logical
|
||||
\noun on
|
||||
or
|
||||
\noun default
|
||||
operation, so use
|
||||
\family typewriter
|
||||
+
|
||||
\family default
|
||||
for that.
|
||||
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
|
@ -5173,7 +5289,7 @@ x
|
|||
y
|
||||
\series default
|
||||
\emph default
|
||||
evaluates to the difference if
|
||||
evaluates to the difference if
|
||||
\emph on
|
||||
x
|
||||
\emph default
|
||||
|
@ -5198,7 +5314,7 @@ x
|
|||
y
|
||||
\series default
|
||||
\emph default
|
||||
evaluates to the product if
|
||||
evaluates to the product if
|
||||
\emph on
|
||||
x
|
||||
\emph default
|
||||
|
@ -5207,15 +5323,6 @@ x
|
|||
y
|
||||
\emph default
|
||||
are numbers.
|
||||
There is no dedicated logical
|
||||
\noun on
|
||||
and
|
||||
\noun default
|
||||
operation, so use
|
||||
\family typewriter
|
||||
*
|
||||
\family default
|
||||
for that.
|
||||
You can multiply a location by an integer, or take the dot product of the
|
||||
coordinates of two locations (although the use case for that is unclear).
|
||||
\end_layout
|
||||
|
@ -5233,7 +5340,7 @@ x
|
|||
y
|
||||
\series default
|
||||
\emph default
|
||||
evaluates to the quotient if
|
||||
evaluates to the quotient if
|
||||
\emph on
|
||||
x
|
||||
\emph default
|
||||
|
@ -5258,7 +5365,7 @@ x
|
|||
y
|
||||
\series default
|
||||
\emph default
|
||||
evaluates to the remainder of the division if
|
||||
evaluates to the remainder of the division if
|
||||
\emph on
|
||||
x
|
||||
\emph default
|
||||
|
@ -5273,24 +5380,6 @@ y
|
|||
|
||||
\begin_layout Description
|
||||
|
||||
\series bold
|
||||
\emph on
|
||||
x^y
|
||||
\series default
|
||||
\emph default
|
||||
evaluates to
|
||||
\emph on
|
||||
x
|
||||
\emph default
|
||||
to the power of
|
||||
\emph on
|
||||
y
|
||||
\emph default
|
||||
.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
|
||||
\family typewriter
|
||||
\series bold
|
||||
-
|
||||
|
@ -5310,13 +5399,38 @@ x
|
|||
\emph on
|
||||
x
|
||||
\emph default
|
||||
is a number or location.
|
||||
is a number or location, or the negation of
|
||||
\emph on
|
||||
x
|
||||
\emph default
|
||||
if
|
||||
\emph on
|
||||
x
|
||||
\emph default
|
||||
is Boolean.
|
||||
If
|
||||
\emph on
|
||||
x
|
||||
\emph default
|
||||
is empty, the result will be empty, too.
|
||||
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
|
||||
\series bold
|
||||
\emph on
|
||||
x^y
|
||||
\series default
|
||||
\emph default
|
||||
evaluates to
|
||||
\emph on
|
||||
x
|
||||
\emph default
|
||||
to the power of
|
||||
\emph on
|
||||
y
|
||||
\emph default
|
||||
.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
|
@ -5517,8 +5631,8 @@ the arguments are interpreted in exactly the same way as for
|
|||
\series bold
|
||||
&
|
||||
\series default
|
||||
with no arguments or even parentheses evaluates to the location of the
|
||||
current cell.
|
||||
with no arguments (with or without parentheses) evaluates to the location
|
||||
of the current cell.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
|
@ -5603,14 +5717,21 @@ displaced (by).
|
|||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
Thus,
|
||||
Thus, both
|
||||
\family sans
|
||||
\series bold
|
||||
D
|
||||
\series default
|
||||
(-1)
|
||||
\family default
|
||||
returns the location of the cell immediately to the left of this one, and
|
||||
and
|
||||
\family sans
|
||||
\series bold
|
||||
D
|
||||
\series default
|
||||
(left)
|
||||
\family default
|
||||
return the location of the cell immediately to the left of this one, and
|
||||
\family sans
|
||||
\series bold
|
||||
D
|
||||
|
@ -5690,12 +5811,19 @@ R
|
|||
\series default
|
||||
(,,1)
|
||||
\family default
|
||||
returns the same cell as this one but on the following layer, as does
|
||||
returns the same cell as this one but on the following layer, as do
|
||||
\family sans
|
||||
\series bold
|
||||
R
|
||||
\series default
|
||||
(&(0,0,1)
|
||||
\family default
|
||||
) and
|
||||
\family sans
|
||||
\series bold
|
||||
R
|
||||
\series default
|
||||
(&(0,0,1)
|
||||
(below
|
||||
\family default
|
||||
), but
|
||||
\family sans
|
||||
|
@ -5703,7 +5831,8 @@ R
|
|||
R
|
||||
\family default
|
||||
\series default
|
||||
(TABLE,,1) returns the value of the cell just below the one labeled
|
||||
(TABLE,,1) returns the value of the cell immediately down from the one labeled
|
||||
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
|
@ -6553,6 +6682,18 @@ location
|
|||
|
||||
\begin_layout Description
|
||||
|
||||
\series medium
|
||||
boolean
|
||||
\begin_inset space ~
|
||||
\end_inset
|
||||
|
||||
|
||||
\series default
|
||||
false represents the false Boolean value.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
|
||||
\series medium
|
||||
float
|
||||
\begin_inset space ~
|
||||
|
@ -8003,6 +8144,18 @@ status open
|
|||
|
||||
\begin_layout Description
|
||||
|
||||
\series medium
|
||||
boolean
|
||||
\begin_inset space ~
|
||||
\end_inset
|
||||
|
||||
|
||||
\series default
|
||||
true represents the true Boolean value.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
|
||||
\series medium
|
||||
float
|
||||
\begin_inset space ~
|
||||
|
@ -8456,7 +8609,11 @@ negterm
|
|||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
powterm::=
|
||||
powterm::= [
|
||||
\family typewriter
|
||||
-
|
||||
\family default
|
||||
]
|
||||
\emph on
|
||||
primary
|
||||
\emph default
|
||||
|
@ -8516,7 +8673,7 @@ mathterm
|
|||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
term::=
|
||||
relterm::=
|
||||
\emph on
|
||||
factor
|
||||
\emph default
|
||||
|
@ -8551,6 +8708,48 @@ factor
|
|||
}
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
conjterm::=
|
||||
\emph on
|
||||
relterm
|
||||
\family sans
|
||||
|
||||
\emph default
|
||||
{
|
||||
\family typewriter
|
||||
and
|
||||
\family sans
|
||||
|
||||
\family default
|
||||
\emph on
|
||||
relterm
|
||||
\family sans
|
||||
|
||||
\emph default
|
||||
}
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
term::=
|
||||
\emph on
|
||||
conjterm
|
||||
\family sans
|
||||
|
||||
\emph default
|
||||
{
|
||||
\family typewriter
|
||||
or
|
||||
\family sans
|
||||
|
||||
\family default
|
||||
\emph on
|
||||
conjterm
|
||||
\family sans
|
||||
|
||||
\emph default
|
||||
}
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsection
|
||||
Implementation notes
|
||||
\end_layout
|
||||
|
@ -8634,6 +8833,20 @@ round
|
|||
to be used as keywords for the int() function.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
Note also that some functions are actually implemented as
|
||||
\emph on
|
||||
macros
|
||||
\emph default
|
||||
, which are just like functions but receive their arguments unevaluated.
|
||||
The difference is meant to be transparent to usage of the function, so
|
||||
it is not mentioned elsewhere in this documentation.
|
||||
However, the macro facility is necessary when the function would need to
|
||||
control the evaluation of the arguments, as in the short-circuiting logical
|
||||
operations, or takes an expression as an argument, say to evaluate it on
|
||||
other cells.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Section
|
||||
Frequently Asked Questions
|
||||
\end_layout
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue