Ejemplo n.º 1
0
        private static KecaknoahFunctionResult CreateArray(KecaknoahContext context, KecaknoahObject self, KecaknoahObject[] args)
        {
            if (args.Length == 0)
            {
                throw new ArgumentException("次元数が不正です");
            }
            if (args.Length >= 5)
            {
                throw new ArgumentException("次元数が多すぎます");
            }
            var dq     = args.Select(p => (int)p.ToInt64()).ToArray();
            var result = new KecaknoahArray(dq);

            return(result.NoResume());
        }
Ejemplo n.º 2
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);
        }