Exemple #1
0
            //------------------------------------------------------------ 
            // 評価準備。 
            bool eventAnalyze(SemanticAnalyzeComponent aComp)
            {
                // BuiltInTypeの選択
                BuiltInType builtInType;

                switch (mExpr.mToken.Value)
                {
                case Token.Kind.NumSInt32:
                    builtInType = BuiltInType.SInt32;
                    break;

                case Token.Kind.KeyTrue:
                case Token.Kind.KeyFalse:
                    builtInType = BuiltInType.Bool;
                    break;

                default:
                    // todo: いろんな型の対応
                    aComp.ThrowErrorException(SymbolTree.ErrorKind.NOT_SUPPORTED_EXPRESSION, mExpr.mToken);
                    return(false);
                }

                // EvaluateInfo作成
                TypePath typePath = new TypePath(mExpr.mToken, builtInType);

                mEvaluateInfo = EvaluateInfo.CreateAsValue(
                    aComp.CreateTypeInfo(typePath, true, true)
                    );

                return(true);
            }
Exemple #2
0
            //------------------------------------------------------------
            // Negative,BitwiseNot用評価関数。
            void evaluateNegativeBitwiseNot(SemanticAnalyzeComponent aComp, bool aIsNegative)
            {
                // todo:
                // 暗黙の変換の対応
                // 今はintしか対応しない
                if (mFirstNode.GetEvaluateInfo().Kind != EvaluateInfo.InfoKind.Value ||
                    mFirstNode.GetEvaluateInfo().TypeInfo.Symbol.GetBuiltInType() != BuiltInType.SInt32
                    )
                {
                    aComp.ThrowErrorException(SymbolTree.ErrorKind.NOT_SUPPORTED_EXPRESSION, mExpr.mOpToken);
                }

                // SR設定
                mTransferredEIHolder.ReceiveAndSetSR(aComp);

                // 伝達できるなら伝達する
                mTransferredEIHolder.TransferIfPossible(aComp);

                // 1つめを評価
                mFirstNode.SendEvent(aComp, EvaluateNodeEventKind.Evaluate);

                // 伝達情報リセット
                aComp.TransferredEvaluateInfoReset();

                // 命令追加
                aComp.BCFunction.AddOPCode_SReg1_SReg2(
                    aIsNegative ? BCOpCode.OpType.NEGS32 : BCOpCode.OpType.NTI32
                    , mEvaluateInfo.SR
                    , mFirstNode.GetEvaluateInfo().SR
                    );

                // イベント送信
                mFirstNode.SendEvent(aComp, EvaluateNodeEventKind.Release);
            }
Exemple #3
0
            //------------------------------------------------------------ 
            // 評価準備。 
            void eventAnalyze(SemanticAnalyzeComponent aComp)
            {
                // 型情報取得
                TypeInfo typeInfo = mSymbol.GetTypeInfo();

                // todo: いろんな型の対応
                // - 現時点はint,boolのみ対応
                if (typeInfo.Symbol.GetKind() != TypeInfo.TypeSymbol.Kind.BuiltIn ||
                    (typeInfo.Symbol.GetBuiltInType() != BuiltInType.SInt32 && typeInfo.Symbol.GetBuiltInType() != BuiltInType.Bool)
                    )
                {
                    aComp.ThrowErrorException(SymbolTree.ErrorKind.NOT_SUPPORTED_TYPENAME, typeInfo.Symbol.GetToken());
                }

                // 評価情報作成
                mEvaluateInfo = EvaluateInfo.CreateAsValue(typeInfo);

                // 初期化式があるか
                if (mExpr != null)
                {// 初期化式の結果でロード命令を挟む
                    // 作成
                    mExprNode = mExpr.CreateEvaluateNode();

                    // 評価
                    mExprNode.SendEvent(aComp, EvaluateNodeEventKind.Analyze);
                }
            }
