Add functions for unit displacements in the siz cardinal directions

This change is the "easy" part of #64, but to reduce the amount of duplicated
   code, this change also modifies the internals of implementing a function.
   The function identifier is now passed to the implementation as well, allowing
   many implementations of similar functions to be collapsed more easily.
This commit is contained in:
Glen Whitney 2019-08-25 23:19:34 -07:00
parent 9670e8b4a1
commit 7e0ba7370d
5 changed files with 673 additions and 688 deletions

View File

@ -5900,7 +5900,65 @@ env
\series default
evaluates to the contents of the specified environment variable.
If the variable does not exist, then an empty string will be returned.
\end_layout
\begin_layout Description
above|below|left|right|up|down
\series medium
[([location
\emph on
\begin_inset space ~
\end_inset
l
\emph default
])] As bare words (without any arguments and also without the parentheses)
these symbols return a one-cell displacement in the named direction, e.g.
\family sans
\series bold
D
\series default
(above)
\family default
\series medium
gives the location of the same cell as the current on but in the previous
layer and
\family sans
\series bold
R
\series default
(up)
\family default
\series medium
yields the value of the cell one up from the current cell.
With parentheses, they act like
\series bold
@
\series default
()
\series medium
but displaced by one cell in the named direction, so
\family sans
\series default
right()
\family default
\series medium
returns the value of the cell immediately to the right of the current one,
and
\family sans
\series default
down(MYTABLE)
\family default
\series medium
gives the value one line down from the cell labeled
\family sans
\series default
MYTABLE
\family default
\series medium
, etc.
\end_layout
\begin_layout Description
@ -6153,6 +6211,30 @@ x
is given in radians.
\end_layout
\begin_layout Description
below
\series medium
[([location
\emph on
\begin_inset space ~
\end_inset
l
\emph default
])] displacement by one cell in the positive
\series default
\emph on
z
\emph default
direction; see the fuller description at
\family sans
\series bold
above
\series default
.
\end_layout
\begin_layout Description
\series medium
@ -6385,6 +6467,30 @@ x
\end_layout
\begin_layout Description
down
\series medium
[([location
\emph on
\begin_inset space ~
\end_inset
l
\emph default
])] displacement by one cell in the positive
\series default
\emph on
y
\emph default
direction; see the fuller description at
\family sans
\series bold
above
\series default
.
\end_layout
\begin_layout Description
\series medium
@ -6809,6 +6915,30 @@ trunc
value is returned.
\end_layout
\begin_layout Description
left
\series medium
[([location
\emph on
\begin_inset space ~
\end_inset
l
\emph default
])] displacement by one cell in the negative
\series default
\emph on
x
\emph default
direction; see the fuller description at
\family sans
\series bold
above
\series default
.
\end_layout
\begin_layout Description
\series medium
@ -7248,6 +7378,30 @@ x
\end_layout
\begin_layout Description
right
\series medium
[([location
\emph on
\begin_inset space ~
\end_inset
l
\emph default
])] displacement by one cell in the positive
\series default
\emph on
x
\emph default
direction; see the fuller description at
\family sans
\series bold
above
\series default
.
\end_layout
\begin_layout Description
\series medium
@ -7882,6 +8036,23 @@ x
).
\end_layout
\begin_layout Description
up
\series medium
[([location
\emph on
\begin_inset space ~
\end_inset
l
\emph default
])] displacement by one cell in the negative
\series default
\emph on
y
\end_layout
\begin_layout Description
\series medium
@ -8405,28 +8576,61 @@ func
in the former case it receives an argument count of 0, and in the latter
an argument count of -1.
So the same symbol can have different semantics depending on which way
it is called, but in most cases that would probably be counterintuitive.
The no-parentheses form is useful, however, for constants like
it is called.
In most cases such a difference is counterintuitive, but it seems to work
fairly well for the directional
\begin_inset Quotes eld
\end_inset
e,
constants,
\begin_inset Quotes erd
\end_inset
and it is also used to allow, for example, the names of the functions
i.e.
bare
\begin_inset Quotes eld
\end_inset
floor,
\begin_inset Quotes eld
\end_inset
round,
left
\begin_inset Quotes erd
\end_inset
etc.
is the displacement &(-1,0,0), whereas left() is the location one to the
left.
The no-parentheses form is also useful for constants like
\begin_inset Quotes eld
\end_inset
e
\begin_inset Quotes erd
\end_inset
and
\begin_inset Quotes eld
\end_inset
tau
\begin_inset Quotes erd
\end_inset
, and it is also used, for example, to allow the names of the functions
\begin_inset Quotes eld
\end_inset
floor
\begin_inset Quotes erd
\end_inset
,
\begin_inset Quotes eld
\end_inset
round
\begin_inset Quotes erd
\end_inset
, etc.
to be used as keywords for the int() function.
\end_layout

