예제 #1
0
        /// <summary>
        /// .NETメソッドをトップレベルに登録します。
        /// </summary>
        /// <param name="func">登録する<see cref="KecaknoahInteropDelegate"/>形式のメソッド</param>
        /// <param name="name">メソッド名</param>
        public void RegisterFunction(KecaknoahInteropDelegate func, string name)
        {
            var fo = new KecaknoahInteropMethodInfo(name, func);

            topMethods.Add(fo);
            methodReferences.Add(KecaknoahReference.CreateRightReference(null, func));
        }
예제 #2
0
 private KecaknoahReference GetReference(string name)
 {
     KecaknoahReference result;
     if (Locals.ContainsKey(name)) return Locals[name];
     if ((result = RunningContext.Module.GetReference(name)) != KecaknoahNil.Reference) return result;
     result = new KecaknoahReference { IsLeftValue = true };
     locals[name] = result;
     return result;
 }
예제 #3
0
        /// <summary>
        /// .NETメソッドをトップレベルに登録します。
        /// </summary>
        /// <param name="func">登録する<see cref="Func{T1, T2, TResult}"/>形式のメソッド</param>
        /// <param name="name">メソッド名</param>
        public void RegisterFunction(Func <KecaknoahObject, KecaknoahObject[], string> func, string name)
        {
            KecaknoahInteropDelegate wp =
                (ctx, self, args) => func(self, args).AsKecaknoahString().NoResume();
            var fo = new KecaknoahInteropMethodInfo(name, wp);

            topMethods.Add(fo);
            methodReferences.Add(KecaknoahReference.CreateRightReference(null, wp));
        }
예제 #4
0
        /// <summary>
        /// .NETメソッドをトップレベルに登録します。
        /// </summary>
        /// <param name="func">登録する<see cref="Func{T1, T2, TResult}"/>形式のメソッド</param>
        /// <param name="name">メソッド名</param>
        public void RegisterBooleanFunction(Func <KecaknoahObject, KecaknoahObject[], bool> func, string name)
        {
            KecaknoahInteropDelegate wp =
                (ctx, self, args) => func(self, args).AsKecaknoahBoolean().NoResume();
            var fo = new KecaknoahInteropMethodInfo(name, wp);

            topMethods.Add(fo);
            methodReferences.Add(KecaknoahReference.Right(KecaknoahNil.Instance, wp));
        }
예제 #5
0
        /// <summary>
        /// .NETメソッドをトップレベルに登録します。
        /// </summary>
        /// <param name="func">登録する<see cref="Func{T1, T2, TResult}"/>形式のメソッド</param>
        /// <param name="name">メソッド名</param>
        public void RegisterSingleFunction(Func <KecaknoahObject, KecaknoahObject[], float> func, string name)
        {
            KecaknoahInteropDelegate wp =
                (ctx, self, args) => ((double)func(self, args)).AsKecaknoahFloat().NoResume();
            var fo = new KecaknoahInteropMethodInfo(name, wp);

            topMethods.Add(fo);
            methodReferences.Add(KecaknoahReference.Right(KecaknoahNil.Instance, wp));
        }
예제 #6
0
 /// <summary>
 /// プリコンパイルしたソースコードを登録します。
 /// </summary>
 /// <param name="src">登録する<see cref="KecaknoahSource"/></param>
 public void RegisterSource(KecaknoahSource src)
 {
     foreach (var c in src.Classes)
     {
         classes.Add(c);
         classReferences.Add(KecaknoahReference.CreateRightReference(new KecaknoahScriptClassObject(c)));
     }
     foreach (var m in src.TopLevelMethods)
     {
         topMethods.Add(m);
         methodReferences.Add(KecaknoahReference.CreateRightReference(new KecaknoahScriptFunction(KecaknoahNil.Instance, m)));
     }
 }
예제 #7
0
        private KecaknoahReference GetReference(string name)
        {
            KecaknoahReference result;

            if (Locals.ContainsKey(name))
            {
                return(Locals[name]);
            }
            if ((result = RunningContext.Module.GetReference(name)) != KecaknoahNil.Reference)
            {
                return(result);
            }
            result = new KecaknoahReference {
                IsLeftValue = true
            };
            locals[name] = result;
            return(result);
        }