Exemple #4
0
            //------------------------------------------------------------ 
            // 評価準備。 
            void eventAnalyze(SemanticAnalyzeComponent aComp)
            {
                // 1つめを評価
                mFirstNode.SendEvent(aComp, EvaluateNodeEventKind.Analyze);

                // 関数シンボルかどうかのチェック
                if (mFirstNode.GetEvaluateInfo().Kind != EvaluateInfo.InfoKind.StaticSymbol ||
                    mFirstNode.GetEvaluateInfo().Symbol.GetNodeKind() != SymbolNodeKind.Function
                    )
                {// エラー
                    aComp.ThrowErrorException(SymbolTree.ErrorKind.FUNCTION_SYMBOL_EXPECTED, mFirstExpr.GetToken());
                }

                // 引数ありの対応
                if (mSeqNode != null)
                {
                    mSeqNode.SendEvent(aComp, EvaluateNodeEventKind.Analyze);
                }

                // シンボルの取得
                FunctionSymbolNode funcSymbol = (FunctionSymbolNode)mFirstNode.GetEvaluateInfo().Symbol;

                // 評価情報を作成
                mEvaluateInfo = EvaluateInfo.CreateAsValue(funcSymbol.ReturnTypeInfo());

                // 伝搬情報ホルダーの作成
                mTransferredEI = new TransferredEIHolder(mEvaluateInfo);
            }
Exemple #5
0
            //------------------------------------------------------------
            // 同じ数値の演算しか許さないタイプの演算。
            void evaluateNumberType(
                SemanticAnalyzeComponent aComp
                , BCOpCode.OpType aOpType
                , bool aSwapLR // trueなら左辺と右辺を逆転させる。
                )
            {
                // レジスタ設定
                mTransferredEIHolder.ReceiveAndSetSR(aComp);

                // 伝達設定
                mTransferredEIHolder.TransferIfPossible(aComp);

                // 1つめ
                mFirstNode.SendEvent(aComp, EvaluateNodeEventKind.Evaluate);

                // 伝達リセット
                aComp.TransferredEvaluateInfoReset();

                // 可能なら2つめに伝達する
                if (!mFirstNode.GetEvaluateInfo().SR.IsSame(mEvaluateInfo.SR))
                {
                    mTransferredEIHolder.TransferIfPossible(aComp);
                }

                // 2つめ
                mSecondNode.SendEvent(aComp, EvaluateNodeEventKind.Evaluate);

                // 伝達リセット
                aComp.TransferredEvaluateInfoReset();

                // todo:
                // 暗黙の変換の対応
                // 今はintしか対応しない
                if (mFirstNode.GetEvaluateInfo().Kind != EvaluateInfo.InfoKind.Value ||
                    mFirstNode.GetEvaluateInfo().TypeInfo.Symbol.GetBuiltInType() != BuiltInType.SInt32 ||
                    mSecondNode.GetEvaluateInfo().Kind != EvaluateInfo.InfoKind.Value ||
                    mSecondNode.GetEvaluateInfo().TypeInfo.Symbol.GetBuiltInType() != BuiltInType.SInt32
                    )
                {
                    aComp.ThrowErrorException(SymbolTree.ErrorKind.NOT_SUPPORTED_EXPRESSION, mExpr.mOpToken);
                }

                // 演算
                StackRegister leftSR  = mFirstNode.GetEvaluateInfo().SR;
                StackRegister rightSR = mSecondNode.GetEvaluateInfo().SR;

                aComp.BCFunction.AddOPCode_SReg1_SReg2_SReg3(
                    aOpType
                    , mEvaluateInfo.SR
                    , aSwapLR ? rightSR : leftSR
                    , aSwapLR ? leftSR : rightSR
                    );

                // 通知
                mSecondNode.SendEvent(aComp, EvaluateNodeEventKind.Release);
                mFirstNode.SendEvent(aComp, EvaluateNodeEventKind.Release);
            }
