diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1998-01-07 14:26:48 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1998-01-07 14:26:48 -0200 |
| commit | 26679b1a48de4f7cfcde985764cb31c78ece4fc3 (patch) | |
| tree | df30c6972204791dd6a792dd36c1dd132bc5dbf4 | |
| parent | e04c2b9aa817ed59b4e05025e0d33bfb3bba8f59 (diff) | |
| download | lua-26679b1a48de4f7cfcde985764cb31c78ece4fc3.tar.gz lua-26679b1a48de4f7cfcde985764cb31c78ece4fc3.tar.bz2 lua-26679b1a48de4f7cfcde985764cb31c78ece4fc3.zip | |
back to upavalues as extra arguments for C closures; this way it's
trivial to make currying.
| -rw-r--r-- | lapi.c | 11 | ||||
| -rw-r--r-- | lbuiltin.c | 3 | ||||
| -rw-r--r-- | ldo.c | 19 | ||||
| -rw-r--r-- | liolib.c | 20 | ||||
| -rw-r--r-- | lua.h | 3 | ||||
| -rw-r--r-- | manual.tex | 30 |
6 files changed, 45 insertions, 41 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lapi.c,v 1.16 1997/12/22 17:52:20 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 1.17 1998/01/02 17:46:32 roberto Exp roberto $ |
| 3 | ** Lua API | 3 | ** Lua API |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -124,15 +124,6 @@ lua_Object lua_lua2C (int number) | |||
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | 126 | ||
| 127 | lua_Object lua_upvalue (int n) | ||
| 128 | { | ||
| 129 | TObject *f = L->stack.stack+L->Cstack.lua2C-1; | ||
| 130 | if (ttype(f) != LUA_T_CLMARK || n <= 0 || n > clvalue(f)->nelems) | ||
| 131 | return LUA_NOOBJECT; | ||
| 132 | return put_luaObject(&clvalue(f)->consts[n]); | ||
| 133 | } | ||
| 134 | |||
| 135 | |||
| 136 | int lua_callfunction (lua_Object function) | 127 | int lua_callfunction (lua_Object function) |
| 137 | { | 128 | { |
| 138 | if (function == LUA_NOOBJECT) | 129 | if (function == LUA_NOOBJECT) |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lbuiltin.c,v 1.20 1997/12/30 17:57:45 roberto Exp roberto $ | 2 | ** $Id: lbuiltin.c,v 1.21 1998/01/02 17:46:32 roberto Exp roberto $ |
| 3 | ** Built-in functions | 3 | ** Built-in functions |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -441,7 +441,6 @@ static void testC (void) | |||
| 441 | case 'r': { int n=getnum(s); reg[n]=lua_getref(locks[getnum(s)]); break; } | 441 | case 'r': { int n=getnum(s); reg[n]=lua_getref(locks[getnum(s)]); break; } |
| 442 | case 'u': lua_unref(locks[getnum(s)]); break; | 442 | case 'u': lua_unref(locks[getnum(s)]); break; |
| 443 | case 'p': { int n = getnum(s); reg[n] = lua_getparam(getnum(s)); break; } | 443 | case 'p': { int n = getnum(s); reg[n] = lua_getparam(getnum(s)); break; } |
| 444 | case 'U': { int n = getnum(s); reg[n] = lua_upvalue(getnum(s)); break; } | ||
| 445 | case '=': lua_setglobal(getname(s)); break; | 444 | case '=': lua_setglobal(getname(s)); break; |
| 446 | case 's': lua_pushstring(getname(s)); break; | 445 | case 's': lua_pushstring(getname(s)); break; |
| 447 | case 'o': lua_pushobject(reg[getnum(s)]); break; | 446 | case 'o': lua_pushobject(reg[getnum(s)]); break; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldo.c,v 1.19 1997/12/23 12:50:49 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 1.20 1997/12/26 18:38:16 roberto Exp roberto $ |
| 3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -157,6 +157,21 @@ static StkId callC (lua_CFunction f, StkId base) | |||
| 157 | } | 157 | } |
| 158 | 158 | ||
| 159 | 159 | ||
| 160 | static StkId callCclosure (struct Closure *cl, lua_CFunction f, StkId base) | ||
| 161 | { | ||
| 162 | TObject *pbase; | ||
| 163 | int nup = cl->nelems; /* number of upvalues */ | ||
| 164 | luaD_checkstack(nup); | ||
| 165 | pbase = L->stack.stack+base; /* care: previous call may change this */ | ||
| 166 | /* open space for upvalues as extra arguments */ | ||
| 167 | luaO_memup(pbase+nup, pbase, (L->stack.top-pbase)*sizeof(TObject)); | ||
| 168 | /* copy upvalues into stack */ | ||
| 169 | memcpy(pbase, cl->consts+1, nup*sizeof(TObject)); | ||
| 170 | L->stack.top += nup; | ||
| 171 | return callC(f, base); | ||
| 172 | } | ||
| 173 | |||
| 174 | |||
| 160 | void luaD_callTM (TObject *f, int nParams, int nResults) | 175 | void luaD_callTM (TObject *f, int nParams, int nResults) |
| 161 | { | 176 | { |
| 162 | luaD_openstack(nParams); | 177 | luaD_openstack(nParams); |
| @@ -190,7 +205,7 @@ void luaD_call (StkId base, int nResults) | |||
| 190 | TObject *proto = &(c->consts[0]); | 205 | TObject *proto = &(c->consts[0]); |
| 191 | ttype(func) = LUA_T_CLMARK; | 206 | ttype(func) = LUA_T_CLMARK; |
| 192 | firstResult = (ttype(proto) == LUA_T_CPROTO) ? | 207 | firstResult = (ttype(proto) == LUA_T_CPROTO) ? |
| 193 | callC(fvalue(proto), base) : | 208 | callCclosure(c, fvalue(proto), base) : |
| 194 | luaV_execute(c, tfvalue(proto), base); | 209 | luaV_execute(c, tfvalue(proto), base); |
| 195 | break; | 210 | break; |
| 196 | } | 211 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: liolib.c,v 1.12 1997/12/18 19:11:43 roberto Exp roberto $ | 2 | ** $Id: liolib.c,v 1.13 1997/12/26 18:38:16 roberto Exp roberto $ |
| 3 | ** Standard I/O (and system) library | 3 | ** Standard I/O (and system) library |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -34,6 +34,8 @@ | |||
| 34 | #define CLOSEDTAG 2 | 34 | #define CLOSEDTAG 2 |
| 35 | #define IOTAG 1 | 35 | #define IOTAG 1 |
| 36 | 36 | ||
| 37 | #define FIRSTARG 3 /* 1st and 2nd are upvalues */ | ||
| 38 | |||
| 37 | #define FINPUT "_INPUT" | 39 | #define FINPUT "_INPUT" |
| 38 | #define FOUTPUT "_OUTPUT" | 40 | #define FOUTPUT "_OUTPUT" |
| 39 | 41 | ||
| @@ -49,7 +51,7 @@ int pclose(); | |||
| 49 | 51 | ||
| 50 | static int gettag (int i) | 52 | static int gettag (int i) |
| 51 | { | 53 | { |
| 52 | return lua_getnumber(lua_upvalue(i)); | 54 | return lua_getnumber(lua_getparam(i)); |
| 53 | } | 55 | } |
| 54 | 56 | ||
| 55 | 57 | ||
| @@ -124,7 +126,7 @@ static void setreturn (FILE *f, char *name) | |||
| 124 | static void io_readfrom (void) | 126 | static void io_readfrom (void) |
| 125 | { | 127 | { |
| 126 | FILE *current; | 128 | FILE *current; |
| 127 | lua_Object f = lua_getparam(1); | 129 | lua_Object f = lua_getparam(FIRSTARG); |
| 128 | if (f == LUA_NOOBJECT) { | 130 | if (f == LUA_NOOBJECT) { |
| 129 | closefile(FINPUT); | 131 | closefile(FINPUT); |
| 130 | current = stdin; | 132 | current = stdin; |
| @@ -132,7 +134,7 @@ static void io_readfrom (void) | |||
| 132 | else if (lua_tag(f) == gettag(IOTAG)) | 134 | else if (lua_tag(f) == gettag(IOTAG)) |
| 133 | current = lua_getuserdata(f); | 135 | current = lua_getuserdata(f); |
| 134 | else { | 136 | else { |
| 135 | char *s = luaL_check_string(1); | 137 | char *s = luaL_check_string(FIRSTARG); |
| 136 | current = (*s == '|') ? popen(s+1, "r") : fopen(s, "r"); | 138 | current = (*s == '|') ? popen(s+1, "r") : fopen(s, "r"); |
| 137 | if (current == NULL) { | 139 | if (current == NULL) { |
| 138 | pushresult(0); | 140 | pushresult(0); |
| @@ -146,7 +148,7 @@ static void io_readfrom (void) | |||
| 146 | static void io_writeto (void) | 148 | static void io_writeto (void) |
| 147 | { | 149 | { |
| 148 | FILE *current; | 150 | FILE *current; |
| 149 | lua_Object f = lua_getparam(1); | 151 | lua_Object f = lua_getparam(FIRSTARG); |
| 150 | if (f == LUA_NOOBJECT) { | 152 | if (f == LUA_NOOBJECT) { |
| 151 | closefile(FOUTPUT); | 153 | closefile(FOUTPUT); |
| 152 | current = stdout; | 154 | current = stdout; |
| @@ -154,7 +156,7 @@ static void io_writeto (void) | |||
| 154 | else if (lua_tag(f) == gettag(IOTAG)) | 156 | else if (lua_tag(f) == gettag(IOTAG)) |
| 155 | current = lua_getuserdata(f); | 157 | current = lua_getuserdata(f); |
| 156 | else { | 158 | else { |
| 157 | char *s = luaL_check_string(1); | 159 | char *s = luaL_check_string(FIRSTARG); |
| 158 | current = (*s == '|') ? popen(s+1,"w") : fopen(s,"w"); | 160 | current = (*s == '|') ? popen(s+1,"w") : fopen(s,"w"); |
| 159 | if (current == NULL) { | 161 | if (current == NULL) { |
| 160 | pushresult(0); | 162 | pushresult(0); |
| @@ -167,7 +169,7 @@ static void io_writeto (void) | |||
| 167 | 169 | ||
| 168 | static void io_appendto (void) | 170 | static void io_appendto (void) |
| 169 | { | 171 | { |
| 170 | char *s = luaL_check_string(1); | 172 | char *s = luaL_check_string(FIRSTARG); |
| 171 | FILE *fp = fopen (s, "a"); | 173 | FILE *fp = fopen (s, "a"); |
| 172 | if (fp != NULL) | 174 | if (fp != NULL) |
| 173 | setreturn(fp, FOUTPUT); | 175 | setreturn(fp, FOUTPUT); |
| @@ -180,7 +182,7 @@ static void io_appendto (void) | |||
| 180 | 182 | ||
| 181 | static void io_read (void) | 183 | static void io_read (void) |
| 182 | { | 184 | { |
| 183 | int arg = 1; | 185 | int arg = FIRSTARG; |
| 184 | FILE *f = getfileparam(FINPUT, &arg); | 186 | FILE *f = getfileparam(FINPUT, &arg); |
| 185 | char *buff; | 187 | char *buff; |
| 186 | char *p = luaL_opt_string(arg, "[^\n]*{\n}"); | 188 | char *p = luaL_opt_string(arg, "[^\n]*{\n}"); |
| @@ -232,7 +234,7 @@ static void io_read (void) | |||
| 232 | 234 | ||
| 233 | static void io_write (void) | 235 | static void io_write (void) |
| 234 | { | 236 | { |
| 235 | int arg = 1; | 237 | int arg = FIRSTARG; |
| 236 | FILE *f = getfileparam(FOUTPUT, &arg); | 238 | FILE *f = getfileparam(FOUTPUT, &arg); |
| 237 | int status = 1; | 239 | int status = 1; |
| 238 | char *s; | 240 | char *s; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lua.h,v 1.12 1997/12/18 18:32:39 roberto Exp roberto $ | 2 | ** $Id: lua.h,v 1.13 1998/01/02 17:46:32 roberto Exp roberto $ |
| 3 | ** Lua - An Extensible Extension Language | 3 | ** Lua - An Extensible Extension Language |
| 4 | ** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil | 4 | ** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil |
| 5 | ** e-mail: lua@tecgraf.puc-rio.br | 5 | ** e-mail: lua@tecgraf.puc-rio.br |
| @@ -77,7 +77,6 @@ void lua_beginblock (void); | |||
| 77 | void lua_endblock (void); | 77 | void lua_endblock (void); |
| 78 | 78 | ||
| 79 | lua_Object lua_lua2C (int number); | 79 | lua_Object lua_lua2C (int number); |
| 80 | lua_Object lua_upvalue (int n); | ||
| 81 | #define lua_getparam(_) lua_lua2C(_) | 80 | #define lua_getparam(_) lua_lua2C(_) |
| 82 | #define lua_getresult(_) lua_lua2C(_) | 81 | #define lua_getresult(_) lua_lua2C(_) |
| 83 | 82 | ||
| @@ -1,4 +1,4 @@ | |||
| 1 | % $Id: manual.tex,v 1.1 1998/01/02 18:34:00 roberto Exp roberto $ | 1 | % $Id: manual.tex,v 1.2 1998/01/06 19:17:31 roberto Exp roberto $ |
| 2 | 2 | ||
| 3 | \documentstyle[fullpage,11pt,bnf]{article} | 3 | \documentstyle[fullpage,11pt,bnf]{article} |
| 4 | 4 | ||
| @@ -38,7 +38,7 @@ Waldemar Celes | |||
| 38 | \tecgraf\ --- Computer Science Department --- PUC-Rio | 38 | \tecgraf\ --- Computer Science Department --- PUC-Rio |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | \date{\small \verb$Date: 1998/01/02 18:34:00 $} | 41 | \date{\small \verb$Date: 1998/01/06 19:17:31 $} |
| 42 | 42 | ||
| 43 | \maketitle | 43 | \maketitle |
| 44 | 44 | ||
| @@ -1647,7 +1647,8 @@ many results. | |||
| 1647 | 1647 | ||
| 1648 | When a C function is created, | 1648 | When a C function is created, |
| 1649 | it is possible to associate some \emph{upvalues} to it; | 1649 | it is possible to associate some \emph{upvalues} to it; |
| 1650 | then these values can be accessed by the function whenever it is called. | 1650 | then these values are passed to the function whenever it is called, |
| 1651 | as common arguments. | ||
| 1651 | To associate upvalues to a function, | 1652 | To associate upvalues to a function, |
| 1652 | first these values must be pushed on C2lua. | 1653 | first these values must be pushed on C2lua. |
| 1653 | Then the function: | 1654 | Then the function: |
| @@ -1660,14 +1661,11 @@ with the argument \verb|n| telling how many upvalues must be | |||
| 1660 | associated with the function | 1661 | associated with the function |
| 1661 | (notice that the macro \verb|lua_pushcfunction| is defined as | 1662 | (notice that the macro \verb|lua_pushcfunction| is defined as |
| 1662 | \verb|lua_pushCclosure| with \verb|n| set to 0). | 1663 | \verb|lua_pushCclosure| with \verb|n| set to 0). |
| 1663 | Any time the function \verb|fn| is called, | 1664 | Then, any time the function is called, |
| 1664 | it can access those upvalues using: | 1665 | these upvalues are inserted as the first arguments to the function, |
| 1665 | \Deffunc{lua_upvalue} | 1666 | before the actual arguments provided in the call. |
| 1666 | \begin{verbatim} | ||
| 1667 | lua_Object lua_upvalue (int n); | ||
| 1668 | \end{verbatim} | ||
| 1669 | 1667 | ||
| 1670 | For some examples, see files \verb|lstrlib.c|, | 1668 | For some examples of C functions, see files \verb|lstrlib.c|, |
| 1671 | \verb|liolib.c| and \verb|lmathlib.c| in Lua distribution. | 1669 | \verb|liolib.c| and \verb|lmathlib.c| in Lua distribution. |
| 1672 | 1670 | ||
| 1673 | \subsection{References to Lua Objects} | 1671 | \subsection{References to Lua Objects} |
| @@ -2080,7 +2078,7 @@ If \verb|i| is absent, then it is assumed to be 1. | |||
| 2080 | 2078 | ||
| 2081 | \subsubsection*{\ff \T{format (formatstring, e1, e2, \ldots)}}\Deffunc{format} | 2079 | \subsubsection*{\ff \T{format (formatstring, e1, e2, \ldots)}}\Deffunc{format} |
| 2082 | \label{format} | 2080 | \label{format} |
| 2083 | This function returns a formated version of its variable number of arguments | 2081 | This function returns a formatted version of its variable number of arguments |
| 2084 | following the description given in its first argument (which must be a string). | 2082 | following the description given in its first argument (which must be a string). |
| 2085 | The format string follows the same rules as the \verb|printf| family of | 2083 | The format string follows the same rules as the \verb|printf| family of |
| 2086 | standard C functions. | 2084 | standard C functions. |
| @@ -2112,7 +2110,7 @@ decimal digit in the range [1,9], | |||
| 2112 | giving the position of the argument in the argument list. | 2110 | giving the position of the argument in the argument list. |
| 2113 | For instance, the call \verb|format("%2$d -> %1$03d", 1, 34)| will | 2111 | For instance, the call \verb|format("%2$d -> %1$03d", 1, 34)| will |
| 2114 | result in \verb|"34 -> 001"|. | 2112 | result in \verb|"34 -> 001"|. |
| 2115 | The same argument can be used in more than one convertion. | 2113 | The same argument can be used in more than one conversion. |
| 2116 | 2114 | ||
| 2117 | The options \verb|c|, \verb|d|, \verb|E|, \verb|e|, \verb|f|, | 2115 | The options \verb|c|, \verb|d|, \verb|E|, \verb|e|, \verb|f|, |
| 2118 | \verb|g|, \verb|G|, \verb|i|, \verb|o|, \verb|u|, \verb|X|, and \verb|x| all | 2116 | \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. | |||
| 2506 | \subsubsection*{\ff \T{setlocale (locale [, category])}}\Deffunc{setlocale} | 2504 | \subsubsection*{\ff \T{setlocale (locale [, category])}}\Deffunc{setlocale} |
| 2507 | 2505 | ||
| 2508 | This function is an interface to the ANSI C function \verb|setlocale|. | 2506 | This function is an interface to the ANSI C function \verb|setlocale|. |
| 2509 | \verb|locale| is a string specifing a locale; | 2507 | \verb|locale| is a string specifying a locale; |
| 2510 | \verb|category| is a number describing which category to change: | 2508 | \verb|category| is a number describing which category to change: |
| 2511 | 0 is \verb|LC_ALL|, 1 is \verb|LC_COLLATE|, 2 is \verb|LC_CTYPE|, | 2509 | 0 is \verb|LC_ALL|, 1 is \verb|LC_COLLATE|, 2 is \verb|LC_CTYPE|, |
| 2512 | 3 is \verb|LC_MONETARY|, 4 is \verb|LC_NUMERIC|, and 5 is \verb|LC_TIME|; | 2510 | 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: | |||
| 2659 | \item[\T{-e stat}] executes \verb|stat| as a Lua chunk. | 2657 | \item[\T{-e stat}] executes \verb|stat| as a Lua chunk. |
| 2660 | \item[\T{-i}] runs interactively, | 2658 | \item[\T{-i}] runs interactively, |
| 2661 | accepting commands from standard input until an \verb|EOF|. | 2659 | accepting commands from standard input until an \verb|EOF|. |
| 2662 | Each line entered is immediatly executed. | 2660 | Each line entered is immediately executed. |
| 2663 | \item[\T{-q}] same as \T{-i}, but without a prompt (quiet mode). | 2661 | \item[\T{-q}] same as \T{-i}, but without a prompt (quiet mode). |
| 2664 | \item[\T{-}] executes \verb|stdin| as a file. | 2662 | \item[\T{-}] executes \verb|stdin| as a file. |
| 2665 | \item[\T{var=value}] sets global \verb|var| with string \verb|value|. | 2663 | \item[\T{var=value}] sets global \verb|var| with string \verb|value|. |
| @@ -2711,7 +2709,7 @@ Here is a list of all these incompatibilities. | |||
| 2711 | \begin{itemize} | 2709 | \begin{itemize} |
| 2712 | 2710 | ||
| 2713 | \item To support for multiple contexts, | 2711 | \item To support for multiple contexts, |
| 2714 | the whole library must be explicitly openen before used. | 2712 | the whole library must be explicitly opened before used. |
| 2715 | However, all standard libraries check whether Lua is already opened, | 2713 | However, all standard libraries check whether Lua is already opened, |
| 2716 | so any program that opens at least one standard library before using | 2714 | so any program that opens at least one standard library before using |
| 2717 | Lua API does not need to be corrected. | 2715 | Lua API does not need to be corrected. |
| @@ -2727,7 +2725,7 @@ Closures make this feature irrelevant. | |||
| 2727 | \item The syntax for function declaration is now more restricted; | 2725 | \item The syntax for function declaration is now more restricted; |
| 2728 | for instance, the old syntax \verb|function f[exp] (x) ... end| is not | 2726 | for instance, the old syntax \verb|function f[exp] (x) ... end| is not |
| 2729 | accepted in 3.1. | 2727 | accepted in 3.1. |
| 2730 | Progams should use an explicit assignment instead, like this: | 2728 | Programs should use an explicit assignment instead, like this: |
| 2731 | \verb|f[exp] = function (x) ... end|. | 2729 | \verb|f[exp] = function (x) ... end|. |
| 2732 | 2730 | ||
| 2733 | \item Old pre-compiled code is obsolete, and must be re-compiled. | 2731 | \item Old pre-compiled code is obsolete, and must be re-compiled. |
