Kecaknoahで利用されるILの一連を定義します。
Exemple #1
0
        /// <summary>
        /// 指定した<see cref="KecaknoahIL"/>を式として実行し、<see cref="KecaknoahStackFrame"/>を返します。
        /// </summary>
        /// <param name="il"></param>
        /// <returns>結果</returns>
        public KecaknoahStackFrame ExecuteWithStackFrame(KecaknoahIL il)
        {
            var sf = new KecaknoahStackFrame(this, il);

            sf.Execute();
            return(sf);
        }
        /// <summary>
        /// 式からなる<see cref="KecaknoahAst"/>をプリコンパイルします。
        /// </summary>
        /// <param name="ast">対象の<see cref="KecaknoahAst"/></param>
        /// <returns>プリコンパイル結果</returns>
        public KecaknoahIL PrecompileExpression(KecaknoahAst ast)
        {
            var result = new KecaknoahIL();

            result.PushCodes(PrecompileExpression(ast.RootNode));
            return(result);
        }
        /// <summary>
        /// 指定されたILを式として実行し、結果を返します。
        /// </summary>
        /// <param name="il">実行する<see cref="KecaknoahIL"/></param>
        /// <returns>結果</returns>
        public KecaknoahObject ExecuteExpressionIL(KecaknoahIL il)
        {
            var s = new KecaknoahStackFrame(this, il);

            s.Execute();
            return(s.ReturningObject);
        }
 private KecaknoahScriptClassInfo PrecompileClass(KecaknoahClassAstNode ast)
 {
     //TODO: local初期値式対応
     var result = new KecaknoahScriptClassInfo(ast.Name);
     cuc.Push(result);
     foreach (var i in ast.Functions)
     {
         if (i.StaticMethod)
         {
             result.AddClassMethod(PrecompileFunction(i));
         }
         else
         {
             result.AddInstanceMethod(PrecompileFunction(i));
         }
     }
     foreach (var i in ast.Locals)
     {
         if (i.InitialExpression != null)
         {
             var il = new KecaknoahIL();
             il.PushCodes(PrecompileExpression(i.InitialExpression));
             result.AddLocal(i.Name, il);
         }
         else
         {
             result.AddLocal(i.Name, null);
         }
     }
     cuc.Pop();
     return result;
 }
