//------------------------------------------------------------ // OP SReg形式の命令コードを追加する。 public void AddOPCode_SReg(BCOpCode.OpType aOP, StackRegister aSR) { mBCOpCodeList.Add(new BCOpCode( aOP , aSR )); }
//------------------------------------------------------------ // OP CU1形式の命令コードを追加する。 public void AddOPCode_CU1(BCOpCode.OpType aOP, byte aValue) { mBCOpCodeList.Add(new BCOpCode( aOP , aValue )); }
//------------------------------------------------------------ // OP SymbolTableIndex形式の命令コードを追加する。 public void AddOPCode_SymbolTableIndex(BCOpCode.OpType aOP, ISymbolNode aSymbol) { mBCOpCodeList.Add(new BCOpCode( aOP , mBCModule.GetSymbolLink(aSymbol) )); }
//------------------------------------------------------------ // OP CU1 SReg形式の命令コードを追加する。 public void AddOPCode_CU1_SR(BCOpCode.OpType aOP, byte aValue, StackRegister aSR) { mBCOpCodeList.Add(new BCOpCode( aOP , aValue , aSR )); }
//------------------------------------------------------------ // OP CU1形式の命令コードを先頭に追加する。 public void PushFrontOPCode_CU1_CU1(BCOpCode.OpType aOP, byte aValue1, byte aValue2) { mBCOpCodeList.Insert(0, new BCOpCode( aOP , aValue1 , aValue2 )); }
//------------------------------------------------------------ // OP SReg1 SReg2形式の命令コードを追加する。 public void AddOPCode_SReg1_SReg2(BCOpCode.OpType aOP, StackRegister aSR1, StackRegister aSR2) { mBCOpCodeList.Add(new BCOpCode( aOP , aSR1 , aSR2 )); }
//------------------------------------------------------------ // 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)) )); }
//------------------------------------------------------------ // 同じ数値の演算しか許さないタイプの演算。 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); }
//------------------------------------------------------------ // 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)); }
//------------------------------------------------------------ // 後始末。 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); }
//------------------------------------------------------------ // '==','!='の演算。 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 ); }