Exemple #6
0
            //------------------------------------------------------------ 
            // 評価実行。 
            void eventEvaluate(SemanticAnalyzeComponent aComp)
            {
                // 各演算ごとの処理
                switch (mExpr.mOpKind)
                {
                case OpKind.AdditiveAdd: evaluateNumberType(aComp, BCOpCode.OpType.ADDI32, false); break;

                case OpKind.AdditiveSub: evaluateNumberType(aComp, BCOpCode.OpType.SUBI32, false); break;

                case OpKind.BitwiseAnd: evaluateNumberType(aComp, BCOpCode.OpType.ANDI32, false); break;

                case OpKind.BitwiseOr: evaluateNumberType(aComp, BCOpCode.OpType.ORI32, false); break;

                case OpKind.BitwiseXor: evaluateNumberType(aComp, BCOpCode.OpType.XORI32, false); break;

                case OpKind.EqualityEqual: evaluateEquality(aComp, false); break;

                case OpKind.EqualityNotEqual: evaluateEquality(aComp, true); break;

                case OpKind.LogicalAnd: evaluateLogicalOp(aComp, true); break;

                case OpKind.LogicalOr: evaluateLogicalOp(aComp, false); break;

                case OpKind.MultiplicativeMul: evaluateNumberType(aComp, BCOpCode.OpType.MULS32, false); break;

                case OpKind.MultiplicativeDiv: evaluateNumberType(aComp, BCOpCode.OpType.DIVS32, false); break;

                case OpKind.MultiplicativeMod: evaluateNumberType(aComp, BCOpCode.OpType.MODS32, false); break;

                case OpKind.RelationalLess: evaluateNumberType(aComp, BCOpCode.OpType.LTS32, false); break;

                case OpKind.RelationalLessEqual: evaluateNumberType(aComp, BCOpCode.OpType.LES32, false); break;

                case OpKind.RelationalGreater: evaluateNumberType(aComp, BCOpCode.OpType.LTS32, true); break;

                case OpKind.RelationalGreaterEqual: evaluateNumberType(aComp, BCOpCode.OpType.LES32, true); break;

                case OpKind.ShiftLeft: evaluateNumberType(aComp, BCOpCode.OpType.SLLI32, false); break;

                case OpKind.ShiftRight: evaluateNumberType(aComp, BCOpCode.OpType.SLRI32, false); break;

                default:
                {
                    // todo:
                    // いろんな演算の対応
                    aComp.ThrowErrorException(
                        SymbolTree.ErrorKind.NOT_SUPPORTED_EXPRESSION
                        , mExpr.mOpToken
                        );
                }
                break;
                }
            }
Exemple #7
0
            //------------------------------------------------------------
            // Positive用評価関数。
            void evaluatePositive(SemanticAnalyzeComponent aComp)
            {
                // todo:
                // 暗黙の変換の対応
                // 今はintしか対応しない
                if (mFirstNode.GetEvaluateInfo().Kind != EvaluateInfo.InfoKind.Value ||
                    mFirstNode.GetEvaluateInfo().TypeInfo.Symbol.GetBuiltInType() != BuiltInType.SInt32
                    )
                {
                    aComp.ThrowErrorException(SymbolTree.ErrorKind.NOT_SUPPORTED_EXPRESSION, mExpr.mOpToken);
                }

                // 1つめを評価
                mFirstNode.SendEvent(aComp, EvaluateNodeEventKind.Evaluate);
            }
Exemple #8
0
            //------------------------------------------------------------ 
            // 評価実行。 
            bool eventEvaluate(SemanticAnalyzeComponent aComp)
            {
                // 伝達された評価情報を取得
                mTransferredEI = aComp.TransferredEvaluateInfoReceive();

                // レジスタ確保 
                mEvaluateInfo.SR = mTransferredEI == null
                    ? aComp.SRReserve()
                    : mTransferredEI.SR;

                // ロードする
                switch (mExpr.mToken.Value)
                {
                case Token.Kind.NumSInt32:
                    aComp.BCFunction.AddOPCode_SReg_ConstantTableIndex(
                        BCOpCode.OpType.LDSRC4
                        , mEvaluateInfo.SR
                        , (int)mExpr.mToken.Int64Value
                        );
                    break;

                case Token.Kind.KeyTrue:
                    aComp.BCFunction.AddOPCode_SReg(
                        BCOpCode.OpType.LDSRBT
                        , mEvaluateInfo.SR
                        );
                    break;

                case Token.Kind.KeyFalse:
                    aComp.BCFunction.AddOPCode_SReg(
                        BCOpCode.OpType.LDSRZR
                        , mEvaluateInfo.SR
                        );
                    break;

                default:
                    // todo: いろんな型の対応
                    aComp.ThrowErrorException(SymbolTree.ErrorKind.NOT_SUPPORTED_EXPRESSION, mExpr.mToken);
                    return(false);
                }

                // 成功
                return(true);
            }
Exemple #9
0
        //------------------------------------------------------------
        // 意味解析。
        public void SemanticAnalyze(SemanticAnalyzeComponent aComp)
        {
            // break命令をやりつつ、breakラベルを取得する
            BCLabel label = aComp.ExecBreakStatement();

            if (label == null)
            {// 見つからず
                aComp.ThrowErrorException(
                    SymbolTree.ErrorKind.INVALID_BREAK
                    , mToken
                    );
            }

            // break場所へジャンプ
            aComp.BCFunction.AddOPCode_Label(
                BCOpCode.OpType.JMP
                , label
                );
        }
