Add relative address and at functions
This commit is contained in:
parent
a5bf64b061
commit
b3ea9f7ad9
114
doc/teapot.lyx
114
doc/teapot.lyx
@ -5393,20 +5393,8 @@ l
|
||||
\emph default
|
||||
)
|
||||
\series default
|
||||
returns the value of the cell at position
|
||||
\emph on
|
||||
x
|
||||
\emph default
|
||||
,
|
||||
\emph on
|
||||
y
|
||||
\emph default
|
||||
,
|
||||
\emph on
|
||||
z
|
||||
\emph default
|
||||
.
|
||||
If any of
|
||||
returns the value of the cell at the specified location.
|
||||
In the first form, if any of
|
||||
\emph on
|
||||
x
|
||||
\emph default
|
||||
@ -5466,8 +5454,29 @@ y
|
||||
z
|
||||
\emph default
|
||||
]]])
|
||||
\begin_inset space ~
|
||||
\end_inset
|
||||
|
||||
|
|
||||
\begin_inset space ~
|
||||
\end_inset
|
||||
|
||||
|
||||
\series default
|
||||
returns a pointer to the cell at location
|
||||
&
|
||||
\series medium
|
||||
(location
|
||||
\emph on
|
||||
|
||||
\begin_inset space ~
|
||||
\end_inset
|
||||
|
||||
l
|
||||
\emph default
|
||||
)
|
||||
\series default
|
||||
returns the specified location.
|
||||
In the first form, if any of
|
||||
\emph on
|
||||
x
|
||||
\emph default
|
||||
@ -5475,30 +5484,65 @@ x
|
||||
\emph on
|
||||
y
|
||||
\emph default
|
||||
,
|
||||
or
|
||||
\emph on
|
||||
z
|
||||
\emph default
|
||||
.
|
||||
If
|
||||
\emph on
|
||||
z
|
||||
\emph default
|
||||
is omitted, the
|
||||
\emph on
|
||||
z
|
||||
\emph default
|
||||
position of the current cell is used.
|
||||
If
|
||||
\emph on
|
||||
y
|
||||
\emph default
|
||||
is missing as well, the
|
||||
\emph on
|
||||
y
|
||||
\emph default
|
||||
position (row) of the cell is used.
|
||||
is omitted, the coordinate of the cell is used.
|
||||
The second form is in fact a no-op, but it is allowed for convenience
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
R() Exactly the same as
|
||||
\series bold
|
||||
@
|
||||
\series default
|
||||
, except the coordinates of the argument are interpreted as an offset to
|
||||
the current location (rather than as absolute coordinates in the sheet);
|
||||
think
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
R
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
for
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
relative.
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
Thus R(-1) returns the value of the cell immediately to the left of this
|
||||
one.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
D() Exactly the same as
|
||||
\series bold
|
||||
&
|
||||
\series default
|
||||
, except the coordinates of the argument are added to the current location.
|
||||
Think
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
D
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
for
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
displaced (by).
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
Thus, D(-1) returns the location of the cell immediately to the left of
|
||||
this one.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
|
@ -305,68 +305,15 @@ static double deg2rad(double x)
|
||||
|
||||
#define INTPATIBLE(t) (t.type == INT || t.type == EMPTY)
|
||||
|
||||
/* @ */ /*{{{*/
|
||||
static Token at_func(int argc, const Token argv[])
|
||||
{
|
||||
/* variables */ /*{{{*/
|
||||
Token result;
|
||||
Location tmp;
|
||||
Dimensions dim;
|
||||
/*}}}*/
|
||||
|
||||
/* asserts */ /*{{{*/
|
||||
assert(argv!=(Token*)0);
|
||||
/*}}}*/
|
||||
if (argc==0)
|
||||
/* return value at current location */ /*{{{*/
|
||||
return (getvalue(upd_sheet, upd_l));
|
||||
/*}}}*/
|
||||
if (argc==1 && argv[0].type==LOCATION)
|
||||
/* return value at location pointed to by argument */ /*{{{*/
|
||||
return (getvalue(upd_sheet, argv[0].u.location));
|
||||
/*}}}*/
|
||||
LOCATION_GETS(tmp, upd_l);
|
||||
if (argc==1 && (argv[0].type==INT || argv[0].type==EMPTY))
|
||||
/* return value at x on current y,z */ /*{{{*/
|
||||
{
|
||||
if (argv[0].type == INT) tmp[X] = argv[0].u.integer;
|
||||
return getvalue(upd_sheet, tmp);
|
||||
}
|
||||
/*}}}*/
|
||||
if (argc==2 && INTPATIBLE(argv[0]) && INTPATIBLE(argv[1]))
|
||||
/* return value at x,y on current z */ /*{{{*/
|
||||
{
|
||||
if (argv[0].type == INT) tmp[X] = argv[0].u.integer;
|
||||
if (argv[1].type == INT) tmp[Y] = argv[1].u.integer;
|
||||
return getvalue(upd_sheet, tmp);
|
||||
}
|
||||
/*}}}*/
|
||||
if (argc==3 && INTPATIBLE(argv[0]) && INTPATIBLE(argv[1]) &&
|
||||
INTPATIBLE(argv[2]))
|
||||
/* return value at x,y,z */ /*{{{*/
|
||||
{
|
||||
for (dim = X; dim < HYPER; ++dim)
|
||||
if (argv[dim].type == INT) tmp[dim] = argv[dim].u.integer;
|
||||
return getvalue(upd_sheet, tmp);
|
||||
}
|
||||
/*}}}*/
|
||||
else
|
||||
/* return error */ /*{{{*/
|
||||
{
|
||||
result.type=EEK;
|
||||
result.u.err=strcpy(malloc(strlen(_("Usage: @([integer x][,[integer y][,[integer z]]]) or @(location)"))+1),_("Usage: @([integer x][,[integer y][,[integer z]]]) or @(location)"));
|
||||
return result;
|
||||
}
|
||||
/*}}}*/
|
||||
}
|
||||
/*}}}*/
|
||||
typedef enum {ABSOLUTE, RELATIVE} LocConvention;
|
||||
|
||||
/* & */ /*{{{*/
|
||||
static Token adr_func(int argc, const Token argv[])
|
||||
static Token adr_func(int argc, const Token argv[], LocConvention lcon)
|
||||
{
|
||||
/* variables */ /*{{{*/
|
||||
Token result;
|
||||
Dimensions dim;
|
||||
size_t i;
|
||||
/*}}}*/
|
||||
|
||||
/* asserts */ /*{{{*/
|
||||
@ -374,47 +321,64 @@ static Token adr_func(int argc, const Token argv[])
|
||||
/*}}}*/
|
||||
|
||||
LOCATION_GETS(result.u.location, upd_l);
|
||||
if (argc==3 && INTPATIBLE(argv[0]) && INTPATIBLE(argv[1]) &&
|
||||
INTPATIBLE(argv[2]))
|
||||
/* result is location of the given position */ /*{{{*/
|
||||
if (argc == 1 && argv[0].type == LOCATION) return argv[0];
|
||||
for (i = 0; i < argc && i < HYPER; ++i)
|
||||
{
|
||||
result.type=LOCATION;
|
||||
for (dim = X; dim < HYPER; ++dim)
|
||||
if (argv[dim].type == INT) result.u.location[dim] = argv[dim].u.integer;
|
||||
if (!INTPATIBLE(argv[i])) break;
|
||||
if (lcon == ABSOLUTE) result.u.location[i] = argv[i].u.integer;
|
||||
else result.u.location[i] += argv[i].u.integer;
|
||||
}
|
||||
/*}}}*/
|
||||
else if (argc==2 && INTPATIBLE(argv[0]) && INTPATIBLE(argv[1]))
|
||||
/* result is location of the given position in the current z layer */ /*{{{*/
|
||||
{
|
||||
result.type=LOCATION;
|
||||
for (dim = X; dim <= Y; ++dim)
|
||||
if (argv[dim].type == INT) result.u.location[dim] = argv[dim].u.integer;
|
||||
}
|
||||
/*}}}*/
|
||||
else if (argc==1 && INTPATIBLE(argv[0]))
|
||||
/* result is location of the given position in the current y,z layer */ /*{{{*/
|
||||
{
|
||||
result.type=LOCATION;
|
||||
if (argv[0].type == INT) result.u.location[X] = argv[0].u.integer;
|
||||
}
|
||||
/*}}}*/
|
||||
else if (argc==0)
|
||||
/* result is location of the current position */ /*{{{*/
|
||||
{
|
||||
result.type=LOCATION;
|
||||
}
|
||||
/*}}}*/
|
||||
else
|
||||
/* result is type error */ /*{{{*/
|
||||
if (i < argc)
|
||||
{
|
||||
result.type=EEK;
|
||||
result.u.err=strcpy(malloc(strlen(_("Usage: &([integer x][,[integer y][,[integer z]]])"))+1),_("Usage: &([integer x][,[integer y][,[integer z]]])"));
|
||||
}
|
||||
/*}}}*/
|
||||
else
|
||||
result.type = LOCATION;
|
||||
return result;
|
||||
}
|
||||
/*}}}*/
|
||||
|
||||
/* @ */ /*{{{*/
|
||||
static Token at_func(int argc, const Token argv[], LocConvention lcon)
|
||||
{
|
||||
Token location;
|
||||
|
||||
location = adr_func(argc, argv, lcon);
|
||||
if (location.type == EEK)
|
||||
{
|
||||
Token result;
|
||||
result.type = EEK;
|
||||
char *pref = _("Inside @: ");
|
||||
result.u.err = malloc(strlen(location.u.err) + strlen(pref) + 1);
|
||||
strcpy(result.u.err, pref);
|
||||
strcat(result.u.err, location.u.err);
|
||||
tfree(&location);
|
||||
return result;
|
||||
}
|
||||
return getvalue(upd_sheet, location.u.location);
|
||||
}
|
||||
|
||||
static Token abs_adr_func(int argc, const Token argv[])
|
||||
{
|
||||
return adr_func(argc, argv, ABSOLUTE);
|
||||
}
|
||||
|
||||
static Token abs_at_func(int argc, const Token argv[])
|
||||
{
|
||||
return at_func(argc, argv, ABSOLUTE);
|
||||
}
|
||||
|
||||
static Token rel_adr_func(int argc, const Token argv[])
|
||||
{
|
||||
return adr_func(argc, argv, RELATIVE);
|
||||
}
|
||||
|
||||
static Token rel_at_func(int argc, const Token argv[])
|
||||
{
|
||||
return at_func(argc, argv, RELATIVE);
|
||||
}
|
||||
|
||||
/* x */ /*{{{*/
|
||||
static Token x_func(int argc, const Token argv[])
|
||||
{
|
||||
@ -1446,8 +1410,8 @@ static Token time_func(int argc, const Token argv[])
|
||||
compatible, new entries should be appended. */
|
||||
Tfunc tfunc[]=
|
||||
{
|
||||
{ "@", at_func },
|
||||
{ "&", adr_func },
|
||||
{ "@", abs_at_func },
|
||||
{ "&", abs_adr_func },
|
||||
{ "x", x_func },
|
||||
{ "y", y_func },
|
||||
{ "z", z_func },
|
||||
@ -1489,6 +1453,8 @@ Tfunc tfunc[]=
|
||||
{ "time", time_func },
|
||||
{ "bitand", bitand_func },
|
||||
{ "bitor", bitor_func },
|
||||
{ "D", rel_adr_func },
|
||||
{ "R", rel_at_func },
|
||||
{ "", (Token (*)(int, const Token[]))0 }
|
||||
};
|
||||
/*}}}*/
|
||||
|
Loading…
Reference in New Issue
Block a user