back to upavalues as extra arguments for C closures; this way it's

trivial to make currying.
This commit is contained in:
Roberto Ierusalimschy 1998-01-07 14:26:48 -02:00
parent e04c2b9aa8
commit 26679b1a48
6 changed files with 45 additions and 41 deletions

11
lapi.c
View File

@ -1,5 +1,5 @@
/*
** $Id: lapi.c,v 1.16 1997/12/22 17:52:20 roberto Exp roberto $
** $Id: lapi.c,v 1.17 1998/01/02 17:46:32 roberto Exp roberto $
** Lua API
** See Copyright Notice in lua.h
*/
@ -124,15 +124,6 @@ lua_Object lua_lua2C (int number)
}
lua_Object lua_upvalue (int n)
{
TObject *f = L->stack.stack+L->Cstack.lua2C-1;
if (ttype(f) != LUA_T_CLMARK || n <= 0 || n > clvalue(f)->nelems)
return LUA_NOOBJECT;
return put_luaObject(&clvalue(f)->consts[n]);
}
int lua_callfunction (lua_Object function)
{
if (function == LUA_NOOBJECT)

View File

@ -1,5 +1,5 @@
/*
** $Id: lbuiltin.c,v 1.20 1997/12/30 17:57:45 roberto Exp roberto $
** $Id: lbuiltin.c,v 1.21 1998/01/02 17:46:32 roberto Exp roberto $
** Built-in functions
** See Copyright Notice in lua.h
*/
@ -441,7 +441,6 @@ static void testC (void)
case 'r': { int n=getnum(s); reg[n]=lua_getref(locks[getnum(s)]); break; }
case 'u': lua_unref(locks[getnum(s)]); break;
case 'p': { int n = getnum(s); reg[n] = lua_getparam(getnum(s)); break; }
case 'U': { int n = getnum(s); reg[n] = lua_upvalue(getnum(s)); break; }
case '=': lua_setglobal(getname(s)); break;
case 's': lua_pushstring(getname(s)); break;
case 'o': lua_pushobject(reg[getnum(s)]); break;

19
ldo.c
View File

@ -1,5 +1,5 @@
/*
** $Id: ldo.c,v 1.19 1997/12/23 12:50:49 roberto Exp roberto $
** $Id: ldo.c,v 1.20 1997/12/26 18:38:16 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@ -157,6 +157,21 @@ static StkId callC (lua_CFunction f, StkId base)
}
static StkId callCclosure (struct Closure *cl, lua_CFunction f, StkId base)
{
TObject *pbase;
int nup = cl->nelems; /* number of upvalues */
luaD_checkstack(nup);
pbase = L->stack.stack+base; /* care: previous call may change this */
/* open space for upvalues as extra arguments */
luaO_memup(pbase+nup, pbase, (L->stack.top-pbase)*sizeof(TObject));
/* copy upvalues into stack */
memcpy(pbase, cl->consts+1, nup*sizeof(TObject));
L->stack.top += nup;
return callC(f, base);
}
void luaD_callTM (TObject *f, int nParams, int nResults)
{
luaD_openstack(nParams);
@ -190,7 +205,7 @@ void luaD_call (StkId base, int nResults)
TObject *proto = &(c->consts[0]);
ttype(func) = LUA_T_CLMARK;
firstResult = (ttype(proto) == LUA_T_CPROTO) ?
callC(fvalue(proto), base) :
callCclosure(c, fvalue(proto), base) :
luaV_execute(c, tfvalue(proto), base);
break;
}

View File