Exemple #10
0
        //------------------------------------------------------------
        // 意味解析。
        public void SemanticAnalyze(SemanticAnalyzeComponent aComp)
        {
            // Continue命令をやりつつ、Continueラベルを取得する
            BCLabel label = aComp.ExecContinueStatement();

            if (label == null)
            {// 見つからず
                aComp.ThrowErrorException(
                    SymbolTree.ErrorKind.INVALID_CONTINUE
                    , mToken
                    );
            }

            // Continue場所へジャンプ
            aComp.BCFunction.AddOPCode_Label(
                BCOpCode.OpType.JMP
                , label
                );
        }
Exemple #11
0
            //------------------------------------------------------------
            // Inc,Dec用評価関数。
            void evaluateIncDec(SemanticAnalyzeComponent aComp, bool aIsInc)
            {
                // todo:
                // 暗黙の変換の対応
                // 今はintしか対応しない
                if (mFirstNode.GetEvaluateInfo().Kind != EvaluateInfo.InfoKind.Value ||
                    mFirstNode.GetEvaluateInfo().TypeInfo.Symbol.GetBuiltInType() != BuiltInType.SInt32
                    )
                {
                    aComp.ThrowErrorException(SymbolTree.ErrorKind.NOT_SUPPORTED_EXPRESSION, mExpr.mOpToken);
                }

                // 1つめを評価
                mFirstNode.SendEvent(aComp, EvaluateNodeEventKind.Evaluate);

                // 命令を追加
                aComp.BCFunction.AddOPCode_SReg(
                    aIsInc ? BCOpCode.OpType.INCI32 : BCOpCode.OpType.DECI32
                    , mEvaluateInfo.SR
                    );
            }
Exemple #12
0
        //------------------------------------------------------------
        // 意味解析。
        public void SemanticAnalyze(SemanticAnalyzeComponent aComp)
        {
            // 戻り値用の評価情報を取得
            EvaluateInfo returnEI = aComp.ReturnEvaluateInfoGet();

            if (returnEI == null)
            {// 戻り値がないとき
                // 式がないことをチェック
                if (mExpression != null)
                {// エラー
                    aComp.ThrowErrorException(SymbolTree.ErrorKind.SEMICOLON_EXPECTED, mExpression.GetToken());
                }

                // Return実行
                execReturn(aComp);
            }
            else
            {
                // 式があることをチェック
                if (mExpression == null)
                {// エラー
                    aComp.ThrowErrorException(SymbolTree.ErrorKind.EXPRESSION_EXPECTED, mKeyToken);
                }

                // 評価ノードを作成
                var exprNode = mExpression.CreateEvaluateNode();

                // 評価準備
                exprNode.SendEvent(aComp, EvaluateNodeEventKind.Analyze);

                // 評価情報を伝達
                aComp.TransferredEvaluateInfoSet(returnEI);

                // 評価実行
                exprNode.SendEvent(aComp, EvaluateNodeEventKind.Evaluate);

                // 伝達リセット
                aComp.TransferredEvaluateInfoReset();

                // 型確認
                Assert.Check(exprNode.GetEvaluateInfo().Kind == EvaluateInfo.InfoKind.Value);
                EvaluateInfo exprEI       = exprNode.GetEvaluateInfo();
                TypeInfo     exprTypeInfo = exprEI.TypeInfo;
                if (exprTypeInfo.Symbol.GetKind() != TypeInfo.TypeSymbol.Kind.BuiltIn ||
                    (exprTypeInfo.Symbol.GetBuiltInType() != BuiltInType.SInt32 && exprTypeInfo.Symbol.GetBuiltInType() != BuiltInType.Bool)
                    )
                {// todo: 今はboolとintしかサポートしない
                    aComp.ThrowErrorException(SymbolTree.ErrorKind.NOT_SUPPORTED_TYPENAME, exprTypeInfo.Symbol.GetToken());
                }

                // 型が同じか確認
                if (returnEI.TypeInfo.Symbol.GetBuiltInType() != exprTypeInfo.Symbol.GetBuiltInType())
                {// 違う型
                    // エラーメッセージ
                    throw new SymbolTree.ErrorException(new SymbolTree.ErrorInfo(
                                                            SymbolTree.ErrorKind.CANT_IMPLICIT_CAST_TYPEA_TO_TYPEB
                                                            , aComp.TypeSymbolNode.ModuleContext()
                                                            , mKeyToken
                                                            , exprTypeInfo
                                                            , returnEI.TypeInfo
                                                            ));
                }

                // レジスタが異なればロード命令を追加する
                if (!returnEI.SR.IsSame(exprEI.SR))
                {
                    aComp.BCFunction.AddOPCode_SReg1_SReg2(
                        BCOpCode.OpType.LDSRSR
                        , returnEI.SR
                        , exprEI.SR
                        );
                }

                // 親の評価終了
                exprNode.SendEvent(aComp, EvaluateNodeEventKind.Release);

                // return実行
                execReturn(aComp);
            }
        }
