Exemplo 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();
 }
Exemplo 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;
        }