Exemple #5
0
        /// <summary>
        /// 指定した<see cref="KecaknoahIL"/>を式として実行します。
        /// </summary>
        /// <param name="il"></param>
        /// <returns>結果</returns>
        public KecaknoahObject Execute(KecaknoahIL il)
        {
            var sf = new KecaknoahStackFrame(this, il);

            sf.Execute();
            return(sf.ReturningObject);
        }
 /// <summary>
 /// 新しいインスタンスを初期化します。
 /// </summary>
 /// <param name="ctx">実行している<see cref="KecaknoahContext"/></param>
 /// <param name="il">実行する<see cref="KecaknoahIL"/></param>
 public KecaknoahStackFrame(KecaknoahContext ctx, KecaknoahIL il)
 {
     Codes          = il.Codes;
     ProgramCounter = 0;
     RunningContext = ctx;
 }
 /// <summary>
 /// 新しいインスタンスを初期化します。
 /// </summary>
 /// <param name="ctx">実行している<see cref="KecaknoahContext"/></param>
 /// <param name="il">実行する<see cref="KecaknoahIL"/></param>
 public KecaknoahStackFrame(KecaknoahContext ctx, KecaknoahIL il)
 {
     Codes = il.Codes;
     ProgramCounter = 0;
     RunningContext = ctx;
 }
        internal IReadOnlyList <KecaknoahILCode> PrecompileBlock(IReadOnlyList <KecaknoahAstNode> ast, string loopId)
        {
            var           result = new KecaknoahIL();
            List <string> locals = new List <string>();

            foreach (var i in ast)
            {
                if (i is KecaknoahExpressionAstNode)
                {
                    if (i is KecaknoahFactorExpressionAstNode)
                    {
                        var exp = i as KecaknoahFactorExpressionAstNode;
                        if (exp.FactorType != KecaknoahFactorType.CoroutineResume)
                        {
                            throw new InvalidOperationException("ステートメントにできる式はcoresume・代入・呼び出し・インクリメント・デクリメントのみです");
                        }
                    }
                    else if (i is KecaknoahArgumentCallExpressionAstNode)
                    {
                        var exp = i as KecaknoahArgumentCallExpressionAstNode;
                        if (exp.ExpressionType != KecaknoahOperatorType.FunctionCall)
                        {
                            throw new InvalidOperationException("ステートメントにできる式はcoresume・代入・呼び出し・インクリメント・デクリメントのみです");
                        }
                        result.PushCodes(PrecompileFunctionCall(exp));
                        result.PushCode(KecaknoahILCodeType.Pop);
                    }
                    else if (i is KecaknoahBinaryExpressionAstNode)
                    {
                        var exp = i as KecaknoahBinaryExpressionAstNode;
                        switch (exp.ExpressionType)
                        {
                        case KecaknoahOperatorType.Assign:
                        case KecaknoahOperatorType.PlusAssign:
                        case KecaknoahOperatorType.MinusAssign:
                        case KecaknoahOperatorType.MultiplyAssign:
                        case KecaknoahOperatorType.DivideAssign:
                        case KecaknoahOperatorType.AndAssign:
                        case KecaknoahOperatorType.OrAssign:
                        case KecaknoahOperatorType.XorAssign:
                        case KecaknoahOperatorType.ModularAssign:
                        case KecaknoahOperatorType.LeftBitShiftAssign:
                        case KecaknoahOperatorType.RightBitShiftAssign:
                        case KecaknoahOperatorType.NilAssign:
                            result.PushCodes(PrecompileBinaryExpression(exp));
                            result.PushCode(KecaknoahILCodeType.Pop);
                            break;

                        default:
                            throw new InvalidOperationException("ステートメントにできる式はcoresume・代入・呼び出し・インクリメント・デクリメントのみです");
                        }
                    }
                    else if (i is KecaknoahPrimaryExpressionAstNode)
                    {
                        var exp = i as KecaknoahPrimaryExpressionAstNode;
                        switch (exp.ExpressionType)
                        {
                        case KecaknoahOperatorType.Increment:
                            result.PushCodes(PrecompileSuffixIncrement(exp));
                            result.PushCode(KecaknoahILCodeType.Pop);
                            break;

                        case KecaknoahOperatorType.Decrement:
                            result.PushCodes(PrecompileSuffixDecrement(exp));
                            result.PushCode(KecaknoahILCodeType.Pop);
                            break;

                        default:
                            throw new InvalidOperationException("ステートメントにできる式はcoresume・代入・呼び出し・インクリメント・デクリメントのみです");
                        }
                    }
                    else if (i is KecaknoahUnaryExpressionAstNode)
                    {
                        var exp = i as KecaknoahUnaryExpressionAstNode;
                        switch (exp.ExpressionType)
                        {
                        case KecaknoahOperatorType.Increment:
                            result.PushCodes(PrecompilePrefixIncrement(exp));
                            result.PushCode(KecaknoahILCodeType.Pop);
                            break;

                        case KecaknoahOperatorType.Decrement:
                            result.PushCodes(PrecompilePrefixDecrement(exp));
                            result.PushCode(KecaknoahILCodeType.Pop);
                            break;

                        default:
                            throw new InvalidOperationException("ステートメントにできる式はcoresume・代入・呼び出し・インクリメント・デクリメントのみです");
                        }
                    }
                    else
                    {
                        throw new InvalidOperationException("ステートメントにできる式はcoresume・代入・呼び出し・インクリメント・デクリメントのみです");
                    }
                }
                else if (i is KecaknoahLocalAstNode)
                {
                    var lc = i as KecaknoahLocalAstNode;
                    locals.Add(lc.Name);
                    if (lc.InitialExpression != null)
                    {
                        result.PushCode(KecaknoahILCodeType.LoadObject, lc.Name);
                        result.PushCodes(PrecompileExpression(lc.InitialExpression));
                        result.PushCode(KecaknoahILCodeType.Assign);
                    }
                }
                else if (i is KecaknoahReturnAstNode)
                {
                    var rc = i as KecaknoahReturnAstNode;
                    if (rc.Value != null)
                    {
                        result.PushCodes(PrecompileExpression(rc.Value));
                    }
                    else
                    {
                        result.PushCode(KecaknoahILCodeType.PushNil);
                    }
                    result.PushCode(rc.Type == KecaknoahAstNodeType.ReturnStatement ? KecaknoahILCodeType.Return : KecaknoahILCodeType.Yield);
                }
                else if (i is KecaknoahCoroutineDeclareAstNode)
                {
                    var cd = i as KecaknoahCoroutineDeclareAstNode;
                    result.PushCodes(PrecompileExpression(cd.InitialExpression));
                    foreach (var pe in cd.ParameterExpressions)
                    {
                        result.PushCodes(PrecompileExpression(pe));
                    }
                    result.PushCode(new KecaknoahILCode {
                        Type = KecaknoahILCodeType.StartCoroutine, StringValue = cd.Name, IntegerValue = cd.ParameterExpressions.Count
                    });
                }
                else if (i is KecaknoahContinueAstNode)
                {
                    var ca = i as KecaknoahContinueAstNode;
                    var ln = ca.Label != "" ? ca.Label : loopId;
                    result.PushCode(KecaknoahILCodeType.Jump, $"{ln}-" + (i.Type == KecaknoahAstNodeType.ContinueStatement ? "Continue" : "End"));
                }
                else if (i is KecaknoahIfAstNode)
                {
                    result.PushCodes(PrecompileIf(i as KecaknoahIfAstNode, loopId));
                }
                else if (i is KecaknoahForAstNode)
                {
                    result.PushCodes(PrecompileFor(i as KecaknoahForAstNode));
                }
                else if (i is KecaknoahForeachAstNode)
                {
                    result.PushCodes(PrecompileForeach(i as KecaknoahForeachAstNode));
                }
                else if (i is KecaknoahLoopAstNode)
                {
                    result.PushCodes(PrecompileWhile(i as KecaknoahLoopAstNode));
                }
            }
            return(result.Codes);
        }
        private static KecaknoahScriptMethodInfo ReadMethod(BinaryReader reader)
        {
            string name = null;
            var length = 0;
            var vargs = false;

            while (true)
            {
                switch ((MethodElementType)reader.ReadByte())
                {
                    case MethodElementType.Name:
                        name = reader.ReadString();
                        break;
                    case MethodElementType.ArgumentLength:
                        length = reader.ReadInt32();
                        break;
                    case MethodElementType.VariableArgument:
                        vargs = true;
                        break;
                    case MethodElementType.StartCode:
                        var method = new KecaknoahScriptMethodInfo(name, length, vargs);
                        var il = new KecaknoahIL();
                        method.Codes = il;
                        var count = reader.ReadInt32();
                        for (var i = 0; i < count; i++)
                        {
                            switch (reader.ReadByte())
                            {
                                case 0:
                                    il.PushCode(KecaknoahILCodeType.Nop);
                                    break;
                                case 1:
                                    il.PushCode(KecaknoahILCodeType.PushInteger, reader.ReadInt64());
                                    break;
                                case 2:
                                    il.PushCode(KecaknoahILCodeType.PushString, reader.ReadString());
                                    break;
                                case 3:
                                    il.PushCode(KecaknoahILCodeType.PushSingle, reader.ReadSingle());
                                    break;
                                case 4:
                                    il.PushCode(KecaknoahILCodeType.PushDouble, reader.ReadDouble());
                                    break;
                                case 5:
                                    il.PushCode(KecaknoahILCodeType.PushBoolean, false);
                                    break;
                                case 6:
                                    il.PushCode(KecaknoahILCodeType.PushBoolean, true);
                                    break;
                                case 7:
                                    il.PushCode(KecaknoahILCodeType.PushNil);
                                    break;
                                case 8:
                                    il.PushCode(KecaknoahILCodeType.Pop);
                                    break;
                                case 9:
                                    il.PushCode(KecaknoahILCodeType.Plus);
                                    break;
                                case 10:
                                    il.PushCode(KecaknoahILCodeType.Minus);
                                    break;
                                case 11:
                                    il.PushCode(KecaknoahILCodeType.Multiply);
                                    break;
                                case 12:
                                    il.PushCode(KecaknoahILCodeType.Divide);
                                    break;
                                case 13:
                                    il.PushCode(KecaknoahILCodeType.Modular);
                                    break;
                                case 14:
                                    il.PushCode(KecaknoahILCodeType.And);
                                    break;
                                case 15:
                                    il.PushCode(KecaknoahILCodeType.Or);
                                    break;
                                case 16:
                                    il.PushCode(KecaknoahILCodeType.Xor);
                                    break;
                                case 17:
                                    il.PushCode(KecaknoahILCodeType.Not);
                                    break;
                                case 18:
                                    il.PushCode(KecaknoahILCodeType.Negative);
                                    break;
                                case 19:
                                    il.PushCode(KecaknoahILCodeType.AndAlso);
                                    break;
                                case 20:
                                    il.PushCode(KecaknoahILCodeType.OrElse);
                                    break;
                                case 21:
                                    il.PushCode(KecaknoahILCodeType.LeftBitShift);
                                    break;
                                case 22:
                                    il.PushCode(KecaknoahILCodeType.RightBitShift);
                                    break;
                                case 23:
                                    il.PushCode(KecaknoahILCodeType.Equal);
                                    break;
                                case 24:
                                    il.PushCode(KecaknoahILCodeType.NotEqual);
                                    break;
                                case 25:
                                    il.PushCode(KecaknoahILCodeType.Greater);
                                    break;
                                case 26:
                                    il.PushCode(KecaknoahILCodeType.Lesser);
                                    break;
                                case 27:
                                    il.PushCode(KecaknoahILCodeType.GreaterEqual);
                                    break;
                                case 28:
                                    il.PushCode(KecaknoahILCodeType.LesserEqual);
                                    break;
                                case 29:
                                    il.PushCode(KecaknoahILCodeType.Assign);
                                    break;
                                case 30:
                                    il.PushCode(KecaknoahILCodeType.Jump, reader.ReadInt32());
                                    break;
                                case 31:
                                    il.PushCode(KecaknoahILCodeType.TrueJump, reader.ReadInt32());
                                    break;
                                case 32:
                                    il.PushCode(KecaknoahILCodeType.FalseJump, reader.ReadInt32());
                                    break;
                                case 33:
                                    il.PushCode(KecaknoahILCodeType.Return);
                                    break;
                                case 34:
                                    il.PushCode(KecaknoahILCodeType.Yield);
                                    break;
                                case 35:
                                    il.PushCode(KecaknoahILCodeType.Call, reader.ReadInt32());
                                    break;
                                case 36:
                                    il.PushCode(KecaknoahILCodeType.IndexerCall, reader.ReadInt32());
                                    break;
                                case 37:
                                    il.PushCode(KecaknoahILCodeType.PushArgument, reader.ReadInt32());
                                    break;
                                case 38:
                                    il.PushCode(KecaknoahILCodeType.LoadObject, reader.ReadString());
                                    break;
                                case 39:
                                    il.PushCode(KecaknoahILCodeType.LoadMember, reader.ReadString());
                                    break;
                                case 40:
                                    il.PushCode(KecaknoahILCodeType.AsValue);
                                    break;
                                case 41:
                                    il.PushCode(KecaknoahILCodeType.LoadVarg, reader.ReadInt32());
                                    break;
                                case 42:
                                    var code = new KecaknoahILCode() { Type = KecaknoahILCodeType.StartCoroutine };
                                    code.StringValue = reader.ReadString();
                                    code.IntegerValue = reader.ReadInt32();
                                    il.PushCode(code);
                                    break;
                                case 43:
                                    il.PushCode(new KecaknoahILCode()
                                    {
                                        Type = KecaknoahILCodeType.ResumeCoroutine,
                                        StringValue = reader.ReadString(),
                                        BooleanValue = false
                                    });
                                    break;
                                case 44:
                                    il.PushCode(new KecaknoahILCode()
                                    {
                                        Type = KecaknoahILCodeType.ResumeCoroutine,
                                        StringValue = reader.ReadString(),
                                        BooleanValue = true
                                    });
                                    break;
                                case 45:
                                    il.PushCode(KecaknoahILCodeType.MakeArray, reader.ReadInt32());
                                    break;
                                case 46:
                                    il.PushCode(KecaknoahILCodeType.PlusAssign);
                                    break;
                                case 47:
                                    il.PushCode(KecaknoahILCodeType.MinusAssign);
                                    break;
                                case 48:
                                    il.PushCode(KecaknoahILCodeType.MultiplyAssign);
                                    break;
                                case 49:
                                    il.PushCode(KecaknoahILCodeType.DivideAssign);
                                    break;
                                case 50:
                                    il.PushCode(KecaknoahILCodeType.AndAssign);
                                    break;
                                case 51:
                                    il.PushCode(KecaknoahILCodeType.OrAssign);
                                    break;
                                case 52:
                                    il.PushCode(KecaknoahILCodeType.XorAssign);
                                    break;
                                case 53:
                                    il.PushCode(KecaknoahILCodeType.ModularAssign);
                                    break;
                                case 54:
                                    il.PushCode(KecaknoahILCodeType.LeftBitShiftAssign);
                                    break;
                                case 55:
                                    il.PushCode(KecaknoahILCodeType.RightBitShiftAssign);
                                    break;
                                case 56:
                                    il.PushCode(KecaknoahILCodeType.NilAssign);
                                    break;
                                default:
                                    throw new InvalidDataException("危険オペコードにはダマされない!!近づかない!!");
                            }
                        }

                        return method;
                    default:
                        throw new InvalidDataException("無効なメソッド");
                }
            }
        }
        internal IReadOnlyList<KecaknoahILCode> PrecompileBlock(IReadOnlyList<KecaknoahAstNode> ast, string loopId)
        {
            var result = new KecaknoahIL();
            List<string> locals = new List<string>();
            foreach (var i in ast)
            {
                if (i is KecaknoahExpressionAstNode)
                {
                    if (i is KecaknoahFactorExpressionAstNode)
                    {
                        var exp = i as KecaknoahFactorExpressionAstNode;
                        if (exp.FactorType != KecaknoahFactorType.CoroutineResume) throw new InvalidOperationException("ステートメントにできる式はcoresume・代入・呼び出し・インクリメント・デクリメントのみです");
                    }
                    else if (i is KecaknoahArgumentCallExpressionAstNode)
                    {
                        var exp = i as KecaknoahArgumentCallExpressionAstNode;
                        if (exp.ExpressionType != KecaknoahOperatorType.FunctionCall) throw new InvalidOperationException("ステートメントにできる式はcoresume・代入・呼び出し・インクリメント・デクリメントのみです");
                        result.PushCodes(PrecompileFunctionCall(exp));
                        result.PushCode(KecaknoahILCodeType.Pop);
                    }
                    else if (i is KecaknoahBinaryExpressionAstNode)
                    {
                        var exp = i as KecaknoahBinaryExpressionAstNode;
                        switch (exp.ExpressionType)
                        {
                            case KecaknoahOperatorType.Assign:
                            case KecaknoahOperatorType.PlusAssign:
                            case KecaknoahOperatorType.MinusAssign:
                            case KecaknoahOperatorType.MultiplyAssign:
                            case KecaknoahOperatorType.DivideAssign:
                            case KecaknoahOperatorType.AndAssign:
                            case KecaknoahOperatorType.OrAssign:
                            case KecaknoahOperatorType.XorAssign:
                            case KecaknoahOperatorType.ModularAssign:
                            case KecaknoahOperatorType.LeftBitShiftAssign:
                            case KecaknoahOperatorType.RightBitShiftAssign:
                            case KecaknoahOperatorType.NilAssign:
                                result.PushCodes(PrecompileBinaryExpression(exp));
                                result.PushCode(KecaknoahILCodeType.Pop);
                                break;
                            default:
                                throw new InvalidOperationException("ステートメントにできる式はcoresume・代入・呼び出し・インクリメント・デクリメントのみです");
                        }

                    }
                    else if (i is KecaknoahPrimaryExpressionAstNode)
                    {
                        var exp = i as KecaknoahPrimaryExpressionAstNode;
                        switch (exp.ExpressionType)
                        {
                            case KecaknoahOperatorType.Increment:
                                result.PushCodes(PrecompileSuffixIncrement(exp));
                                result.PushCode(KecaknoahILCodeType.Pop);
                                break;
                            case KecaknoahOperatorType.Decrement:
                                result.PushCodes(PrecompileSuffixDecrement(exp));
                                result.PushCode(KecaknoahILCodeType.Pop);
                                break;
                            default:
                                throw new InvalidOperationException("ステートメントにできる式はcoresume・代入・呼び出し・インクリメント・デクリメントのみです");
                        }
                    }
                    else if (i is KecaknoahUnaryExpressionAstNode)
                    {
                        var exp = i as KecaknoahUnaryExpressionAstNode;
                        switch (exp.ExpressionType)
                        {
                            case KecaknoahOperatorType.Increment:
                                result.PushCodes(PrecompilePrefixIncrement(exp));
                                result.PushCode(KecaknoahILCodeType.Pop);
                                break;
                            case KecaknoahOperatorType.Decrement:
                                result.PushCodes(PrecompilePrefixDecrement(exp));
                                result.PushCode(KecaknoahILCodeType.Pop);
                                break;
                            default:
                                throw new InvalidOperationException("ステートメントにできる式はcoresume・代入・呼び出し・インクリメント・デクリメントのみです");
                        }
                    }
                    else
                    {
                        throw new InvalidOperationException("ステートメントにできる式はcoresume・代入・呼び出し・インクリメント・デクリメントのみです");
                    }
                }
                else if (i is KecaknoahLocalAstNode)
                {
                    var lc = i as KecaknoahLocalAstNode;
                    locals.Add(lc.Name);
                    if (lc.InitialExpression != null)
                    {
                        result.PushCode(KecaknoahILCodeType.LoadObject, lc.Name);
                        result.PushCodes(PrecompileExpression(lc.InitialExpression));
                        result.PushCode(KecaknoahILCodeType.Assign);
                    }
                }
                else if (i is KecaknoahReturnAstNode)
                {
                    var rc = i as KecaknoahReturnAstNode;
                    if (rc.Value != null)
                    {
                        result.PushCodes(PrecompileExpression(rc.Value));
                    }
                    else
                    {
                        result.PushCode(KecaknoahILCodeType.PushNil);
                    }
                    result.PushCode(rc.Type == KecaknoahAstNodeType.ReturnStatement ? KecaknoahILCodeType.Return : KecaknoahILCodeType.Yield);
                }
                else if (i is KecaknoahCoroutineDeclareAstNode)
                {
                    var cd = i as KecaknoahCoroutineDeclareAstNode;
                    result.PushCodes(PrecompileExpression(cd.InitialExpression));
                    foreach (var pe in cd.ParameterExpressions) result.PushCodes(PrecompileExpression(pe));
                    result.PushCode(new KecaknoahILCode { Type = KecaknoahILCodeType.StartCoroutine, StringValue = cd.Name, IntegerValue = cd.ParameterExpressions.Count });
                }
                else if (i is KecaknoahContinueAstNode)
                {
                    var ca = i as KecaknoahContinueAstNode;
                    result.PushCode(KecaknoahILCodeType.Jump, $"{loopId}-" + (i.Type == KecaknoahAstNodeType.ContinueStatement ? "Continue" : "End"));
                }
                else if (i is KecaknoahIfAstNode)
                {
                    result.PushCodes(PrecompileIf(i as KecaknoahIfAstNode, loopId));
                }
                else if (i is KecaknoahForAstNode)
                {
                    result.PushCodes(PrecompileFor(i as KecaknoahForAstNode));
                }
                else if (i is KecaknoahForeachAstNode)
                {
                    result.PushCodes(PrecompileForeach(i as KecaknoahForeachAstNode));
                }
                else if (i is KecaknoahLoopAstNode)
                {
                    result.PushCodes(PrecompileWhile(i as KecaknoahLoopAstNode));
                }
            }
            return result.Codes;
        }
 /// <summary>
 /// 式からなる<see cref="KecaknoahAst"/>をプリコンパイルします。
 /// </summary>
 /// <param name="ast">対象の<see cref="KecaknoahAst"/></param>
 /// <returns>プリコンパイル結果</returns>
 public KecaknoahIL PrecompileExpression(KecaknoahAst ast)
 {
     var result = new KecaknoahIL();
     result.PushCodes(PrecompileExpression(ast.RootNode));
     return result;
 }
 /// <summary>
 /// フィールドを追加します。
 /// </summary>
 /// <param name="local">追加するメソッド</param>
 /// <param name="exp">初期化式を定義する<see cref="KecaknoahIL"/></param>
 internal void AddLocal(string local, KecaknoahIL exp)
 {
     LocalInfos.Add(new KecaknoahScriptLocalInfo { Name = local, InitializeIL = exp });
     localnames.Add(local);
 }