예제 #8
0
        /// <summary>
        /// 現在の状態で、現在のコードの実行を再開します。
        /// </summary>
        /// <returns></returns>
        public bool Resume()
        {
            KecaknoahObject         v1, v2;
            KecaknoahReference      rfr;
            Stack <KecaknoahObject> args;

            while (ProgramCounter < Codes.Count)
            {
                var c = Codes[ProgramCounter];
                switch (c.Type)
                {
                //基本--------------------------------------------------------------------
                case KecaknoahILCodeType.Nop:
                    break;

                case KecaknoahILCodeType.Label:
                    break;

                case KecaknoahILCodeType.PushInteger:
                    ReferenceStack.Push(KecaknoahReference.Right(c.IntegerValue));
                    break;

                case KecaknoahILCodeType.PushString:
                    ReferenceStack.Push(KecaknoahReference.Right(c.StringValue));
                    break;

                case KecaknoahILCodeType.PushDouble:
                    ReferenceStack.Push(KecaknoahReference.Right(c.FloatValue));
                    break;

                case KecaknoahILCodeType.PushBoolean:
                    ReferenceStack.Push(KecaknoahReference.Right(c.BooleanValue));
                    break;

                case KecaknoahILCodeType.PushNil:
                    ReferenceStack.Push(KecaknoahNil.Reference);
                    break;

                case KecaknoahILCodeType.Pop:
                    ReferenceStack.Pop();
                    break;

                //二項演算子--------------------------------------------------------------
                case KecaknoahILCodeType.Plus:
                case KecaknoahILCodeType.Minus:
                case KecaknoahILCodeType.Multiply:
                case KecaknoahILCodeType.Divide:
                case KecaknoahILCodeType.Modular:
                case KecaknoahILCodeType.And:
                case KecaknoahILCodeType.Or:
                case KecaknoahILCodeType.Xor:
                case KecaknoahILCodeType.AndAlso:
                case KecaknoahILCodeType.OrElse:
                case KecaknoahILCodeType.LeftBitShift:
                case KecaknoahILCodeType.RightBitShift:
                case KecaknoahILCodeType.Equal:
                case KecaknoahILCodeType.NotEqual:
                case KecaknoahILCodeType.Greater:
                case KecaknoahILCodeType.Lesser:
                case KecaknoahILCodeType.GreaterEqual:
                case KecaknoahILCodeType.LesserEqual:
                    v2 = ReferenceStack.Pop().RawObject;
                    v1 = ReferenceStack.Pop().RawObject;
                    ReferenceStack.Push(KecaknoahReference.Right(v1.ExpressionOperation(c.Type, v2)));
                    break;

                case KecaknoahILCodeType.Not:
                case KecaknoahILCodeType.Negative:
                    v1 = ReferenceStack.Pop().RawObject;
                    ReferenceStack.Push(KecaknoahReference.Right(v1.ExpressionOperation(c.Type, null)));
                    break;

                //代入など--------------------------------------------------------------
                case KecaknoahILCodeType.Assign:
                    v1            = ReferenceStack.Pop().RawObject;
                    rfr           = ReferenceStack.Pop();
                    rfr.RawObject = v1;
                    ReferenceStack.Push(KecaknoahReference.Right(v1));
                    break;

                case KecaknoahILCodeType.PlusAssign:
                    v1            = ReferenceStack.Pop().RawObject;
                    rfr           = ReferenceStack.Pop();
                    v2            = rfr.RawObject.ExpressionOperation(KecaknoahILCodeType.Plus, v1);
                    rfr.RawObject = v2;
                    ReferenceStack.Push(KecaknoahReference.Right(v2));
                    break;

                case KecaknoahILCodeType.MinusAssign:
                    v1            = ReferenceStack.Pop().RawObject;
                    rfr           = ReferenceStack.Pop();
                    v2            = rfr.RawObject.ExpressionOperation(KecaknoahILCodeType.Minus, v1);
                    rfr.RawObject = v2;
                    ReferenceStack.Push(KecaknoahReference.Right(v2));
                    break;

                case KecaknoahILCodeType.MultiplyAssign:
                    v1            = ReferenceStack.Pop().RawObject;
                    rfr           = ReferenceStack.Pop();
                    v2            = rfr.RawObject.ExpressionOperation(KecaknoahILCodeType.Multiply, v1);
                    rfr.RawObject = v2;
                    ReferenceStack.Push(KecaknoahReference.Right(v2));
                    break;

                case KecaknoahILCodeType.DivideAssign:
                    v1            = ReferenceStack.Pop().RawObject;
                    rfr           = ReferenceStack.Pop();
                    v2            = rfr.RawObject.ExpressionOperation(KecaknoahILCodeType.Divide, v1);
                    rfr.RawObject = v2;
                    ReferenceStack.Push(KecaknoahReference.Right(v2));
                    break;

                case KecaknoahILCodeType.AndAssign:
                    v1            = ReferenceStack.Pop().RawObject;
                    rfr           = ReferenceStack.Pop();
                    v2            = rfr.RawObject.ExpressionOperation(KecaknoahILCodeType.And, v1);
                    rfr.RawObject = v2;
                    ReferenceStack.Push(KecaknoahReference.Right(v2));
                    break;

                case KecaknoahILCodeType.OrAssign:
                    v1            = ReferenceStack.Pop().RawObject;
                    rfr           = ReferenceStack.Pop();
                    v2            = rfr.RawObject.ExpressionOperation(KecaknoahILCodeType.Or, v1);
                    rfr.RawObject = v2;
                    ReferenceStack.Push(KecaknoahReference.Right(v2));
                    break;

                case KecaknoahILCodeType.XorAssign:
                    v1            = ReferenceStack.Pop().RawObject;
                    rfr           = ReferenceStack.Pop();
                    v2            = rfr.RawObject.ExpressionOperation(KecaknoahILCodeType.Xor, v1);
                    rfr.RawObject = v2;
                    ReferenceStack.Push(KecaknoahReference.Right(v2));
                    break;

                case KecaknoahILCodeType.ModularAssign:
                    v1            = ReferenceStack.Pop().RawObject;
                    rfr           = ReferenceStack.Pop();
                    v2            = rfr.RawObject.ExpressionOperation(KecaknoahILCodeType.Modular, v1);
                    rfr.RawObject = v2;
                    ReferenceStack.Push(KecaknoahReference.Right(v2));
                    break;

                case KecaknoahILCodeType.LeftBitShiftAssign:
                    v1            = ReferenceStack.Pop().RawObject;
                    rfr           = ReferenceStack.Pop();
                    v2            = rfr.RawObject.ExpressionOperation(KecaknoahILCodeType.LeftBitShift, v1);
                    rfr.RawObject = v2;
                    ReferenceStack.Push(KecaknoahReference.Right(v2));
                    break;

                case KecaknoahILCodeType.RightBitShiftAssign:
                    v1            = ReferenceStack.Pop().RawObject;
                    rfr           = ReferenceStack.Pop();
                    v2            = rfr.RawObject.ExpressionOperation(KecaknoahILCodeType.RightBitShift, v1);
                    rfr.RawObject = v2;
                    ReferenceStack.Push(KecaknoahReference.Right(v2));
                    break;

                case KecaknoahILCodeType.NilAssign:
                    v1            = ReferenceStack.Pop().RawObject;
                    rfr           = ReferenceStack.Pop();
                    v2            = rfr.RawObject.ExpressionOperation(KecaknoahILCodeType.NilAssign, v1);
                    rfr.RawObject = v2;
                    ReferenceStack.Push(KecaknoahReference.Right(v2));
                    break;

                //特殊----------------------------------------------------------------------------
                case KecaknoahILCodeType.StartCoroutine:
                    args = new Stack <KecaknoahObject>();
                    for (int i = 0; i < c.IntegerValue; i++)
                    {
                        args.Push(ReferenceStack.Pop().RawObject.AsByValValue());
                    }
                    var ct  = ReferenceStack.Peek().RawObject as KecaknoahScriptFunction;
                    var ict = ReferenceStack.Peek().RawObject as KecaknoahInteropFunction;
                    ReferenceStack.Pop();
                    if (ct == null && ict == null)
                    {
                        throw new InvalidOperationException("スクリプト上のメソッド以外はコルーチン化出来ません");
                    }
                    if (!ct.Equals(null))
                    {
                        cors[c.StringValue] = new KecaknoahScriptCoroutineFrame(RunningContext, ct, args.ToArray());
                    }
                    else
                    {
                        cors[c.StringValue] = new KecaknoahInteropCoroutineFrame(RunningContext, ict, args.ToArray());
                    }
                    break;

                case KecaknoahILCodeType.ResumeCoroutine:
                    var cobj = cors[c.StringValue];
                    if (cobj == null)
                    {
                        if (c.BooleanValue)
                        {
                            ReferenceStack.Pop();
                        }
                        ReferenceStack.Push(KecaknoahNil.Reference);
                        break;
                    }
                    var cr = cobj.Resume();
                    if (c.BooleanValue)
                    {
                        //2引数
                        var vas = ReferenceStack.Pop();
                        vas.RawObject = cr.ReturningObject;
                        ReferenceStack.Push(KecaknoahReference.Right(cr.CanResume.AsKecaknoahBoolean()));
                    }
                    else
                    {
                        //1引数
                        ReferenceStack.Push(KecaknoahReference.Right(cr.ReturningObject));
                    }
                    if (!cr.CanResume)
                    {
                        cors[c.StringValue] = null;
                    }
                    break;

                case KecaknoahILCodeType.MakeArray:
                    var ars = new Stack <KecaknoahObject>();
                    for (int i = 0; i < c.IntegerValue; i++)
                    {
                        ars.Push(ReferenceStack.Pop().RawObject);
                    }
                    var arr = new KecaknoahArray(new[] { (int)c.IntegerValue });
                    for (int i = 0; i < c.IntegerValue; i++)
                    {
                        arr.array[i] = new KecaknoahReference {
                            IsLeftValue = true, RawObject = ars.Pop()
                        }
                    }
                    ;
                    ReferenceStack.Push(KecaknoahReference.Right(arr));
                    break;

                case KecaknoahILCodeType.Jump:
                    ProgramCounter = (int)c.IntegerValue;
                    continue;

                case KecaknoahILCodeType.TrueJump:
                    v1 = ReferenceStack.Pop().RawObject;
                    if (v1.ToBoolean())
                    {
                        ProgramCounter = (int)c.IntegerValue;
                        continue;
                    }
                    break;

                case KecaknoahILCodeType.FalseJump:
                    v1 = ReferenceStack.Pop().RawObject;
                    if (!v1.ToBoolean())
                    {
                        ProgramCounter = (int)c.IntegerValue;
                        continue;
                    }
                    break;

                case KecaknoahILCodeType.Return:
                    ReturningObject = ReferenceStack.Pop().RawObject;
                    return(false);

                case KecaknoahILCodeType.Yield:
                    ReturningObject = ReferenceStack.Pop().RawObject;
                    ProgramCounter++;
                    return(true);

                case KecaknoahILCodeType.Call:
                    args = new Stack <KecaknoahObject>();
                    for (int i = 0; i < c.IntegerValue; i++)
                    {
                        args.Push(ReferenceStack.Pop().RawObject);
                    }
                    v1 = ReferenceStack.Pop().RawObject.AsByValValue();
                    ReferenceStack.Push(KecaknoahReference.Right(v1.Call(RunningContext, args.ToArray()).ReturningObject));
                    break;

                case KecaknoahILCodeType.IndexerCall:
                    args = new Stack <KecaknoahObject>();
                    for (int i = 0; i < c.IntegerValue; i++)
                    {
                        args.Push(ReferenceStack.Pop().RawObject);
                    }
                    v1 = ReferenceStack.Pop().RawObject.AsByValValue();
                    ReferenceStack.Push(v1.GetIndexerReference(args.ToArray()));
                    break;

                case KecaknoahILCodeType.PushArgument:
                    ReferenceStack.Push(KecaknoahReference.Right(Arguments[(int)c.IntegerValue]));
                    break;

                case KecaknoahILCodeType.LoadObject:
                    string refname = c.StringValue;
                    ReferenceStack.Push(GetReference(refname));
                    break;

                case KecaknoahILCodeType.LoadMember:
                    var or = ReferenceStack.Pop();
                    ReferenceStack.Push(or.GetMemberReference(c.StringValue));
                    break;

                case KecaknoahILCodeType.LoadVarg:
                    args = new Stack <KecaknoahObject>();
                    for (int i = 0; i < c.IntegerValue; i++)
                    {
                        args.Push(ReferenceStack.Pop().RawObject);
                    }
                    ReferenceStack.Push(KecaknoahReference.Right(VariableArguments[(int)args.Pop().ToInt64()]));
                    break;

                case KecaknoahILCodeType.AsValue:
                    ReferenceStack.Push(KecaknoahReference.Right(ReferenceStack.Pop().RawObject.AsByValValue()));
                    break;
                }
                ProgramCounter++;
            }
            if (ReferenceStack.Count == 0)
            {
                ReferenceStack.Push(KecaknoahNil.Reference);
            }
            ReturningObject = ReferenceStack.Pop().RawObject;
            return(false);
        }
