Beispiel #1
0
 //------------------------------------------------------------
 // OP SReg形式の命令コードを追加する。
 public void AddOPCode_SReg(BCOpCode.OpType aOP, StackRegister aSR)
 {
     mBCOpCodeList.Add(new BCOpCode(
                           aOP
                           , aSR
                           ));
 }
Beispiel #2
0
 //------------------------------------------------------------
 // OP CU1形式の命令コードを追加する。
 public void AddOPCode_CU1(BCOpCode.OpType aOP, byte aValue)
 {
     mBCOpCodeList.Add(new BCOpCode(
                           aOP
                           , aValue
                           ));
 }
Beispiel #3
0
 //------------------------------------------------------------
 // OP SymbolTableIndex形式の命令コードを追加する。
 public void AddOPCode_SymbolTableIndex(BCOpCode.OpType aOP, ISymbolNode aSymbol)
 {
     mBCOpCodeList.Add(new BCOpCode(
                           aOP
                           , mBCModule.GetSymbolLink(aSymbol)
                           ));
 }
Beispiel #4
0
 //------------------------------------------------------------
 // OP CU1 SReg形式の命令コードを追加する。
 public void AddOPCode_CU1_SR(BCOpCode.OpType aOP, byte aValue, StackRegister aSR)
 {
     mBCOpCodeList.Add(new BCOpCode(
                           aOP
                           , aValue
                           , aSR
                           ));
 }
Beispiel #5
0
 //------------------------------------------------------------
 // OP CU1形式の命令コードを先頭に追加する。
 public void PushFrontOPCode_CU1_CU1(BCOpCode.OpType aOP, byte aValue1, byte aValue2)
 {
     mBCOpCodeList.Insert(0, new BCOpCode(
                              aOP
                              , aValue1
                              , aValue2
                              ));
 }
Beispiel #6
0
 //------------------------------------------------------------
 // OP SReg1 SReg2形式の命令コードを追加する。
 public void AddOPCode_SReg1_SReg2(BCOpCode.OpType aOP, StackRegister aSR1, StackRegister aSR2)
 {
     mBCOpCodeList.Add(new BCOpCode(
                           aOP
                           , aSR1
                           , aSR2
                           ));
 }
Beispiel #7
0
 //------------------------------------------------------------
 // OP SReg ConstantTableIndex形式の命令コードを追加する。
 public void AddOPCode_SReg_ConstantTableIndex(BCOpCode.OpType aOP, StackRegister aSR, int aValue)
 {
     mBCOpCodeList.Add(new BCOpCode(
                           aOP
                           , aSR
                           , mBCModule.GetConstantValue(new BCConstantValue(aValue))
                           ));
 }
Beispiel #8
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);
            }
Beispiel #9
0
        //------------------------------------------------------------
        // OP Label形式の命令コードを追加する。
        public void AddOPCode_Label(BCOpCode.OpType aOP, BCLabel aLabel)
        {
            // OpCode作成
            var opCode = new BCOpCode(
                aOP
                , (short)0
                );

            // 追加されるindexをメモ
            uint index = (uint)mBCOpCodeList.Count;

            // OpCode追加
            mBCOpCodeList.Add(opCode);

            // LabelReference追加
            mBCLabelReferenceList.Add(new BCLabelReference(aLabel, opCode, index));
        }
Beispiel #10
0
            //------------------------------------------------------------
            // 後始末。
            void eventRelease(SemanticAnalyzeComponent aComp)
            {
                // 命令の選択
                BCOpCode.OpType opType = BCOpCode.OpType.NOP;
                switch (mExpr.mOpKind)
                {
                case OpKind.Inc: opType = BCOpCode.OpType.INCI32; break;

                case OpKind.Dec: opType = BCOpCode.OpType.DECI32; break;

                default:
                    Assert.NotReachHere();
                    break;
                }

                // 命令を追加
                aComp.BCFunction.AddOPCode_SReg(
                    opType
                    , mFirstNode.GetEvaluateInfo().SR
                    );

                // OnParentEvaluateEnd
                mFirstNode.SendEvent(aComp, EvaluateNodeEventKind.Release);
            }
Beispiel #11
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);
            }
Beispiel #12
0
            //------------------------------------------------------------ 
            // 評価実行。 
            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
                    );
            }