protected static lua_Integer LuaType(LuaState L, lua_Integer p) { switch (GetArgument(L, p).Type) { case DataType.Void: return LUA_TNONE; case DataType.Nil: return LUA_TNIL; case DataType.Boolean: return LUA_TNIL; case DataType.Number: return LUA_TNUMBER; case DataType.String: return LUA_TSTRING; case DataType.Function: return LUA_TFUNCTION; case DataType.Table: return LUA_TTABLE; case DataType.UserData: return LUA_TUSERDATA; case DataType.Thread: return LUA_TTHREAD; case DataType.ClrFunction: return LUA_TFUNCTION; case DataType.TailCallRequest: case DataType.YieldRequest: case DataType.Tuple: default: throw new ScriptRuntimeException("Can't call LuaType on any type"); } }
protected static DynValue ArgAsType(LuaState L, int pos, DataType type, bool allowNil = false) { return GetArgument(L, pos) .CheckType(L.FunctionName, type, pos - 1, allowNil ? TypeValidationFlags.AllowNil | TypeValidationFlags.AutoConvert : TypeValidationFlags.AutoConvert); }
protected static void LuaGetTable(LuaState L, lua_Integer p) { // DEBT: this should call metamethods, now it performs raw access DynValue key = L.Pop(); DynValue table = L.At(p); if (table.Type != DataType.Table) throw new NotImplementedException(); var v = table.Table.Get(key); L.Push(v); }
public static int str_format(LuaState L) { var top = LuaGetTop(L); var arg = 1; uint sfl; CharPtr strfrmt = LuaLCheckLString(L, arg, out sfl); var strfrmt_end = strfrmt + sfl; var b = new LuaLBuffer(L); LuaLBuffInit(L, b); while (strfrmt < strfrmt_end) { if (strfrmt[0] != L_ESC) { LuaLAddChar(b, strfrmt[0]); strfrmt = strfrmt.next(); } else if (strfrmt[1] == L_ESC) { LuaLAddChar(b, strfrmt[0]); /* %% */ strfrmt = strfrmt + 2; } else { /* format item */ strfrmt = strfrmt.next(); CharPtr form = new char[MAX_FORMAT]; /* to store the format (`%...') */ CharPtr buff = new char[MAX_ITEM]; /* to store the formatted item */ if (++arg > top) LuaLArgError(L, arg, "no value"); strfrmt = scanformat(L, strfrmt, form); var ch = strfrmt[0]; strfrmt = strfrmt.next(); switch (ch) { case 'c': { sprintf(buff, form, (int) LuaLCheckNumber(L, arg)); break; } case 'd': case 'i': { addintlen(form); sprintf(buff, form, (long) LuaLCheckNumber(L, arg)); break; } case 'o': case 'u': case 'x': case 'X': { addintlen(form); sprintf(buff, form, (ulong) LuaLCheckNumber(L, arg)); break; } case 'e': case 'E': case 'f': case 'g': case 'G': { sprintf(buff, form, LuaLCheckNumber(L, arg)); break; } case 'q': { addquoted(L, b, arg); continue; /* skip the 'addsize' at the end */ } case 's': { uint l; CharPtr s = LuaLCheckLString(L, arg, out l); if ((strchr(form, '.') == null) && l >= 100) { /* no precision and string is too long to be formatted; keep original string */ LuaPushValue(L, arg); LuaLAddValue(b); continue; /* skip the `addsize' at the end */ } sprintf(buff, form, s); break; } default: { /* also treat cases `pnLlh' */ return LuaLError(L, "invalid option " + LUA_QL("%" + ch) + " to " + LUA_QL("format"), strfrmt[-1]); } } LuaLAddLString(b, buff, (uint) strlen(buff)); } } LuaLPushResult(b); return 1; }
protected static void LuaPop(LuaState L, lua_Integer p) { for (int i = 0; i < p; i++) L.Pop(); }
protected static DynValue GetArgument(LuaState L, lua_Integer pos) { return L.At(pos); }
/// <summary> /// Calls a callback function implemented in "classic way". /// Useful to port C code from Lua, or C# code from UniLua and KopiLua. /// Lua : http://www.lua.org/ /// UniLua : http://github.com/xebecnan/UniLua /// KopiLua : http://github.com/NLua/KopiLua /// </summary> /// <param name="args">The arguments.</param> /// <param name="functionName">Name of the function - for error messages.</param> /// <param name="callback">The callback.</param> /// <returns></returns> public DynValue EmulateClassicCall(CallbackArguments args, string functionName, Func<LuaState, int> callback) { LuaState L = new LuaState(this, args, functionName); int retvals = callback(L); return L.GetReturnValue(retvals); }
protected static void LuaLArgError(LuaState L, lua_Integer arg, string p) { throw ScriptRuntimeException.BadArgument(arg - 1, L.FunctionName, p); }
protected static void LuaPushValue(LuaState L, lua_Integer arg) { DynValue v = L.At(arg); L.Push(v); }
protected static void LuaLBuffInit(LuaState L, LuaLBuffer b) { }
protected static void LuaPushLiteral(LuaState L, string literalString) { L.Push(DynValue.NewString(literalString)); }
protected static lua_Integer LuaGetTop(LuaState L) { return L.Count; }
protected static lua_Integer LuaLError(LuaState luaState, string message, params object[] args) { throw new ScriptRuntimeException(message, args); }
protected static lua_Integer LuaLCheckInt(LuaState L, lua_Integer argNum) { return LuaLCheckInteger(L, argNum); }
protected static void LuaLArgCheck(LuaState L, bool condition, lua_Integer argNum, string message) { if (!condition) LuaLArgError(L, argNum, message); }
protected static lua_Integer LuaLOptInteger(LuaState L, lua_Integer pos, lua_Integer def) { DynValue v = ArgAsType(L, pos, DataType.Number, true); if (v.IsNil()) return def; else return (int)v.Number; }
protected static int LuaLOptInt(LuaState L, lua_Integer pos, lua_Integer def) { return LuaLOptInteger(L, pos, def); }
protected static void LuaPushLString(LuaState L, CharPtr s, uint len) { string ss = s.ToString((int)len); L.Push(DynValue.NewString(ss)); }
protected static string LuaLCheckStringStr(LuaState L, lua_Integer p) { uint dummy; return LuaLCheckLString(L, p, out dummy); }
protected static void LuaLCheckStack(LuaState L, lua_Integer n, string message) { // nop ? }
protected static double LuaLCheckNumber(LuaState L, lua_Integer pos) { DynValue v = ArgAsType(L, pos, DataType.Number, false); return v.Number; }
protected static string LuaLCheckLString(LuaState L, lua_Integer argNum, out uint l) { string str = ArgAsType(L, argNum, DataType.String, false).String; l = (uint)str.Length; return str; }
/// <summary> /// Calls a function. /// To call a function you must use the following protocol: first, the function to be called is pushed onto the stack; then, /// the arguments to the function are pushed in direct order; that is, the first argument is pushed first. Finally you call /// lua_call; nargs is the number of arguments that you pushed onto the stack. All arguments and the function value are /// popped from the stack when the function is called. The function results are pushed onto the stack when the function /// returns. The number of results is adjusted to nresults, unless nresults is LUA_MULTRET. In this case, all results from /// the function are pushed. Lua takes care that the returned values fit into the stack space. The function results are /// pushed onto the stack in direct order (the first result is pushed first), so that after the call the last result is on /// the top of the stack. /// </summary> /// <param name="L">The LuaState</param> /// <param name="nargs">The number of arguments.</param> /// <param name="nresults">The number of expected results.</param> /// <exception cref="System.NotImplementedException"></exception> protected static void LuaCall(LuaState L, lua_Integer nargs, lua_Integer nresults = LUA_MULTRET) { DynValue[] args = L.GetTopArray(nargs); L.Discard(nargs); DynValue func = L.Pop(); DynValue ret = L.ExecutionContext.Call(func, args); if (nresults != 0) { if (nresults == -1) { nresults = (ret.Type == DataType.Tuple) ? ret.Tuple.Length : 1; } DynValue[] vals = (ret.Type == DataType.Tuple) ? ret.Tuple : new DynValue[1] { ret }; int copied = 0; for (int i = 0; i < vals.Length && copied < nresults; i++, copied++) { L.Push(vals[i]); } while (copied < nresults) { L.Push(DynValue.Nil); } } }
protected static lua_Integer LuaToBoolean(LuaState L, lua_Integer p) { return GetArgument(L, p).CastToBool() ? 1 : 0; }
protected static void LuaPushNil(LuaState L) { L.Push(DynValue.Nil); }
public LuaLBuffer(LuaState l) { StringBuilder = new StringBuilder(); LuaState = l; }
protected static void LuaPushInteger(LuaState L, lua_Integer val) { L.Push(DynValue.NewNumber(val)); }
protected static string LuaLTypeName(LuaState L, lua_Integer p) { return L.At(p).Type.ToErrorTypeString(); }
protected static string LuaToLString(LuaState luaState, lua_Integer p, out uint l) { return LuaLCheckLString(luaState, p, out l); }
protected static lua_Integer LuaIsString(LuaState L, lua_Integer p) { var v = L.At(p); return (v.Type == DataType.String || v.Type == DataType.Number) ? 1 : 0; }