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. |