//============================================================ //------------------------------------------------------------ // 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) { // ラベル作成 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); }
//------------------------------------------------------------ // 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)); }
//------------------------------------------------------------ // 意味解析。 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 ); }
//------------------------------------------------------------ // return文用のラベルを登録する public void RegisterLabelReturn(BCLabel aLabel) { Assert.Check(mLabelReturn == null); mLabelReturn = aLabel; }
//------------------------------------------------------------ // continue文用のラベルを登録する public void RegisterLabelContinue(BCLabel aLabel) { Assert.Check(mLabelContinue == null); mLabelContinue = aLabel; }
//------------------------------------------------------------ // break文用のラベルを登録する public void RegisterLabelBreak(BCLabel aLabel) { Assert.Check(mLabelBreak == null); mLabelBreak = aLabel; }
//------------------------------------------------------------ // BCLabelを現在の位置に挿入する。 public void LabelInsert(BCLabel aLabel) { aLabel.SetOpCodeIndex((uint)mBCOpCodeList.Count()); }
public readonly uint OpCodeIndex; // 解決した情報を代入するOpCodeのインデックス。 //------------------------------------------------------------ // コンストラクタ。 public BCLabelReference(BCLabel aLabel, BCOpCode aOpCode, uint aOpCodeIndex) { Label = aLabel; OpCode = aOpCode; OpCodeIndex = aOpCodeIndex; }
//------------------------------------------------------------ // 意味解析。 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); }
//------------------------------------------------------------ // シンボルを展開する。 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 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); }