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
|
\emph default
|
||||||
)
|
)
|
||||||
\series default
|
\series default
|
||||||
returns the value of the cell at position
|
returns the value of the cell at the specified location.
|
||||||
\emph on
|
In the first form, if any of
|
||||||
x
|
|
||||||
\emph default
|
|
||||||
,
|
|
||||||
\emph on
|
|
||||||
y
|
|
||||||
\emph default
|
|
||||||
,
|
|
||||||
\emph on
|
|
||||||
z
|
|
||||||
\emph default
|
|
||||||
.
|
|
||||||
If any of
|
|
||||||
\emph on
|
\emph on
|
||||||
x
|
x
|
||||||
\emph default
|
\emph default
|
||||||
@ -5466,8 +5454,29 @@ y
|
|||||||
z
|
z
|
||||||
\emph default
|
\emph default
|
||||||
]]])
|
]]])
|
||||||
|
\begin_inset space ~
|
||||||
|
\end_inset
|
||||||
|
|
||||||
|
|
|
||||||
|
\begin_inset space ~
|
||||||
|
\end_inset
|
||||||
|
|
||||||
|
|
||||||
\series default
|
\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
|
\emph on
|
||||||
x
|
x
|
||||||
\emph default
|
\emph default
|
||||||
@ -5475,30 +5484,65 @@ x
|
|||||||
\emph on
|
\emph on
|
||||||
y
|
y
|
||||||
\emph default
|
\emph default
|
||||||
,
|
or
|
||||||
\emph on
|
\emph on
|
||||||
z
|
z
|
||||||
\emph default
|
\emph default
|
||||||
.
|
is omitted, the coordinate of the cell is used.
|
||||||
If
|
The second form is in fact a no-op, but it is allowed for convenience
|
||||||
\emph on
|
\end_layout
|
||||||
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.
|
|
||||||
|
|
||||||
|
\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
|
\end_layout
|
||||||
|
|
||||||
\begin_layout Description
|
\begin_layout Description
|
||||||
|
@ -305,68 +305,15 @@ static double deg2rad(double x)
|
|||||||
|
|
||||||
#define INTPATIBLE(t) (t.type == INT || t.type == EMPTY)
|
#define INTPATIBLE(t) (t.type == INT || t.type == EMPTY)
|
||||||
|
|
||||||
/* @ */ /*{{{*/
|
typedef enum {ABSOLUTE, RELATIVE} LocConvention;
|
||||||
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;
|
|
||||||
}
|
|
||||||
/*}}}*/
|
|
||||||
}
|
|
||||||
/*}}}*/
|
|
||||||
|
|
||||||
/* & */ /*{{{*/
|
/* & */ /*{{{*/
|
||||||
static Token adr_func(int argc, const Token argv[])
|
static Token adr_func(int argc, const Token argv[], LocConvention lcon)
|
||||||
{
|
{
|
||||||
/* variables */ /*{{{*/
|
/* variables */ /*{{{*/
|
||||||
Token result;
|
Token result;
|
||||||
Dimensions dim;
|
Dimensions dim;
|
||||||
|
size_t i;
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
|
|
||||||
/* asserts */ /*{{{*/
|
/* asserts */ /*{{{*/
|
||||||
@ -374,47 +321,64 @@ static Token adr_func(int argc, const Token argv[])
|
|||||||
/*}}}*/
|
/*}}}*/
|
||||||
|
|
||||||
LOCATION_GETS(result.u.location, upd_l);
|
LOCATION_GETS(result.u.location, upd_l);
|
||||||
if (argc==3 && INTPATIBLE(argv[0]) && INTPATIBLE(argv[1]) &&
|
if (argc == 1 && argv[0].type == LOCATION) return argv[0];
|
||||||
INTPATIBLE(argv[2]))
|
for (i = 0; i < argc && i < HYPER; ++i)
|
||||||
/* result is location of the given position */ /*{{{*/
|
|
||||||
{
|
{
|
||||||
result.type=LOCATION;
|
if (!INTPATIBLE(argv[i])) break;
|
||||||
for (dim = X; dim < HYPER; ++dim)
|
if (lcon == ABSOLUTE) result.u.location[i] = argv[i].u.integer;
|
||||||
if (argv[dim].type == INT) result.u.location[dim] = argv[dim].u.integer;
|
else result.u.location[i] += argv[i].u.integer;
|
||||||
}
|
}
|
||||||
/*}}}*/
|
if (i < argc)
|
||||||
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 */ /*{{{*/
|
|
||||||
{
|
{
|
||||||
result.type=EEK;
|
result.type=EEK;
|
||||||
result.u.err=strcpy(malloc(strlen(_("Usage: &([integer x][,[integer y][,[integer z]]])"))+1),_("Usage: &([integer x][,[integer y][,[integer z]]])"));
|
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;
|
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 */ /*{{{*/
|
/* x */ /*{{{*/
|
||||||
static Token x_func(int argc, const Token argv[])
|
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. */
|
compatible, new entries should be appended. */
|
||||||
Tfunc tfunc[]=
|
Tfunc tfunc[]=
|
||||||
{
|
{
|
||||||
{ "@", at_func },
|
{ "@", abs_at_func },
|
||||||
{ "&", adr_func },
|
{ "&", abs_adr_func },
|
||||||
{ "x", x_func },
|
{ "x", x_func },
|
||||||
{ "y", y_func },
|
{ "y", y_func },
|
||||||
{ "z", z_func },
|
{ "z", z_func },
|
||||||
@ -1489,6 +1453,8 @@ Tfunc tfunc[]=
|
|||||||
{ "time", time_func },
|
{ "time", time_func },
|
||||||
{ "bitand", bitand_func },
|
{ "bitand", bitand_func },
|
||||||
{ "bitor", bitor_func },
|
{ "bitor", bitor_func },
|
||||||
|
{ "D", rel_adr_func },
|
||||||
|
{ "R", rel_at_func },
|
||||||
{ "", (Token (*)(int, const Token[]))0 }
|
{ "", (Token (*)(int, const Token[]))0 }
|
||||||
};
|
};
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
|
Loading…
Reference in New Issue
Block a user