//------------------------------------------------------------ // 評価準備。 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); }
//------------------------------------------------------------ // 評価準備。 void eventAnalyze(SemanticAnalyzeComponent aComp) { // 1つめを評価 mFirstNode.SendEvent(aComp, EvaluateNodeEventKind.Analyze); // EvaluateInfoの用意 switch (mExpr.mOpKind) { case OpKind.Inc: case OpKind.Dec: case OpKind.Positive: // 式のものをそのまま mEvaluateInfo = mFirstNode.GetEvaluateInfo(); break; case OpKind.Negative: case OpKind.BitwiseNot: // タイプは一緒だけど別のレジスタを使う可能性があるのでEvaluateInfoを作成 mEvaluateInfo = EvaluateInfo.CreateAsValue(mFirstNode.GetEvaluateInfo().TypeInfo); break; case OpKind.LogicalNot: // boolで mEvaluateInfo = EvaluateInfo.CreateAsValue(new TypeInfo(new TypeInfo.TypeSymbol(mExpr.mOpToken, BuiltInType.Bool), new TypeInfo.TypeAttribute(true, false))); break; default: Assert.NotReachHere(); break; } // Holder作成 mTransferredEIHolder = new TransferredEIHolder(mEvaluateInfo); }
//------------------------------------------------------------ // 同じ数値の演算しか許さないタイプの演算。 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); }
//------------------------------------------------------------ // 評価準備。 void eventAnalyze(SemanticAnalyzeComponent aComp) { // 1つめを評価 mFirstNode.SendEvent(aComp, EvaluateNodeEventKind.Analyze); // 2つめがあれば2つめを評価 if (mNextNode != null) { mNextNode.SendEvent(aComp, EvaluateNodeEventKind.Analyze); } // 評価情報を作成 mEvaluateInfo = mFirstNode.GetEvaluateInfo(); }
//------------------------------------------------------------ // 式の結果がboolであることをチェックする。 static public void CheckBoolExpression( SemanticAnalyzeComponent aComp , IEvaluateNode aExprEN , IExpression aExpr ) { if (aExprEN.GetEvaluateInfo().Kind != EvaluateInfo.InfoKind.Value || aExprEN.GetEvaluateInfo().TypeInfo.Symbol.GetBuiltInType() != BuiltInType.Bool) { throw new SymbolTree.ErrorException(new SymbolTree.ErrorInfo( SymbolTree.ErrorKind.CANT_IMPLICIT_CAST_TYPEA_TO_TYPEB , aComp.TypeSymbolNode.ModuleContext() , aExpr.GetToken() , aExprEN.GetEvaluateInfo().TypeInfo , new TypeInfo(new TypeInfo.TypeSymbol(null, BuiltInType.Bool), new TypeInfo.TypeAttribute(true, false)) )); } }
//------------------------------------------------------------ // 評価実行。 void eventEvaluate(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); // 伝達リセット aComp.TransferredEvaluateInfoReset(); }
//------------------------------------------------------------ // 評価準備。 void eventAnalyze(SemanticAnalyzeComponent aComp) { // 1つめ mFirstNode.SendEvent(aComp, EvaluateNodeEventKind.Analyze); // 2つめ mSecondNode.SendEvent(aComp, EvaluateNodeEventKind.Analyze); // 評価情報の作成 TypeInfo ti; switch (mExpr.mOpKind) { case OpKind.RelationalGreater: case OpKind.RelationalGreaterEqual: case OpKind.RelationalLess: case OpKind.RelationalLessEqual: case OpKind.EqualityEqual: case OpKind.EqualityNotEqual: case OpKind.IdentityEqual: case OpKind.IdentityNotEqual: case OpKind.LogicalAnd: case OpKind.LogicalOr: // boolの情報を返す ti = new TypeInfo(new TypeInfo.TypeSymbol(mExpr.mOpToken, BuiltInType.Bool), new TypeInfo.TypeAttribute(true, false)); break; default: // 左辺の情報をそのまま返す // todo: 暗黙の変換対応 ti = mFirstNode.GetEvaluateInfo().TypeInfo; break; } mEvaluateInfo = EvaluateInfo.CreateAsValue(ti); // Holder作成 mTransferredEIHolder = new TransferredEIHolder(mEvaluateInfo); }
//------------------------------------------------------------ // 評価実行。 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); } }
//------------------------------------------------------------ // 評価実行。 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 ); }