예제 #9
0
 /// <summary>
 /// .NETメソッドをトップレベルに登録します。
 /// </summary>
 /// <param name="method">登録する<see cref="KecaknoahInteropMethodInfo"/>形式のメソッド</param>
 public void RegisterMethod(KecaknoahInteropMethodInfo method)
 {
     topMethods.Add(method);
     methodReferences.Add(KecaknoahReference.CreateRightReference(new KecaknoahInteropFunction(null, method.Body)));
 }
예제 #10
0
 /// <summary>
 /// .NET上のKecaknoah連携クラスを登録します。
 /// </summary>
 /// <param name="klass"></param>
 public void RegisterClass(KecaknoahInteropClassInfo klass)
 {
     classes.Add(klass);
     classReferences.Add(KecaknoahReference.CreateRightReference(new KecaknoahInteropClassObject(klass)));
 }
예제 #11
0
 /// <summary>
 /// .NETメソッドをトップレベルに登録します。
 /// </summary>
 /// <param name="method">登録する<see cref="KecaknoahInteropMethodInfo"/>形式のメソッド</param>
 public void RegisterMethod(KecaknoahInteropMethodInfo method)
 {
     topMethods.Add(method);
     methodReferences.Add(KecaknoahReference.Right(KecaknoahNil.Instance, method.Body));
 }