Exemple #13
0
            //------------------------------------------------------------ 
            // 評価実行。 
            void eventEvaluate(SemanticAnalyzeComponent aComp)
            {
                // レジスタ確保 
                mEvaluateInfo.SR = aComp.SRReserve();

                // 初期化式があるか否かの分岐
                if (mExpr == null)
                {// 初期化子がないので既定値で初期化する
                    // todo: 組み込み型以外の対応
                    if (mEvaluateInfo.TypeInfo.Symbol.GetKind() != TypeInfo.TypeSymbol.Kind.BuiltIn)
                    {//
                        aComp.ThrowErrorException(SymbolTree.ErrorKind.NOT_SUPPORTED_TYPENAME, mEvaluateInfo.TypeInfo.Symbol.GetToken());
                    }

                    // 組み込み型ならゼロ初期化
                    aComp.BCFunction.AddOPCode_SReg(
                        BCOpCode.OpType.LDSRZR
                        , mEvaluateInfo.SR
                        );
                }
                else
                {// 初期化式の結果でロード命令を挟む
                    // 評価情報を伝達
                    aComp.TransferredEvaluateInfoSet(mEvaluateInfo);

                    // 評価
                    mExprNode.SendEvent(aComp, EvaluateNodeEventKind.Evaluate);

                    // 伝達リセット
                    aComp.TransferredEvaluateInfoReset();

                    // todo:
                    // 暗黙の変換の対応

                    // 型確認
                    Assert.Check(mExprNode.GetEvaluateInfo().Kind == EvaluateInfo.InfoKind.Value);
                    EvaluateInfo exprEI       = mExprNode.GetEvaluateInfo();
                    TypeInfo     exprTypeInfo = exprEI.TypeInfo;
                    if (exprTypeInfo.Symbol.GetKind() != TypeInfo.TypeSymbol.Kind.BuiltIn ||
                        (exprTypeInfo.Symbol.GetBuiltInType() != BuiltInType.SInt32 && exprTypeInfo.Symbol.GetBuiltInType() != BuiltInType.Bool)
                        )
                    {// todo: 今はboolとintしかサポートしない
                        aComp.ThrowErrorException(SymbolTree.ErrorKind.NOT_SUPPORTED_TYPENAME, exprTypeInfo.Symbol.GetToken());
                    }

                    // 型が同じか確認
                    if (mEvaluateInfo.TypeInfo.Symbol.GetBuiltInType() != exprTypeInfo.Symbol.GetBuiltInType())
                    {// 違う型
                        // エラーメッセージ
                        throw new SymbolTree.ErrorException(new SymbolTree.ErrorInfo(
                                                                SymbolTree.ErrorKind.CANT_IMPLICIT_CAST_TYPEA_TO_TYPEB
                                                                , aComp.TypeSymbolNode.ModuleContext()
                                                                , mSymbol.GetIdentifier().Token
                                                                , exprTypeInfo
                                                                , mEvaluateInfo.TypeInfo
                                                                ));
                    }

                    // レジスタが異なればロード命令を追加する
                    if (!mEvaluateInfo.SR.IsSame(exprEI.SR))
                    {
                        aComp.BCFunction.AddOPCode_SReg1_SReg2(
                            BCOpCode.OpType.LDSRSR
                            , mEvaluateInfo.SR
                            , exprEI.SR
                            );
                    }
                    // 親の評価が終わったことを告げる
                    mExprNode.SendEvent(aComp, EvaluateNodeEventKind.Release);
                }
            }
