コード例 #1
0
        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();
                }
            }
        }
コード例 #2
0
        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));
            }));
        }
コード例 #3
0
        public static LuaArguments SetMetaTable(Engine engine, LuaArguments args)
        {
            args.Expect(0, LuaType.Table, LuaType.Nil);

            args[0].SetMetaTable(engine, args[1]);
            return(Lua.Args());
        }
コード例 #4
0
        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));
            }
        }
コード例 #5
0
        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])));
        }
コード例 #6
0
        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));
        }
コード例 #7
0
        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));
        }
コード例 #8
0
        private static LuaArguments CreateArgs(object obj)
        {
            if (obj is LuaArguments args)
            {
                return(args);
            }

            return(Lua.Args(LuaObject.FromObject(obj)));
        }
コード例 #9
0
        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());
        }
コード例 #10
0
        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));
        }
コード例 #11
0
        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));
        }
コード例 #12
0
ファイル: LuaObject.cs プロジェクト: GerardSmit/Yali
        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)));
            }
        }
コード例 #13
0
ファイル: LuaObject.cs プロジェクト: GerardSmit/Yali
        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);
            }
        }
コード例 #14
0
        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));
        }
コード例 #15
0
        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();
            }
        }
コード例 #16
0
        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))));
        }
コード例 #17
0
ファイル: LuaTable.cs プロジェクト: GerardSmit/Yali
        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);
            }
        }
コード例 #18
0
ファイル: LuaTable.cs プロジェクト: GerardSmit/Yali
        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)));
            }
        }
コード例 #19
0
ファイル: RegexExtensions.cs プロジェクト: GerardSmit/Yali
        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));
        }
コード例 #20
0
ファイル: MathLibrary.cs プロジェクト: GerardSmit/Yali
 public static LuaArguments Exp(LuaArguments args)
 {
     return(Lua.Args(Math.Exp(args[0])));
 }
コード例 #21
0
ファイル: AssertLibrary.cs プロジェクト: GerardSmit/Yali
 public static Task Throws(Engine engine, LuaObject obj, LuaArguments args)
 {
     return(Assert.ThrowsAsync <LuaException>(() => obj.CallAsync(engine, Lua.Args(args.Skip(1)))));
 }
コード例 #22
0
ファイル: MathLibrary.cs プロジェクト: GerardSmit/Yali
 public static LuaArguments Ceil(LuaArguments args)
 {
     return(Lua.Args(Math.Ceiling(args[0])));
 }
コード例 #23
0
ファイル: MathLibrary.cs プロジェクト: GerardSmit/Yali
 public static LuaArguments Atan2(LuaArguments args)
 {
     return(Lua.Args(Math.Atan2(args[0], args[1])));
 }
コード例 #24
0
ファイル: MathLibrary.cs プロジェクト: GerardSmit/Yali
 public static LuaArguments Sinh(LuaArguments args)
 {
     return(Lua.Args(Math.Sinh(args[0])));
 }
コード例 #25
0
ファイル: MathLibrary.cs プロジェクト: GerardSmit/Yali
 public static LuaArguments Cos(LuaArguments args)
 {
     return(Lua.Args(Math.Cos(args[0])));
 }
コード例 #26
0
ファイル: MathLibrary.cs プロジェクト: GerardSmit/Yali
 public static LuaArguments Pow(LuaArguments args)
 {
     return(Lua.Args(Math.Pow(args[0], args[1])));
 }
コード例 #27
0
ファイル: MathLibrary.cs プロジェクト: GerardSmit/Yali
        public static LuaArguments Min(LuaArguments args)
        {
            var min = args.Skip(1).Aggregate(args[0], (current, o) => Math.Min(current, o));

            return(Lua.Args(min));
        }
コード例 #28
0
ファイル: MathLibrary.cs プロジェクト: GerardSmit/Yali
        public static LuaArguments Max(LuaArguments args)
        {
            var max = args.Skip(1).Aggregate(args[0], (current, o) => Math.Max(current, o));

            return(Lua.Args(max));
        }
コード例 #29
0
ファイル: MathLibrary.cs プロジェクト: GerardSmit/Yali
 public static LuaArguments Log(LuaArguments args)
 {
     return(Lua.Args(Math.Log(args[0])));
 }
コード例 #30
0
ファイル: MathLibrary.cs プロジェクト: GerardSmit/Yali
 public static LuaArguments Floor(LuaArguments args)
 {
     return(Lua.Args(Math.Floor(args[0])));
 }