//------------------------------------------------------------ // 評価準備。 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) { // 型情報取得 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) { // todo: Rootの対応 Assert.Check(!mExpr.mIsNamespaceRoot); // シンボルの検索 ISymbolNode symbolNode = aComp.FindSymbolNode(mExpr.mIdent); if (symbolNode == null) {// シンボルが見つからない throw new SymbolTree.ErrorException(new SymbolTree.ErrorInfo( SymbolTree.ErrorKind.NOT_DECLARATION_IDENT , aComp.TypeSymbolNode.ModuleContext() , mExpr.mIdent.Token )); } // 評価情報作成 if (symbolNode.GetNodeKind() == SymbolNodeKind.Variable) {// 変数 // 対応する評価済みノードを探す EvaluatedSymbolNode evaluatedSymbolNode = aComp.FindEvaluatedSymbolNode(symbolNode); if (evaluatedSymbolNode == null) {// todo: ローカル変数以外の対応 Assert.NotReachHere(); } // 作成 mEvaluateInfo = evaluatedSymbolNode.EvaluateNode.GetEvaluateInfo(); } else {// シンボル mEvaluateInfo = EvaluateInfo.CreateAsStaticSymbol(symbolNode); } }
//------------------------------------------------------------ // 評価準備。 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); }
//------------------------------------------------------------ // 意味解析。 public void SemanticAnalyze(SemanticAnalyzeComponent aComp) { // TypeInfo作成 TypeInfo typeInfo = aComp.CreateTypeInfo(mVariableDecl.TypePath, mIsConst, false); // シンボルノードを作成 VariableSymbolNode symbolNode = new VariableSymbolNode( aComp.PrevSymbolNode() , mVariableDecl.Ident , typeInfo ); aComp.AddSymbolNode(symbolNode); // 評価ノードを作成 var evaluateNode = new EvaluateNode(symbolNode, mVariableDecl.Expression()); // 評価準備 evaluateNode.SendEvent(aComp, EvaluateNodeEventKind.Analyze); // 評価実行 evaluateNode.SendEvent(aComp, EvaluateNodeEventKind.Evaluate); // 親の評価終了 evaluateNode.SendEvent(aComp, EvaluateNodeEventKind.Release); // 割り当て済みシンボルノードとして登録 aComp.AddEvaluatedSymbolNode(new EvaluatedSymbolNode(symbolNode, evaluateNode)); // Scope終了イベントのために追加 aComp.AddEvaluateNode(evaluateNode); }
//------------------------------------------------------------ // 評価準備。 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); }
//------------------------------------------------------------ // 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); }
//------------------------------------------------------------ // LogicalNot用評価関数。 void evaluateLogicalNot(SemanticAnalyzeComponent aComp) { // boolしか対応しない StatementUtil.CheckBoolExpression(aComp, mFirstNode, mExpr.mExpr); // SR設定 mTransferredEIHolder.ReceiveAndSetSR(aComp); // 伝達できるなら伝達する mTransferredEIHolder.TransferIfPossible(aComp); // 1つめを評価 mFirstNode.SendEvent(aComp, EvaluateNodeEventKind.Evaluate); // 伝達情報リセット aComp.TransferredEvaluateInfoReset(); // 命令追加 aComp.BCFunction.AddOPCode_SReg1_SReg2( BCOpCode.OpType.NTBOOL , mEvaluateInfo.SR , mFirstNode.GetEvaluateInfo().SR ); // イベント送信 mFirstNode.SendEvent(aComp, EvaluateNodeEventKind.Release); }
//------------------------------------------------------------ // レジスタを返却する必要があるなら返却する。 public void ReleaseIfNeccesary(SemanticAnalyzeComponent aComp) { if (mIsReceived) { aComp.SRRelease(mNodeEI.SR); } }
//------------------------------------------------------------ // Releaseイベントを送信。 public void SendEventRelease(SemanticAnalyzeComponent aComp) { // 逆順で。 foreach (var entry in mEvaluateNodeList.Reverse <IEvaluateNode>()) { entry.SendEvent(aComp, EvaluateNodeEventKind.Release); } }
//------------------------------------------------------------ // 評価準備。 void eventAnalyze(SemanticAnalyzeComponent aComp) { // 左を評価 mLeftNode.SendEvent(aComp, EvaluateNodeEventKind.Analyze); // 右を評価 mRightNode.SendEvent(aComp, EvaluateNodeEventKind.Analyze); }
//------------------------------------------------------------ // 評価実行。 void eventEvaluate(SemanticAnalyzeComponent aComp) { // レジスタ確保 mEvaluateInfo.SR = aComp.SRReserve(); // 再利用禁止 mEvaluateInfo.DisableReuseSR(); }
//------------------------------------------------------------ // スコープ離脱命令を挿入。 public void InsertOpCodeOnScopeLeave(SemanticAnalyzeComponent aComp) { // 逆順で。 foreach (var entry in mEvaluateNodeList.Reverse <IEvaluateNode>()) { entry.SendEvent(aComp, EvaluateNodeEventKind.InsertOpCodeOnScopeLeave); } }
//------------------------------------------------------------ // 後始末。 void eventRelease(SemanticAnalyzeComponent aComp) { // todo: // structのデストラクタ呼び出し // レジスタ解放 aComp.SRRelease(mEvaluateInfo.SR); }
//------------------------------------------------------------ // 同じ数値の演算しか許さないタイプの演算。 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 eventRelease(SemanticAnalyzeComponent aComp) { // 評価終了イベント送信 if (mNextNode != null) { mNextNode.SendEvent(aComp, EvaluateNodeEventKind.Release); } mFirstNode.SendEvent(aComp, EvaluateNodeEventKind.Release); }
//------------------------------------------------------------ // 評価実行。 void eventEvaluate(SemanticAnalyzeComponent aComp) { // レジスタの確保 if (mEvaluateInfo.TypeInfo.Symbol.GetKind() != TypeInfo.TypeSymbol.Kind.BuiltIn || // 組み込み型じゃない mEvaluateInfo.TypeInfo.Symbol.GetBuiltInType() != BuiltInType.Void // voidじゃない ) { // レジスタが必要 // 伝搬情報を取得してみる mTransferredEI.ReceiveAndSetSR(aComp); } // 1つめを評価 mFirstNode.SendEvent(aComp, EvaluateNodeEventKind.Evaluate); // シンボルの取得 FunctionSymbolNode funcSymbol = (FunctionSymbolNode)mFirstNode.GetEvaluateInfo().Symbol; // 引数の対応 if (mSeqNode != null) { // まず評価設定 mSeqNode.SendEvent(aComp, EvaluateNodeEventKind.Evaluate); // 関数情報設定 aComp.FunctionCallTargetSet(funcSymbol); // 戻り値用のFRを確保 if (mEvaluateInfo.SR.IsValid) { aComp.FunctionCallFRNextIndex(); } // 引数のFRを確保 mSeqNode.SendEvent(aComp, EvaluateNodeEventKind.SetupFR); // 関数情報リセット aComp.FunctionCallTargetReset(); } // 関数コール命令 aComp.BCFunction.AddOPCode_SymbolTableIndex( BCOpCode.OpType.CALL , funcSymbol ); // 関数の結果を受け取る if (mEvaluateInfo.SR.IsValid) { aComp.BCFunction.AddOPCode_SReg( BCOpCode.OpType.LDSRFZ , mEvaluateInfo.SR ); } // 評価終了イベント送信 mFirstNode.SendEvent(aComp, EvaluateNodeEventKind.Release); }
//------------------------------------------------------------ // 下層に伝達できるなら伝達する。 public void TransferIfPossible(SemanticAnalyzeComponent aComp) { // 可能ならEvaluateInfoを伝達 if (mIsReceived || //自分で確保した mTransferredEI.IsReusableSR // 再利用していいレジスタなので伝達してよい ) { aComp.TransferredEvaluateInfoSet(mNodeEI); } }
//------------------------------------------------------------ // 後始末。 bool eventRelease(SemanticAnalyzeComponent aComp) { // レジスタ返却 if (mTransferredEI == null) { aComp.SRRelease(mEvaluateInfo.SR); } return(true); }
//------------------------------------------------------------ // 評価準備。 void eventAnalyze(SemanticAnalyzeComponent aComp) { // todo:いろいろ対応してません・・・。 // 型情報取得 TypeInfo typeInfo = mSymbol.GetTypeInfo(); // 評価情報作成 mEvaluateInfo = EvaluateInfo.CreateAsValue(typeInfo); }
//------------------------------------------------------------ // 評価実行。 void eventEvaluate(SemanticAnalyzeComponent aComp) { // 1つめを評価 mFirstNode.SendEvent(aComp, EvaluateNodeEventKind.Evaluate); // 2つめがあれば2つめを評価 if (mNextNode != null) { mNextNode.SendEvent(aComp, EvaluateNodeEventKind.Evaluate); } }
//------------------------------------------------------------ // 伝達されたEIを受け取り、NodeEIのSRを設定する。 public void ReceiveAndSetSR(SemanticAnalyzeComponent aComp) { // 伝達されたEvaluateInfoを取得 mTransferredEI = aComp.TransferredEvaluateInfoReceive(); // レジスタ確保 mIsReceived = isNeedToReserveSR(); mNodeEI.SR = mIsReceived ? aComp.SRReserve() : mTransferredEI.SR; }
//------------------------------------------------------------ // 評価実行。 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; } }
//============================================================ //------------------------------------------------------------ // returnを実行。 void execReturn(SemanticAnalyzeComponent aComp) { // Returnを実行 BCLabel label = aComp.ExecReturnStatement(); Assert.Check(label != null); // Returnのラベルにジャンプ aComp.BCFunction.AddOPCode_Label( BCOpCode.OpType.JMP , label ); }
//------------------------------------------------------------ // 意味解析。 public void SemanticAnalyze(SemanticAnalyzeComponent aComp) { // スコープに入る aComp.ScopeEnter(); // 意味解析 foreach (IStatement st in mStatements) { st.SemanticAnalyze(aComp); } // スコープから出る aComp.ScopeLeave(); }
//------------------------------------------------------------ // 評価準備。 void eventAnalyze(SemanticAnalyzeComponent aComp) { // 1つめを評価 mFirstNode.SendEvent(aComp, EvaluateNodeEventKind.Analyze); // 2つめがあれば2つめを評価 if (mNextNode != null) { mNextNode.SendEvent(aComp, EvaluateNodeEventKind.Analyze); } // 評価情報を作成 mEvaluateInfo = mFirstNode.GetEvaluateInfo(); }
//------------------------------------------------------------ // 意味解析。 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); }
//------------------------------------------------------------ // 評価イベントを送信する。 public void SendEvent(SemanticAnalyzeComponent aComp, EvaluateNodeEventKind aEventKind) { switch (aEventKind) { case EvaluateNodeEventKind.Analyze: eventAnalyze(aComp); break; case EvaluateNodeEventKind.Evaluate: eventEvaluate(aComp); break; case EvaluateNodeEventKind.Release: eventRelease(aComp); break; default: Assert.NotReachHere(); return; } }
//------------------------------------------------------------ // 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); }
//------------------------------------------------------------ // 意味解析。 public void SemanticAnalyze(SemanticAnalyzeComponent aComp) { // 評価ノードを作成 var evaluateNode = mExpression.CreateEvaluateNode(); // 評価準備 evaluateNode.SendEvent(aComp, EvaluateNodeEventKind.Analyze); // 評価実行 evaluateNode.SendEvent(aComp, EvaluateNodeEventKind.Evaluate); // 親の評価終了 evaluateNode.SendEvent(aComp, EvaluateNodeEventKind.Release); // Scope終了イベントは送る必要がない }