public async Task ExecuteAssignment(Assignment assign, LuaState state, CancellationToken token = default) { for (var i = 0; i < assign.Variables.Count; i++) { var expr = assign.Variables[i]; var ret = i < assign.Expressions.Count ? await _engine.EvaluateExpression(assign.Expressions[i], state, token) : Lua.Args(); if (expr is Variable var) { var from = var.Prefix != null ? await _engine.EvaluateExpression(var.Prefix, state, token).FirstAsync() : state.Context; await from.NewIndexAsync(state.Engine, var.Name, ret[0], token); } else if (expr is TableAccess tableAccess) { var table = await _engine.EvaluateExpression(tableAccess.Expression, state, token).FirstAsync(); var index = await _engine.EvaluateExpression(tableAccess.Index, state, token).FirstAsync(); await table.NewIndexAsync(state.Engine, index, ret[0], token); } else { throw new NotImplementedException(); } } }
public static LuaFunction CreateFunction(MethodInfo method) { var returnType = method.ReturnType; var isTask = typeof(Task).IsAssignableFrom(returnType); // Non-async if (!isTask) { return(new LuaDirectFunction((engine, args) => CreateArgs(InvokeMethod(method, engine, args)))); } // Async var hasReturn = returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(Task <>); return(new LuaAsyncFunction(async(engine, args, token) => { var task = (Task)InvokeMethod(method, engine, args, token); await task; if (!hasReturn) { return Lua.Args(); } var returnProperty = task.GetType().GetProperty("Result") ?? throw new InvalidOperationException(); return CreateArgs(returnProperty.GetValue(task)); })); }
public static LuaArguments SetMetaTable(Engine engine, LuaArguments args) { args.Expect(0, LuaType.Table, LuaType.Nil); args[0].SetMetaTable(engine, args[1]); return(Lua.Args()); }
public async Task ExecuteGenericFor(GenericFor forStat, LuaState state, CancellationToken token) { var forState = state.WithNewContext(); var varNames = forStat.Variables.Select(LuaObject.FromString).ToArray(); var expressions = await _engine.EvaluateExpression(forStat.Expressions, state, token); var func = expressions[0]; var table = expressions[1]; var args = Lua.Args(expressions.Skip(1)); while (true) { var result = await func.CallAsync(state.Engine, args, token); if (result[0].IsNil()) { break; } for (var i = 0; i < varNames.Length; i++) { forState.Context.NewIndexRaw(varNames[i], result[i]); } await _engine.ExecuteStatement(forStat.Block, forState, token); args = Lua.Args(new[] { table }.Concat(result)); } }
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 static LuaArguments Find(string str, string pattern, int?startIndex = null, bool plain = false) { startIndex -= 1; if (!startIndex.HasValue) { startIndex = 0; } else if (startIndex < 0) { startIndex = str.Length - startIndex * -1; } if (plain) { var index = str.IndexOf(pattern, startIndex.Value, StringComparison.Ordinal); return(index == -1 ? Lua.Args() : Lua.Args(1 + index, 1 + index + pattern.Length)); } var regex = RegexUtils.FromPattern(pattern); var match = regex.Match(str, startIndex.Value); return(!match.Success ? Lua.Args() : Lua.Args(1 + match.Index, 1 + match.Index + match.Length)); }
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)); }
private static LuaArguments CreateArgs(object obj) { if (obj is LuaArguments args) { return(args); } return(Lua.Args(LuaObject.FromObject(obj))); }
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()); }
public async Task <LuaArguments> EvaluateTableConstructor(TableConstructor constructor, LuaState state, CancellationToken token = default) { var table = LuaObject.CreateTable(); var keyCounter = (int?)1; for (var index = 0; index < constructor.Values.Count; index++) { var addAll = keyCounter.HasValue && index == constructor.Values.Count - 1; var kv = constructor.Values[index]; // Get the key. LuaObject key; if (kv.Key == null) { if (addAll) { key = LuaNil.Instance; } else if (keyCounter.HasValue) { key = keyCounter.Value; keyCounter++; } else { continue; } } else { key = await _engine.EvaluateExpression(kv.Key, state, token).FirstAsync(); keyCounter = null; addAll = false; } // Get the value. var value = await _engine.EvaluateExpression(kv.Value, state, token); if (addAll) { for (var i = 0; i < value.Length; i++) { table.NewIndexRaw(keyCounter.Value + i, value[i]); } } else { table.NewIndexRaw(key, value[0]); } } return(Lua.Args(table)); }
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 virtual Task <LuaObject> IndexAsync(Engine engine, LuaObject key, CancellationToken token = default) { var index = GetMetaMethod(engine, "__index"); switch (index.Type) { case LuaType.Function: return(index.CallAsync(engine, Lua.Args(this, key), token).FirstAsync()); case LuaType.Nil: return(Task.FromResult(IndexRaw(key))); default: return(Task.FromResult(index.IndexRaw(key))); } }
public virtual Task NewIndexAsync(Engine engine, LuaObject key, LuaObject value, CancellationToken token = default) { var newindex = GetMetaMethod(engine, "__newindex"); switch (newindex.Type) { case LuaType.Function: return(newindex.CallAsync(engine, Lua.Args(this, key, value), token).FirstAsync()); case LuaType.Nil: NewIndexRaw(key, value); return(Task.CompletedTask); default: newindex.NewIndexRaw(key, value); return(Task.CompletedTask); } }
public static LuaArguments Match(string str, string pattern, int?startIndex = null) { startIndex -= 1; if (!startIndex.HasValue) { startIndex = 0; } else if (startIndex < 0) { startIndex = str.Length - startIndex * -1; } var regex = RegexUtils.FromPattern(pattern); var match = regex.Match(str, startIndex.Value); return(!match.Success ? Lua.Args() : GetArgs(match)); }
public async Task <LuaArguments> EvaluateUnaryExpression(UnaryExpression expr, LuaState state, CancellationToken token = default) { var op = await _engine.EvaluateExpression(expr.Expression, state, token).FirstAsync(); switch (expr.Operation) { case UnaryOp.Negate: return(Lua.Args(!op.AsBool())); case UnaryOp.Invert: return(Lua.Args(-op.AsNumber())); case UnaryOp.Length: return(Lua.Args(op.Length)); default: throw new ArgumentOutOfRangeException(); } }
public static LuaArguments Byte(string str, int startIndex = 1, int?endIndex = null) { startIndex -= 1; endIndex -= 1; var length = endIndex - startIndex ?? 1; if (startIndex < 0) { length = length + startIndex; startIndex = 0; } if (startIndex < 0 || length <= 0) { return(Lua.Args()); } return(Lua.Args(str.Skip(startIndex).Take(1).Select(c => LuaObject.FromNumber(c)))); }
public override Task NewIndexAsync(Engine engine, LuaObject key, LuaObject value, CancellationToken token = default) { var newindex = GetMetaMethod(engine, "__newindex"); var contains = ContainsKey(key); switch (newindex.Type) { case LuaType.Nil when !Parent.IsNil() && !contains: return(Parent.NewIndexAsync(engine, key, value, token)); case LuaType.Function when !contains: return(newindex.CallAsync(engine, Lua.Args(this, key), token)); case LuaType.Table when !contains: newindex.NewIndexRaw(key, value); return(Task.CompletedTask); default: NewIndexRaw(key, value); return(Task.CompletedTask); } }
public override Task <LuaObject> IndexAsync(Engine engine, LuaObject key, CancellationToken token = default) { if (ContainsKey(key)) { return(Task.FromResult(IndexRaw(key))); } var index = GetMetaMethod(engine, "__index"); switch (index.Type) { case LuaType.Nil when !Parent.IsNil(): return(Parent.IndexAsync(engine, key, token)); case LuaType.Nil: return(Task.FromResult(LuaNil.Instance)); case LuaType.Function: return(index.CallAsync(engine, Lua.Args(this, key), token).FirstAsync()); default: return(Task.FromResult(index.IndexRaw(key))); } }
public static async Task <LuaArguments> ReplaceAsync(this Regex regex, string input, Func <Match, Task <string> > replacementFn, int?max = null) { var sb = new StringBuilder(); var lastIndex = 0; var counter = 0; foreach (Match match in regex.Matches(input)) { if (max.HasValue && counter >= max.Value) { break; } sb.Append(input, lastIndex, match.Index - lastIndex) .Append(await replacementFn(match).ConfigureAwait(false)); lastIndex = match.Index + match.Length; counter++; } sb.Append(input, lastIndex, input.Length - lastIndex); return(Lua.Args(sb.ToString(), counter)); }
public static LuaArguments Exp(LuaArguments args) { return(Lua.Args(Math.Exp(args[0]))); }
public static Task Throws(Engine engine, LuaObject obj, LuaArguments args) { return(Assert.ThrowsAsync <LuaException>(() => obj.CallAsync(engine, Lua.Args(args.Skip(1))))); }
public static LuaArguments Ceil(LuaArguments args) { return(Lua.Args(Math.Ceiling(args[0]))); }
public static LuaArguments Atan2(LuaArguments args) { return(Lua.Args(Math.Atan2(args[0], args[1]))); }
public static LuaArguments Sinh(LuaArguments args) { return(Lua.Args(Math.Sinh(args[0]))); }
public static LuaArguments Cos(LuaArguments args) { return(Lua.Args(Math.Cos(args[0]))); }
public static LuaArguments Pow(LuaArguments args) { return(Lua.Args(Math.Pow(args[0], args[1]))); }
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]))); }