@ -1,5 +1,5 @@
/*
** $Id: liolib.c,v 1.12 1997/12/18 19:11:43 roberto Exp roberto $
** $Id: liolib.c,v 1.13 1997/12/26 18:38:16 roberto Exp roberto $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
@ -34,6 +34,8 @@
#define CLOSEDTAG 2
#define IOTAG 1
#define FIRSTARG 3 /* 1st and 2nd are upvalues */
#define FINPUT "_INPUT"
#define FOUTPUT "_OUTPUT"
@ -49,7 +51,7 @@ int pclose();
static int gettag (int i)
{
return lua_getnumber(lua_upvalue(i));
return lua_getnumber(lua_getparam(i));
}
@ -124,7 +126,7 @@ static void setreturn (FILE *f, char *name)
static void io_readfrom (void)
{
FILE *current;
lua_Object f = lua_getparam(1);
lua_Object f = lua_getparam(FIRSTARG);
if (f == LUA_NOOBJECT) {
closefile(FINPUT);
current = stdin;
@ -132,7 +134,7 @@ static void io_readfrom (void)
else if (lua_tag(f) == gettag(IOTAG))
current = lua_getuserdata(f);
else {
char *s = luaL_check_string(1);
char *s = luaL_check_string(FIRSTARG);
current = (*s == '|') ? popen(s+1, "r") : fopen(s, "r");
if (current == NULL) {
pushresult(0);
@ -146,7 +148,7 @@ static void io_readfrom (void)
static void io_writeto (void)
{
FILE *current;
lua_Object f = lua_getparam(1);
lua_Object f = lua_getparam(FIRSTARG);
if (f == LUA_NOOBJECT) {
closefile(FOUTPUT);
current = stdout;
@ -154,7 +156,7 @@ static void io_writeto (void)
else if (lua_tag(f) == gettag(IOTAG))
current = lua_getuserdata(f);
else {
char *s = luaL_check_string(1);
char *s = luaL_check_string(FIRSTARG);
current = (*s == '|') ? popen(s+1,"w") : fopen(s,"w");
if (current == NULL) {
pushresult(0);
@ -167,7 +169,7 @@ static void io_writeto (void)
static void io_appendto (void)
{
char *s = luaL_check_string(1);
char *s = luaL_check_string(FIRSTARG);
FILE *fp = fopen (s, "a");
if (fp != NULL)
setreturn(fp, FOUTPUT);
@ -180,7 +182,7 @@ static void io_appendto (void)
static void io_read (void)
{
int arg = 1;
int arg = FIRSTARG;
FILE *f = getfileparam(FINPUT, &arg);
char *buff;
char *p = luaL_opt_string(arg, "[^\n]*{\n}");
@ -232,7 +234,7 @@ static void io_read (void)
static void io_write (void)
{
int arg = 1;
int arg = FIRSTARG;
FILE *f = getfileparam(FOUTPUT, &arg);
int status = 1;
char *s;

3
lua.h
View File

@ -1,5 +1,5 @@
/*
** $Id: lua.h,v 1.12 1997/12/18 18:32:39 roberto Exp roberto $
** $Id: lua.h,v 1.13 1998/01/02 17:46:32 roberto Exp roberto $
** Lua - An Extensible Extension Language
** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
** e-mail: lua@tecgraf.puc-rio.br
@ -77,7 +77,6 @@ void lua_beginblock (void);
void lua_endblock (void);
lua_Object lua_lua2C (int number);
lua_Object lua_upvalue (int n);
#define lua_getparam(_) lua_lua2C(_)
#define lua_getresult(_) lua_lua2C(_)

View File

@ -1,4 +1,4 @@
% $Id: manual.tex,v 1.1 1998/01/02 18:34:00 roberto Exp roberto $
% $Id: manual.tex,v 1.2 1998/01/06 19:17:31 roberto Exp roberto $
\documentstyle[fullpage,11pt,bnf]{article}
@ -38,7 +38,7 @@ Waldemar Celes
\tecgraf\ --- Computer Science Department --- PUC-Rio
}
\date{\small \verb$Date: 1998/01/02 18:34:00 $}
\date{\small \verb$Date: 1998/01/06 19:17:31 $}
\maketitle
@ -1647,7 +1647,8 @@ many results.
When a C function is created,
it is possible to associate some \emph{upvalues} to it;
then these values can be accessed by the function whenever it is called.
then these values are passed to the function whenever it is called,
as common arguments.
To associate upvalues to a function,
first these values must be pushed on C2lua.
Then the function:
@ -1660,14 +1661,11 @@ with the argument \verb|n| telling how many upvalues must be
associated with the function
(notice that the macro \verb|lua_pushcfunction| is defined as
\verb|lua_pushCclosure| with \verb|n| set to 0).
Any time the function \verb|fn| is called,
it can access those upvalues using:
\Deffunc{lua_upvalue}
\begin{verbatim}
lua_Object lua_upvalue (int n);
\end{verbatim}
Then, any time the function is called,
these upvalues are inserted as the first arguments to the function,
before the actual arguments provided in the call.
For some examples, see files \verb|lstrlib.c|,
For some examples of C functions, see files \verb|lstrlib.c|,
\verb|liolib.c| and \verb|lmathlib.c| in Lua distribution.
\subsection{References to Lua Objects}
@ -2080,7 +2078,7 @@ If \verb|i| is absent, then it is assumed to be 1.
\subsubsection*{\ff \T{format (formatstring, e1, e2, \ldots)}}\Deffunc{format}
\label{format}
This function returns a formated version of its variable number of arguments
This function returns a formatted version of its variable number of arguments
following the description given in its first argument (which must be a string).
The format string follows the same rules as the \verb|printf| family of
standard C functions.
@ -2112,7 +2110,7 @@ decimal digit in the range [1,9],
giving the position of the argument in the argument list.
For instance, the call \verb|format("%2$d -> %1$03d", 1, 34)| will
result in \verb|"34 -> 001"|.
The same argument can be used in more than one convertion.
The same argument can be used in more than one conversion.
The options \verb|c|, \verb|d|, \verb|E|, \verb|e|, \verb|f|,
\verb|g|, \verb|G|, \verb|i|, \verb|o|, \verb|u|, \verb|X|, and \verb|x| all
@ -2506,7 +2504,7 @@ It returns an error code, which is system-dependent.
\subsubsection*{\ff \T{setlocale (locale [, category])}}\Deffunc{setlocale}
This function is an interface to the ANSI C function \verb|setlocale|.
\verb|locale| is a string specifing a locale;
\verb|locale| is a string specifying a locale;
\verb|category| is a number describing which category to change:
0 is \verb|LC_ALL|, 1 is \verb|LC_COLLATE|, 2 is \verb|LC_CTYPE|,
3 is \verb|LC_MONETARY|, 4 is \verb|LC_NUMERIC|, and 5 is \verb|LC_TIME|;
@ -2659,7 +2657,7 @@ This program can be called with any sequence of the following arguments:
\item[\T{-e stat}] executes \verb|stat| as a Lua chunk.
\item[\T{-i}] runs interactively,
accepting commands from standard input until an \verb|EOF|.
Each line entered is immediatly executed.
Each line entered is immediately executed.
\item[\T{-q}] same as \T{-i}, but without a prompt (quiet mode).
\item[\T{-}] executes \verb|stdin| as a file.
\item[\T{var=value}] sets global \verb|var| with string \verb|value|.
@ -2711,7 +2709,7 @@ Here is a list of all these incompatibilities.
\begin{itemize}
\item To support for multiple contexts,
the whole library must be explicitly openen before used.
the whole library must be explicitly opened before used.
However, all standard libraries check whether Lua is already opened,
so any program that opens at least one standard library before using
Lua API does not need to be corrected.
@ -2727,7 +2725,7 @@ Closures make this feature irrelevant.
\item The syntax for function declaration is now more restricted;
for instance, the old syntax \verb|function f[exp] (x) ... end| is not
accepted in 3.1.
Progams should use an explicit assignment instead, like this:
Programs should use an explicit assignment instead, like this:
\verb|f[exp] = function (x) ... end|.
\item Old pre-compiled code is obsolete, and must be re-compiled.