PushCodes() private method

複数のコードを追加します。
private PushCodes ( IEnumerable list ) : void
list IEnumerable コード
return void
        /// <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);
        }
Esempio n. 2
0
 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;
 }
        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);
        }
Esempio n. 4
0
        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;
        }
Esempio n. 5
0
 /// <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;
 }
Esempio n. 6
0
 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;
 }