Exemple #14
0
        //------------------------------------------------------------
        // シンボルを展開する。
        public void SymbolExpand(SymbolExpandCmdKind aCmdKind)
        {
            if (aCmdKind != SymbolExpandCmdKind.FunctionNodeImpl)
            {// 関数実装以外なら何もしない
                return;
            }

            // BCFunction作成
            mBCFunction = mBCObjectType.GenerateFunction(this);

            // コンポーネント
            SemanticAnalyzeComponent comp = new SemanticAnalyzeComponent(
                mBCFunction
                , mParent
                , this
                );

            // コピーするレジスタの数をメモする変数
            byte copyRegCount = 0;

            {// 関数内部のスコープ
                // スコープ追加
                comp.ScopeEnter();

                // 戻り値対応
                if (mReturnTypeInfo.Symbol.GetKind() != TypeInfo.TypeSymbol.Kind.BuiltIn ||
                    mReturnTypeInfo.Symbol.GetBuiltInType() != BuiltInType.Void
                    )
                {// void以外なら。
                    // todo: いろんな型の対応
                    // 組み込み型のint,boolしか対応していません。
                    if (mReturnTypeInfo.Symbol.GetKind() != TypeInfo.TypeSymbol.Kind.BuiltIn ||
                        (mReturnTypeInfo.Symbol.GetBuiltInType() != BuiltInType.SInt32 && mReturnTypeInfo.Symbol.GetBuiltInType() != BuiltInType.Bool)
                        )
                    {
                        comp.ThrowErrorException(SymbolTree.ErrorKind.NOT_SUPPORTED_TYPENAME, mReturnTypeInfo.Symbol.GetToken());
                    }

                    // EI作成
                    var returnEI = EvaluateInfo.CreateAsValue(mReturnTypeInfo);

                    // SRを確保
                    returnEI.SR = comp.SRReserve();

                    // 戻り値として登録 
                    comp.ReturnEvaluateInfoSet(returnEI);

                    // コピーするレジスタカウントアップ
                    ++copyRegCount;
                }

                // this
                if (!mFunctionDecl.IsStatic())
                {
                    // TypeInfo作成
                    var ti = comp.CreateTypeInfo(
                        new TypePath(new IdentPath(mParent))
                        , mFunctionDecl.IsConst()
                        , true
                        );

                    // ダミートークンを作成
                    var token = new Token();
                    token.Value     = Token.Kind.KeyThis;
                    token.pos       = GetIdentifier().Token.pos;
                    token.posColumn = GetIdentifier().Token.posColumn;
                    token.posLine   = GetIdentifier().Token.posLine;

                    // シンボルノードを作成
                    VariableSymbolNode symbolNode = new VariableSymbolNode(
                        comp.PrevSymbolNode()
                        , new Identifier(token)
                        , ti
                        );

                    // ノードを追加
                    comp.AddSymbolNode(symbolNode);

                    // 評価ノードを作成
                    var evaluateNode = new EvaluateNode(symbolNode);

                    // 評価イベント送信
                    evaluateNode.SendEvent(comp, EvaluateNodeEventKind.Analyze);
                    evaluateNode.SendEvent(comp, EvaluateNodeEventKind.Evaluate);

                    // 追加
                    comp.AddEvaluatedSymbolNode(new EvaluatedSymbolNode(symbolNode, evaluateNode));

                    // コピーするレジスタカウントアップ
                    ++copyRegCount;
                }

                // 引数
                foreach (var arg in mArgTypeInfos)
                {
                    // シンボルノードを作成
                    VariableSymbolNode symbolNode = new VariableSymbolNode(
                        comp.PrevSymbolNode()
                        , arg.Ident
                        , arg.TypeInfo
                        );

                    // ノードを追加
                    comp.AddSymbolNode(symbolNode);

                    // 評価ノードを作成
                    var evaluateNode = new EvaluateNode(symbolNode);

                    // 評価イベント送信
                    evaluateNode.SendEvent(comp, EvaluateNodeEventKind.Analyze);
                    evaluateNode.SendEvent(comp, EvaluateNodeEventKind.Evaluate);

                    // 追加
                    comp.AddEvaluatedSymbolNode(new EvaluatedSymbolNode(symbolNode, evaluateNode));

                    // コピーするレジスタカウントアップ
                    ++copyRegCount;
                }

                {// Statement
                    // スコープに入る
                    comp.ScopeEnter();

                    // Returnラベル確保・登録
                    BCLabel labelReturn = comp.BCFunction.LabelCreate();
                    comp.RegisterLabelReturn(labelReturn);

                    // 解析
                    mFunctionDecl.Statement().SemanticAnalyze(comp);

                    // スコープから出る
                    comp.ScopeLeave();

                    // Returnラベル挿入
                    comp.BCFunction.LabelInsert(labelReturn);
                }

                // スコープ終了
                comp.ScopeLeave();
            }

            // 関数命令を追加
            // todo: レジスタ使いすぎチェック
            mBCFunction.PushFrontOPCode_CU1_CU1(BCOpCode.OpType.FENTER, (byte)comp.SRPeakCount(), copyRegCount);
            mBCFunction.AddOPCode_CU1(BCOpCode.OpType.FLEAVE, (byte)comp.SRPeakCount());

            // ラベル解決
            mBCFunction.LabelResolve();
        }
