| 1 |
/******************************************************************************* |
|---|
| 2 |
|
|---|
| 3 |
copyright: Copyright (c) 2008 Matthias Walter. All rights reserved |
|---|
| 4 |
|
|---|
| 5 |
authors: Matthias Walter, Andreas Hollandt, Clemens Hofreither |
|---|
| 6 |
|
|---|
| 7 |
*******************************************************************************/ |
|---|
| 8 |
|
|---|
| 9 |
module lua.state; |
|---|
| 10 |
|
|---|
| 11 |
private import lua.lua, lua.lualib, lua.lauxlib; |
|---|
| 12 |
private import lua.buffer, lua.mixins, lua.error, lua.data, lua.utils; |
|---|
| 13 |
|
|---|
| 14 |
version (Tango) |
|---|
| 15 |
{ |
|---|
| 16 |
private import tango.stdc.stdio : fputs, stdout; |
|---|
| 17 |
} |
|---|
| 18 |
|
|---|
| 19 |
version (Phobos) |
|---|
| 20 |
{ |
|---|
| 21 |
private import std.string : fputs, stdout; |
|---|
| 22 |
} |
|---|
| 23 |
|
|---|
| 24 |
/******************************************************************************* |
|---|
| 25 |
|
|---|
| 26 |
LuaStandardLibraries defines Constants for the different modules, which |
|---|
| 27 |
add basic functionality to a state. They can be OR'ed together to combine |
|---|
| 28 |
them. |
|---|
| 29 |
|
|---|
| 30 |
Use it as an argument to LuaState.openLibraries to select them. |
|---|
| 31 |
|
|---|
| 32 |
*******************************************************************************/ |
|---|
| 33 |
|
|---|
| 34 |
public enum LuaStandardLibraries : int |
|---|
| 35 |
{ |
|---|
| 36 |
BASE = 0, |
|---|
| 37 |
TABLE = 1, |
|---|
| 38 |
STRING = 2, |
|---|
| 39 |
MATH = 4, |
|---|
| 40 |
OS = 8, |
|---|
| 41 |
IO = 16, |
|---|
| 42 |
DEBUG = 32, |
|---|
| 43 |
PACKAGE = 64, |
|---|
| 44 |
SAFE = BASE | TABLE | STRING | MATH | OS | PACKAGE, |
|---|
| 45 |
ALL = BASE | TABLE | STRING | MATH | OS | PACKAGE | IO | DEBUG |
|---|
| 46 |
} |
|---|
| 47 |
|
|---|
| 48 |
/******************************************************************************* |
|---|
| 49 |
|
|---|
| 50 |
LuaType defines Constants for the different Lua-internal types. |
|---|
| 51 |
|
|---|
| 52 |
*******************************************************************************/ |
|---|
| 53 |
|
|---|
| 54 |
public enum LuaType : int |
|---|
| 55 |
{ |
|---|
| 56 |
NONE = LUA_TNONE, |
|---|
| 57 |
NIL = LUA_TNIL, |
|---|
| 58 |
NUMBER = LUA_TNUMBER, |
|---|
| 59 |
BOOL = LUA_TBOOLEAN, |
|---|
| 60 |
STRING = LUA_TSTRING, |
|---|
| 61 |
TABLE = LUA_TTABLE, |
|---|
| 62 |
FUNCTION = LUA_TFUNCTION, |
|---|
| 63 |
USERDATA = LUA_TUSERDATA, |
|---|
| 64 |
THREAD = LUA_TTHREAD, |
|---|
| 65 |
LIGHTUSERDATA = LUA_TLIGHTUSERDATA |
|---|
| 66 |
} |
|---|
| 67 |
|
|---|
| 68 |
/******************************************************************************* |
|---|
| 69 |
|
|---|
| 70 |
LuaGarbageCollectorCommand defines Commands for the LuaState.gc function, |
|---|
| 71 |
which controls the garbage collector of a LuaState. |
|---|
| 72 |
|
|---|
| 73 |
*******************************************************************************/ |
|---|
| 74 |
|
|---|
| 75 |
public enum LuaGarbageCollectorCommand : int |
|---|
| 76 |
{ |
|---|
| 77 |
STOP = LUA_GCSTOP, |
|---|
| 78 |
RESTART = LUA_GCRESTART, |
|---|
| 79 |
COLLECT = LUA_GCCOLLECT, |
|---|
| 80 |
COUNT = LUA_GCCOUNT, |
|---|
| 81 |
STEP = LUA_GCSTEP, |
|---|
| 82 |
SET_PAUSE = LUA_GCSETPAUSE, |
|---|
| 83 |
SET_STEP_MULTIPLIER = LUA_GCSETSTEPMUL |
|---|
| 84 |
} |
|---|
| 85 |
|
|---|
| 86 |
/// Type of Function with C-linkage which can interface to Lua directly. |
|---|
| 87 |
|
|---|
| 88 |
alias lua_CFunction LuaCFunction; |
|---|
| 89 |
|
|---|
| 90 |
/// Type of Integers in Lua |
|---|
| 91 |
|
|---|
| 92 |
alias lua_Integer LuaInteger; |
|---|
| 93 |
|
|---|
| 94 |
/// Type of Floats in Lua |
|---|
| 95 |
|
|---|
| 96 |
alias lua_Number LuaNumber; |
|---|
| 97 |
|
|---|
| 98 |
/// Registration struct for registering C-linkage functions with Lua |
|---|
| 99 |
|
|---|
| 100 |
struct LuaRegistry |
|---|
| 101 |
{ |
|---|
| 102 |
char[] name; |
|---|
| 103 |
LuaCFunction cfunction; |
|---|
| 104 |
int category; |
|---|
| 105 |
} |
|---|
| 106 |
|
|---|
| 107 |
/// Delegate type for redirecting Lua's stdout to the D host program. |
|---|
| 108 |
|
|---|
| 109 |
alias void delegate (char[] output) LuaPrint; |
|---|
| 110 |
|
|---|
| 111 |
/******************************************************************************* |
|---|
| 112 |
|
|---|
| 113 |
LuaState wraps a Lua state which keeps the whole state of the Lua |
|---|
| 114 |
interpreter. It is thread-safe, as there are no global variables in the |
|---|
| 115 |
C library and no unsynchronized static variables in the D wrapper. |
|---|
| 116 |
|
|---|
| 117 |
Nearly all of the standard Lua functions are wrapped or reimplemented |
|---|
| 118 |
somehow. There are the following exceptions: |
|---|
| 119 |
|
|---|
| 120 |
The panic function cannot be changed, which is due to the longjmp |
|---|
| 121 |
implementation of the Lua library. Thus you should always use protected |
|---|
| 122 |
calls as an initial call to Lua code. If you still want the application |
|---|
| 123 |
to panic then, you simply do not catch the exceptions thrown by this |
|---|
| 124 |
call, which should terminate your application. Thus, there is no |
|---|
| 125 |
wrapper for the lua_atpanic function. |
|---|
| 126 |
|
|---|
| 127 |
Also, you cannot set a user-supplied allocation function. As Lua has |
|---|
| 128 |
its own garbage collector and all other C variables are directly |
|---|
| 129 |
freed by the wrapper classes, this is unnecessary. Thus, there is also |
|---|
| 130 |
no wrapper for lua_setallocf and lua_getallocf. |
|---|
| 131 |
|
|---|
| 132 |
Some string manipulation/construction routines are not wrapped, because |
|---|
| 133 |
this is more easily done in D directly or using the standard library of |
|---|
| 134 |
your choice. This has impact on lua_pushfstring, lua_pushvfstring and |
|---|
| 135 |
luaL_gsub. |
|---|
| 136 |
|
|---|
| 137 |
*******************************************************************************/ |
|---|
| 138 |
|
|---|
| 139 |
class LuaState |
|---|
| 140 |
{ |
|---|
| 141 |
/// Wrapper Lua state |
|---|
| 142 |
private lua_State* state_; |
|---|
| 143 |
|
|---|
| 144 |
/// Writer delegate, the Lua stdout |
|---|
| 145 |
private LuaPrint write_; |
|---|
| 146 |
|
|---|
| 147 |
/// Whether the LuaState was created as a sub-thread of another state by calling newThread(). |
|---|
| 148 |
private bool is_thread_state_; |
|---|
| 149 |
|
|---|
| 150 |
/// Constant to pass instead of a number of expected results, if this number is unknown. |
|---|
| 151 |
public const int MULTIPLE_RETURN_VALUES = LUA_MULTRET; |
|---|
| 152 |
|
|---|
| 153 |
/******************************************************************************* |
|---|
| 154 |
|
|---|
| 155 |
Constructs a state with an optional printer delegate. If the latter is |
|---|
| 156 |
null, stdout is not redirected. |
|---|
| 157 |
|
|---|
| 158 |
Params: |
|---|
| 159 |
write = Optional printer delegate. |
|---|
| 160 |
|
|---|
| 161 |
Remarks: |
|---|
| 162 |
Replaces lua_open, lua_newstate and luaL_newstate. |
|---|
| 163 |
|
|---|
| 164 |
*******************************************************************************/ |
|---|
| 165 |
|
|---|
| 166 |
public this (LuaPrint write = null) |
|---|
| 167 |
{ |
|---|
| 168 |
this.state_ = lua_open (); |
|---|
| 169 |
this.write_ = (write is null) ? &writeDefault : write; |
|---|
| 170 |
|
|---|
| 171 |
openLibraries (LuaStandardLibraries.BASE); |
|---|
| 172 |
|
|---|
| 173 |
LuaState.states[this.state_] = this; |
|---|
| 174 |
} |
|---|
| 175 |
|
|---|
| 176 |
/******************************************************************************* |
|---|
| 177 |
|
|---|
| 178 |
Internal Constructor for Lua thread creation. |
|---|
| 179 |
|
|---|
| 180 |
Params: |
|---|
| 181 |
write = Printer delegate |
|---|
| 182 |
state = Lua state |
|---|
| 183 |
|
|---|
| 184 |
*******************************************************************************/ |
|---|
| 185 |
|
|---|
| 186 |
private this (LuaPrint write, lua_State* state) |
|---|
| 187 |
{ |
|---|
| 188 |
this.write_ = write; |
|---|
| 189 |
this.state_ = state; |
|---|
| 190 |
|
|---|
| 191 |
LuaState.states[this.state_] = this; |
|---|
| 192 |
} |
|---|
| 193 |
|
|---|
| 194 |
/******************************************************************************* |
|---|
| 195 |
|
|---|
| 196 |
Destructor |
|---|
| 197 |
|
|---|
| 198 |
Remarks: |
|---|
| 199 |
Replaces lua_close. |
|---|
| 200 |
|
|---|
| 201 |
*******************************************************************************/ |
|---|
| 202 |
|
|---|
| 203 |
private ~this () |
|---|
| 204 |
{ |
|---|
| 205 |
LuaState.states.remove (this.state_); |
|---|
| 206 |
|
|---|
| 207 |
// bugfix by Clemens: |
|---|
| 208 |
// states which represent child threads may not be destroyed |
|---|
| 209 |
if (!is_thread_state_) |
|---|
| 210 |
{ |
|---|
| 211 |
lua_close (this.state_); |
|---|
| 212 |
} |
|---|
| 213 |
} |
|---|
| 214 |
|
|---|
| 215 |
/******************************************************************************* |
|---|
| 216 |
|
|---|
| 217 |
Returns: |
|---|
| 218 |
The internal wrapped lua_State object. |
|---|
| 219 |
|
|---|
| 220 |
Remarks: |
|---|
| 221 |
If you really need to use this function, please contact the author. For |
|---|
| 222 |
most functionality there should be a corresponding wrapper function. |
|---|
| 223 |
|
|---|
| 224 |
*******************************************************************************/ |
|---|
| 225 |
|
|---|
| 226 |
public lua_State* state () |
|---|
| 227 |
{ |
|---|
| 228 |
return this.state_; |
|---|
| 229 |
} |
|---|
| 230 |
|
|---|
| 231 |
/******************************************************************************* |
|---|
| 232 |
|
|---|
| 233 |
Opens the specified standard libraries and adds their functionality to this state. |
|---|
| 234 |
See the LuaStandardLibraries enum for possible choices. |
|---|
| 235 |
|
|---|
| 236 |
Params: |
|---|
| 237 |
categories = choice of standard libraries |
|---|
| 238 |
|
|---|
| 239 |
Remarks: |
|---|
| 240 |
Replaces luaL_openlibs. |
|---|
| 241 |
|
|---|
| 242 |
*******************************************************************************/ |
|---|
| 243 |
|
|---|
| 244 |
public LuaState openLibraries (LuaStandardLibraries categories = LuaStandardLibraries.ALL) |
|---|
| 245 |
{ |
|---|
| 246 |
static LuaRegistry[] lualibs = [ |
|---|
| 247 |
{ "", &luaopen_base, LuaStandardLibraries.BASE }, |
|---|
| 248 |
{ LUA_TABLIBNAME, &luaopen_table, LuaStandardLibraries.TABLE }, |
|---|
| 249 |
{ LUA_IOLIBNAME, &luaopen_io, LuaStandardLibraries.IO }, |
|---|
| 250 |
{ LUA_OSLIBNAME, &luaopen_os, LuaStandardLibraries.OS }, |
|---|
| 251 |
{ LUA_STRLIBNAME, &luaopen_string, LuaStandardLibraries.STRING }, |
|---|
| 252 |
{ LUA_MATHLIBNAME, &luaopen_math, LuaStandardLibraries.MATH }, |
|---|
| 253 |
{ LUA_DBLIBNAME, &luaopen_debug, LuaStandardLibraries.DEBUG }, |
|---|
| 254 |
{ LUA_LOADLIBNAME, &luaopen_package, LuaStandardLibraries.PACKAGE } |
|---|
| 255 |
]; |
|---|
| 256 |
|
|---|
| 257 |
openLibraries (lualibs, categories); |
|---|
| 258 |
|
|---|
| 259 |
registerFunction ("print", &print); |
|---|
| 260 |
|
|---|
| 261 |
return this; |
|---|
| 262 |
} |
|---|
| 263 |
|
|---|
| 264 |
/******************************************************************************* |
|---|
| 265 |
|
|---|
| 266 |
Opens all of the given libraries, which match the given categories bits, |
|---|
| 267 |
and adds their functionality to this state. |
|---|
| 268 |
|
|---|
| 269 |
Params: |
|---|
| 270 |
libraries = Array of possible libraries |
|---|
| 271 |
categories = Choice to open. Default is -1, which opens all. |
|---|
| 272 |
|
|---|
| 273 |
*******************************************************************************/ |
|---|
| 274 |
|
|---|
| 275 |
public LuaState openLibraries (LuaRegistry[] libraries, int categories = -1) |
|---|
| 276 |
{ |
|---|
| 277 |
foreach (LuaRegistry reg; libraries) |
|---|
| 278 |
{ |
|---|
| 279 |
if (reg.category == 0 || (reg.category & categories) != 0) |
|---|
| 280 |
{ |
|---|
| 281 |
openLibrary (reg.name, reg.cfunction); |
|---|
| 282 |
} |
|---|
| 283 |
} |
|---|
| 284 |
return this; |
|---|
| 285 |
} |
|---|
| 286 |
|
|---|
| 287 |
/******************************************************************************* |
|---|
| 288 |
|
|---|
| 289 |
Opens one library, adding its functionality to this state. The |
|---|
| 290 |
registration function must take the library name as its only |
|---|
| 291 |
argument. |
|---|
| 292 |
|
|---|
| 293 |
Params: |
|---|
| 294 |
library_name = Name of the library |
|---|
| 295 |
registration_function = C-linkage function to call for registration |
|---|
| 296 |
|
|---|
| 297 |
******************************************************************************/ |
|---|
| 298 |
|
|---|
| 299 |
public LuaState openLibrary (char[] library_name, LuaCFunction registration_function) |
|---|
| 300 |
{ |
|---|
| 301 |
pushCFunction (registration_function); |
|---|
| 302 |
pushString (library_name); |
|---|
| 303 |
call (false, 1, 0); |
|---|
| 304 |
|
|---|
| 305 |
return this; |
|---|
| 306 |
} |
|---|
| 307 |
|
|---|
| 308 |
/******************************************************************************* |
|---|
| 309 |
|
|---|
| 310 |
Internal method to pass the given data to the writer delegate. |
|---|
| 311 |
|
|---|
| 312 |
Params: |
|---|
| 313 |
data = Output to write. |
|---|
| 314 |
|
|---|
| 315 |
******************************************************************************/ |
|---|
| 316 |
|
|---|
| 317 |
private void write (char[] data) |
|---|
| 318 |
{ |
|---|
| 319 |
this.write_ (data); |
|---|
| 320 |
} |
|---|
| 321 |
|
|---|
| 322 |
/******************************************************************************* |
|---|
| 323 |
|
|---|
| 324 |
Standard writer function, if none is specified in Constructor. |
|---|
| 325 |
|
|---|
| 326 |
Params: |
|---|
| 327 |
output = Output to write. |
|---|
| 328 |
|
|---|
| 329 |
******************************************************************************/ |
|---|
| 330 |
|
|---|
| 331 |
private void writeDefault (char[] output) |
|---|
| 332 |
{ |
|---|
| 333 |
fputs (toStringz (output), stdout); |
|---|
| 334 |
} |
|---|
| 335 |
|
|---|
| 336 |
/******************************************************************************* |
|---|
| 337 |
|
|---|
| 338 |
Calls the C function with only one element in its stack, a LightUserdata, |
|---|
| 339 |
specified as an argument. It does not change the stack. All values |
|---|
| 340 |
returned by the function are discarded. For behavior on errors and the |
|---|
| 341 |
description of proctection schemes, see the other call method. |
|---|
| 342 |
|
|---|
| 343 |
Params: |
|---|
| 344 |
protection = whether this is a protected call. |
|---|
| 345 |
cfunction = Pointer to a C function. |
|---|
| 346 |
userdata = Pointer to C data. |
|---|
| 347 |
|
|---|
| 348 |
Remarks: |
|---|
| 349 |
Replaces lua_cpcall. |
|---|
| 350 |
|
|---|
| 351 |
******************************************************************************/ |
|---|
| 352 |
|
|---|
| 353 |
public LuaState call (bool protection, LuaCFunction cfunction, void* userdata) |
|---|
| 354 |
{ |
|---|
| 355 |
pushCFunction (cfunction); |
|---|
| 356 |
pushLightUserdata (userdata); |
|---|
| 357 |
call (protection, 1, 0); |
|---|
| 358 |
|
|---|
| 359 |
return this; |
|---|
| 360 |
} |
|---|
| 361 |
|
|---|
| 362 |
/******************************************************************************* |
|---|
| 363 |
|
|---|
| 364 |
Method to call a Lua function, using the following protocol: |
|---|
| 365 |
|
|---|
| 366 |
First, the function to be called is pushed onto the stack; then, the |
|---|
| 367 |
arguments to the function are pushed in direct order; that is, the first |
|---|
| 368 |
argument is pushed first. Finally you call this method with |
|---|
| 369 |
the number of arguments that you pushed onto the stack and the expected |
|---|
| 370 |
number of return values. All arguments and the function value are popped |
|---|
| 371 |
from the stack when the function is called. The function results are |
|---|
| 372 |
pushed onto the stack when the function returns. The number of results is |
|---|
| 373 |
adjusted to the expected number, unless the latter is |
|---|
| 374 |
MULTIPLE_RETURN_VALUES, which is the default. In this case, all results |
|---|
| 375 |
from the function are pushed. Lua takes care that the returned values fit |
|---|
| 376 |
into the stack space. The function results are pushed onto the stack in |
|---|
| 377 |
direct order (the first result is pushed first), so that after the call |
|---|
| 378 |
the last result is on the top of the stack. |
|---|
| 379 |
|
|---|
| 380 |
There are two different protection schemes, which define behavior on |
|---|
| 381 |
errors: |
|---|
| 382 |
|
|---|
| 383 |
Protected calls catch errors inside the called function (and all further |
|---|
| 384 |
called functions) and throw according exceptions. Lua errors result in |
|---|
| 385 |
LuaCodeExceptions and exceptions in D routines which are correctly wrapped |
|---|
| 386 |
via the lua mixins result in LuaForwardExceptions. |
|---|
| 387 |
|
|---|
| 388 |
Unprotected calls do not catch errors, but quietly propagate them to the |
|---|
| 389 |
next protected call in the call stack. If there is no such protected call, |
|---|
| 390 |
the application panics, exiting with status 1 and an error message. |
|---|
| 391 |
|
|---|
| 392 |
The author of this library suggests the following rules for protection: |
|---|
| 393 |
|
|---|
| 394 |
1. If the called routine and its subroutines are really safe, |
|---|
| 395 |
use an unprotected call. |
|---|
| 396 |
2. If this call happens to be called as the first function on the Lua |
|---|
| 397 |
call stack, use a protected call. |
|---|
| 398 |
3. If this is not the first function on the call stack (e.g. in a library |
|---|
| 399 |
function called by some Lua code, which is called by a protected call) |
|---|
| 400 |
you have the choice. Unprotected calls should be slightly faster, but |
|---|
| 401 |
on error, a protected call would add one LuaForwardException to the |
|---|
| 402 |
exception stack, which may help to identify error sources. |
|---|
| 403 |
|
|---|
| 404 |
Params: |
|---|
| 405 |
protection = whether this is a protected call. |
|---|
| 406 |
arguments = number of function arguments on the stack. Default is 0 |
|---|
| 407 |
results = expected number of return values. Default is a variable number. |
|---|
| 408 |
|
|---|
| 409 |
Remarks: |
|---|
| 410 |
Replaces lua_call and lua_pcall. |
|---|
| 411 |
|
|---|
| 412 |
******************************************************************************/ |
|---|
| 413 |
|
|---|
| 414 |
public LuaState call (bool protection, uint arguments = 0, int results = MULTIPLE_RETURN_VALUES) |
|---|
| 415 |
{ |
|---|
| 416 |
if (protection) |
|---|
| 417 |
{ |
|---|
| 418 |
int errors = lua_pcall (this.state_, arguments, results, 0); |
|---|
| 419 |
if (errors != 0) |
|---|
| 420 |
{ |
|---|
| 421 |
char[] error = popString (); |
|---|
| 422 |
|
|---|
| 423 |
// parse the error string to extract the address of the exception |
|---|
| 424 |
char[] pointer_string = null; |
|---|
| 425 |
for (int start = error.length-6; start >= 0; start--) |
|---|
| 426 |
{ |
|---|
| 427 |
if (error[start .. start + 4] == "LFE=") |
|---|
| 428 |
{ |
|---|
| 429 |
for (int end = start+5; end < error.length; end++) |
|---|
| 430 |
{ |
|---|
| 431 |
if (error[end] == ';') |
|---|
| 432 |
{ |
|---|
| 433 |
pointer_string = error[start+4 .. end]; |
|---|
| 434 |
break; |
|---|
| 435 |
} |
|---|
| 436 |
} |
|---|
| 437 |
break; |
|---|
| 438 |
} |
|---|
| 439 |
} |
|---|
| 440 |
|
|---|
| 441 |
if (pointer_string != null) |
|---|
| 442 |
{ |
|---|
| 443 |
void* p = cast (void*) string2int !(ulong) (pointer_string); |
|---|
| 444 |
LuaForwardException e = LuaForwardException.exceptions[p]; |
|---|
| 445 |
LuaForwardException.exceptions.remove (p); |
|---|
| 446 |
e.forward ("LuaState.call"); |
|---|
| 447 |
throw e; |
|---|
| 448 |
} |
|---|
| 449 |
else |
|---|
| 450 |
{ |
|---|
| 451 |
throw new LuaCodeException (error); |
|---|
| 452 |
} |
|---|
| 453 |
} |
|---|
| 454 |
} |
|---|
| 455 |
else |
|---|
| 456 |
{ |
|---|
| 457 |
lua_call (this.state_, arguments, results); |
|---|
| 458 |
} |
|---|
| 459 |
|
|---|
| 460 |
return this; |
|---|
| 461 |
} |
|---|
| 462 |
|
|---|
| 463 |
/******************************************************************************* |
|---|
| 464 |
|
|---|
| 465 |
Loads and runs the given string. |
|---|
| 466 |
|
|---|
| 467 |
Params: |
|---|
| 468 |
protection = whether this is a protected call. See LuaState.call |
|---|
| 469 |
code = Lua code to run. |
|---|
| 470 |
arguments = number of function arguments on the stack. Default is 0 |
|---|
| 471 |
results = expected number of return values. Default is a variable number. |
|---|
| 472 |
chunk_name = Name of the code chunk. |
|---|
| 473 |
|
|---|
| 474 |
Remarks: |
|---|
| 475 |
Replaces luaL_dostring. |
|---|
| 476 |
|
|---|
| 477 |
******************************************************************************/ |
|---|
| 478 |
|
|---|
| 479 |
public LuaState doString (bool protection, char[] code, uint arguments = 0, int results = MULTIPLE_RETURN_VALUES, char[] chunk_name = null) |
|---|
| 480 |
{ |
|---|
| 481 |
load (code, chunk_name); |
|---|
| 482 |
|
|---|
| 483 |
return call (protection, arguments, results); |
|---|
| 484 |
} |
|---|
| 485 |
|
|---|
| 486 |
/// ditto |
|---|
| 487 |
|
|---|
| 488 |
public LuaState doString (bool protection, char[] code, char[] chunk_name, uint arguments = 0, int results = MULTIPLE_RETURN_VALUES) |
|---|
| 489 |
{ |
|---|
| 490 |
return doString (protection, code, arguments, results, chunk_name); |
|---|
| 491 |
} |
|---|
| 492 |
|
|---|
| 493 |
/******************************************************************************* |
|---|
| 494 |
|
|---|
| 495 |
Loads and runs the given file. |
|---|
| 496 |
|
|---|
| 497 |
Params: |
|---|
| 498 |
protection = whether this is a protected call. See LuaState.call |
|---|
| 499 |
filename = Lua file to run. |
|---|
| 500 |
arguments = number of function arguments on the stack. Default is 0 |
|---|
| 501 |
results = expected number of return values. Default is a variable number. |
|---|
| 502 |
|
|---|
| 503 |
Remarks: |
|---|
| 504 |
Replaces luaL_dofile. |
|---|
| 505 |
|
|---|
| 506 |
******************************************************************************/ |
|---|
| 507 |
|
|---|
| 508 |
public LuaState doFile (bool protection, char[] filename, uint arguments = 0, int results = MULTIPLE_RETURN_VALUES) |
|---|
| 509 |
{ |
|---|
| 510 |
loadFile (filename); |
|---|
| 511 |
|
|---|
| 512 |
return call (protection, arguments, results); |
|---|
| 513 |
} |
|---|
| 514 |
|
|---|
| 515 |
/******************************************************************************* |
|---|
| 516 |
|
|---|
| 517 |
If the object at the specified index has a metatable with the specified |
|---|
| 518 |
field, this method calls this field and passes the object as its only |
|---|
| 519 |
argument. In this case this function returns true and pushes the returned |
|---|
| 520 |
value onto the stack. If there is no metatable or no metamethod, this |
|---|
| 521 |
function returns false without pushing any value on the stack. |
|---|
| 522 |
|
|---|
| 523 |
Remarks: |
|---|
| 524 |
Replaces luaL_callmeta. |
|---|
| 525 |
|
|---|
| 526 |
******************************************************************************/ |
|---|
| 527 |
|
|---|
| 528 |
public bool callMeta (int index, char[] field) |
|---|
| 529 |
{ |
|---|
| 530 |
return luaL_callmeta (this.state_, index, toStringz (field)) != 0; |
|---|
| 531 |
} |
|---|
| 532 |
|
|---|
| 533 |
/******************************************************************************* |
|---|
| 534 |
|
|---|
| 535 |
If the function argument is number, returns this number cast to an int. |
|---|
| 536 |
If this argument is absent or is nil, returns the default value. |
|---|
| 537 |
Otherwise, raises an error. |
|---|
| 538 |
|
|---|
| 539 |
Remarks: |
|---|
| 540 |
Replaces luaL_optint, luaL_optlong and luaL_optinteger. |
|---|
| 541 |
|
|---|
| 542 |
******************************************************************************/ |
|---|
| 543 |
|
|---|
| 544 |
public LuaInteger optInteger (uint argument, LuaInteger default_value) |
|---|
| 545 |
{ |
|---|
| 546 |
return luaL_optint (this.state_, argument, default_value); |
|---|
| 547 |
} |
|---|
| 548 |
|
|---|
| 549 |
/******************************************************************************* |
|---|
| 550 |
|
|---|
| 551 |
If the function argument is number, returns this number. |
|---|
| 552 |
If this argument is absent or is nil, returns the default value. |
|---|
| 553 |
Otherwise, raises an error. |
|---|
| 554 |
|
|---|
| 555 |
Remarks: |
|---|
| 556 |
Replaces luaL_optnumber. |
|---|
| 557 |
|
|---|
| 558 |
******************************************************************************/ |
|---|
| 559 |
|
|---|
| 560 |
public LuaNumber optNumber (uint argument, LuaNumber default_value) |
|---|
| 561 |
{ |
|---|
| 562 |
return luaL_optnumber (this.state_, argument, default_value); |
|---|
| 563 |
} |
|---|
| 564 |
|
|---|
| 565 |
/******************************************************************************* |
|---|
| 566 |
|
|---|
| 567 |
If the function argument is a string, returns this string. If this |
|---|
| 568 |
argument is absent or is nil, returns the default value. Otherwise, |
|---|
| 569 |
raises an error. |
|---|
| 570 |
|
|---|
| 571 |
Remarks: |
|---|
| 572 |
Replaces luaL_optlstring and luaL_optstring. |
|---|
| 573 |
|
|---|
| 574 |
******************************************************************************/ |
|---|
| 575 |
|
|---|
| 576 |
public char[] optString (uint argument, char[] default_value) |
|---|
| 577 |
{ |
|---|
| 578 |
size_t len; |
|---|
| 579 |
char* ptr = luaL_optlstring (this.state_, argument, toStringz (default_value), &len); |
|---|
| 580 |
|
|---|
| 581 |
return ptr[0 .. len]; |
|---|
| 582 |
} |
|---|
| 583 |
|
|---|
| 584 |
/******************************************************************************* |
|---|
| 585 |
|
|---|
| 586 |
Checks whether the function argument is a string and searches for this |
|---|
| 587 |
string in the array value_list. Returns the index in the array where the |
|---|
| 588 |
string was found. Raises an error if the argument is not a string or if |
|---|
| 589 |
the string cannot be found. |
|---|
| 590 |
|
|---|
| 591 |
If default_value is not null, the function uses default_value as a default |
|---|
| 592 |
value when there is no argument or if this argument is nil. |
|---|
| 593 |
|
|---|
| 594 |
This is a useful function for mapping strings to enums. (The usual |
|---|
| 595 |
convention in Lua libraries is to use strings instead of numbers to |
|---|
| 596 |
select options.) |
|---|
| 597 |
|
|---|
| 598 |
Remarks: |
|---|
| 599 |
Replaces luaL_checkoption. |
|---|
| 600 |
|
|---|
| 601 |
******************************************************************************/ |
|---|
| 602 |
|
|---|
| 603 |
public int checkOption (uint argument, char[][] value_list, char[] default_value = null) |
|---|
| 604 |
{ |
|---|
| 605 |
char[] name = (default_value !is null) ? optString (argument, default_value) : checkString (argument); |
|---|
| 606 |
|
|---|
| 607 |
foreach (i, s; value_list) |
|---|
| 608 |
{ |
|---|
| 609 |
if (s == name) |
|---|
| 610 |
return i; |
|---|
| 611 |
} |
|---|
| 612 |
|
|---|
| 613 |
throw new LuaCodeException ("Invalid option: '" ~ name ~ "'"); |
|---|
| 614 |
} |
|---|
| 615 |
|
|---|
| 616 |
/******************************************************************************* |
|---|
| 617 |
|
|---|
| 618 |
Raises a Lua error specified by the message argument. If the latter is |
|---|
| 619 |
null, this method takes the object on top of the stack as the error |
|---|
| 620 |
message. This method does a long jump, and therefore never returns. |
|---|
| 621 |
|
|---|
| 622 |
Params: |
|---|
| 623 |
message = The message to pass as the error code. |
|---|
| 624 |
|
|---|
| 625 |
Remarks: |
|---|
| 626 |
Replaces lua_error and luaL_error. |
|---|
| 627 |
|
|---|
| 628 |
******************************************************************************/ |
|---|
| 629 |
|
|---|
| 630 |
public int raiseError (char[] message = null) |
|---|
| 631 |
{ |
|---|
| 632 |
if (message !is null) |
|---|
| 633 |
{ |
|---|
| 634 |
pushString (message); |
|---|
| 635 |
} |
|---|
| 636 |
return lua_error (this.state_); |
|---|
| 637 |
} |
|---|
| 638 |
|
|---|
| 639 |
/******************************************************************************* |
|---|
| 640 |
|
|---|
| 641 |
Raises a Lua error due to a bad function argument, where the function |
|---|
| 642 |
name is taken from the call stack. |
|---|
| 643 |
|
|---|
| 644 |
bad argument #<argument> to <function> (<message>) |
|---|
| 645 |
|
|---|
| 646 |
This method does a long jump, and therefore never returns. |
|---|
| 647 |
|
|---|
| 648 |
Params: |
|---|
| 649 |
argument = Which argument is wrong or missing. |
|---|
| 650 |
message = The error message. |
|---|
| 651 |
|
|---|
| 652 |
Remarks: |
|---|
| 653 |
Replaces luaL_argerror. |
|---|
| 654 |
|
|---|
| 655 |
******************************************************************************/ |
|---|
| 656 |
|
|---|
| 657 |
public int argumentError (uint argument, char[] message) |
|---|
| 658 |
{ |
|---|
| 659 |
return luaL_argerror (this.state_, argument, toStringz (message)); |
|---|
| 660 |
} |
|---|
| 661 |
|
|---|
| 662 |
/******************************************************************************* |
|---|
| 663 |
|
|---|
| 664 |
Raises an error with a message like the following: |
|---|
| 665 |
|
|---|
| 666 |
<loc>: bad argument <argument> to '<func>' (<typename> expected, got <rt>) |
|---|
| 667 |
|
|---|
| 668 |
where loc is produced by LuaState.where, func is the name of the current |
|---|
| 669 |
function, and rt is the type name of the actual argument. |
|---|
| 670 |
|
|---|
| 671 |
This method does a long jump, and therefore never returns. |
|---|
| 672 |
|
|---|
| 673 |
Params: |
|---|
| 674 |
argument = Which argument is wrong or missing. |
|---|
| 675 |
typename = The expected type name. |
|---|
| 676 |
|
|---|
| 677 |
Remarks: |
|---|
| 678 |
Replaces luaL_typerror. |
|---|
| 679 |
|
|---|
| 680 |
******************************************************************************/ |
|---|
| 681 |
|
|---|
| 682 |
public int typeError (uint argument, char[] typename) |
|---|
| 683 |
{ |
|---|
| 684 |
return luaL_typerror (this.state_, argument, toStringz (typename)); |
|---|
| 685 |
} |
|---|
| 686 |
|
|---|
| 687 |
/******************************************************************************* |
|---|
| 688 |
|
|---|
| 689 |
Constructs a LuaBuffer and attaches it to this state. |
|---|
| 690 |
|
|---|
| 691 |
Returns: |
|---|
| 692 |
The constructed Lua buffer. |
|---|
| 693 |
|
|---|
| 694 |
*******************************************************************************/ |
|---|
| 695 |
|
|---|
| 696 |
public LuaBuffer createBuffer () |
|---|
| 697 |
{ |
|---|
| 698 |
return new LuaBuffer (this); |
|---|
| 699 |
} |
|---|
| 700 |
|
|---|
| 701 |
/******************************************************************************* |
|---|
| 702 |
|
|---|
| 703 |
Dumps a function as a binary chunk. Receives a Lua function on the top |
|---|
| 704 |
of the stack and produces a binary chunk that, if loaded again, results |
|---|
| 705 |
in a function equivalent to the one dumped. As it produces parts of the |
|---|
| 706 |
chunk, dump call the delegate with the given data to write them. |
|---|
| 707 |
|
|---|
| 708 |
The value returned is the error code returned by the last call to the |
|---|
| 709 |
delegate; 0 means no errors. |
|---|
| 710 |
|
|---|
| 711 |
This method does not pop the Lua function from the stack. |
|---|
| 712 |
|
|---|
| 713 |
Params: |
|---|
| 714 |
dg = Writer delegate |
|---|
| 715 |
|
|---|
| 716 |
Remarks: |
|---|
| 717 |
Replaces lua_dump. |
|---|
| 718 |
|
|---|
| 719 |
*******************************************************************************/ |
|---|
| 720 |
|
|---|
| 721 |
public int dump (int delegate (char[] data) dg) |
|---|
| 722 |
{ |
|---|
| 723 |
return lua_dump (this.state_, &writer, &dg); |
|---|
| 724 |
} |
|---|
| 725 |
|
|---|
| 726 |
/******************************************************************************* |
|---|
| 727 |
|
|---|
| 728 |
Dumps a function as a binary chunk. It works exactly like the above dump |
|---|
| 729 |
method, but instead of passing the data to a delegate, it returns the |
|---|
| 730 |
complete result in one character array. |
|---|
| 731 |
|
|---|
| 732 |
*******************************************************************************/ |
|---|
| 733 |
|
|---|
| 734 |
public char[] dump () |
|---|
| 735 |
{ |
|---|
| 736 |
char[] result = []; |
|---|
| 737 |
|
|---|
| 738 |
int dumper (char[] data) |
|---|
| 739 |
{ |
|---|
| 740 |
result ~= data; |
|---|
| 741 |
return 0; |
|---|
| 742 |
} |
|---|
| 743 |
|
|---|
| 744 |
dump (&dumper); |
|---|
| 745 |
|
|---|
| 746 |
return result; |
|---|
| 747 |
} |
|---|
| 748 |
|
|---|
| 749 |
/******************************************************************************* |
|---|
| 750 |
|
|---|
| 751 |
Loads a Lua chunk. If there are no errors, load pushes the compiled |
|---|
| 752 |
chunk as a Lua function on top of the stack. Otherwise, it raises |
|---|
| 753 |
either a LuaCodeException, if the code cannot be compiled or a |
|---|
| 754 |
LuaFatalException on other errors. |
|---|
| 755 |
|
|---|
| 756 |
This function only loads a chunk; it does not run it. It automatically |
|---|
| 757 |
detects whether the chunk is text or binary, and loads it accordingly. |
|---|
| 758 |
|
|---|
| 759 |
The load method uses a user-supplied reader delegate to read the chunk, |
|---|
| 760 |
which must return either data or null when called. The latter means, |
|---|
| 761 |
that there is no further data to read. |
|---|
| 762 |
|
|---|
| 763 |
The chunk_name argument gives a name to the chunk, which is used for |
|---|
| 764 |
error messages and in debug information. |
|---|
| 765 |
|
|---|
| 766 |
--- |
|---|
| 767 |
auto L = new LuaState; |
|---|
| 768 |
L.doString (true, ` |
|---|
| 769 |
function fac (n) |
|---|
| 770 |
if n == 0 then |
|---|
| 771 |
return 1; |
|---|
| 772 |
else |
|---|
| 773 |
return n * fac(n-1); |
|---|
| 774 |
end |
|---|
| 775 |
end |
|---|
| 776 |
`); |
|---|
| 777 |
|
|---|
| 778 |
L.getGlobal ("fac"); // put function onto stack |
|---|
| 779 |
char[] data = L.dump (); // dump it |
|---|
| 780 |
L.pop (); // pop it |
|---|
| 781 |
L.load (data, "foo"); // reload function as chunk 'foo' |
|---|
| 782 |
L.setGlobal ("fac2"); // save it as the global function fac2 |
|---|
| 783 |
--- |
|---|
| 784 |
|
|---|
| 785 |
Params: |
|---|
| 786 |
dg = Reader delegate |
|---|
| 787 |
chunk_name = Name of this chunk |
|---|
| 788 |
|
|---|
|
|---|