View File

@ -513,12 +513,28 @@ Token tmul(Token l, Token r)
else result.u.flt = l.u.flt * ((FltT)r.u.integer);
}
/*}}}*/
else if ((l.type == EMPTY && r.type == LOCATION)
|| (l.type == LOCATION && r.type == EMPTY))
/* result is 0 location */ /*{{{*/
{
result.type = LOCATION;
OLOCATION(result.u.location);
}
/*}}}*/
else if (l.type == LOCATION && r.type == INT)
/* result is each component of location times right */ /*{{{*/
{
result.type = LOCATION;
for (size_t len = 0; len < 3; ++len)
result.u.location[len] = l.u.location[len] * r.u.integer;
for (Dimensions dim = X; dim < HYPER; ++dim)
result.u.location[dim] = l.u.location[dim] * r.u.integer;
}
/*}}}*/
else if (l.type == INT && r.type == LOCATION)
/* result is each component of right location times left */ /*{{{*/
{
result.type = LOCATION;
for (Dimensions dim = X; dim < HYPER; ++dim)
result.u.location[dim] = l.u.integer * r.u.location[dim];
}
/*}}}*/
else if (l.type == LOCATION && r.type == LOCATION)
@ -526,8 +542,8 @@ Token tmul(Token l, Token r)
{
result.type = INT;
result.u.integer = 0;
for (size_t len = 0; len < 3; ++len)
result.u.integer += l.u.location[len] * r.u.location[len];
for (Dimensions dim = X; dim < HYPER; ++dim)
result.u.integer += l.u.location[dim] * r.u.location[dim];
}
/*}}}*/
else if ((l.type == INT && r.type == STRING)
@ -681,9 +697,9 @@ Token tpow(Token l, Token r)
/*}}}*/
/* tfuncall -- function operator */ /*{{{*/
Token tfuncall(int fident, int argc, Token argv[])
Token tfuncall(FunctionIdentifier fident, int argc, Token argv[])
{
return tfunc[fident].func(argc, argv);
return tfunc[fident].func(fident, argc, argv);
}
/*}}}*/

View File

@ -17,7 +17,7 @@ Token tadd(Token l, Token r);
Token tconcat(Token l, Token r);
Token tsub(Token l, Token r);
Token tneg(Token x);
Token tfuncall(int fident, int argc, Token argv[]);
Token tfuncall(FunctionIdentifier fident, int argc, Token argv[]);
Token tlt(Token l, Token r);
Token tle(Token l, Token r);
Token tge(Token l, Token r);

File diff suppressed because it is too large Load Diff

View File

@ -26,7 +26,7 @@ typedef enum
FUNC_EQUAL_EQUAL, FUNC_TILDE_EQUAL, FUNC_BANG_EQUAL, FUNC_CARET,
FUNC_PER_CENT, FUNC_CONCAT, FUNC_TAU, FUNC_SQRT, FUNC_FLOOR, FUNC_CEIL,
FUNC_TRUNC, FUNC_ROUND, FUNC_DECIMAL, FUNC_SCIENTIFIC, FUNC_COMPACT,
FUNC_HEXACT,
FUNC_HEXACT, FUNC_RIGHT, FUNC_LEFT, FUNC_DOWN, FUNC_UP, FUNC_BELOW, FUNC_ABOVE,
N_FUNCTION_IDS
} FunctionIdentifier;
@ -45,7 +45,7 @@ typedef enum { FUNCT, MACRO } EvaluationStrategy;
typedef struct
{
const char name[MAX_FUNC_NAME_LENGTH + 1];
Token (*func)(int, const Token*);
Token (*func)(FunctionIdentifier self, int, const Token*);
FunctionPrecedence precedence;
EvaluationStrategy eval_as;
const char* display_symbol;