Exemple #15
0
            //------------------------------------------------------------
            // '==','!='の演算。
            void evaluateEquality(
                SemanticAnalyzeComponent aComp
                , bool aIsNotEqual
                )
            {
                // レジスタ設定
                mTransferredEIHolder.ReceiveAndSetSR(aComp);

                // 伝達設定
                mTransferredEIHolder.TransferIfPossible(aComp);

                // 1つめ
                mFirstNode.SendEvent(aComp, EvaluateNodeEventKind.Evaluate);

                // 伝達リセット
                aComp.TransferredEvaluateInfoReset();

                // 可能なら2つめに伝達する
                if (!mFirstNode.GetEvaluateInfo().SR.IsSame(mEvaluateInfo.SR))
                {
                    mTransferredEIHolder.TransferIfPossible(aComp);
                }

                // 2つめ
                mSecondNode.SendEvent(aComp, EvaluateNodeEventKind.Evaluate);

                // 伝達リセット
                aComp.TransferredEvaluateInfoReset();

                // todo:
                // 暗黙の変換の対応
                // 今はint,boolしか対応しない
                var firstEI  = mFirstNode.GetEvaluateInfo();
                var secondEI = mSecondNode.GetEvaluateInfo();

                if (firstEI.Kind != EvaluateInfo.InfoKind.Value ||
                    (firstEI.TypeInfo.Symbol.GetBuiltInType() != BuiltInType.SInt32 && firstEI.TypeInfo.Symbol.GetBuiltInType() != BuiltInType.Bool) ||
                    secondEI.Kind != EvaluateInfo.InfoKind.Value ||
                    (secondEI.TypeInfo.Symbol.GetBuiltInType() != BuiltInType.SInt32 && secondEI.TypeInfo.Symbol.GetBuiltInType() != BuiltInType.Bool)
                    )
                {
                    aComp.ThrowErrorException(SymbolTree.ErrorKind.NOT_SUPPORTED_EXPRESSION, mExpr.mOpToken);
                }

                // 命令の選択
                BCOpCode.OpType opType = BCOpCode.OpType.NOP;
                switch (firstEI.TypeInfo.Symbol.GetBuiltInType())
                {
                case BuiltInType.SInt32:
                case BuiltInType.UInt32:
                    opType = aIsNotEqual ? BCOpCode.OpType.NEI32 : BCOpCode.OpType.EQI32;
                    break;

                case BuiltInType.Bool:
                    opType = aIsNotEqual ? BCOpCode.OpType.NEBOOL : BCOpCode.OpType.EQBOOL;
                    break;

                default:
                    aComp.ThrowErrorException(SymbolTree.ErrorKind.NOT_SUPPORTED_EXPRESSION, mExpr.mOpToken);
                    break;
                }

                // 追加
                aComp.BCFunction.AddOPCode_SReg1_SReg2_SReg3(opType, mEvaluateInfo.SR, firstEI.SR, secondEI.SR);

                // 通知
                mSecondNode.SendEvent(aComp, EvaluateNodeEventKind.Release);
                mFirstNode.SendEvent(aComp, EvaluateNodeEventKind.Release);
            }
            //------------------------------------------------------------ 
            // 評価実行。 
            void eventEvaluate(SemanticAnalyzeComponent aComp)
            {
                // todo:
                // 暗黙の変換の対応
                // 今はint,boolしか対応しない
                if (mLeftNode.GetEvaluateInfo().Kind != EvaluateInfo.InfoKind.Value ||
                    mRightNode.GetEvaluateInfo().Kind != EvaluateInfo.InfoKind.Value ||
                    (mLeftNode.GetEvaluateInfo().TypeInfo.Symbol.GetBuiltInType() != mRightNode.GetEvaluateInfo().TypeInfo.Symbol.GetBuiltInType()) ||
                    (mLeftNode.GetEvaluateInfo().TypeInfo.Symbol.GetBuiltInType() != BuiltInType.SInt32 && mLeftNode.GetEvaluateInfo().TypeInfo.Symbol.GetBuiltInType() != BuiltInType.Bool) ||
                    (mRightNode.GetEvaluateInfo().TypeInfo.Symbol.GetBuiltInType() != BuiltInType.SInt32 && mRightNode.GetEvaluateInfo().TypeInfo.Symbol.GetBuiltInType() != BuiltInType.Bool)
                    )
                {
                    aComp.ThrowErrorException(SymbolTree.ErrorKind.NOT_SUPPORTED_EXPRESSION, mExpr.mOpToken);
                }

                // 左を評価
                mLeftNode.SendEvent(aComp, EvaluateNodeEventKind.Evaluate);

                // 伝達リセット
                aComp.TransferredEvaluateInfoReset();

                // 左のEvaluateInfoを伝達設定
                if (mExpr.mOpKind == OpKind.Assign)
                {// Assignのときだけ
                    // 再利用禁止設定
                    var ei = mLeftNode.GetEvaluateInfo();
                    ei.DisableReuseSR();

                    // 伝達
                    aComp.TransferredEvaluateInfoSet(ei);
                }

                // 右を評価
                mRightNode.SendEvent(aComp, EvaluateNodeEventKind.Evaluate);

                // 伝達リセット
                aComp.TransferredEvaluateInfoReset();

                // Assignならここで終了
                if (mExpr.mOpKind == OpKind.Assign)
                {
                    if (!mLeftNode.GetEvaluateInfo().SR.IsSame(mRightNode.GetEvaluateInfo().SR))
                    {// レジスタが異なればロード命令を追加する
                        aComp.BCFunction.AddOPCode_SReg1_SReg2(
                            BCOpCode.OpType.LDSRSR
                            , mLeftNode.GetEvaluateInfo().SR
                            , mRightNode.GetEvaluateInfo().SR
                            );
                    }
                    return;
                }

                // boolなら演算ができないのでエラー扱い
                if (mLeftNode.GetEvaluateInfo().TypeInfo.Symbol.GetBuiltInType() == BuiltInType.Bool)
                {
                    throw new SymbolTree.ErrorException(new SymbolTree.ErrorInfo(
                                                            SymbolTree.ErrorKind.CANT_IMPLICIT_CAST_TYPEA_TO_TYPEB
                                                            , aComp.TypeSymbolNode.ModuleContext()
                                                            , mExpr.mOpToken
                                                            , mLeftNode.GetEvaluateInfo().TypeInfo
                                                            , new TypeInfo(new TypeInfo.TypeSymbol(null, BuiltInType.SInt32), new TypeInfo.TypeAttribute(true, false))
                                                            ));
                }

                // 演算子に対応する命令を選択
                BCOpCode.OpType opType = BCOpCode.OpType.NOP;
                switch (mExpr.mOpKind)
                {
                case OpKind.AddAssign: opType = BCOpCode.OpType.ADDI32; break;

                case OpKind.SubAssign: opType = BCOpCode.OpType.SUBI32; break;

                case OpKind.MulAssign: opType = BCOpCode.OpType.MULS32; break;

                case OpKind.DivAssign: opType = BCOpCode.OpType.DIVS32; break;

                case OpKind.ModAssign: opType = BCOpCode.OpType.MODS32; break;

                case OpKind.AndAssign: opType = BCOpCode.OpType.ANDI32; break;

                case OpKind.OrAssign: opType = BCOpCode.OpType.ORI32; break;

                case OpKind.XorAssign: opType = BCOpCode.OpType.XORI32; break;

                case OpKind.LShiftAssign: opType = BCOpCode.OpType.SLLI32; break;

                case OpKind.RShiftAssign: opType = BCOpCode.OpType.SLRI32; break;

                default:
                    Assert.NotReachHere();
                    break;
                }

                // 命令追加
                aComp.BCFunction.AddOPCode_SReg1_SReg2_SReg3(
                    opType
                    , mLeftNode.GetEvaluateInfo().SR
                    , mLeftNode.GetEvaluateInfo().SR
                    , mRightNode.GetEvaluateInfo().SR
                    );
            }