Exemple #13
0
 /// <summary>
 /// 指定した<see cref="KecaknoahIL"/>を式として実行し、<see cref="KecaknoahStackFrame"/>を返します。
 /// </summary>
 /// <param name="il"></param>
 /// <returns>結果</returns>
 public KecaknoahStackFrame ExecuteWithStackFrame(KecaknoahIL il)
 {
     var sf = new KecaknoahStackFrame(this, il);
     sf.Execute();
     return sf;
 }
Exemple #14
0
 /// <summary>
 /// 指定した<see cref="KecaknoahIL"/>を式として実行します。
 /// </summary>
 /// <param name="il"></param>
 /// <returns>結果</returns>
 public KecaknoahObject Execute(KecaknoahIL il)
 {
     var sf = new KecaknoahStackFrame(this, il);
     sf.Execute();
     return sf.ReturningObject;
 }
 private IList<KecaknoahILCode> PrecompileLexicalLambda(IList<KecaknoahILCode> il, List<string> lma)
 {
     var caps = new List<string>();
     for (int i = 0; i < il.Count; i++)
     {
         var c = il[i];
         if (c.Type == KecaknoahILCodeType.LoadObject)
         {
             var name = c.StringValue;
             if (lma.Contains(name))
             {
                 c.Type = KecaknoahILCodeType.PushArgument;
                 c.IntegerValue = lma.IndexOf(name);
             }
             else
             {
                 //キャプチャ対象
                 c.Type = KecaknoahILCodeType.LoadMember;
                 if (caps.Contains(name))
                 {
                     c.StringValue = $"cap_{caps.IndexOf(name)}";
                 }
                 else
                 {
                     c.StringValue = $"cap_{caps.Count}";
                     caps.Add(name);
                 }
                 il.Insert(i, new KecaknoahILCode { Type = KecaknoahILCodeType.LoadObject, StringValue = "self" });
             }
         }
     }
     var ln = $"Lambda-{Guid.NewGuid().ToString().Substring(0, 17)}";
     var cl = new KecaknoahScriptClassInfo(ln);
     var ctor = new KecaknoahIL();
     for (int i = 0; i < caps.Count; i++)
     {
         cl.AddLocal($"cap_{i}", null);
         ctor.PushCode(KecaknoahILCodeType.LoadObject, "self");
         ctor.PushCode(KecaknoahILCodeType.LoadMember, $"cap_{i}");
         ctor.PushCode(KecaknoahILCodeType.PushArgument, i);
         ctor.PushCode(KecaknoahILCodeType.Assign);
     }
     var ci = new KecaknoahScriptMethodInfo("new", caps.Count, false);
     ci.Codes = ctor;
     cl.AddClassMethod(ci);
     var fi = new KecaknoahScriptMethodInfo("body", lma.Count, false);
     fi.Codes = new KecaknoahIL();
     fi.Codes.PushCodes(il);
     cl.AddInstanceMethod(fi);
     current.classes.Add(cl);
     var result = new List<KecaknoahILCode>();
     result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.LoadObject, StringValue = ln });
     result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.LoadMember, StringValue = "new" });
     foreach (var i in caps) result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.LoadObject, StringValue = i });
     result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Call, IntegerValue = caps.Count });
     result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.LoadMember, StringValue = "body" });
     return result;
 }
 private IList<KecaknoahILCode> PrecompileClassLambda(IList<KecaknoahILCode> il, List<string> lma)
 {
     var caps = new List<string>();
     for (int i = 0; i < il.Count; i++)
     {
         var c = il[i];
         if (c.Type == KecaknoahILCodeType.LoadObject)
         {
             var name = c.StringValue;
             if (lma.Contains(name))
             {
                 c.Type = KecaknoahILCodeType.PushArgument;
                 c.IntegerValue = lma.IndexOf(name);
             }
         }
     }
     var ln = $"Lambda-{Guid.NewGuid().ToString().Substring(0, 17)}"; ;
     var mi = new KecaknoahScriptMethodInfo(ln, lma.Count, false);
     var lc = new KecaknoahIL();
     lc.PushCodes(il);
     mi.Codes = lc;
     var result = new List<KecaknoahILCode>();
     current.methods.Add(mi);
     result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.LoadObject, StringValue = ln });
     return result;
 }