//----------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All Rights Reserved. // //----------------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Cci; using Microsoft.Cci.MetadataReader; using Microsoft.Cci.MutableCodeModel; using Microsoft.Cci.Contracts; using Microsoft.Cci.ILToCodeModel; using Bpl = Microsoft.Boogie; namespace BytecodeTranslator { internal class StatementTraverser : BaseCodeTraverser { public readonly MethodTraverser MethodTraverser; public readonly Bpl.Variable HeapVariable; public readonly Bpl.StmtListBuilder StmtBuilder = new Bpl.StmtListBuilder(); #region Constructors public StatementTraverser(MethodTraverser mt) { HeapVariable = mt.HeapVariable; MethodTraverser = mt; } public StatementTraverser(MethodTraverser mt, Bpl.Variable heapvar) { HeapVariable = heapvar; MethodTraverser = mt; } #endregion public override void Visit(IBlockStatement block) { BasicBlock b = (BasicBlock)block; this.Visit(b); } #region Basic Statements /// /// Visit all statements in a single block /// /// private void Visit(BasicBlock b) { Bpl.StmtListBuilder slb = new Bpl.StmtListBuilder(); foreach (IStatement st in b.Statements) { this.Visit(st); } } /// /// /// /// (mschaef) Works, but still a stub /// public override void Visit(IConditionalStatement conditionalStatement) { StatementTraverser thenTraverser = new StatementTraverser(this.MethodTraverser); StatementTraverser elseTraverser = new StatementTraverser(this.MethodTraverser); ExpressionTraverser condTraverser = new ExpressionTraverser(this); condTraverser.Visit(conditionalStatement.Condition); thenTraverser.Visit(conditionalStatement.TrueBranch); elseTraverser.Visit(conditionalStatement.FalseBranch); Bpl.IfCmd ifcmd = new Bpl.IfCmd(TranslationHelper.CciLocationToBoogieToken(conditionalStatement.Locations), condTraverser.TranslatedExpressions.Pop(), thenTraverser.StmtBuilder.Collect(TranslationHelper.CciLocationToBoogieToken(conditionalStatement.TrueBranch.Locations)), null, elseTraverser.StmtBuilder.Collect(TranslationHelper.CciLocationToBoogieToken(conditionalStatement.FalseBranch.Locations)) ); StmtBuilder.Add(ifcmd); } /// /// /// /// /// TODO: might be wrong for the general case public override void Visit(IExpressionStatement expressionStatement) { ExpressionTraverser etrav = new ExpressionTraverser(this); etrav.Visit(expressionStatement.Expression); } /// /// /// /// (mschaef) Not Implemented /// public override void Visit(IBreakStatement breakStatement) { StmtBuilder.Add(new Bpl.BreakCmd(TranslationHelper.CciLocationToBoogieToken(breakStatement.Locations), "I dont know")); } /// /// /// /// (mschaef) not implemented /// public override void Visit(IReturnStatement returnStatement) { Bpl.IToken tok = TranslationHelper.CciLocationToBoogieToken(returnStatement.Locations); #region Copy values of all out parameters to outvariables foreach (MethodTraverser.MethodParameter mp in MethodTraverser.OutVars) { StmtBuilder.Add(Bpl.Cmd.SimpleAssign(tok, new Bpl.IdentifierExpr(tok, mp.outParameterCopy), new Bpl.IdentifierExpr(tok, mp.localParameter))); } #endregion if (returnStatement.Expression != null) { ExpressionTraverser etrav = new ExpressionTraverser(this); etrav.Visit(returnStatement.Expression); if (this.MethodTraverser.RetVariable == null || etrav.TranslatedExpressions.Count < 1) { throw new TranslationException(String.Format("{0} returns a value that is not supported by the function", returnStatement.ToString())); } StmtBuilder.Add(Bpl.Cmd.SimpleAssign(tok, new Bpl.IdentifierExpr(tok, this.MethodTraverser.RetVariable), etrav.TranslatedExpressions.Pop())); } StmtBuilder.Add(new Bpl.ReturnCmd(TranslationHelper.CciLocationToBoogieToken(returnStatement.Locations))); } #endregion #region Goto and Labels /// /// /// /// STUB /// public override void Visit(IGotoStatement gotoStatement) { String[] target = new String[1]; target[0] = gotoStatement.TargetStatement.Label.Value; Bpl.GotoCmd gotocmd = new Microsoft.Boogie.GotoCmd(TranslationHelper.CciLocationToBoogieToken(gotoStatement.Locations), new Bpl.StringSeq(target)); StmtBuilder.Add(gotocmd); } /// /// /// /// (mschaef) not sure if there is more work to do /// public override void Visit(ILabeledStatement labeledStatement) { StmtBuilder.AddLabelCmd(labeledStatement.Label.Value); base.Visit(labeledStatement.Statement); } #endregion #region Looping Statements public override void Visit(IWhileDoStatement whileDoStatement) { throw new NotImplementedException("While Statements are not implemented"); } #endregion } }