Esempio n. 1
0
        //============================================================

        //------------------------------------------------------------
        // returnを実行。
        void execReturn(SemanticAnalyzeComponent aComp)
        {
            // Returnを実行
            BCLabel label = aComp.ExecReturnStatement();

            Assert.Check(label != null);

            // Returnのラベルにジャンプ
            aComp.BCFunction.AddOPCode_Label(
                BCOpCode.OpType.JMP
                , label
                );
        }
Esempio n. 2
0
        //------------------------------------------------------------
        // 意味解析。
        public void SemanticAnalyze(SemanticAnalyzeComponent aComp)
        {
            // ラベル作成
            BCLabel labelContinue = aComp.BCFunction.LabelCreate();
            BCLabel labelBreak    = aComp.BCFunction.LabelCreate();

            // 式の意味解析
            var exprEvaluateNode = mExpression.CreateEvaluateNode();

            exprEvaluateNode.SendEvent(aComp, EvaluateNodeEventKind.Analyze);

            // boolチェック
            StatementUtil.CheckBoolExpression(aComp, exprEvaluateNode, mExpression);

            // continueラベル挿入
            aComp.BCFunction.LabelInsert(labelContinue);

            // 式の評価
            exprEvaluateNode.SendEvent(aComp, EvaluateNodeEventKind.Evaluate);
            exprEvaluateNode.SendEvent(aComp, EvaluateNodeEventKind.Release);

            // 分岐
            aComp.BCFunction.AddOPCode_SReg_Label(
                BCOpCode.OpType.JMPNEG
                , exprEvaluateNode.GetEvaluateInfo().SR
                , labelBreak
                );

            // スコープに入る
            aComp.ScopeEnter();

            // ラベルの登録
            aComp.RegisterLabelContinue(labelContinue);
            aComp.RegisterLabelBreak(labelBreak);

            // 文の解析
            mStatement.SemanticAnalyze(aComp);

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

            // continueする
            aComp.BCFunction.AddOPCode_Label(
                BCOpCode.OpType.JMP
                , labelContinue
                );

            // breakラベル挿入
            aComp.BCFunction.LabelInsert(labelBreak);
        }
Esempio n. 3
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));
        }
Esempio n. 4
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
                );
        }
Esempio n. 5
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
                );
        }
Esempio n. 6
0
 //------------------------------------------------------------
 // return文用のラベルを登録する
 public void RegisterLabelReturn(BCLabel aLabel)
 {
     Assert.Check(mLabelReturn == null);
     mLabelReturn = aLabel;
 }
Esempio n. 7
0
 //------------------------------------------------------------
 // continue文用のラベルを登録する
 public void RegisterLabelContinue(BCLabel aLabel)
 {
     Assert.Check(mLabelContinue == null);
     mLabelContinue = aLabel;
 }
Esempio n. 8
0
 //------------------------------------------------------------
 // break文用のラベルを登録する
 public void RegisterLabelBreak(BCLabel aLabel)
 {
     Assert.Check(mLabelBreak == null);
     mLabelBreak = aLabel;
 }
Esempio n. 9
0
 //------------------------------------------------------------
 // BCLabelを現在の位置に挿入する。
 public void LabelInsert(BCLabel aLabel)
 {
     aLabel.SetOpCodeIndex((uint)mBCOpCodeList.Count());
 }
Esempio n. 10
0
        public readonly uint OpCodeIndex; // 解決した情報を代入するOpCodeのインデックス。

        //------------------------------------------------------------
        // コンストラクタ。
        public BCLabelReference(BCLabel aLabel, BCOpCode aOpCode, uint aOpCodeIndex)
        {
            Label       = aLabel;
            OpCode      = aOpCode;
            OpCodeIndex = aOpCodeIndex;
        }
Esempio n. 11
0
        //------------------------------------------------------------
        // 意味解析。
        public void SemanticAnalyze(SemanticAnalyzeComponent aComp)
        {
            // ラベル作成
            BCLabel labelElse = aComp.BCFunction.LabelCreate();
            BCLabel labelEnd  = aComp.BCFunction.LabelCreate();

            // 式の意味解析
            var exprEvaluateNode = mExpression.CreateEvaluateNode();

            exprEvaluateNode.SendEvent(aComp, EvaluateNodeEventKind.Analyze);

            // boolチェック
            StatementUtil.CheckBoolExpression(aComp, exprEvaluateNode, mExpression);

            // 式の評価
            exprEvaluateNode.SendEvent(aComp, EvaluateNodeEventKind.Evaluate);
            exprEvaluateNode.SendEvent(aComp, EvaluateNodeEventKind.Release);

            // 式がfalseならelseに飛ぶ
            aComp.BCFunction.AddOPCode_SReg_Label(
                BCOpCode.OpType.JMPNEG
                , exprEvaluateNode.GetEvaluateInfo().SR
                , labelElse
                );

            // Thenの解析
            {
                // スコープに入る
                aComp.ScopeEnter();

                // Thenの解析
                mThenStatement.SemanticAnalyze(aComp);

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

                // endに飛ぶ
                if (mElseStatement != null)
                {// elseがあるときだけでよい
                    aComp.BCFunction.AddOPCode_Label(
                        BCOpCode.OpType.JMP
                        , labelEnd
                        );
                }
            }

            // elseラベル挿入
            aComp.BCFunction.LabelInsert(labelElse);

            // Elseの解析
            if (mElseStatement != null)
            {
                // スコープに入る
                aComp.ScopeEnter();

                // Thenの解析
                mElseStatement.SemanticAnalyze(aComp);

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

            // endラベル挿入
            aComp.BCFunction.LabelInsert(labelEnd);
        }
Esempio n. 12
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();
        }
Esempio n. 13
0
            //------------------------------------------------------------
            // '&&','||'の演算。
            void evaluateLogicalOp(
                SemanticAnalyzeComponent aComp
                , bool aIsAnd
                )
            {
                // boolしか対応しない
                var firstEI  = mFirstNode.GetEvaluateInfo();
                var secondEI = mSecondNode.GetEvaluateInfo();

                if (firstEI.Kind != EvaluateInfo.InfoKind.Value ||
                    firstEI.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
                                                            , firstEI.TypeInfo
                                                            , mEvaluateInfo.TypeInfo
                                                            ));
                }
                if (secondEI.Kind != EvaluateInfo.InfoKind.Value ||
                    secondEI.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
                                                            , secondEI.TypeInfo
                                                            , mEvaluateInfo.TypeInfo
                                                            ));
                }

                // レジスタ設定
                mTransferredEIHolder.ReceiveAndSetSR(aComp);

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

                // ラベル確保
                BCLabel labelEnd = aComp.BCFunction.LabelCreate(); // End用

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

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

                // 1つめの結果を受けた短絡評価
                // 条件が整っていたら2つ目の式を飛ばす
                aComp.BCFunction.AddOPCode_SReg_Label(
                    aIsAnd ? BCOpCode.OpType.JMPNEG : BCOpCode.OpType.JMPPOS
                    , mEvaluateInfo.SR // 伝達しているので自分のSRに結果が格納されているはず 
                    , labelEnd
                    );

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

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

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

                // 2つめの結果を代入
                if (!mEvaluateInfo.SR.IsSame(secondEI.SR))
                {
                    aComp.BCFunction.AddOPCode_SReg1_SReg2(
                        BCOpCode.OpType.LDSRSR
                        , mEvaluateInfo.SR
                        , secondEI.SR
                        );
                }

                // Endラベル挿入
                aComp.BCFunction.LabelInsert(labelEnd);
            }