//------------------------------------------------------------ // 評価準備。 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); }
//------------------------------------------------------------ // 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); }
//------------------------------------------------------------ // 評価準備。 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); } }
//------------------------------------------------------------ // 評価準備。 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 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 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; } }
//------------------------------------------------------------ // 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); }
//------------------------------------------------------------ // 評価実行。 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); }
//------------------------------------------------------------ // 意味解析。 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 ); }
//------------------------------------------------------------ // 意味解析。 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 ); }
//------------------------------------------------------------ // 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 ); }
//------------------------------------------------------------ // 意味解析。 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); } }
//------------------------------------------------------------ // 評価実行。 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); } }
//------------------------------------------------------------ // シンボルを展開する。 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(); }
//------------------------------------------------------------ // '==','!='の演算。 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 ); }