public static LuaArguments SetMetaTable(Engine engine, LuaArguments args) { args.Expect(0, LuaType.Table, LuaType.Nil); args[0].SetMetaTable(engine, args[1]); return(Lua.Args()); }
static LuaArguments io_open(LuaArguments args) { var file = args[0]; var mode = args[1]; if (file.IsString) { FileMode fmode = FileMode.Open; FileAccess faccess = FileAccess.Read; if (mode.IsString) { switch (mode.ToString()) { case "r": faccess = FileAccess.Read; break; case "w": fmode = FileMode.Create; faccess = FileAccess.ReadWrite; break; case "a": fmode = FileMode.Append; faccess = FileAccess.Write; break; case "r+": case "w+": case "a+": // TODO: Implement rwa+ throw new NotImplementedException(); } } FileStream stream = new FileStream(file.ToString(), fmode, faccess); return Lua.Return(CreateFileObject(stream)); } else return Lua.Return(); }
public static LuaArguments Next(Engine engine, LuaArguments args) { var table = args[0]; var index = args[1]; if (!table.IsTable()) { throw new LuaException("t must be a table"); } var keys = table.Keys.ToArray(); if (index.IsNil()) { return(keys.Length == 0 ? Lua.Args() : Lua.Args(keys[0], table.IndexRaw(keys[0]))); } var pos = Array.IndexOf(keys, index); return(pos == keys.Length - 1 ? Lua.Args() : Lua.Args(keys[pos + 1], table.IndexRaw(keys[pos + 1]))); }
public virtual Task <LuaArguments> CallAsync(Engine engine, LuaArguments args, CancellationToken token = default) { var call = GetMetaMethod(engine, "__call"); return(call.IsFunction() ? call.CallAsync(engine, args, token) : throw new LuaException($"attempt to call a {Type.ToLuaName()} value")); }
public static Task <LuaArguments> Pairs(Engine engine, LuaArguments args, CancellationToken token = default) { var handler = args[0].GetMetaMethod(engine, "__pairs"); return(!handler.IsNil() ? handler.CallAsync(engine, args, token) : Lua.ArgsAsync(LuaObject.FromFunction(Next), args[0], LuaNil.Instance)); }
private static async Task <LuaArguments> GetNext(Engine engine, LuaArguments x, CancellationToken token = default) { var s = x[0]; var var = x[1].AsNumber() + 1; var val = await s.IndexAsync(engine, var, token); return(val.IsNil() ? Lua.Args(LuaNil.Instance) : Lua.Args(var, val)); }
static LuaArguments math_min(LuaArguments args) { var min = args[0]; foreach (LuaObject o in args) { min = Math.Min(min, o); } return Lua.Return(min); }
public static LuaArguments Assert(LuaArguments args) { if (args.Length > 0 && !args[0].AsBool()) { throw new LuaException(args.Length == 1 ? "Assertion failed" : args[1].ToString()); } return(Lua.Args()); }
static LuaArguments math_max(LuaArguments args) { var max = args[0]; foreach (LuaObject o in args) { max = Math.Max(max, o); } return Lua.Return(max); }
public static void Expect(this LuaArguments args, int id, params LuaType[] types) { var obj = args[id]; if (types.Any(t => obj.Type == t)) { return; } var typeNames = string.Join(" or ", types.Select(t => t.ToLuaName())); throw new LuaException($"bad argument #{id + 1} to 'setmetatable' ({typeNames} expected)"); }
public override Task <LuaArguments> CallAsync(Engine engine, LuaArguments args, CancellationToken token = default) { var first = args[0]; if (first.IsNil()) { throw new LuaException("bad argument #1"); } var instance = (ICallableProxy)first.ToObject(); return(instance.CallAsync(Lua.Args(args.Skip(1)), token)); }
public static Task <LuaArguments> Ipairs(Engine engine, LuaArguments args, CancellationToken token = default) { var handler = args[0].GetMetaMethod(engine, "__ipairs"); if (!handler.IsNil()) { return(handler.CallAsync(engine, args, token)); } if (!args[0].IsTable()) { throw new LuaException("t must be a table"); } return(Lua.ArgsAsync(LuaObject.FromFunction(GetNext), args[0], 0)); }
public override async Task <LuaArguments> CallAsync(Engine engine, LuaArguments args, CancellationToken token = default) { var context = new LuaTableFunction(Context, _useParent); // Set the arguments. var i = 0; for (; i < _definition.Arguments.Count; i++) { context.NewIndexRaw(_definition.Arguments[i].Name, args[i]); } if (_definition.Varargs) { context.Varargs = args.Skip(i).ToArray(); } // Execute the statements. var state = new LuaState(engine, context); await engine.ExecuteStatement(_definition.Body, state, token); return(state.FunctionState.ReturnArguments); }
LuaArguments tonumber(LuaArguments args) { LuaObject obj = args[0]; if (args.Length == 1) { double d = 0; if (obj.IsString) { if (double.TryParse(obj.AsString(), out d)) return Return(d); else return Return(); } else if (obj.IsNumber) { return Return(obj.AsNumber()); } else { return Return(); } } else { //TODO: Implement tonumber for bases different from 10 throw new NotImplementedException(); } }
LuaArguments rawset(LuaArguments args) { LuaEvents.rawset(args[0], args[1], args[2]); return Return(args[0]); }
LuaArguments rawequal(LuaArguments args) { return Return(args[0] == args[1]); }
static LuaArguments close(LuaArguments args) { var obj = args[0]; if (isStream(obj)) { FileObject fobj = obj.luaobj as FileObject; fobj.stream.Close(); } return Lua.Return(); }
static LuaArguments io_write(LuaArguments args) { var obj = args[0]; if (!obj.IsNil) return currentOutput["write"].MethodCall(currentOutput, args); else return Lua.Return(); }
static LuaArguments io_type(LuaArguments args) { var obj = args[0]; if (isStream(obj)) { FileObject fobj = obj.luaobj as FileObject; if (!fobj.stream.CanWrite && !fobj.stream.CanRead) return Lua.Return("closed file"); else return Lua.Return("file"); } return Lua.Return(); }
public static LuaArguments Min(LuaArguments args) { var min = args.Skip(1).Aggregate(args[0], (current, o) => Math.Min(current, o)); return(Lua.Args(min)); }
public static LuaArguments Max(LuaArguments args) { var max = args.Skip(1).Aggregate(args[0], (current, o) => Math.Max(current, o)); return(Lua.Args(max)); }
public static LuaArguments Log(LuaArguments args) { return(Lua.Args(Math.Log(args[0]))); }
public static LuaArguments Floor(LuaArguments args) { return(Lua.Args(Math.Floor(args[0]))); }
public static LuaArguments Exp(LuaArguments args) { return(Lua.Args(Math.Exp(args[0]))); }
public static LuaArguments Cos(LuaArguments args) { return(Lua.Args(Math.Cos(args[0]))); }
LuaArguments type(LuaArguments args) { switch (args[0].Type) { case LuaType.boolean: return Return("boolean"); case LuaType.function: return Return("function"); case LuaType.nil: return Return("nil"); case LuaType.number: return Return("number"); case LuaType.@string: return Return("string"); case LuaType.table: return Return("table"); case LuaType.thread: return Return("thread"); case LuaType.userdata: return Return("userdata"); } return Return(); }
LuaArguments next(LuaArguments args) { var table = args[0]; var index = args[1]; if (!table.IsTable) { throw new LuaException("t must be a table"); } List<LuaObject> keys = new List<LuaObject>(table.AsTable().Keys); if (index.IsNil) { if (keys.Count == 0) return Return(); return Return(keys[0], table[keys[0]]); } else { int pos = keys.IndexOf(index); if (pos == keys.Count - 1) { return Return(); } else { return Return(keys[pos + 1], table[keys[pos + 1]]); } } }
public static LuaArguments Pow(LuaArguments args) { return(Lua.Args(Math.Pow(args[0], args[1]))); }
static LuaArguments io_output(LuaArguments args) { var obj = args[0]; if (isStream(obj)) { currentOutput = obj; return Lua.Return(currentOutput); } else if (obj.IsString) { FileStream stream = new FileStream(obj.ToString(), FileMode.OpenOrCreate); currentOutput = CreateFileObject(stream); return Lua.Return(currentOutput); } else if (args.Length == 0) return Lua.Return(currentOutput); else throw new LuaException("Invalid argument"); }
public static LuaArguments Sinh(LuaArguments args) { return(Lua.Args(Math.Sinh(args[0]))); }
static LuaArguments io_read(LuaArguments args) { return currentInput["read"].MethodCall(currentInput, args); }
private static object InvokeMethod(MethodBase method, Engine engine, LuaArguments args, CancellationToken token = default) { var instance = (object)null; var offset = 0; if (!method.IsStatic) { try { if (args[0].IsNil()) { throw new ArgumentException(); } offset = 1; instance = args[0].ToObject(method.DeclaringType); } catch (ArgumentException) { throw new LuaException("bad argument #1"); } } var index = offset; var parameters = method.GetParameters(); var methodArgs = new object[parameters.Length]; var argCount = args.Length - offset; for (var i = 0; i < parameters.Length; i++) { var parameter = parameters[i]; // Convert the argument object arg; if (parameter.ParameterType == typeof(LuaArguments)) { arg = args; } else if (parameter.ParameterType == typeof(CancellationToken)) { arg = token; } else if (parameter.ParameterType == typeof(Engine)) { arg = engine; } else if (index >= argCount) { if (!parameter.HasDefaultValue) { var paramCount = parameters.Count(p => p.ParameterType != typeof(LuaArguments) && p.ParameterType != typeof(CancellationToken) && p.ParameterType != typeof(Engine) ); throw new LuaException($"expected {paramCount} arguments, got {argCount} instead"); } arg = parameter.DefaultValue; } else { try { arg = args[index++].ToObject(parameter.ParameterType); } catch (ArgumentException) { throw new LuaException($"bad argument #{index + 1}"); } } methodArgs[i] = arg; } return(method.Invoke(instance, methodArgs)); }
static LuaArguments seek(LuaArguments args) { var obj = args[0]; var whence = args[1] | "cur"; var offset = args[2] | 0; if (isStream(obj)) { var fobj = obj.luaobj as FileObject; switch (whence.ToString()) { case "cur": fobj.stream.Position += (long)offset; break; case "set": fobj.stream.Position = (long)offset; break; case "end": fobj.stream.Position = fobj.stream.Length + (long)offset; break; } return Lua.Return(fobj.stream.Position); } return Lua.Return(); }
public override Task <LuaArguments> CallAsync(Engine engine, LuaArguments args, CancellationToken token = default) { return(_func(engine, args, token)); }
public static LuaArguments Ceil(LuaArguments args) { return(Lua.Args(Math.Ceiling(args[0]))); }
public static Task Throws(Engine engine, LuaObject obj, LuaArguments args) { return(Assert.ThrowsAsync <LuaException>(() => obj.CallAsync(engine, Lua.Args(args.Skip(1))))); }
LuaArguments rawget(LuaArguments args) { return Return(LuaEvents.rawget(args[0], args[1])); }
public Task <LuaArguments> CallAsync(LuaArguments args, CancellationToken token = default) { Assert.True(args[0].ToBoolean()); return(Lua.ArgsAsync()); }
LuaArguments rawlen(LuaArguments args) { LuaObject obj = args[0]; if (obj.IsString) return Return(obj.AsString().Length); else if (obj.IsTable) return Return(obj.AsTable().Count); else throw new LuaException("invalid argument"); }
static LuaArguments print(LuaArguments args) { Console.WriteLine(String.Join("\t", Array.ConvertAll <LuaObject, string>(args, x => x.ToString()))); return(Lua.Return()); }
LuaArguments tostring(LuaArguments args) { return Return(LuaEvents.tostring_event(args[0])); }
static LuaArguments io_write(LuaArguments args) { Console.Write(args[0].ToString()); return(Lua.Return()); }
LuaArguments ipairs(LuaArguments args) { LuaObject handler = LuaEvents.getMetamethod(args[0], "__ipairs"); if (!handler.IsNil) { return handler.Call(args); } else { if (args[0].IsTable) { LuaFunction f = delegate(LuaArguments x) { var s = x[0]; var var = x[1].AsNumber() + 1; var val = s[var]; if (val == LuaObject.Nil) return Return(LuaObject.Nil); else return Return(var, val); }; return Return(f, args[0], 0); } else { throw new LuaException("t must be a table"); } } }
static LuaArguments read(LuaArguments args) { return(Lua.Return(Console.ReadLine())); }
LuaArguments pairs(LuaArguments args) { LuaObject handler = LuaEvents.getMetamethod(args[0], "__pairs"); if (!handler.IsNil) { return handler.Call(args); } else { return Return((LuaFunction)next, args[0], LuaObject.Nil); } }
public static LuaArguments Asin(LuaArguments args) { return(Lua.Args(Math.Asin(args[0]))); }
static LuaArguments io_input(LuaArguments args) { var obj = args[0]; if (isStream(obj)) { currentInput = obj; return Lua.Return(currentInput); } else if (obj.IsString) { currentInput = io_open(args)[0]; return Lua.Return(currentInput); } else if (args.Length == 0) return Lua.Return(currentInput); else throw new LuaException("Invalid argument"); }
public void SetResult(LuaArguments args) { ReturnArguments = args; DidReturn = true; }
static LuaArguments io_temp(LuaArguments args) { string path = Path.GetTempFileName(); Stream s = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.Write, Int16.MaxValue, FileOptions.DeleteOnClose); return Lua.Return(CreateFileObject(s)); }
LuaArguments assert(LuaArguments args) { if (args.Length > 0) { if (args[0].AsBool() == false) { if (args.Length == 1) throw new LuaException("Assertion failed"); else throw new LuaException(args[1].ToString()); } } return Return(); }
static LuaArguments io_close(LuaArguments args) { var obj = args[0]; if (obj.IsNil) return currentOutput["close"].MethodCall(currentOutput, args); else return obj["close"].MethodCall(obj, args); }
LuaArguments dofile(LuaArguments args) { return DoFile(args[0].ToString()); }
static LuaArguments write(LuaArguments args) { var self = args[0]; if (isStream(self)) { FileObject fobj = self.luaobj as FileObject; foreach (var arg in args) { if (arg == self) continue; if (!(arg.IsString || arg.IsNumber)) Lua.Return(); if (fobj.stream.CanWrite) fobj.writer.Write(arg.ToString()); else Lua.Return(); } return Lua.Return(self); } else return Lua.Return(); }
LuaArguments error(LuaArguments args) { throw new LuaException(args[0].ToString()); }
static LuaArguments flush(LuaArguments args) { var obj = args[0]; if (isStream(obj)) { FileObject fobj = obj.luaobj as FileObject; fobj.writer.Flush(); } return Lua.Return(); }
LuaArguments getmetatable(LuaArguments args) { return Return(args[0].Metatable); }
static LuaArguments read(LuaArguments args) { var self = args[0]; if (isStream(self)) { var fobj = self.luaobj as FileObject; if (args.Length == 1) { var line = fobj.reader.ReadLine(); return Lua.Return(line); } else { List<LuaObject> ret = new List<LuaObject>(); foreach (var arg in args) { if (arg == self) continue; if (arg.IsNumber) { StringBuilder bld = new StringBuilder(); for (int i = 0; i < arg; i++) { bld.Append((char)fobj.reader.Read()); } ret.Add(bld.ToString()); } else if (arg == "*a") ret.Add(fobj.reader.ReadToEnd()); else if (arg == "*l") ret.Add(fobj.reader.ReadLine()); else if (arg == "*n") { //TODO: Implement io.read("*n") throw new NotImplementedException(); } } return Lua.Return(ret.ToArray()); } } else return Lua.Return(); }
LuaArguments setmetatable(LuaArguments args) { args[0].Metatable = args[1]; return Return(); }
public static int Bxor(LuaArguments args) { return(args.Select(o => o.AsInt()).Aggregate((l, r) => l ^ r)); }
public static LuaArguments Atan2(LuaArguments args) { return(Lua.Args(Math.Atan2(args[0], args[1]))); }