summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.hgignore8
-rw-r--r--BCT/BytecodeTranslator/ExpressionTraverser.cs735
-rw-r--r--BCT/BytecodeTranslator/Heap.cs512
-rw-r--r--BCT/BytecodeTranslator/HeapFactory.cs237
-rw-r--r--BCT/BytecodeTranslator/MetadataTraverser.cs145
-rw-r--r--BCT/BytecodeTranslator/Program.cs16
-rw-r--r--BCT/BytecodeTranslator/Sink.cs219
-rw-r--r--BCT/BytecodeTranslator/StatementTraverser.cs21
-rw-r--r--BCT/BytecodeTranslator/TranslationException.cs13
-rw-r--r--BCT/BytecodeTranslator/TranslationHelper.cs52
-rw-r--r--BCT/BytecodeTranslator/WholeProgram.cs4
-rw-r--r--BCT/RegressionTests/RegressionTestInput/Class1.cs27
-rw-r--r--BCT/RegressionTests/TranslationTest/GeneralHeapInput.txt483
-rw-r--r--BCT/RegressionTests/TranslationTest/SplitFieldsHeapInput.txt467
-rw-r--r--BCT/RegressionTests/TranslationTest/TranslationTest.csproj6
-rw-r--r--BCT/RegressionTests/TranslationTest/TwoDBoxHeapInput.txt729
-rw-r--r--BCT/RegressionTests/TranslationTest/TwoDIntHeapInput.txt719
-rw-r--r--BCT/RegressionTests/TranslationTest/UnitTest0.cs30
-rw-r--r--BCT/Samples/CodeCounter/codecounter.sln51
-rw-r--r--BCT/Samples/CodeCounter/codecounter.suobin0 -> 33792 bytes
-rw-r--r--BCT/Samples/CodeCounter/codecounter.vssscc10
-rw-r--r--BCT/Samples/CodeCounter/console/App.config18
-rw-r--r--BCT/Samples/CodeCounter/console/CodeCounter.csproj87
-rw-r--r--BCT/Samples/CodeCounter/console/CodeCounter.csproj.user6
-rw-r--r--BCT/Samples/CodeCounter/console/CodeCounter.csproj.vspscc10
-rw-r--r--BCT/Samples/CodeCounter/console/CodeCounterEngine.cs270
-rw-r--r--BCT/Samples/CodeCounter/console/CountCounterEvents.cs169
-rw-r--r--BCT/Samples/CodeCounter/console/FileTypes.cs47
-rw-r--r--BCT/Samples/CodeCounter/console/MSSCCPRJ.SCC5
-rw-r--r--BCT/Samples/CodeCounter/console/Program.cs642
-rw-r--r--BCT/Samples/CodeCounter/console/Properties/AssemblyInfo.cs36
-rw-r--r--BCT/Samples/CodeCounter/dependencies/Big Woo.NET.dllbin0 -> 155648 bytes
-rw-r--r--BCT/Samples/CodeCounter/library/CSharpCodeCounterLogic.cs177
-rw-r--r--BCT/Samples/CodeCounter/library/CodeCounterLogicImplementers.cs136
-rw-r--r--BCT/Samples/CodeCounter/library/ConfigFileSections.cs122
-rw-r--r--BCT/Samples/CodeCounter/library/CustomExceptions.cs60
-rw-r--r--BCT/Samples/CodeCounter/library/ICodeCounterLogic.cs120
-rw-r--r--BCT/Samples/CodeCounter/library/MSSCCPRJ.SCC5
-rw-r--r--BCT/Samples/CodeCounter/library/Properties/AssemblyInfo.cs57
-rw-r--r--BCT/Samples/CodeCounter/library/SqlCodeCounterLogic.cs169
-rw-r--r--BCT/Samples/CodeCounter/library/XamlCodeCounterLogic.cs161
-rw-r--r--BCT/Samples/CodeCounter/library/codecounterlibrary.csproj139
-rw-r--r--BCT/Samples/CodeCounter/library/codecounterlibrary.csproj.vspscc10
-rw-r--r--BCT/Samples/Generics/GenericsExample.cs20
-rw-r--r--BCT/Samples/Strings/StringsExample.cs20
-rw-r--r--Binaries/DafnyRuntime.cs1
-rw-r--r--Binaries/UnivBackPred2.smt21
-rw-r--r--Source/BoogieDriver/BoogieDriver.cs6
-rw-r--r--Source/Core/Absy.cs26
-rw-r--r--Source/Core/AbsyCmd.cs4
-rw-r--r--Source/Core/CommandLineOptions.cs15
-rw-r--r--Source/Core/DeadVarElim.cs2
-rw-r--r--Source/Core/ResolutionContext.cs142
-rw-r--r--Source/Dafny/Compiler.cs106
-rw-r--r--Source/Dafny/Dafny.atg2
-rw-r--r--Source/Dafny/Parser.cs51
-rw-r--r--Source/Dafny/Resolver.cs15
-rw-r--r--Source/Dafny/Scanner.cs102
-rw-r--r--Source/ModelViewer/bvdicon.designbin0 -> 7272 bytes
-rw-r--r--Source/Provers/SMTLib/ProverInterface.cs54
-rw-r--r--Source/Provers/SMTLib/SMTLibLineariser.cs2
-rw-r--r--Source/Provers/SMTLib/Z3.cs2
-rw-r--r--Source/VCGeneration/VC.cs2
-rw-r--r--Source/VCGeneration/Wlp.cs3
-rw-r--r--Test/VSComp2010/runtest.bat4
-rw-r--r--Test/VSI-Benchmarks/runtest.bat14
-rw-r--r--Test/dafny0/Answer7
-rw-r--r--Test/dafny0/ResolutionErrors.dfy25
-rw-r--r--Test/dafny0/runtest.bat4
-rw-r--r--Test/dafny1/runtest.bat9
-rw-r--r--Test/test0/Answer13
-rw-r--r--Test/test0/SeparateVerification0.bpl21
-rw-r--r--Test/test0/SeparateVerification1.bpl19
-rw-r--r--Test/test0/runtest.bat9
-rw-r--r--Test/vacid0/runtest.bat9
-rw-r--r--_admin/Boogie/aste/summary.log15
76 files changed, 4776 insertions, 2879 deletions
diff --git a/.hgignore b/.hgignore
index 1905d88e..ccf5384a 100644
--- a/.hgignore
+++ b/.hgignore
@@ -4,13 +4,17 @@ syntax: regexp
^(Source|BCT|Jennisys)/.*\.(user|suo|cache)$
^Source/(Core|Dafny)/(Parser|Scanner).cs.old$
^Binaries/.*\.(dll|pdb|exe|manifest|config)$
-^.*(bin|obj)/([^/]*/)?(Debug|Release)/.*$
+^.*(bin|obj)/([^/]*/)?(Debug|Release|Checked|Debug All|DEBUG ALL)/.*$
^Binaries/BytecodeTranslator$
^BCT/Binaries/.*$
+^Chalice/bin/
Test/([^/]*)/Output
Test/([^/]*)/([^/]*)\.sx
-Test/(dafny0|dafny1|VSI-Benchmarks|vacid0|VSComp2010)/out\.cs
+Test/(dafny0|dafny1|VSI-Benchmarks|vacid0|VSComp2010)/(out\.cs|.*\.dll|.*\.pdb|.*\.exe)
+Test/desktop/
^.*~$
syntax: glob
BCT/TestResults/
BCT/testimpactdata.sdf
+backup.diff
+BCT/Samples/CodeCounter/console/ClassDiagram1.cd
diff --git a/BCT/BytecodeTranslator/ExpressionTraverser.cs b/BCT/BytecodeTranslator/ExpressionTraverser.cs
index 3db99307..29c0033f 100644
--- a/BCT/BytecodeTranslator/ExpressionTraverser.cs
+++ b/BCT/BytecodeTranslator/ExpressionTraverser.cs
@@ -23,17 +23,12 @@ namespace BytecodeTranslator
{
public class ExpressionTraverser : BaseCodeTraverser
{
-
- public readonly Bpl.Variable ArrayContentsVariable;
- public readonly Bpl.Variable ArrayLengthVariable;
-
public readonly Stack<Bpl.Expr> TranslatedExpressions;
protected readonly Sink sink;
protected readonly StatementTraverser StmtTraverser;
- private Bpl.Expr assignmentSourceExpr;
private bool contractContext;
#region Constructors
@@ -53,12 +48,9 @@ namespace BytecodeTranslator
public ExpressionTraverser(Sink sink, StatementTraverser/*?*/ statementTraverser, bool contractContext)
{
this.sink = sink;
- ArrayContentsVariable = sink.ArrayContentsVariable;
- ArrayLengthVariable = sink.ArrayLengthVariable;
this.StmtTraverser = statementTraverser;
TranslatedExpressions = new Stack<Bpl.Expr>();
- assignmentSourceExpr = null;
this.contractContext = contractContext;
}
@@ -86,9 +78,24 @@ namespace BytecodeTranslator
return;
}
IFieldReference/*?*/ field = addressableExpression.Definition as IFieldReference;
- if (field != null)
- {
- TranslatedExpressions.Push(Bpl.Expr.Ident(this.sink.FindOrCreateFieldVariable(field.ResolvedField)));
+ if (field != null) {
+ var f = Bpl.Expr.Ident(this.sink.FindOrCreateFieldVariable(field.ResolvedField));
+ var instance = addressableExpression.Instance;
+ if (instance == null) {
+ TranslatedExpressions.Push(f);
+ }
+ else {
+ this.Visit(instance);
+ if (this.collectStructFields) {
+ this.structFields.Add(field.ResolvedField);
+ }
+ else {
+ Bpl.Expr instanceExpr = TranslatedExpressions.Pop();
+ Bpl.IdentifierExpr temp = Bpl.Expr.Ident(this.sink.CreateFreshLocal(field.ResolvedField.Type));
+ this.StmtTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(temp, this.sink.Heap.ReadHeap(instanceExpr, f, field.ContainingType.ResolvedType.IsStruct ? AccessType.Struct : AccessType.Heap, temp.Type)));
+ TranslatedExpressions.Push(temp);
+ }
+ }
return;
}
IArrayIndexer/*?*/ arrayIndexer = addressableExpression.Definition as IArrayIndexer;
@@ -127,47 +134,34 @@ namespace BytecodeTranslator
}
}
this.Visit(addressDereference.Address);
- throw new NotImplementedException();
+ return;
}
- public override void Visit(IArrayIndexer arrayIndexer)
- {
+ public override void Visit(IArrayIndexer arrayIndexer) {
this.Visit(arrayIndexer.IndexedObject);
Bpl.Expr arrayExpr = TranslatedExpressions.Pop();
this.Visit(arrayIndexer.Indices);
- List<Bpl.Expr> indexExprs = new List<Bpl.Expr>();
- for (int i = 0; i < arrayIndexer.Indices.Count(); i++)
- {
- indexExprs.Insert(0, TranslatedExpressions.Pop());
+ int count = arrayIndexer.Indices.Count();
+ Bpl.Expr[] indexExprs = new Bpl.Expr[count];
+ for (int i = count; i > 0; i--) {
+ indexExprs[i - 1] = TranslatedExpressions.Pop();
}
- if (assignmentSourceExpr != null)
- {
- Bpl.Expr currSelectExpr = new Bpl.IdentifierExpr(arrayIndexer.Token(), ArrayContentsVariable);
- Bpl.Expr currIndexExpr = arrayExpr;
- List<Bpl.Expr> selectExprs = new List<Bpl.Expr>();
- foreach (Bpl.Expr e in indexExprs)
- {
- currSelectExpr = Bpl.Expr.Select(currSelectExpr, currIndexExpr);
- selectExprs.Add(currSelectExpr);
- currIndexExpr = e;
- }
- Contract.Assert(selectExprs.Count == indexExprs.Count);
- Bpl.Expr currentStoreExpr = assignmentSourceExpr;
- for (int i = selectExprs.Count - 1; i >= 0; i--)
- {
- currentStoreExpr = Bpl.Expr.Store(selectExprs[i], indexExprs[i], currentStoreExpr);
- }
- TranslatedExpressions.Push(Bpl.Expr.Store(new Bpl.IdentifierExpr(arrayIndexer.Token(), ArrayContentsVariable), arrayExpr, currentStoreExpr));
+ Bpl.Expr indexExpr;
+ if (indexExprs.Length == 1) {
+ indexExpr = indexExprs[0];
}
- else
- {
- Bpl.Expr currSelectExpr = Bpl.Expr.Select(new Bpl.IdentifierExpr(arrayIndexer.Token(), ArrayContentsVariable), arrayExpr);
- foreach (Bpl.Expr e in indexExprs)
- {
- currSelectExpr = Bpl.Expr.Select(currSelectExpr, e);
- }
- TranslatedExpressions.Push(currSelectExpr);
+ else {
+ Bpl.Function f = this.sink.FindOrCreateNaryIntFunction(indexExprs.Length);
+ indexExpr = new Bpl.NAryExpr(arrayIndexer.Token(), new Bpl.FunctionCall(f), new Bpl.ExprSeq(indexExprs));
}
+
+ Bpl.IdentifierExpr temp = Bpl.Expr.Ident(this.sink.CreateFreshLocal(arrayIndexer.Type));
+ Bpl.Expr selectExpr = sink.Heap.ReadHeap(arrayExpr, indexExpr, AccessType.Array, temp.Type);
+ this.StmtTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(temp, selectExpr));
+ TranslatedExpressions.Push(temp);
+
+ this.arrayExpr = arrayExpr;
+ this.indexExpr = indexExpr;
}
public override void Visit(ITargetExpression targetExpression)
@@ -240,16 +234,11 @@ namespace BytecodeTranslator
IFieldReference field = targetExpression.Definition as IFieldReference;
if (field != null)
{
- //ProcessFieldVariable(field, targetExpression.Instance, false);
- //return;
- var f = Bpl.Expr.Ident(this.sink.FindOrCreateFieldVariable(field.ResolvedField));
- TranslatedExpressions.Push(f);
var instance = targetExpression.Instance;
if (instance != null) {
this.Visit(instance);
}
return;
-
}
#endregion
@@ -293,10 +282,18 @@ namespace BytecodeTranslator
var instance = boundExpression.Instance;
if (instance == null) {
TranslatedExpressions.Push(f);
- } else {
+ }
+ else {
this.Visit(instance);
- Bpl.Expr instanceExpr = TranslatedExpressions.Pop();
- TranslatedExpressions.Push(this.sink.Heap.ReadHeap(instanceExpr, f));
+ if (this.collectStructFields) {
+ this.structFields.Add(field.ResolvedField);
+ }
+ else {
+ Bpl.Expr instanceExpr = TranslatedExpressions.Pop();
+ Bpl.IdentifierExpr temp = Bpl.Expr.Ident(this.sink.CreateFreshLocal(field.ResolvedField.Type));
+ this.StmtTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(temp, this.sink.Heap.ReadHeap(instanceExpr, f, field.ContainingType.ResolvedType.IsStruct ? AccessType.Struct : AccessType.Heap, temp.Type)));
+ TranslatedExpressions.Push(temp);
+ }
}
return;
}
@@ -342,66 +339,81 @@ namespace BytecodeTranslator
#endregion
}
+ public override void Visit(IPopValue popValue) {
+ var locExpr = this.StmtTraverser.operandStack.Pop();
+ this.TranslatedExpressions.Push(locExpr);
+ }
+
/// <summary>
- ///
+ /// If the expression is a struct, then this returns a "boxed" struct.
+ /// Otherwise it just translates the expression and skips the address-of
+ /// operation.
/// </summary>
- /// <param name="addressOf"></param>
- /// <remarks>Since we are doing Copy-In,Copy-Out for function calls we can ignore it.
- /// But will this work for the general case?</remarks>
public override void Visit(IAddressOf addressOf)
{
Visit(addressOf.Expression);
+ //if (addressOf.Expression.Type.IsValueType)
+ //{
+ // var e = this.TranslatedExpressions.Pop();
+ // var callBox = new Bpl.NAryExpr(
+ // addressOf.Token(),
+ // new Bpl.FunctionCall(this.sink.Heap.Struct2Ref),
+ // new Bpl.ExprSeq(e)
+ // );
+ // TranslatedExpressions.Push(callBox);
+ //}
}
#endregion
#region Translate Constant Access
- public override void Visit(ICompileTimeConstant constant)
- {
- if (constant.Value == null)
- {
- var bplType = TranslationHelper.CciTypeToBoogie(constant.Type);
+ public override void Visit(ICompileTimeConstant constant) {
+ if (constant.Value == null) {
+ var bplType = sink.CciTypeToBoogie(constant.Type);
if (bplType == Bpl.Type.Int) {
var lit = Bpl.Expr.Literal(0);
lit.Type = Bpl.Type.Int;
TranslatedExpressions.Push(lit);
} else if (bplType == Bpl.Type.Bool) {
TranslatedExpressions.Push(Bpl.Expr.False);
+ } else if (bplType == this.sink.Heap.RefType) {
+ TranslatedExpressions.Push(Bpl.Expr.Ident(this.sink.Heap.NullRef));
} else {
- throw new NotImplementedException("Don't know how to translate type");
+ throw new NotImplementedException(String.Format("Don't know how to translate type: '{0}'", TypeHelper.GetTypeName(constant.Type)));
}
- }
- else if (constant.Value is bool)
- {
- TranslatedExpressions.Push(((bool)constant.Value) ? Bpl.Expr.True : Bpl.Expr.False);
+ return;
}
- else if (constant.Value is string)
- {
+ if (constant.Value is string) {
var c = this.sink.FindOrCreateConstant((string)(constant.Value));
TranslatedExpressions.Push(Bpl.Expr.Ident(c));
-
- //throw new NotImplementedException("Strings are not translated");
- } else {
- // TODO: (mschaef) hack
- var lit = Bpl.Expr.Literal((int)constant.Value);
- lit.Type = Bpl.Type.Int;
- TranslatedExpressions.Push(lit);
+ return;
}
+ switch (constant.Type.TypeCode) {
+ case PrimitiveTypeCode.Boolean:
+ TranslatedExpressions.Push(((bool)constant.Value) ? Bpl.Expr.True : Bpl.Expr.False);
+ break;
+ case PrimitiveTypeCode.Char: // chars are represented as ints
+ case PrimitiveTypeCode.Int16:
+ case PrimitiveTypeCode.Int32:
+ case PrimitiveTypeCode.Int64:
+ case PrimitiveTypeCode.Int8:
+ var lit = Bpl.Expr.Literal((int)constant.Value);
+ lit.Type = Bpl.Type.Int;
+ TranslatedExpressions.Push(lit);
+ break;
+ case PrimitiveTypeCode.Float32:
+ case PrimitiveTypeCode.Float64:
+ var c = this.sink.FindOrCreateConstant((double)(constant.Value));
+ TranslatedExpressions.Push(Bpl.Expr.Ident(c));
+ return;
+ default:
+ throw new NotImplementedException();
+ }
+ return;
}
public override void Visit(IDefaultValue defaultValue) {
- var bplType = TranslationHelper.CciTypeToBoogie(defaultValue.Type);
- if (bplType == Bpl.Type.Int) {
- var lit = Bpl.Expr.Literal(0);
- lit.Type = Bpl.Type.Int;
- TranslatedExpressions.Push(lit);
- } else if (bplType == Bpl.Type.Bool) {
- var lit = Bpl.Expr.False;
- lit.Type = Bpl.Type.Bool;
- TranslatedExpressions.Push(lit);
- } else {
- throw new NotImplementedException("Don't know how to translate type");
- }
+ TranslatedExpressions.Push(this.sink.DefaultValue(defaultValue.Type));
}
#endregion
@@ -412,156 +424,185 @@ namespace BytecodeTranslator
/// </summary>
/// <param name="methodCall"></param>
/// <remarks>Stub, This one really needs comments!</remarks>
- public override void Visit(IMethodCall methodCall)
- {
- var resolvedMethod = methodCall.MethodToCall.ResolvedMethod;
-
- #region Translate In Parameters
+ public override void Visit(IMethodCall methodCall) {
+ var resolvedMethod = Sink.Unspecialize(methodCall.MethodToCall).ResolvedMethod;
+ if (resolvedMethod == Dummy.Method) {
+ throw new TranslationException(
+ ExceptionType.UnresolvedMethod,
+ MemberHelper.GetMethodSignature(methodCall.MethodToCall, NameFormattingOptions.None));
+ }
+
+ #region Translate In and Out Parameters
var inexpr = new List<Bpl.Expr>();
+ var outvars = new List<Bpl.IdentifierExpr>();
#region Create the 'this' argument for the function call
- Bpl.Expr thisExpr = null;
- if (!methodCall.IsStaticCall)
- {
+ Bpl.IdentifierExpr thisExpr = null;
+ List<Bpl.Variable> locals = null;
+ List<IFieldDefinition> args = null;
+ Bpl.Expr arrayExpr = null;
+ Bpl.Expr indexExpr = null;
+ if (!methodCall.IsStaticCall) {
+ this.collectStructFields = true;
+ this.structFields = new List<IFieldDefinition>();
+ this.arrayExpr = null;
+ this.indexExpr = null;
this.Visit(methodCall.ThisArgument);
- thisExpr = this.TranslatedExpressions.Pop();
- inexpr.Add(thisExpr);
+ this.collectStructFields = false;
+ args = this.structFields;
+ arrayExpr = this.arrayExpr;
+ indexExpr = this.indexExpr;
+
+ var e = this.TranslatedExpressions.Pop();
+ inexpr.Add(e);
+ if (e is Bpl.NAryExpr) {
+ e = ((Bpl.NAryExpr)e).Args[0];
+ }
+ thisExpr = e as Bpl.IdentifierExpr;
+ locals = new List<Bpl.Variable>();
+ Bpl.Variable x = thisExpr.Decl;
+ locals.Add(x);
+ for (int i = 0; i < args.Count; i++) {
+ Bpl.IdentifierExpr g = Bpl.Expr.Ident(this.sink.FindOrCreateFieldVariable(args[i]));
+ Bpl.Variable y = this.sink.CreateFreshLocal(args[i].Type);
+ StmtTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(y), this.sink.Heap.ReadHeap(Bpl.Expr.Ident(x), g, args[i].ContainingType.ResolvedType.IsStruct ? AccessType.Struct : AccessType.Heap, y.TypedIdent.Type)));
+ x = y;
+ locals.Add(y);
+ }
+ }
+ if (!methodCall.IsStaticCall && methodCall.MethodToCall.ContainingType.ResolvedType.IsStruct) {
+ outvars.Add(thisExpr);
}
#endregion
- Dictionary<IParameterDefinition, Bpl.Expr> p2eMap = new Dictionary<IParameterDefinition, Bpl.Expr>();
+ Dictionary<Bpl.IdentifierExpr, Bpl.IdentifierExpr> toBoxed = new Dictionary<Bpl.IdentifierExpr, Bpl.IdentifierExpr>();
+ Dictionary<IParameterDefinition, Bpl.IdentifierExpr> p2eMap = new Dictionary<IParameterDefinition, Bpl.IdentifierExpr>();
IEnumerator<IParameterDefinition> penum = resolvedMethod.Parameters.GetEnumerator();
penum.MoveNext();
- foreach (IExpression exp in methodCall.Arguments)
- {
- if (penum.Current == null)
- {
- throw new TranslationException("More Arguments than Parameters in functioncall");
+ foreach (IExpression exp in methodCall.Arguments) {
+ if (penum.Current == null) {
+ throw new TranslationException("More arguments than parameters in method call");
}
this.Visit(exp);
Bpl.Expr e = this.TranslatedExpressions.Pop();
-
- p2eMap.Add(penum.Current, e);
- if (!penum.Current.IsOut)
- {
+ if (penum.Current.Type is IGenericTypeParameter)
+ inexpr.Add(sink.Heap.Box(methodCall.Token(), this.sink.CciTypeToBoogie(exp.Type), e));
+ else
inexpr.Add(e);
+ if (penum.Current.IsByReference) {
+ Bpl.IdentifierExpr unboxed = e as Bpl.IdentifierExpr;
+ if (unboxed == null) {
+ throw new TranslationException("Trying to pass a complex expression for an out or ref parameter");
+ }
+ if (penum.Current.Type is IGenericTypeParameter) {
+ Bpl.IdentifierExpr boxed = Bpl.Expr.Ident(sink.CreateFreshLocal(this.sink.Heap.BoxType));
+ toBoxed[unboxed] = boxed;
+ outvars.Add(boxed);
+ }
+ else {
+ outvars.Add(unboxed);
+ }
}
-
penum.MoveNext();
}
#endregion
Bpl.IToken cloc = methodCall.Token();
-
- // meeting a constructor is always something special
- if (false && resolvedMethod.IsConstructor)
- {
- // Todo: do something with the constructor call
+ if (resolvedMethod.Type.ResolvedType.TypeCode != PrimitiveTypeCode.Void) {
+ Bpl.Variable v = this.sink.CreateFreshLocal(methodCall.Type.ResolvedType);
+ Bpl.IdentifierExpr unboxed = new Bpl.IdentifierExpr(cloc, v);
+ if (resolvedMethod.Type is IGenericTypeParameter) {
+ Bpl.IdentifierExpr boxed = Bpl.Expr.Ident(this.sink.CreateFreshLocal(this.sink.Heap.BoxType));
+ toBoxed[unboxed] = boxed;
+ outvars.Add(boxed);
+ }
+ else {
+ outvars.Add(unboxed);
+ }
+ TranslatedExpressions.Push(unboxed);
}
- else
- {
- // Todo: if there is no stmttraverser we are visiting a contract and should use a boogie function instead of procedure!
+ var proc = this.sink.FindOrCreateProcedure(resolvedMethod);
+ string methodname = proc.Name;
- #region Translate Out vars
- var outvars = new List<Bpl.IdentifierExpr>();
-
- foreach (KeyValuePair<IParameterDefinition, Bpl.Expr> kvp in p2eMap)
- {
- if (kvp.Key.IsOut || kvp.Key.IsByReference)
- {
- Bpl.IdentifierExpr iexp = kvp.Value as Bpl.IdentifierExpr;
- if (iexp == null)
- {
- throw new TranslationException("Trying to pass complex expression as out in functioncall");
- }
- outvars.Add(iexp);
- }
+ Bpl.QKeyValue attrib = null;
+ foreach (var a in resolvedMethod.Attributes) {
+ if (TypeHelper.GetTypeName(a.Type).EndsWith("AsyncAttribute")) {
+ attrib = new Bpl.QKeyValue(cloc, "async", new List<object>(), null);
}
- #endregion
+ }
- if (methodCall.Type.ResolvedType.TypeCode != PrimitiveTypeCode.Void)
- {
- Bpl.Variable v = this.sink.CreateFreshLocal(methodCall.Type.ResolvedType);
- outvars.Add(new Bpl.IdentifierExpr(cloc, v));
- TranslatedExpressions.Push(new Bpl.IdentifierExpr(cloc, v));
+ Bpl.CallCmd call;
+ bool isEventAdd = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("add_");
+ bool isEventRemove = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("remove_");
+ if (isEventAdd || isEventRemove) {
+ var mName = resolvedMethod.Name.Value;
+ var eventName = mName.Substring(mName.IndexOf('_') + 1);
+ var eventDef = TypeHelper.GetEvent(resolvedMethod.ContainingTypeDefinition, this.sink.host.NameTable.GetNameFor(eventName));
+ Contract.Assert(eventDef != Dummy.Event);
+ Bpl.Variable eventVar = this.sink.FindOrCreateEventVariable(eventDef);
+ Bpl.Variable local = this.sink.CreateFreshLocal(eventDef.Type);
+
+ if (methodCall.IsStaticCall) {
+ this.StmtTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(local), Bpl.Expr.Ident(eventVar)));
+ inexpr.Insert(0, Bpl.Expr.Ident(local));
}
- var proc = this.sink.FindOrCreateProcedure(resolvedMethod);
- string methodname = proc.Name;
-
- Bpl.QKeyValue attrib = null;
- foreach (var a in resolvedMethod.Attributes)
- {
- if (TypeHelper.GetTypeName(a.Type).EndsWith("AsyncAttribute"))
- {
- attrib = new Bpl.QKeyValue(cloc, "async", new List<object>(), null);
- }
+ else {
+ this.StmtTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(local), this.sink.Heap.ReadHeap(thisExpr, Bpl.Expr.Ident(eventVar), resolvedMethod.ContainingType.ResolvedType.IsStruct ? AccessType.Struct : AccessType.Heap, local.TypedIdent.Type)));
+ inexpr[0] = Bpl.Expr.Ident(local);
}
- Bpl.CallCmd call;
- bool isEventAdd = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("add_");
- bool isEventRemove = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("remove_");
- if (isEventAdd || isEventRemove)
- {
- IEventDefinition ed = null;
- foreach (var e in resolvedMethod.ContainingTypeDefinition.Events)
- {
- if (e.Adder != null && e.Adder.ResolvedMethod == resolvedMethod)
- {
- ed = e;
- break;
- }
- }
- Bpl.Variable eventVar = null;
- Bpl.Variable local = null;
- foreach (var f in resolvedMethod.ContainingTypeDefinition.Fields) {
- if (ed.Name == f.Name) {
- eventVar = this.sink.FindOrCreateFieldVariable(f);
- local = this.sink.CreateFreshLocal(f.Type);
- break;
- }
- }
+ System.Diagnostics.Debug.Assert(outvars.Count == 0);
+ outvars.Add(Bpl.Expr.Ident(local));
+ string methodName = isEventAdd ? this.sink.DelegateAddName : this.sink.DelegateRemoveName;
+ call = new Bpl.CallCmd(methodCall.Token(), methodName, inexpr, outvars);
+ this.StmtTraverser.StmtBuilder.Add(call);
+ if (methodCall.IsStaticCall) {
+ this.StmtTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(eventVar), Bpl.Expr.Ident(local)));
+ }
+ else {
+ this.StmtTraverser.StmtBuilder.Add(this.sink.Heap.WriteHeap(methodCall.Token(), thisExpr, Bpl.Expr.Ident(eventVar), Bpl.Expr.Ident(local), resolvedMethod.ContainingType.ResolvedType.IsStruct ? AccessType.Struct : AccessType.Heap, local.TypedIdent.Type));
+ }
+ }
+ else {
+ if (attrib != null)
+ call = new Bpl.CallCmd(cloc, methodname, inexpr, outvars, attrib);
+ else
+ call = new Bpl.CallCmd(cloc, methodname, inexpr, outvars);
+ this.StmtTraverser.StmtBuilder.Add(call);
+ }
- if (methodCall.IsStaticCall)
- {
- this.StmtTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(local), Bpl.Expr.Ident(eventVar)));
- inexpr.Insert(0, Bpl.Expr.Ident(local));
- }
- else
- {
- this.StmtTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(local), this.sink.Heap.ReadHeap(thisExpr, Bpl.Expr.Ident(eventVar))));
- inexpr[0] = Bpl.Expr.Ident(local);
- }
+ foreach (KeyValuePair<Bpl.IdentifierExpr, Bpl.IdentifierExpr> kv in toBoxed) {
+ this.StmtTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(kv.Key, this.sink.Heap.Unbox(Bpl.Token.NoToken, kv.Key.Type, kv.Value)));
+ }
- System.Diagnostics.Debug.Assert(outvars.Count == 0);
- outvars.Add(Bpl.Expr.Ident(local));
- string methodName = isEventAdd ? this.sink.DelegateAddName : this.sink.DelegateRemoveName;
- call = new Bpl.CallCmd(methodCall.Token(), methodName, inexpr, outvars);
- this.StmtTraverser.StmtBuilder.Add(call);
- if (methodCall.IsStaticCall)
- {
- this.StmtTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(eventVar), Bpl.Expr.Ident(local)));
- }
- else
- {
- this.StmtTraverser.StmtBuilder.Add(this.sink.Heap.WriteHeap(methodCall.Token(), thisExpr, Bpl.Expr.Ident(eventVar), Bpl.Expr.Ident(local)));
- }
+ if (!methodCall.IsStaticCall) {
+ Debug.Assert(args != null && locals != null);
+ int count = args.Count;
+ Bpl.Variable x = locals[count];
+ count--;
+ while (0 <= count) {
+ IFieldDefinition currField = args[count];
+ Bpl.IdentifierExpr g = Bpl.Expr.Ident(this.sink.FindOrCreateFieldVariable(currField));
+ Bpl.Variable y = locals[count];
+ StmtTraverser.StmtBuilder.Add(this.sink.Heap.WriteHeap(methodCall.Token(), Bpl.Expr.Ident(y), g, Bpl.Expr.Ident(x), currField.ContainingType.ResolvedType.IsStruct ? AccessType.Struct : AccessType.Heap, x.TypedIdent.Type));
+ x = y;
+ count--;
}
- else
- {
- if (attrib != null)
- call = new Bpl.CallCmd(cloc, methodname, inexpr, outvars, attrib);
- else
- call = new Bpl.CallCmd(cloc, methodname, inexpr, outvars);
- this.StmtTraverser.StmtBuilder.Add(call);
+ if (indexExpr != null) {
+ Debug.Assert(arrayExpr != null);
+ StmtTraverser.StmtBuilder.Add(sink.Heap.WriteHeap(Bpl.Token.NoToken, arrayExpr, indexExpr, Bpl.Expr.Ident(x), AccessType.Array, x.TypedIdent.Type));
}
}
-
}
#endregion
#region Translate Assignments
+ private List<IFieldDefinition> structFields = null;
+ private bool collectStructFields = false;
+ private Bpl.Expr arrayExpr = null;
+ private Bpl.Expr indexExpr = null;
/// <summary>
///
@@ -576,28 +617,72 @@ namespace BytecodeTranslator
Bpl.Expr sourceexp = this.TranslatedExpressions.Pop();
#endregion
- var target = assignment.Target;
-
- this.assignmentSourceExpr = sourceexp;
+ // Simplify the LHS so that all nested dereferences and method calls are broken
+ // up into separate assignments to locals.
+ var blockExpression = AssignmentSimplifier.Simplify(this.sink, assignment.Target);
+ foreach (var s in blockExpression.BlockStatement.Statements) {
+ this.StmtTraverser.Visit(s);
+ }
+ var target = blockExpression.Expression as ITargetExpression;
+
+ List<IFieldDefinition> args = null;
+ Bpl.Expr arrayExpr = null;
+ Bpl.Expr indexExpr = null;
+ this.collectStructFields = true;
+ this.structFields = new List<IFieldDefinition>();
+ this.arrayExpr = null;
+ this.indexExpr = null;
this.Visit(target);
- this.assignmentSourceExpr = null;
+ this.collectStructFields = false;
+ args = this.structFields;
+ arrayExpr = this.arrayExpr;
+ indexExpr = this.indexExpr;
- if (target.Definition is IArrayIndexer) {
- StmtTraverser.StmtBuilder.Add(
- Bpl.Cmd.SimpleAssign(assignment.Token(),
- new Bpl.IdentifierExpr(assignment.Token(), ArrayContentsVariable),
- TranslatedExpressions.Pop()));
+ var fieldReference = target.Definition as IFieldReference;
+ if (fieldReference != null) {
+ Bpl.IdentifierExpr f = Bpl.Expr.Ident(this.sink.FindOrCreateFieldVariable(fieldReference.ResolvedField));
+ if (target.Instance == null) {
+ StmtTraverser.StmtBuilder.Add(Bpl.Cmd.SimpleAssign(assignment.Token(), f, sourceexp));
+ }
+ else {
+ Debug.Assert(args != null);
+ List<Bpl.Variable> locals = new List<Bpl.Variable>();
+ Bpl.IdentifierExpr instanceExpr = TranslatedExpressions.Pop() as Bpl.IdentifierExpr;
+ Bpl.Variable x = instanceExpr.Decl;
+ locals.Add(x);
+ for (int i = 0; i < args.Count; i++) {
+ Bpl.IdentifierExpr g = Bpl.Expr.Ident(this.sink.FindOrCreateFieldVariable(args[i]));
+ Bpl.Variable y = this.sink.CreateFreshLocal(args[i].Type);
+ StmtTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(y), this.sink.Heap.ReadHeap(Bpl.Expr.Ident(x), g, args[i].ContainingType.ResolvedType.IsStruct ? AccessType.Struct : AccessType.Heap, y.TypedIdent.Type)));
+ x = y;
+ locals.Add(y);
+ }
+ var boogieType = sink.CciTypeToBoogie(fieldReference.Type);
+ StmtTraverser.StmtBuilder.Add(this.sink.Heap.WriteHeap(assignment.Token(), Bpl.Expr.Ident(x), f, sourceexp, fieldReference.ResolvedField.ContainingType.ResolvedType.IsStruct ? AccessType.Struct : AccessType.Heap, boogieType));
+
+ int count = args.Count;
+ x = locals[count];
+ count--;
+ while (0 <= count) {
+ IFieldDefinition currField = args[count];
+ Bpl.IdentifierExpr g = Bpl.Expr.Ident(this.sink.FindOrCreateFieldVariable(currField));
+ Bpl.Variable y = locals[count];
+ StmtTraverser.StmtBuilder.Add(this.sink.Heap.WriteHeap(assignment.Token(), Bpl.Expr.Ident(y), g, Bpl.Expr.Ident(x), currField.ContainingType.ResolvedType.IsStruct ? AccessType.Struct : AccessType.Heap, x.TypedIdent.Type));
+ x = y;
+ count--;
+ }
+ if (indexExpr != null) {
+ Debug.Assert(arrayExpr != null);
+ StmtTraverser.StmtBuilder.Add(sink.Heap.WriteHeap(Bpl.Token.NoToken, arrayExpr, indexExpr, Bpl.Expr.Ident(x), AccessType.Array, x.TypedIdent.Type));
+ }
+ }
return;
}
- var fieldReference = target.Definition as IFieldReference;
- if (fieldReference != null) {
- Bpl.Expr o = null;
- if (target.Instance != null)
- o = TranslatedExpressions.Pop();
- Bpl.IdentifierExpr f = this.TranslatedExpressions.Pop() as Bpl.IdentifierExpr;
- var c = this.sink.Heap.WriteHeap(assignment.Token(), o, f, sourceexp);
- StmtTraverser.StmtBuilder.Add(c);
+ // this is the case when it is just an array indexer expression
+ if (indexExpr != null) {
+ Debug.Assert(arrayExpr != null);
+ StmtTraverser.StmtBuilder.Add(sink.Heap.WriteHeap(Bpl.Token.NoToken, arrayExpr, indexExpr, sourceexp, AccessType.Array, sink.CciTypeToBoogie(target.Type)));
return;
}
@@ -640,7 +725,7 @@ namespace BytecodeTranslator
/// </summary>
public override void Visit(ICreateObjectInstance createObjectInstance)
{
- TranslateObjectCreation(createObjectInstance.MethodToCall, createObjectInstance.Arguments, createObjectInstance.Type, createObjectInstance);
+ TranslateObjectCreation(createObjectInstance.MethodToCall, createObjectInstance.Arguments, createObjectInstance);
}
public override void Visit(ICreateArray createArrayInstance)
@@ -672,35 +757,32 @@ namespace BytecodeTranslator
TranslatedExpressions.Push(Bpl.Expr.Ident(a));
}
- private void TranslateObjectCreation(IMethodReference ctor, IEnumerable<IExpression> arguments, ITypeReference ctorType, IExpression creationAST)
+ private void TranslateObjectCreation(IMethodReference ctor, IEnumerable<IExpression> arguments, IExpression creationAST)
{
+ var resolvedMethod = Sink.Unspecialize(ctor).ResolvedMethod;
Bpl.IToken token = creationAST.Token();
-
+
var a = this.sink.CreateFreshLocal(creationAST.Type);
// First generate an Alloc() call
this.StmtTraverser.StmtBuilder.Add(new Bpl.CallCmd(token, this.sink.AllocationMethodName, new Bpl.ExprSeq(), new Bpl.IdentifierExprSeq(Bpl.Expr.Ident(a))));
// Second, generate the call to the appropriate ctor
- var proc = this.sink.FindOrCreateProcedure(ctor.ResolvedMethod);
+ var proc = this.sink.FindOrCreateProcedure(resolvedMethod);
Bpl.ExprSeq inexpr = new Bpl.ExprSeq();
inexpr.Add(Bpl.Expr.Ident(a));
- IEnumerator<IParameterDefinition> penum = ctor.ResolvedMethod.Parameters.GetEnumerator();
+ IEnumerator<IParameterDefinition> penum = resolvedMethod.Parameters.GetEnumerator();
penum.MoveNext();
- foreach (IExpression exp in arguments)
- {
- if (penum.Current == null)
- {
+ foreach (IExpression exp in arguments) {
+ if (penum.Current == null) {
throw new TranslationException("More Arguments than Parameters in functioncall");
}
this.Visit(exp);
Bpl.Expr e = this.TranslatedExpressions.Pop();
-
- if (!penum.Current.IsOut)
- {
+ if (penum.Current.Type is IGenericTypeParameter)
+ inexpr.Add(sink.Heap.Box(ctor.Token(), this.sink.CciTypeToBoogie(exp.Type), e));
+ else
inexpr.Add(e);
- }
-
penum.MoveNext();
}
@@ -731,8 +813,8 @@ namespace BytecodeTranslator
Bpl.Expr methodExpr = Bpl.Expr.Ident(constant);
Bpl.Expr instanceExpr = TranslatedExpressions.Pop();
- this.StmtTraverser.StmtBuilder.Add(new Bpl.CallCmd(cloc, this.sink.DelegateAddHelperName,
- new Bpl.ExprSeq(Bpl.Expr.Literal(0), Bpl.Expr.Ident(constant), instanceExpr),
+ this.StmtTraverser.StmtBuilder.Add(new Bpl.CallCmd(cloc, this.sink.DelegateAddHelperName,
+ new Bpl.ExprSeq(Bpl.Expr.Ident(this.sink.Heap.NullRef), Bpl.Expr.Ident(constant), instanceExpr),
new Bpl.IdentifierExprSeq(Bpl.Expr.Ident(a))));
TranslatedExpressions.Push(Bpl.Expr.Ident(a));
}
@@ -836,8 +918,8 @@ namespace BytecodeTranslator
/// TODO:
/// If it isn't either of these short forms then emit the proper expression!
/// </summary>
- public override void Visit(IConditional conditional)
- {
+ public override void Visit(IConditional conditional) {
+ #region Try and reconstruct And, Or, Not expressions
CompileTimeConstant ctc = conditional.ResultIfFalse as CompileTimeConstant;
if (ctc != null && ctc.Type == BCT.Host.PlatformType.SystemInt32)
{
@@ -882,6 +964,8 @@ namespace BytecodeTranslator
return;
}
}
+ #endregion
+ #region Just translate it as an if-then-else expression
base.Visit(conditional);
var ifFalse = TranslatedExpressions.Pop();
var ifTrue = TranslatedExpressions.Pop();
@@ -889,7 +973,9 @@ namespace BytecodeTranslator
var tok = conditional.Token();
TranslatedExpressions.Push(
new Bpl.NAryExpr(tok, new Bpl.IfThenElse(tok), new Bpl.ExprSeq(c, ifTrue, ifFalse))
- );
+ );
+ return;
+ #endregion
}
@@ -897,6 +983,18 @@ namespace BytecodeTranslator
#region Translate Unary Operators
+ public override void Visit(ICastIfPossible castIfPossible) {
+ base.Visit(castIfPossible.ValueToCast);
+ var exp = TranslatedExpressions.Pop();
+ var v = this.sink.FindOrCreateType(castIfPossible.TargetType);
+ var callAs = new Bpl.NAryExpr(
+ castIfPossible.Token(),
+ new Bpl.FunctionCall(this.sink.Heap.AsFunction),
+ new Bpl.ExprSeq(exp, new Bpl.IdentifierExpr(castIfPossible.Token(), v))
+ );
+ TranslatedExpressions.Push(callAs);
+ return;
+ }
public override void Visit(ICheckIfInstance checkIfInstance) {
var v = this.sink.FindOrCreateType(checkIfInstance.TypeToCheck);
//var callTypeOf = new Bpl.NAryExpr(
@@ -911,6 +1009,99 @@ namespace BytecodeTranslator
return;
}
+ public override void Visit(IConversion conversion) {
+ var tok = conversion.ValueToConvert.Token();
+ Visit(conversion.ValueToConvert);
+ var boogieTypeOfValue = this.sink.CciTypeToBoogie(conversion.ValueToConvert.Type);
+ var boogieTypeToBeConvertedTo = this.sink.CciTypeToBoogie(conversion.TypeAfterConversion);
+ if (boogieTypeOfValue == boogieTypeToBeConvertedTo) {
+ // then this conversion is a nop, just ignore it
+ return;
+ }
+ var exp = TranslatedExpressions.Pop();
+ switch (conversion.TypeAfterConversion.TypeCode) {
+ case PrimitiveTypeCode.Int16:
+ case PrimitiveTypeCode.Int32:
+ case PrimitiveTypeCode.Int64:
+ case PrimitiveTypeCode.Int8:
+ case PrimitiveTypeCode.UInt16:
+ case PrimitiveTypeCode.UInt32:
+ case PrimitiveTypeCode.UInt64:
+ case PrimitiveTypeCode.UInt8:
+ switch (conversion.ValueToConvert.Type.TypeCode) {
+ case PrimitiveTypeCode.Boolean:
+ TranslatedExpressions.Push(
+ new Bpl.NAryExpr(tok, new Bpl.IfThenElse(tok), new Bpl.ExprSeq(exp, Bpl.Expr.Literal(1), Bpl.Expr.Literal(0)))
+ );
+ return;
+ case PrimitiveTypeCode.IntPtr:
+ // just ignore the conversion. REVIEW: is that the right thing to do?
+ this.TranslatedExpressions.Push(exp);
+ return;
+ case PrimitiveTypeCode.Float32:
+ case PrimitiveTypeCode.Float64: {
+ var convExpr = new Bpl.NAryExpr(
+ conversion.Token(),
+ new Bpl.FunctionCall(this.sink.Heap.Real2Int),
+ new Bpl.ExprSeq(exp,
+ new Bpl.IdentifierExpr(tok, this.sink.FindOrCreateType(conversion.ValueToConvert.Type)),
+ new Bpl.IdentifierExpr(tok, this.sink.FindOrCreateType(conversion.TypeAfterConversion))
+ )
+ );
+ TranslatedExpressions.Push(convExpr);
+ return;
+ }
+
+ default:
+ throw new NotImplementedException();
+ }
+ case PrimitiveTypeCode.Boolean:
+ if (TypeHelper.IsPrimitiveInteger(conversion.ValueToConvert.Type)) {
+ TranslatedExpressions.Push(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, exp, Bpl.Expr.Literal(0)));
+ return;
+ } else {
+ throw new NotImplementedException();
+ }
+ case PrimitiveTypeCode.NotPrimitive:
+ Bpl.Function func;
+ if (conversion.ValueToConvert.Type.TypeCode == PrimitiveTypeCode.Boolean){
+ func = this.sink.Heap.Bool2Ref;
+ }else if (TypeHelper.IsPrimitiveInteger(conversion.ValueToConvert.Type)) {
+ func = this.sink.Heap.Int2Ref;
+ } else if (conversion.ValueToConvert.Type.TypeCode == PrimitiveTypeCode.NotPrimitive) {
+ // REVIEW: Do we need to check to make sure that conversion.ValueToConvert.Type.IsValueType?
+ func = this.sink.Heap.Struct2Ref;
+ } else {
+ throw new NotImplementedException();
+ }
+ var boxExpr = new Bpl.NAryExpr(
+ conversion.Token(),
+ new Bpl.FunctionCall(func),
+ new Bpl.ExprSeq(exp)
+ );
+ TranslatedExpressions.Push(boxExpr);
+ return;
+ case PrimitiveTypeCode.Float32:
+ case PrimitiveTypeCode.Float64:
+ if (TypeHelper.IsPrimitiveInteger(conversion.ValueToConvert.Type)) {
+ var convExpr = new Bpl.NAryExpr(
+ conversion.Token(),
+ new Bpl.FunctionCall(this.sink.Heap.Int2Real),
+ new Bpl.ExprSeq(exp,
+ new Bpl.IdentifierExpr(tok, this.sink.FindOrCreateType(conversion.ValueToConvert.Type)),
+ new Bpl.IdentifierExpr(tok, this.sink.FindOrCreateType(conversion.TypeAfterConversion))
+ )
+ );
+ TranslatedExpressions.Push(convExpr);
+ return;
+ } else {
+ throw new NotImplementedException();
+ }
+ default:
+ throw new NotImplementedException();
+ }
+ }
+
public override void Visit(IUnaryNegation unaryNegation)
{
base.Visit(unaryNegation);
@@ -944,7 +1135,7 @@ namespace BytecodeTranslator
base.Visit(vectorLength.Vector);
var e = TranslatedExpressions.Pop();
TranslatedExpressions.Push(
- Bpl.Expr.Select(new Bpl.IdentifierExpr(vectorLength.Token(), this.sink.ArrayLengthVariable), new Bpl.Expr[] { e })
+ Bpl.Expr.Select(new Bpl.IdentifierExpr(vectorLength.Token(), this.sink.Heap.ArrayLengthVariable), new Bpl.Expr[] { e })
);
}
@@ -969,6 +1160,76 @@ namespace BytecodeTranslator
}
#endregion
+
+ /// <summary>
+ /// This is a rewriter so it must be used on a mutable Code Model!!!
+ /// </summary>
+ private class AssignmentSimplifier : CodeRewriter {
+
+ Sink sink;
+ private List<IStatement> localDeclarations = new List<IStatement>();
+
+ private AssignmentSimplifier(Sink sink)
+ : base(sink.host) {
+ this.sink = sink;
+ }
+
+ public static IBlockExpression Simplify(Sink sink, ITargetExpression targetExpression) {
+ var a = new AssignmentSimplifier(sink);
+ var leftOverExpression = a.Rewrite(targetExpression);
+ return new BlockExpression() {
+ BlockStatement = new BlockStatement() { Statements = a.localDeclarations, },
+ Expression = leftOverExpression,
+ Type = targetExpression.Type,
+ };
+ }
+
+ public override IExpression Rewrite(IBoundExpression boundExpression) {
+ if (boundExpression.Instance == null)
+ return base.Rewrite(boundExpression); // REVIEW: Maybe just stop the rewriting and return boundExpression?
+ var e = base.Rewrite(boundExpression);
+ boundExpression = e as IBoundExpression;
+ if (boundExpression == null) return e;
+ var loc = new LocalDefinition() {
+ Name = this.host.NameTable.GetNameFor("_loc" + this.sink.LocalCounter.ToString()), // TODO: should make the name unique within the method containing the assignment
+ Type = boundExpression.Type,
+ };
+ this.localDeclarations.Add(
+ new LocalDeclarationStatement() {
+ InitialValue = boundExpression,
+ LocalVariable = loc,
+ }
+ );
+ return new BoundExpression() {
+ Definition = loc,
+ Instance = null,
+ Type = boundExpression.Type,
+ };
+ }
+
+ public override IExpression Rewrite(IMethodCall methodCall) {
+
+ var e = base.Rewrite(methodCall); // simplify anything deeper in the tree
+ methodCall = e as IMethodCall;
+ if (methodCall == null) return e;
+
+ var loc = new LocalDefinition() {
+ Name = this.host.NameTable.GetNameFor("_loc"), // TODO: should make the name unique within the method containing the assignment
+ Type = methodCall.Type,
+ };
+ this.localDeclarations.Add(
+ new LocalDeclarationStatement() {
+ InitialValue = methodCall,
+ LocalVariable = loc,
+ }
+ );
+ return new BoundExpression() {
+ Definition = loc,
+ Instance = null,
+ Type = methodCall.Type,
+ };
+ }
+ }
}
}
diff --git a/BCT/BytecodeTranslator/Heap.cs b/BCT/BytecodeTranslator/Heap.cs
index 8f21d59a..283a59a3 100644
--- a/BCT/BytecodeTranslator/Heap.cs
+++ b/BCT/BytecodeTranslator/Heap.cs
@@ -23,126 +23,6 @@ using System.Reflection;
namespace BytecodeTranslator {
/// <summary>
- /// A heap representation that uses a global variable, $Heap, which is
- /// a two-dimensional array indexed by objects and fields, each of which
- /// are represented as an integer.
- /// </summary>
- public class TwoDIntHeap : Heap {
-
- #region Fields
- [RepresentationFor("$Heap", "var $Heap: HeapType where IsGoodHeap($Heap);", true)]
- private Bpl.Variable HeapVariable = null;
-
- //[RepresentationFor("HeapType", "type HeapType = [int,int]int;")]
- //private Bpl.TypeSynonymDecl HeapType = null;
-
- //[RepresentationFor("IsGoodHeap", "function IsGoodHeap(HeapType): bool;")]
- //private Bpl.Function IsGoodHeap = null;
-
- /// <summary>
- /// Prelude text for which access to the ASTs is not needed
- /// </summary>
- private readonly string InitialPreludeText =
- @"const null: int;
-type HeapType = [int,int]int;
-function IsGoodHeap(HeapType): bool;
-var $ArrayContents: [int][int]int;
-var $ArrayLength: [int]int;
-
-var $Alloc: [int] bool;
-procedure {:inline 1} Alloc() returns (x: int)
- free ensures x != 0;
- modifies $Alloc;
-{
- assume $Alloc[x] == false;
- $Alloc[x] := true;
-}
-
-";
-
- #endregion
-
- public override bool MakeHeap(Sink sink, out Heap heap, out Bpl.Program/*?*/ program) {
- heap = this;
- program = null;
- string prelude = this.InitialPreludeText + this.DelegateEncodingText;
- var b = RepresentationFor.ParsePrelude(prelude, this, out program);
- if (b) {
- this.TypeType = new Bpl.CtorType(this.TypeTypeDecl.tok, this.TypeTypeDecl, new Bpl.TypeSeq());
- }
- return b;
- }
-
- /// <summary>
- /// Creates a fresh BPL variable to represent <paramref name="field"/>, deciding
- /// on its type based on the heap representation.
- /// </summary>
- public override Bpl.Variable CreateFieldVariable(IFieldReference field) {
- Bpl.Variable v;
- string fieldname = TypeHelper.GetTypeName(field.ContainingType) + "." + field.Name.Value;
- Bpl.IToken tok = field.Token();
- Bpl.Type t = TranslationHelper.CciTypeToBoogie(field.Type.ResolvedType);
-
- if (field.IsStatic) {
- Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldname, t);
- v = new Bpl.GlobalVariable(tok, tident);
- }
- else {
- Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldname, t);
- v = new Bpl.Constant(tok, tident, true);
- }
- return v;
- }
-
- public override Bpl.Variable CreateEventVariable(IEventDefinition e) {
- Bpl.Variable v;
- string eventName = TypeHelper.GetTypeName(e.ContainingType) + "." + e.Name.Value;
- Bpl.IToken tok = e.Token();
- Bpl.Type t = TranslationHelper.CciTypeToBoogie(e.Type.ResolvedType);
-
- if (e.Adder.ResolvedMethod.IsStatic) {
- Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, eventName, t);
- v = new Bpl.GlobalVariable(tok, tident);
- }
- else {
- Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, eventName, t);
- v = new Bpl.Constant(tok, tident, true);
- }
- return v;
- }
-
- /// <summary>
- /// Returns the (typed) BPL expression that corresponds to the value of the field
- /// <paramref name="f"/> belonging to the object <paramref name="o"/> (when
- /// <paramref name="o"/> is non-null, otherwise the value of the static field.
- /// </summary>
- /// <param name="o">The expression that represents the object to be dereferenced.
- /// Null if <paramref name="f"/> is a static field.
- /// </param>
- /// <param name="f">The field that is used to dereference the object <paramref name="o"/>, when
- /// it is not null. Otherwise the static field whose value should be read.
- /// </param>
- public override Bpl.Expr ReadHeap(Bpl.Expr/*?*/ o, Bpl.IdentifierExpr f) {
- return Bpl.Expr.Select(new Bpl.IdentifierExpr(f.tok, HeapVariable), new Bpl.Expr[] { o, f });
- }
-
- /// <summary>
- /// Returns the BPL command that corresponds to assigning the value <paramref name="value"/>
- /// to the field <paramref name="f"/> of the object <paramref name="o"/> (when
- /// <paramref name="o"/> is non-null, otherwise it is an assignment to the static
- /// field.
- /// </summary>
- public override Bpl.Cmd WriteHeap(Bpl.IToken tok, Bpl.Expr/*?*/ o, Bpl.IdentifierExpr f, Bpl.Expr value) {
- if (o == null)
- return Bpl.Cmd.SimpleAssign(tok, f, value);
- else
- return
- Bpl.Cmd.MapAssign(tok,
- new Bpl.IdentifierExpr(tok, this.HeapVariable), new Bpl.ExprSeq(o, f), value);
- }
- }
-
- /// <summary>
/// A heap representation that uses a separate global variable for each
/// field. Each global variable is a map from int to T where T is the
/// type of the field.
@@ -153,32 +33,44 @@ procedure {:inline 1} Alloc() returns (x: int)
/// Prelude text for which access to the ASTs is not needed
/// </summary>
private readonly string InitialPreludeText =
- @"const null: int;
-type HeapType = [int,int]int;
-var $Heap: HeapType where IsGoodHeap($Heap);
-function IsGoodHeap(HeapType): bool;
-var $ArrayContents: [int][int]int;
-var $ArrayLength: [int]int;
-
-var $Alloc: [int] bool;
-procedure {:inline 1} Alloc() returns (x: int)
- free ensures x != 0;
+ @"type Struct = [Field]Box;
+type HeapType = [Ref,Field]Box;
+var $Heap: HeapType;
+
+var $Alloc: [Ref] bool;
+procedure {:inline 1} Alloc() returns (x: Ref)
modifies $Alloc;
{
- assume $Alloc[x] == false;
+ assume $Alloc[x] == false && x != null;
$Alloc[x] := true;
}
-type ref = int;
+axiom (forall x : Field :: $DefaultStruct[x] == $DefaultBox);
+axiom Box2Int($DefaultBox) == 0;
+axiom Box2Bool($DefaultBox) == false;
+axiom Box2Ref($DefaultBox) == null;
+axiom Box2Struct($DefaultBox) == $DefaultStruct;
+
+axiom (forall x: int :: { Int2Box(x) } Box2Int(Int2Box(x)) == x );
+axiom (forall x: bool :: { Bool2Box(x) } Box2Bool(Bool2Box(x)) == x );
+axiom (forall x: Ref :: { Ref2Box(x) } Box2Ref(Ref2Box(x)) == x );
+axiom (forall x: Struct :: { Struct2Box(x) } Box2Struct(Struct2Box(x)) == x );
+
";
+ private Sink sink;
public override bool MakeHeap(Sink sink, out Heap heap, out Bpl.Program/*?*/ program) {
heap = this;
program = null;
+ this.sink = sink;
string prelude = this.InitialPreludeText + this.DelegateEncodingText;
var b = RepresentationFor.ParsePrelude(prelude, this, out program);
if (b) {
+ this.BoxType = new Bpl.CtorType(this.BoxTypeDecl.tok, this.BoxTypeDecl, new Bpl.TypeSeq());
+ this.FieldType = new Bpl.CtorType(this.FieldTypeDecl.tok, this.FieldTypeDecl, new Bpl.TypeSeq());
this.TypeType = new Bpl.CtorType(this.TypeTypeDecl.tok, this.TypeTypeDecl, new Bpl.TypeSeq());
+ this.RefType = new Bpl.CtorType(this.RefTypeDecl.tok, this.RefTypeDecl, new Bpl.TypeSeq());
+ this.RealType = new Bpl.CtorType(this.RealTypeDecl.tok, this.RealTypeDecl, new Bpl.TypeSeq());
}
return b;
}
@@ -191,14 +83,14 @@ type ref = int;
Bpl.Variable v;
string fieldname = TypeHelper.GetTypeName(field.ContainingType) + "." + field.Name.Value;
Bpl.IToken tok = field.Token();
- Bpl.Type t = TranslationHelper.CciTypeToBoogie(field.Type.ResolvedType);
+ Bpl.Type t = this.sink.CciTypeToBoogie(field.Type.ResolvedType);
if (field.IsStatic) {
Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldname, t);
v = new Bpl.GlobalVariable(tok, tident);
}
else {
- Bpl.Type mt = new Bpl.MapType(tok, new Bpl.TypeVariableSeq(), new Bpl.TypeSeq(Bpl.Type.Int), t);
+ Bpl.Type mt = new Bpl.MapType(tok, new Bpl.TypeVariableSeq(), new Bpl.TypeSeq(this.RefType), t);
Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldname, mt);
v = new Bpl.GlobalVariable(tok, tident);
}
@@ -209,7 +101,7 @@ type ref = int;
Bpl.Variable v;
string eventName = TypeHelper.GetTypeName(e.ContainingType) + "." + e.Name.Value;
Bpl.IToken tok = e.Token();
- Bpl.Type t = TranslationHelper.CciTypeToBoogie(e.Type.ResolvedType);
+ Bpl.Type t = this.sink.CciTypeToBoogie(e.Type.ResolvedType);
if (e.Adder.ResolvedMethod.IsStatic) {
Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, eventName, t);
@@ -225,195 +117,33 @@ type ref = int;
/// <summary>
/// Returns the (typed) BPL expression that corresponds to the value of the field
- /// <paramref name="f"/> belonging to the object <paramref name="o"/> (when
- /// <paramref name="o"/> is non-null, otherwise the value of the static field.
+ /// <paramref name="f"/> belonging to the object <paramref name="o"/> (which must be non-null).
/// </summary>
/// <param name="o">The expression that represents the object to be dereferenced.
- /// Null if <paramref name="f"/> is a static field.
/// </param>
- /// <param name="f">The field that is used to dereference the object <paramref name="o"/>, when
- /// it is not null. Otherwise the static field whose value should be read.
+ /// <param name="f">The field that is used to dereference the object <paramref name="o"/>.
/// </param>
- public override Bpl.Expr ReadHeap(Bpl.Expr/*?*/ o, Bpl.IdentifierExpr f) {
- return Bpl.Expr.Select(f, o);
- }
-
- /// <summary>
- /// Returns the BPL command that corresponds to assigning the value <paramref name="value"/>
- /// to the field <paramref name="f"/> of the object <paramref name="o"/> (when
- /// <paramref name="o"/> is non-null, otherwise it is an assignment to the static
- /// field.
- /// </summary>
- public override Bpl.Cmd WriteHeap(Bpl.IToken tok, Bpl.Expr/*?*/ o, Bpl.IdentifierExpr f, Bpl.Expr value) {
- if (o == null)
- return Bpl.Cmd.SimpleAssign(tok, f, value);
+ public override Bpl.Expr ReadHeap(Bpl.Expr/*?*/ o, Bpl.Expr f, AccessType accessType, Bpl.Type unboxType) {
+ if (accessType == AccessType.Struct)
+ return Bpl.Expr.Select(o, f);
+ else if (accessType == AccessType.Heap)
+ return Bpl.Expr.Select(f, o);
else
- return Bpl.Cmd.MapAssign(tok, f, o, value);
- }
-
- }
-
- /// <summary>
- /// A heap representation that uses a global variable, $Heap, which is
- /// a two-dimensional array indexed by objects and fields. Objects
- /// are values of type "int", fields are unique constants, and the
- /// elements of the heap are of type "box". Each value that is read/written
- /// from/to the heap is wrapped in a type conversion function.
- /// </summary>
- public class TwoDBoxHeap : Heap {
-
- #region Fields
- [RepresentationFor("$Heap", "var $Heap: HeapType where IsGoodHeap($Heap);", true)]
- private Bpl.Variable HeapVariable = null;
-
- [RepresentationFor("Box2Int", "function Box2Int(box): int;")]
- private Bpl.Function Box2Int = null;
-
- [RepresentationFor("Box2Bool", "function Box2Bool(box): bool;")]
- private Bpl.Function Box2Bool = null;
-
- [RepresentationFor("Int2Box", "function Int2Box(int): box;")]
- private Bpl.Function Int2Box = null;
-
- [RepresentationFor("Bool2Box", "function Bool2Box(bool): box;")]
- private Bpl.Function Bool2Box = null;
-
- /// <summary>
- /// Prelude text for which access to the ASTs is not needed
- /// </summary>
- private readonly string InitialPreludeText =
- @"const null: int;
-type box;
-type HeapType = [int,int]box;
-function IsGoodHeap(HeapType): bool;
-var $ArrayContents: [int][int]int;
-var $ArrayLength: [int]int;
-
-var $Alloc: [int] bool;
-procedure {:inline 1} Alloc() returns (x: int)
- free ensures x != 0;
- modifies $Alloc;
-{
- assume $Alloc[x] == false;
- $Alloc[x] := true;
-}
-";
- private Sink sink;
-
- #endregion
-
- public override bool MakeHeap(Sink sink, out Heap heap, out Bpl.Program/*?*/ program) {
- this.sink = sink;
- heap = this;
- program = null;
- string prelude = this.InitialPreludeText + this.DelegateEncodingText;
- var b = RepresentationFor.ParsePrelude(prelude, this, out program);
- if (b) {
- this.TypeType = new Bpl.CtorType(this.TypeTypeDecl.tok, this.TypeTypeDecl, new Bpl.TypeSeq());
- }
- return b;
- }
-
- /// <summary>
- /// Creates a fresh BPL variable to represent <paramref name="field"/>, deciding
- /// on its type based on the heap representation.
- /// </summary>
- public override Bpl.Variable CreateFieldVariable(IFieldReference field) {
- Bpl.Variable v;
- string fieldname = TypeHelper.GetTypeName(field.ContainingType) + "." + field.Name.Value;
- Bpl.IToken tok = field.Token();
- Bpl.Type t = TranslationHelper.CciTypeToBoogie(field.Type.ResolvedType);
-
- if (field.IsStatic) {
- Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldname, t);
- v = new Bpl.GlobalVariable(tok, tident);
- }
- else {
- Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldname, t);
- v = new Bpl.Constant(tok, tident, true);
- }
- return v;
- }
-
- public override Bpl.Variable CreateEventVariable(IEventDefinition e) {
- Bpl.Variable v;
- string fieldname = TypeHelper.GetTypeName(e.ContainingType) + "." + e.Name.Value;
- Bpl.IToken tok = e.Token();
- Bpl.Type t = TranslationHelper.CciTypeToBoogie(e.Type.ResolvedType);
-
- if (e.Adder.ResolvedMethod.IsStatic) {
- Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldname, t);
- v = new Bpl.GlobalVariable(tok, tident);
- }
- else {
- Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldname, t);
- v = new Bpl.Constant(tok, tident, true);
- }
- return v;
- }
-
- /// <summary>
- /// Returns the (typed) BPL expression that corresponds to the value of the field
- /// <paramref name="f"/> belonging to the object <paramref name="o"/> (when
- /// <paramref name="o"/> is non-null, otherwise the value of the static field.
- /// </summary>
- /// <param name="o">The expression that represents the object to be dereferenced.
- /// Null if <paramref name="f"/> is a static field.
- /// </param>
- /// <param name="f">The field that is used to dereference the object <paramref name="o"/>, when
- /// it is not null. Otherwise the static field whose value should be read.
- /// </param>
- public override Bpl.Expr ReadHeap(Bpl.Expr/*?*/ o, Bpl.IdentifierExpr f) {
- // $Heap[o,f]
- var selectExpr = Bpl.Expr.Select(new Bpl.IdentifierExpr(f.tok, HeapVariable), new Bpl.Expr[] { o, f });
- // wrap it in the right conversion function
- Bpl.Function conversion;
- if (f.Type == Bpl.Type.Bool)
- conversion = this.Box2Bool;
- else if (f.Type == Bpl.Type.Int)
- conversion = this.Box2Int;
- else
- throw new InvalidOperationException("Unknown Boogie type");
- var callExpr = new Bpl.NAryExpr(
- f.tok,
- new Bpl.FunctionCall(conversion),
- new Bpl.ExprSeq(selectExpr)
- );
- callExpr.Type = f.Type;
- return callExpr;
-
+ return Bpl.Expr.Select(Bpl.Expr.Select(Bpl.Expr.Ident(ArrayContentsVariable), o), f);
}
/// <summary>
/// Returns the BPL command that corresponds to assigning the value <paramref name="value"/>
- /// to the field <paramref name="f"/> of the object <paramref name="o"/> (when
- /// <paramref name="o"/> is non-null, otherwise it is an assignment to the static
- /// field.
+ /// to the field <paramref name="f"/> of the object <paramref name="o"/> (which should be non-null).
/// </summary>
- public override Bpl.Cmd WriteHeap(Bpl.IToken tok, Bpl.Expr/*?*/ o, Bpl.IdentifierExpr f, Bpl.Expr value) {
- if (o == null) {
- return Bpl.Cmd.SimpleAssign(tok, f, value);
- }
- else {
- // wrap it in the right conversion function
- Bpl.Function conversion;
- if (f.Type == Bpl.Type.Bool)
- conversion = this.Bool2Box;
- else if (f.Type == Bpl.Type.Int)
- conversion = this.Int2Box;
- else
- throw new InvalidOperationException("Unknown Boogie type");
-
- // $Heap[o,f] := conversion(value)
- var callExpr = new Bpl.NAryExpr(
- f.tok,
- new Bpl.FunctionCall(conversion),
- new Bpl.ExprSeq(value)
- );
- return
- Bpl.Cmd.MapAssign(tok,
- new Bpl.IdentifierExpr(tok, this.HeapVariable), new Bpl.ExprSeq(o, f), callExpr);
- }
+ public override Bpl.Cmd WriteHeap(Bpl.IToken tok, Bpl.Expr/*?*/ o, Bpl.Expr f, Bpl.Expr value, AccessType accessType, Bpl.Type boxType) {
+ Debug.Assert(o != null);
+ if (accessType == AccessType.Struct)
+ return Bpl.Cmd.MapAssign(tok, (Bpl.IdentifierExpr)o, f, value);
+ else if (accessType == AccessType.Heap)
+ return Bpl.Cmd.MapAssign(tok, (Bpl.IdentifierExpr)f, o, value);
+ else
+ return TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(ArrayContentsVariable), Bpl.Expr.Store(Bpl.Expr.Ident(ArrayContentsVariable), o, Bpl.Expr.Store(Bpl.Expr.Select(Bpl.Expr.Ident(ArrayContentsVariable), o), f, value)));
}
}
@@ -427,51 +157,41 @@ procedure {:inline 1} Alloc() returns (x: int)
#region Fields
- [RepresentationFor("Field", "type Field;")]
- private Bpl.TypeCtorDecl FieldTypeDecl = null;
- private Bpl.CtorType FieldType;
-
- [RepresentationFor("$Heap", "var $Heap: HeapType where IsGoodHeap($Heap);", true)]
+ [RepresentationFor("$Heap", "var $Heap: HeapType;", true)]
private Bpl.Variable HeapVariable = null;
-
- [RepresentationFor("Box2Int", "function Box2Int(box): int;")]
- private Bpl.Function Box2Int = null;
-
- [RepresentationFor("Box2Bool", "function Box2Bool(box): bool;")]
- private Bpl.Function Box2Bool = null;
-
- [RepresentationFor("Int2Box", "function Int2Box(int): box;")]
- private Bpl.Function Int2Box = null;
-
- [RepresentationFor("Bool2Box", "function Bool2Box(bool): box;")]
- private Bpl.Function Bool2Box = null;
-
- [RepresentationFor("Read", "function {:inline true} Read(H:HeapType, o:ref, f:Field): box { H[o, f] }")]
+
+ [RepresentationFor("Read", "function {:inline true} Read(H:HeapType, o:Ref, f:Field): Box { H[o, f] }")]
private Bpl.Function Read = null;
- [RepresentationFor("Write", "function {:inline true} Write(H:HeapType, o:ref, f:Field, v:box): HeapType { H[o,f := v] }")]
+ [RepresentationFor("Write", "function {:inline true} Write(H:HeapType, o:Ref, f:Field, v:Box): HeapType { H[o,f := v] }")]
private Bpl.Function Write = null;
/// <summary>
/// Prelude text for which access to the ASTs is not needed
/// </summary>
private readonly string InitialPreludeText =
- @"const null: ref;
-type box;
-type ref = int;
-type HeapType = [ref,Field]box;
-function IsGoodHeap(HeapType): bool;
-var $ArrayContents: [int][int]int;
-var $ArrayLength: [int]int;
-
-var $Alloc: [ref] bool;
-procedure {:inline 1} Alloc() returns (x: ref)
- free ensures x != null;
+ @"type Struct = [Field]Box;
+type HeapType = [Ref,Field]Box;
+
+var $Alloc: [Ref] bool;
+procedure {:inline 1} Alloc() returns (x: Ref)
modifies $Alloc;
{
- assume $Alloc[x] == false;
+ assume $Alloc[x] == false && x != null;
$Alloc[x] := true;
}
+
+axiom (forall x : Field :: $DefaultStruct[x] == $DefaultBox);
+axiom Box2Int($DefaultBox) == 0;
+axiom Box2Bool($DefaultBox) == false;
+axiom Box2Ref($DefaultBox) == null;
+axiom Box2Struct($DefaultBox) == $DefaultStruct;
+
+axiom (forall x: int :: { Int2Box(x) } Box2Int(Int2Box(x)) == x );
+axiom (forall x: bool :: { Bool2Box(x) } Box2Bool(Bool2Box(x)) == x );
+axiom (forall x: Ref :: { Ref2Box(x) } Box2Ref(Ref2Box(x)) == x );
+axiom (forall x: Struct :: { Struct2Box(x) } Box2Struct(Struct2Box(x)) == x );
+
";
private Sink sink;
@@ -484,8 +204,11 @@ procedure {:inline 1} Alloc() returns (x: ref)
string prelude = this.InitialPreludeText + this.DelegateEncodingText;
var b = RepresentationFor.ParsePrelude(prelude, this, out program);
if (b) {
+ this.BoxType = new Bpl.CtorType(this.BoxTypeDecl.tok, this.BoxTypeDecl, new Bpl.TypeSeq());
this.FieldType = new Bpl.CtorType(this.FieldTypeDecl.tok, this.FieldTypeDecl, new Bpl.TypeSeq());
this.TypeType = new Bpl.CtorType(this.TypeTypeDecl.tok, this.TypeTypeDecl, new Bpl.TypeSeq());
+ this.RefType = new Bpl.CtorType(this.RefTypeDecl.tok, this.RefTypeDecl, new Bpl.TypeSeq());
+ this.RealType = new Bpl.CtorType(this.RealTypeDecl.tok, this.RealTypeDecl, new Bpl.TypeSeq());
}
return b;
}
@@ -501,7 +224,7 @@ procedure {:inline 1} Alloc() returns (x: ref)
Bpl.IToken tok = field.Token();
if (field.IsStatic) {
- Bpl.Type t = TranslationHelper.CciTypeToBoogie(field.Type.ResolvedType);
+ Bpl.Type t = this.sink.CciTypeToBoogie(field.Type.ResolvedType);
Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldname, t);
v = new Bpl.GlobalVariable(tok, tident);
}
@@ -510,10 +233,8 @@ procedure {:inline 1} Alloc() returns (x: ref)
Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldname, t);
v = new Bpl.Constant(tok, tident, true);
}
- this.underlyingTypes.Add(v, field.Type);
return v;
}
- private Dictionary<Bpl.Variable, ITypeReference> underlyingTypes = new Dictionary<Bpl.Variable, ITypeReference>();
public override Bpl.Variable CreateEventVariable(IEventDefinition e) {
Bpl.Variable v;
@@ -521,7 +242,7 @@ procedure {:inline 1} Alloc() returns (x: ref)
Bpl.IToken tok = e.Token();
if (e.Adder.ResolvedMethod.IsStatic) {
- Bpl.Type t = TranslationHelper.CciTypeToBoogie(e.Type.ResolvedType);
+ Bpl.Type t = this.sink.CciTypeToBoogie(e.Type.ResolvedType);
Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldname, t);
v = new Bpl.GlobalVariable(tok, tident);
}
@@ -530,84 +251,57 @@ procedure {:inline 1} Alloc() returns (x: ref)
Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldname, t);
v = new Bpl.Constant(tok, tident, true);
}
- this.underlyingTypes.Add(v, e.Type);
return v;
}
/// <summary>
/// Returns the (typed) BPL expression that corresponds to the value of the field
- /// <paramref name="f"/> belonging to the object <paramref name="o"/> (when
- /// <paramref name="o"/> is non-null, otherwise the value of the static field.
+ /// <paramref name="f"/> belonging to the object <paramref name="o"/> (which must be non-null).
/// </summary>
/// <param name="o">The expression that represents the object to be dereferenced.
- /// Null if <paramref name="f"/> is a static field.
/// </param>
- /// <param name="f">The field that is used to dereference the object <paramref name="o"/>, when
- /// it is not null. Otherwise the static field whose value should be read.
+ /// <param name="f">The field that is used to dereference the object <paramref name="o"/>.
/// </param>
- public override Bpl.Expr ReadHeap(Bpl.Expr/*?*/ o, Bpl.IdentifierExpr f) {
- // $Read($Heap, o, f)
- var callRead = new Bpl.NAryExpr(
- f.tok,
- new Bpl.FunctionCall(this.Read),
- new Bpl.ExprSeq(new Bpl.IdentifierExpr(f.tok, this.HeapVariable), o, f)
- );
- // wrap it in the right conversion function
- Bpl.Function conversion;
- var originalType = this.underlyingTypes[f.Decl];
- var boogieType = TranslationHelper.CciTypeToBoogie(originalType);
- if (boogieType == Bpl.Type.Bool)
- conversion = this.Box2Bool;
- else if (boogieType == Bpl.Type.Int)
- conversion = this.Box2Int;
+ public override Bpl.Expr ReadHeap(Bpl.Expr/*?*/ o, Bpl.Expr f, AccessType accessType, Bpl.Type unboxType) {
+ Debug.Assert(o != null);
+
+ Bpl.NAryExpr callRead;
+ if (accessType == AccessType.Struct)
+ callRead = Bpl.Expr.Select(o, f);
+ else if (accessType == AccessType.Heap)
+ callRead = new Bpl.NAryExpr(f.tok, new Bpl.FunctionCall(this.Read), new Bpl.ExprSeq(new Bpl.IdentifierExpr(f.tok, this.HeapVariable), o, f));
else
- throw new InvalidOperationException("Unknown Boogie type");
- var callExpr = new Bpl.NAryExpr(
- f.tok,
- new Bpl.FunctionCall(conversion),
- new Bpl.ExprSeq(callRead)
- );
- callExpr.Type = boogieType;
- return callExpr;
+ callRead = Bpl.Expr.Select(Bpl.Expr.Select(Bpl.Expr.Ident(ArrayContentsVariable), o), f);
+ // wrap it in the right conversion function
+ var callExpr = Unbox(f.tok, unboxType, callRead);
+ return callExpr;
}
/// <summary>
/// Returns the BPL command that corresponds to assigning the value <paramref name="value"/>
- /// to the field <paramref name="f"/> of the object <paramref name="o"/> (when
- /// <paramref name="o"/> is non-null, otherwise it is an assignment to the static
- /// field.
+ /// to the field <paramref name="f"/> of the object <paramref name="o"/> (which should be non-null).
/// </summary>
- public override Bpl.Cmd WriteHeap(Bpl.IToken tok, Bpl.Expr/*?*/ o, Bpl.IdentifierExpr f, Bpl.Expr value) {
- if (o == null) {
- return Bpl.Cmd.SimpleAssign(tok, f, value);
+ public override Bpl.Cmd WriteHeap(Bpl.IToken tok, Bpl.Expr/*?*/ o, Bpl.Expr f, Bpl.Expr value, AccessType accessType, Bpl.Type boxType) {
+ Debug.Assert(o != null);
+
+ Bpl.IdentifierExpr h;
+ Bpl.NAryExpr callWrite;
+ var callConversion = Box(f.tok, boxType, value);
+
+ if (accessType == AccessType.Struct) {
+ h = (Bpl.IdentifierExpr)o;
+ callWrite = Bpl.Expr.Store(h, f, callConversion);
+ }
+ else if (accessType == AccessType.Heap) {
+ h = Bpl.Expr.Ident(HeapVariable);
+ callWrite = new Bpl.NAryExpr(f.tok, new Bpl.FunctionCall(this.Write), new Bpl.ExprSeq(h, o, f, callConversion));
}
else {
- // wrap it in the right conversion function
- Bpl.Function conversion;
- var originalType = this.underlyingTypes[f.Decl];
- var boogieType = TranslationHelper.CciTypeToBoogie(originalType);
- if (boogieType == Bpl.Type.Bool)
- conversion = this.Bool2Box;
- else if (boogieType == Bpl.Type.Int)
- conversion = this.Int2Box;
- else
- throw new InvalidOperationException("Unknown Boogie type");
-
- var callConversion = new Bpl.NAryExpr(
- f.tok,
- new Bpl.FunctionCall(conversion),
- new Bpl.ExprSeq(value)
- );
- // $Write($Heap, o, f)
- var h = new Bpl.IdentifierExpr(f.tok, this.HeapVariable);
- var callWrite = new Bpl.NAryExpr(
- f.tok,
- new Bpl.FunctionCall(this.Write),
- new Bpl.ExprSeq(h, o, f, callConversion)
- );
- return Bpl.Cmd.SimpleAssign(f.tok, h, callWrite);
+ h = Bpl.Expr.Ident(ArrayContentsVariable);
+ callWrite = Bpl.Expr.Store(Bpl.Expr.Ident(ArrayContentsVariable), o, Bpl.Expr.Store(Bpl.Expr.Select(Bpl.Expr.Ident(ArrayContentsVariable), o), f, callConversion));
}
+ return Bpl.Cmd.SimpleAssign(f.tok, h, callWrite);
}
}
diff --git a/BCT/BytecodeTranslator/HeapFactory.cs b/BCT/BytecodeTranslator/HeapFactory.cs
index 464846d4..6d03ef9f 100644
--- a/BCT/BytecodeTranslator/HeapFactory.cs
+++ b/BCT/BytecodeTranslator/HeapFactory.cs
@@ -40,24 +40,19 @@ namespace BytecodeTranslator {
/// <summary>
/// Returns the (typed) BPL expression that corresponds to the value of the field
- /// <paramref name="f"/> belonging to the object <paramref name="o"/> (when
- /// <paramref name="o"/> is non-null, otherwise the value of the static field.
+ /// <paramref name="f"/> belonging to the object <paramref name="o"/> (which should be non-null).
/// </summary>
/// <param name="o">The expression that represents the object to be dereferenced.
- /// Null if <paramref name="f"/> is a static field.
/// </param>
- /// <param name="f">The field that is used to dereference the object <paramref name="o"/>, when
- /// it is not null. Otherwise the static field whose value should be read.
+ /// <param name="f">The field that is used to dereference the object <paramref name="o"/>.
/// </param>
- Bpl.Expr ReadHeap(Bpl.Expr/*?*/ o, Bpl.IdentifierExpr f);
+ Bpl.Expr ReadHeap(Bpl.Expr/*?*/ o, Bpl.Expr f, AccessType accessType, Bpl.Type unboxType);
/// <summary>
/// Returns the BPL command that corresponds to assigning the value <paramref name="value"/>
- /// to the field <paramref name="f"/> of the object <paramref name="o"/> (when
- /// <paramref name="o"/> is non-null, otherwise it is an assignment to the static
- /// field.
+ /// to the field <paramref name="f"/> of the object <paramref name="o"/> (which should be non-null).
/// </summary>
- Bpl.Cmd WriteHeap(Bpl.IToken tok, Bpl.Expr/*?*/ o, Bpl.IdentifierExpr f, Bpl.Expr value);
+ Bpl.Cmd WriteHeap(Bpl.IToken tok, Bpl.Expr/*?*/ o, Bpl.Expr f, Bpl.Expr value, AccessType accessType, Bpl.Type boxType);
/// <summary>
/// Returns the BPL expression that corresponds to the value of the dynamic type
@@ -66,15 +61,170 @@ namespace BytecodeTranslator {
Bpl.Expr DynamicType(Bpl.Expr o);
}
+
+ public enum AccessType { Array, Heap, Struct };
public abstract class Heap : HeapFactory, IHeap
{
+ [RepresentationFor("$ArrayContents", "var $ArrayContents: [Ref][int]Box;")]
+ public Bpl.Variable ArrayContentsVariable = null;
+ [RepresentationFor("$ArrayLength", "var $ArrayLength: [Ref]int;")]
+ public Bpl.Variable ArrayLengthVariable = null;
+
public abstract Bpl.Variable CreateFieldVariable(IFieldReference field);
+ #region Boogie Types
+
+ [RepresentationFor("Field", "type Field;")]
+ public Bpl.TypeCtorDecl FieldTypeDecl = null;
+ public Bpl.CtorType FieldType;
+
+ [RepresentationFor("Box", "type Box;")]
+ public Bpl.TypeCtorDecl BoxTypeDecl = null;
+ public Bpl.CtorType BoxType;
+
+ [RepresentationFor("$DefaultBox", "const unique $DefaultBox : Box;")]
+ public Bpl.Constant DefaultBox;
+
+ [RepresentationFor("Ref", "type Ref;")]
+ public Bpl.TypeCtorDecl RefTypeDecl = null;
+ public Bpl.CtorType RefType;
+ [RepresentationFor("null", "const unique null : Ref;")]
+ public Bpl.Constant NullRef;
+
[RepresentationFor("Type", "type Type;")]
protected Bpl.TypeCtorDecl TypeTypeDecl = null;
protected Bpl.CtorType TypeType;
-
+
+ private Bpl.Type structType = null;
+ public Bpl.Type StructType {
+ get {
+ if (structType == null) {
+ structType = new Bpl.MapType(Bpl.Token.NoToken, new Bpl.TypeVariableSeq(), new Bpl.TypeSeq(FieldType), BoxType);
+ }
+ return structType;
+ }
+ }
+ [RepresentationFor("$DefaultStruct", "const unique $DefaultStruct : Struct;")]
+ public Bpl.Constant DefaultStruct;
+
+ [RepresentationFor("Real", "type Real;")]
+ protected Bpl.TypeCtorDecl RealTypeDecl = null;
+ public Bpl.CtorType RealType;
+
+ #endregion
+
+ #region Conversions
+
+ #region Heap values
+
+ [RepresentationFor("Box2Int", "function Box2Int(Box): int;")]
+ public Bpl.Function Box2Int = null;
+
+ [RepresentationFor("Box2Bool", "function Box2Bool(Box): bool;")]
+ public Bpl.Function Box2Bool = null;
+
+ [RepresentationFor("Box2Struct", "function Box2Struct(Box): Struct;")]
+ public Bpl.Function Box2Struct = null;
+
+ [RepresentationFor("Box2Ref", "function Box2Ref(Box): Ref;")]
+ public Bpl.Function Box2Ref = null;
+
+ [RepresentationFor("Box2Real", "function Box2Real(Box): Real;")]
+ public Bpl.Function Box2Real = null;
+
+ [RepresentationFor("Int2Box", "function Int2Box(int): Box;")]
+ public Bpl.Function Int2Box = null;
+
+ [RepresentationFor("Bool2Box", "function Bool2Box(bool): Box;")]
+ public Bpl.Function Bool2Box = null;
+
+ [RepresentationFor("Struct2Box", "function Struct2Box(Struct): Box;")]
+ public Bpl.Function Struct2Box = null;
+
+ [RepresentationFor("Ref2Box", "function Ref2Box(Ref): Box;")]
+ public Bpl.Function Ref2Box = null;
+
+ [RepresentationFor("Real2Box", "function Real2Box(Real): Box;")]
+ public Bpl.Function Real2Box = null;
+
+ [RepresentationFor("Box2Box", "function {:inline true} Box2Box(b: Box): Box { b }")]
+ public Bpl.Function Box2Box = null;
+
+ public Bpl.Expr Box(Bpl.IToken tok, Bpl.Type boogieType, Bpl.Expr expr) {
+ Bpl.Function conversion;
+ if (boogieType == Bpl.Type.Bool)
+ conversion = this.Bool2Box;
+ else if (boogieType == Bpl.Type.Int)
+ conversion = this.Int2Box;
+ else if (boogieType == StructType)
+ conversion = this.Struct2Box;
+ else if (boogieType == RefType)
+ conversion = this.Ref2Box;
+ else if (boogieType == RealType)
+ conversion = this.Real2Box;
+ else if (boogieType == BoxType)
+ conversion = this.Box2Box;
+ else
+ throw new InvalidOperationException(String.Format("Unknown Boogie type: '{0}'", boogieType.ToString()));
+
+ var callConversion = new Bpl.NAryExpr(
+ tok,
+ new Bpl.FunctionCall(conversion),
+ new Bpl.ExprSeq(expr)
+ );
+ return callConversion;
+ }
+
+ public Bpl.Expr Unbox(Bpl.IToken tok, Bpl.Type boogieType, Bpl.Expr expr) {
+ Bpl.Function conversion = null;
+ if (boogieType == Bpl.Type.Bool)
+ conversion = this.Box2Bool;
+ else if (boogieType == Bpl.Type.Int)
+ conversion = this.Box2Int;
+ else if (boogieType == StructType)
+ conversion = this.Box2Struct;
+ else if (boogieType == RefType)
+ conversion = this.Box2Ref;
+ else if (boogieType == RealType)
+ conversion = this.Box2Real;
+ else if (boogieType == BoxType)
+ conversion = this.Box2Box;
+ else
+ throw new InvalidOperationException(String.Format("Unknown Boogie type: '{0}'", boogieType.ToString()));
+
+ var callExpr = new Bpl.NAryExpr(
+ tok,
+ new Bpl.FunctionCall(conversion),
+ new Bpl.ExprSeq(expr)
+ );
+ callExpr.Type = boogieType;
+ return callExpr;
+ }
+
+ #endregion
+
+ #region "Boxing" as done in the CLR
+ /// <summary>
+ /// Used to represent "boxing" as it is done in the CLR.
+ /// </summary>
+ [RepresentationFor("Struct2Ref", "function Struct2Ref(Struct): Ref;")]
+ public Bpl.Function Struct2Ref = null;
+ [RepresentationFor("Int2Ref", "function Int2Ref(int): Ref;")]
+ public Bpl.Function Int2Ref = null;
+ [RepresentationFor("Bool2Ref", "function Bool2Ref(bool): Ref;")]
+ public Bpl.Function Bool2Ref = null;
+ #endregion
+
+ #region Real number conversions
+ [RepresentationFor("Int2Real", "function Int2Real(int, Type, Type): Real;")]
+ public Bpl.Function Int2Real = null;
+ [RepresentationFor("Real2Int", "function Real2Int(Real, Type, Type): Real;")]
+ public Bpl.Function Real2Int = null;
+ #endregion
+
+ #endregion
+
/// <summary>
/// Creates a fresh BPL variable to represent <paramref name="type"/>, deciding
/// on its type based on the heap representation. I.e., the value of this
@@ -95,11 +245,11 @@ namespace BytecodeTranslator {
public abstract Bpl.Variable CreateEventVariable(IEventDefinition e);
- public abstract Bpl.Expr ReadHeap(Bpl.Expr o, Bpl.IdentifierExpr f);
+ public abstract Bpl.Expr ReadHeap(Bpl.Expr o, Bpl.Expr f, AccessType accessType, Bpl.Type unboxType);
- public abstract Bpl.Cmd WriteHeap(Bpl.IToken tok, Bpl.Expr o, Bpl.IdentifierExpr f, Bpl.Expr value);
+ public abstract Bpl.Cmd WriteHeap(Bpl.IToken tok, Bpl.Expr o, Bpl.Expr f, Bpl.Expr value, AccessType accessType, Bpl.Type boxType);
- [RepresentationFor("$DynamicType", "function $DynamicType(ref): Type;")]
+ [RepresentationFor("$DynamicType", "function $DynamicType(Ref): Type;")]
protected Bpl.Function DynamicTypeFunction = null;
/// <summary>
@@ -116,19 +266,22 @@ namespace BytecodeTranslator {
return callDynamicType;
}
- [RepresentationFor("$TypeOf", "function $TypeOf(Type): ref;")]
+ [RepresentationFor("$TypeOf", "function $TypeOf(Type): Ref;")]
public Bpl.Function TypeOfFunction = null;
+ [RepresentationFor("$As", "function $As(Ref, Type): Ref;")]
+ public Bpl.Function AsFunction = null;
+
protected readonly string DelegateEncodingText =
- @"procedure DelegateAdd(a: int, b: int) returns (c: int)
+ @"procedure DelegateAdd(a: Ref, b: Ref) returns (c: Ref)
{
var m: int;
- var o: int;
+ var o: Ref;
- if (a == 0) {
+ if (a == null) {
c := b;
return;
- } else if (b == 0) {
+ } else if (b == null) {
c := a;
return;
}
@@ -143,15 +296,15 @@ namespace BytecodeTranslator {
call c := DelegateAddHelper(c, m, o);
}
-procedure DelegateRemove(a: int, b: int) returns (c: int)
+procedure DelegateRemove(a: Ref, b: Ref) returns (c: Ref)
{
var m: int;
- var o: int;
+ var o: Ref;
- if (a == 0) {
- c := 0;
+ if (a == null) {
+ c := null;
return;
- } else if (b == 0) {
+ } else if (b == null) {
c := a;
return;
}
@@ -166,20 +319,20 @@ procedure DelegateRemove(a: int, b: int) returns (c: int)
call c := DelegateRemoveHelper(c, m, o);
}
-procedure GetFirstElement(i: int) returns (m: int, o: int)
+procedure GetFirstElement(i: Ref) returns (m: int, o: Ref)
{
- var first: int;
+ var first: Ref;
first := $Next[i][$Head[i]];
m := $Method[i][first];
o := $Receiver[i][first];
}
-procedure DelegateAddHelper(oldi: int, m: int, o: int) returns (i: int)
+procedure DelegateAddHelper(oldi: Ref, m: int, o: Ref) returns (i: Ref)
{
- var x: int;
- var h: int;
+ var x: Ref;
+ var h: Ref;
- if (oldi == 0) {
+ if (oldi == null) {
call i := Alloc();
call x := Alloc();
$Head[i] := x;
@@ -198,18 +351,18 @@ procedure DelegateAddHelper(oldi: int, m: int, o: int) returns (i: int)
$Head[i] := x;
}
-procedure DelegateRemoveHelper(oldi: int, m: int, o: int) returns (i: int)
+procedure DelegateRemoveHelper(oldi: Ref, m: int, o: Ref) returns (i: Ref)
{
- var prev: int;
- var iter: int;
- var niter: int;
+ var prev: Ref;
+ var iter: Ref;
+ var niter: Ref;
i := oldi;
- if (i == 0) {
+ if (i == null) {
return;
}
- prev := 0;
+ prev := null;
iter := $Head[i];
while (true) {
niter := $Next[i][iter];
@@ -221,28 +374,28 @@ procedure DelegateRemoveHelper(oldi: int, m: int, o: int) returns (i: int)
}
iter := niter;
}
- if (prev == 0) {
+ if (prev == null) {
return;
}
$Next[i] := $Next[i][prev := $Next[i][$Next[i][prev]]];
if ($Next[i][$Head[i]] == $Head[i]) {
- i := 0;
+ i := null;
}
}
";
- [RepresentationFor("$Head", "var $Head: [int]int;")]
+ [RepresentationFor("$Head", "var $Head: [Ref]Ref;")]
public Bpl.GlobalVariable DelegateHead = null;
- [RepresentationFor("$Next", "var $Next: [int][int]int;")]
+ [RepresentationFor("$Next", "var $Next: [Ref][Ref]Ref;")]
public Bpl.GlobalVariable DelegateNext = null;
- [RepresentationFor("$Method", "var $Method: [int][int]int;")]
+ [RepresentationFor("$Method", "var $Method: [Ref][Ref]int;")]
public Bpl.GlobalVariable DelegateMethod = null;
- [RepresentationFor("$Receiver", "var $Receiver: [int][int]int;")]
+ [RepresentationFor("$Receiver", "var $Receiver: [Ref][Ref]Ref;")]
public Bpl.GlobalVariable DelegateReceiver = null;
}
diff --git a/BCT/BytecodeTranslator/MetadataTraverser.cs b/BCT/BytecodeTranslator/MetadataTraverser.cs
index 2a984cfb..58bec27f 100644
--- a/BCT/BytecodeTranslator/MetadataTraverser.cs
+++ b/BCT/BytecodeTranslator/MetadataTraverser.cs
@@ -72,7 +72,9 @@ namespace BytecodeTranslator {
} else if (typeDefinition.IsEnum) {
return; // enums just are translated as ints
} else if (typeDefinition.IsStruct) {
- Console.WriteLine("Skipping definition of '" + TypeHelper.GetTypeName(typeDefinition) + "' because it is a struct!");
+ sink.FindOrCreateType(typeDefinition);
+ //CreateDefaultStructConstructor(typeDefinition);
+ base.Visit(typeDefinition);
} else {
Console.WriteLine("Unknown kind of type definition '{0}' was found",
TypeHelper.GetTypeName(typeDefinition));
@@ -80,6 +82,39 @@ namespace BytecodeTranslator {
}
}
+ private void CreateDefaultStructConstructor(ITypeDefinition typeDefinition) {
+ Contract.Requires(typeDefinition.IsStruct);
+
+ var proc = this.sink.FindOrCreateProcedureForDefaultStructCtor(typeDefinition);
+
+ var stmtBuilder = new Bpl.StmtListBuilder();
+
+ foreach (var f in typeDefinition.Fields) {
+ var e = this.sink.DefaultValue(f.Type);
+ var fExp = Bpl.Expr.Ident(this.sink.FindOrCreateFieldVariable(f));
+ var o = Bpl.Expr.Ident(proc.OutParams[0]);
+ var boogieType = sink.CciTypeToBoogie(f.Type);
+ var c = this.sink.Heap.WriteHeap(Bpl.Token.NoToken, o, fExp, e, AccessType.Struct, boogieType);
+ stmtBuilder.Add(c);
+ }
+
+ var attrib = new Bpl.QKeyValue(typeDefinition.Token(), "inline", new List<object>(1), null); // TODO: Need to have it be {:inine 1} (and not just {:inline})?
+ Bpl.Implementation impl =
+ new Bpl.Implementation(Bpl.Token.NoToken,
+ proc.Name,
+ new Bpl.TypeVariableSeq(),
+ proc.InParams,
+ proc.OutParams,
+ new Bpl.VariableSeq(),
+ stmtBuilder.Collect(Bpl.Token.NoToken),
+ attrib,
+ new Bpl.Errors()
+ );
+
+ impl.Proc = (Bpl.Procedure) proc; // TODO: get rid of cast
+ this.sink.TranslatedProgram.TopLevelDeclarations.Add(impl);
+ }
+
private bool sawCctor = false;
private void CreateStaticConstructor(ITypeDefinition typeDefinition) {
@@ -100,18 +135,7 @@ namespace BytecodeTranslator {
foreach (var f in typeDefinition.Fields) {
if (f.IsStatic) {
- Bpl.Expr e;
- var bplType = TranslationHelper.CciTypeToBoogie(f.Type);
- if (bplType == Bpl.Type.Int) {
- e = Bpl.Expr.Literal(0);
- e.Type = Bpl.Type.Int;
- } else if (bplType == Bpl.Type.Bool) {
- e = Bpl.Expr.False;
- e.Type = Bpl.Type.Bool;
- } else {
- throw new NotImplementedException("Don't know how to translate type");
- }
-
+ var e = this.sink.DefaultValue(f.Type);
stmtBuilder.Add(
TranslationHelper.BuildAssignCmd(
Bpl.Expr.Ident(this.sink.FindOrCreateFieldVariable(f)),
@@ -146,7 +170,6 @@ namespace BytecodeTranslator {
if (isEventAddOrRemove)
return;
- this.sink.BeginMethod();
Sink.ProcedureInfo procAndFormalMap;
IMethodDefinition stubMethod = null;
@@ -160,6 +183,7 @@ namespace BytecodeTranslator {
return;
}
+ this.sink.BeginMethod();
var decl = procAndFormalMap.Decl;
var proc = decl as Bpl.Procedure;
var formalMap = procAndFormalMap.FormalMap;
@@ -180,6 +204,13 @@ namespace BytecodeTranslator {
}
}
+ if (!method.IsStatic && method.ContainingType.ResolvedType.IsStruct) {
+ Bpl.IToken tok = method.Token();
+ stmtTraverser.StmtBuilder.Add(Bpl.Cmd.SimpleAssign(tok,
+ new Bpl.IdentifierExpr(tok, proc.OutParams[0]),
+ new Bpl.IdentifierExpr(tok, proc.InParams[0])));
+ }
+
#endregion
#region For non-deferring ctors and all cctors, initialize all fields to null-equivalent values
@@ -189,44 +220,6 @@ namespace BytecodeTranslator {
}
#endregion
- try {
- method.Body.Dispatch(stmtTraverser);
- } catch (TranslationException te) {
- throw new NotImplementedException("No Errorhandling in Methodvisitor / " + te.ToString());
- } catch {
- throw;
- }
-
- #region Create Local Vars For Implementation
- List<Bpl.Variable> vars = new List<Bpl.Variable>();
- foreach (MethodParameter mparam in formalMap.Values) {
- if (!(mparam.underlyingParameter.IsByReference || mparam.underlyingParameter.IsOut))
- vars.Add(mparam.outParameterCopy);
- }
- foreach (Bpl.Variable v in this.sink.LocalVarMap.Values) {
- vars.Add(v);
- }
-
- Bpl.VariableSeq vseq = new Bpl.VariableSeq(vars.ToArray());
- #endregion
-
- if (proc != null) {
- Bpl.Implementation impl =
- new Bpl.Implementation(method.Token(),
- decl.Name,
- new Microsoft.Boogie.TypeVariableSeq(),
- decl.InParams,
- decl.OutParams,
- vseq,
- stmtTraverser.StmtBuilder.Collect(Bpl.Token.NoToken));
-
- impl.Proc = proc;
- this.sink.TranslatedProgram.TopLevelDeclarations.Add(impl);
- } else { // method is translated as a function
- //Bpl.Function func = decl as Bpl.Function;
- //func.Body = new Bpl.CodeExpr(new Bpl.VariableSeq(), new List<Bpl.Block>{ new Bpl.Block(
- }
-
#region Translate method attributes
// Don't need an expression translator because there is a limited set of things
// that can appear as arguments to custom attributes
@@ -262,13 +255,51 @@ namespace BytecodeTranslator {
}
#endregion
+ #region Translate body
+ method.Body.Dispatch(stmtTraverser);
+ #endregion
+
+ #region Create Local Vars For Implementation
+ List<Bpl.Variable> vars = new List<Bpl.Variable>();
+ foreach (MethodParameter mparam in formalMap.Values) {
+ if (!mparam.underlyingParameter.IsByReference)
+ vars.Add(mparam.outParameterCopy);
+ }
+ foreach (Bpl.Variable v in this.sink.LocalVarMap.Values) {
+ vars.Add(v);
+ }
+
+ Bpl.VariableSeq vseq = new Bpl.VariableSeq(vars.ToArray());
+ #endregion
+
+ #region Add implementation to Boogie program
+ if (proc != null) {
+ Bpl.Implementation impl =
+ new Bpl.Implementation(method.Token(),
+ decl.Name,
+ new Microsoft.Boogie.TypeVariableSeq(),
+ decl.InParams,
+ decl.OutParams,
+ vseq,
+ stmtTraverser.StmtBuilder.Collect(Bpl.Token.NoToken));
+
+ impl.Proc = proc;
+ this.sink.TranslatedProgram.TopLevelDeclarations.Add(impl);
+ } else { // method is translated as a function
+ //Bpl.Function func = decl as Bpl.Function;
+ //func.Body = new Bpl.CodeExpr(new Bpl.VariableSeq(), new List<Bpl.Block>{ new Bpl.Block(
+ }
+ #endregion
} catch (TranslationException te) {
- throw new NotImplementedException(te.ToString());
- } catch {
- throw;
+ Console.WriteLine("Translation error in body of '{0}'.",
+ MemberHelper.GetMethodSignature(method, NameFormattingOptions.None));
+ Console.WriteLine("\t" + te.Message);
+ } catch (Exception e) {
+ Console.WriteLine("Unknown error in body of '{0}'.",
+ MemberHelper.GetMethodSignature(method, NameFormattingOptions.None));
+ Console.WriteLine("\t" + e.Message);
} finally {
- // Maybe this is a good place to add the procedure to the toplevel declarations
}
}
@@ -282,7 +313,7 @@ namespace BytecodeTranslator {
foreach (var f in method.ContainingTypeDefinition.Fields) {
if (f.IsStatic == method.IsStatic) {
var a = new Assignment() {
- Source = new DefaultValue() { Type = f.Type, },
+ Source = new DefaultValue() { DefaultValueType = f.Type, Type = f.Type, },
Target = new TargetExpression() { Definition = f, Instance = method.IsConstructor ? thisExp : null, Type = f.Type },
Type = f.Type,
};
diff --git a/BCT/BytecodeTranslator/Program.cs b/BCT/BytecodeTranslator/Program.cs
index 68107f82..f42c34d9 100644
--- a/BCT/BytecodeTranslator/Program.cs
+++ b/BCT/BytecodeTranslator/Program.cs
@@ -73,12 +73,6 @@ namespace BytecodeTranslator {
case Options.HeapRepresentation.splitFields:
heap = new SplitFieldsHeap();
break;
- case Options.HeapRepresentation.twoDInt:
- heap = new TwoDIntHeap();
- break;
- case Options.HeapRepresentation.twoDBox:
- heap = new TwoDBoxHeap();
- break;
case Options.HeapRepresentation.general:
heap = new GeneralHeap();
break;
@@ -90,8 +84,8 @@ namespace BytecodeTranslator {
result = TranslateAssembly(assemblyNames, heap, options.libpaths, options.wholeProgram, options.stubAssemblies);
} catch (Exception e) { // swallow everything and just return an error code
- Console.WriteLine("The byte-code translator failed with uncaught exception: {0}", e.Message);
- Console.WriteLine("Stack trace: {0}", e.StackTrace);
+ Console.WriteLine("The byte-code translator failed: {0}", e.Message);
+ //Console.WriteLine("Stack trace: {0}", e.StackTrace);
return -1;
}
return result;
@@ -243,7 +237,7 @@ namespace BytecodeTranslator {
Bpl.IToken token = invokeMethod.Token();
Bpl.Formal method = new Bpl.Formal(token, new Bpl.TypedIdent(token, "method", Bpl.Type.Int), true);
- Bpl.Formal receiver = new Bpl.Formal(token, new Bpl.TypedIdent(token, "receiver", Bpl.Type.Int), true);
+ Bpl.Formal receiver = new Bpl.Formal(token, new Bpl.TypedIdent(token, "receiver", sink.Heap.RefType), true);
Bpl.VariableSeq dispatchProcInvars = new Bpl.VariableSeq();
dispatchProcInvars.Add(method);
@@ -301,8 +295,8 @@ namespace BytecodeTranslator {
dispatchImpl.Proc = dispatchProc;
sink.TranslatedProgram.TopLevelDeclarations.Add(dispatchImpl);
- Bpl.LocalVariable iter = new Bpl.LocalVariable(token, new Bpl.TypedIdent(token, "iter", Bpl.Type.Int));
- Bpl.LocalVariable niter = new Bpl.LocalVariable(token, new Bpl.TypedIdent(token, "niter", Bpl.Type.Int));
+ Bpl.LocalVariable iter = new Bpl.LocalVariable(token, new Bpl.TypedIdent(token, "iter", sink.Heap.RefType));
+ Bpl.LocalVariable niter = new Bpl.LocalVariable(token, new Bpl.TypedIdent(token, "niter", sink.Heap.RefType));
Bpl.StmtListBuilder implStmtBuilder = new Bpl.StmtListBuilder();
implStmtBuilder.Add(TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(iter), sink.ReadHead(Bpl.Expr.Ident(invars[0]))));
diff --git a/BCT/BytecodeTranslator/Sink.cs b/BCT/BytecodeTranslator/Sink.cs
index b33edf96..b8d8334d 100644
--- a/BCT/BytecodeTranslator/Sink.cs
+++ b/BCT/BytecodeTranslator/Sink.cs
@@ -52,18 +52,6 @@ namespace BytecodeTranslator {
}
readonly Heap heap;
- public Bpl.Variable ArrayContentsVariable
- {
- get { return this.arrayContentsVariable; }
- }
- readonly Bpl.Variable arrayContentsVariable = TranslationHelper.TempArrayContentsVar();
-
- public Bpl.Variable ArrayLengthVariable
- {
- get { return this.arrayLengthVariable; }
- }
- readonly Bpl.Variable arrayLengthVariable = TranslationHelper.TempArrayLengthVar();
-
public Bpl.Variable ThisVariable = TranslationHelper.TempThisVar();
public Bpl.Variable RetVariable;
@@ -97,6 +85,45 @@ namespace BytecodeTranslator {
public readonly Bpl.Program TranslatedProgram;
+ public Bpl.Expr DefaultValue(ITypeReference type) {
+ var bplType = CciTypeToBoogie(type);
+ if (bplType == Bpl.Type.Int) {
+ var lit = Bpl.Expr.Literal(0);
+ lit.Type = Bpl.Type.Int;
+ return lit;
+ } else if (bplType == Bpl.Type.Bool) {
+ var lit = Bpl.Expr.False;
+ lit.Type = Bpl.Type.Bool;
+ return lit;
+ } else if (type.ResolvedType.IsStruct) {
+ return Bpl.Expr.Ident(this.Heap.DefaultStruct);
+ } else if (bplType == this.Heap.RefType) {
+ return Bpl.Expr.Ident(this.Heap.NullRef);
+ }
+ else if (bplType == this.Heap.BoxType) {
+ return Bpl.Expr.Ident(this.Heap.DefaultBox);
+ } else {
+ throw new NotImplementedException(String.Format("Don't know how to translate type: '{0}'", TypeHelper.GetTypeName(type)));
+ }
+ }
+
+ public Bpl.Type CciTypeToBoogie(ITypeReference type) {
+ if (TypeHelper.TypesAreEquivalent(type, type.PlatformType.SystemBoolean))
+ return Bpl.Type.Bool;
+ else if (TypeHelper.IsPrimitiveInteger(type))
+ return Bpl.Type.Int;
+ else if (type.TypeCode == PrimitiveTypeCode.Float32 || type.TypeCode == PrimitiveTypeCode.Float64)
+ return heap.RealType;
+ else if (type.ResolvedType.IsStruct)
+ return heap.StructType;
+ else if (type.IsEnum)
+ return Bpl.Type.Int; // The underlying type of an enum is always some kind of integer
+ else if (type is IGenericTypeParameter)
+ return heap.BoxType;
+ else
+ return heap.RefType;
+ }
+
/// <summary>
/// Creates a fresh local var of the given Type and adds it to the
/// Bpl Implementation
@@ -105,17 +132,30 @@ namespace BytecodeTranslator {
/// <returns> A fresh Variable with automatic generated name and location </returns>
public Bpl.Variable CreateFreshLocal(ITypeReference typeReference) {
Bpl.IToken loc = Bpl.Token.NoToken; // Helper Variables do not have a location
- Bpl.Type t = TranslationHelper.CciTypeToBoogie(typeReference);
+ Bpl.Type t = CciTypeToBoogie(typeReference);
+ Bpl.LocalVariable v = new Bpl.LocalVariable(loc, new Bpl.TypedIdent(loc, TranslationHelper.GenerateTempVarName(), t));
+ ILocalDefinition dummy = new LocalDefinition(); // Creates a dummy entry for the Dict, since only locals in the dict are translated to boogie
+ localVarMap.Add(dummy, v);
+ return v;
+ }
+
+ public Bpl.Variable CreateFreshLocal(Bpl.Type t) {
+ Bpl.IToken loc = Bpl.Token.NoToken; // Helper Variables do not have a location
Bpl.LocalVariable v = new Bpl.LocalVariable(loc, new Bpl.TypedIdent(loc, TranslationHelper.GenerateTempVarName(), t));
ILocalDefinition dummy = new LocalDefinition(); // Creates a dummy entry for the Dict, since only locals in the dict are translated to boogie
localVarMap.Add(dummy, v);
return v;
}
+ /// <summary>
+ /// State that gets re-initialized per method
+ /// </summary>
private Dictionary<ILocalDefinition, Bpl.LocalVariable> localVarMap = null;
public Dictionary<ILocalDefinition, Bpl.LocalVariable> LocalVarMap {
get { return this.localVarMap; }
}
+ private int localCounter;
+ public int LocalCounter { get { return this.localCounter++; } }
/// <summary>
///
@@ -125,7 +165,7 @@ namespace BytecodeTranslator {
public Bpl.Variable FindOrCreateLocalVariable(ILocalDefinition local) {
Bpl.LocalVariable v;
Bpl.IToken tok = local.Token();
- Bpl.Type t = TranslationHelper.CciTypeToBoogie(local.Type.ResolvedType);
+ Bpl.Type t = CciTypeToBoogie(local.Type.ResolvedType);
if (!localVarMap.TryGetValue(local, out v)) {
v = new Bpl.LocalVariable(tok, new Bpl.TypedIdent(tok, local.Name.Value, t));
localVarMap.Add(local, v);
@@ -164,6 +204,7 @@ namespace BytecodeTranslator {
}
return v;
}
+
/// <summary>
/// The keys to the table are the interned key of the field.
/// </summary>
@@ -174,9 +215,22 @@ namespace BytecodeTranslator {
Bpl.Variable v;
if (!this.declaredEvents.TryGetValue(e, out v))
{
- v = this.Heap.CreateEventVariable(e);
+ v = null;
+
+ // First, see if the compiler generated a field (which happens when the event did not explicitly
+ // define an adder and remover. If so, then just use the variable that corresponds to that field.
+ foreach (var f in e.ContainingTypeDefinition.Fields) {
+ if (e.Name == f.Name) {
+ v = this.FindOrCreateFieldVariable(f);
+ break;
+ }
+ }
+
+ if (v == null) {
+ v = this.Heap.CreateEventVariable(e);
+ this.TranslatedProgram.TopLevelDeclarations.Add(v);
+ }
this.declaredEvents.Add(e, v);
- this.TranslatedProgram.TopLevelDeclarations.Add(v);
}
return v;
}
@@ -192,8 +246,8 @@ namespace BytecodeTranslator {
Bpl.Constant c;
if (!this.declaredStringConstants.TryGetValue(str, out c)) {
var tok = Bpl.Token.NoToken;
- var t = Bpl.Type.Int;
- var name = "$string_literal_" + TranslationHelper.TurnStringIntoValidIdentifier(str);
+ var t = Heap.RefType;
+ var name = "$string_literal_" + TranslationHelper.TurnStringIntoValidIdentifier(str) + "_" + declaredStringConstants.Count;
var tident = new Bpl.TypedIdent(tok, name, t);
c = new Bpl.Constant(tok, tident, true);
this.declaredStringConstants.Add(str, c);
@@ -203,8 +257,63 @@ namespace BytecodeTranslator {
}
private Dictionary<string, Bpl.Constant> declaredStringConstants = new Dictionary<string, Bpl.Constant>();
+ public Bpl.Constant FindOrCreateConstant(double d) {
+ Bpl.Constant c;
+ var str = d.ToString();
+ if (!this.declaredRealConstants.TryGetValue(str, out c)) {
+ var tok = Bpl.Token.NoToken;
+ var t = Heap.RealType;
+ var name = "$real_literal_" + TranslationHelper.TurnStringIntoValidIdentifier(str) + "_" + declaredStringConstants.Count;
+ var tident = new Bpl.TypedIdent(tok, name, t);
+ c = new Bpl.Constant(tok, tident, true);
+ this.declaredRealConstants.Add(str, c);
+ this.TranslatedProgram.TopLevelDeclarations.Add(c);
+ }
+ return c;
+ }
+ private Dictionary<string, Bpl.Constant> declaredRealConstants = new Dictionary<string, Bpl.Constant>();
+
private Dictionary<IPropertyDefinition, Bpl.Variable> declaredProperties = new Dictionary<IPropertyDefinition, Bpl.Variable>();
+ private List<Bpl.Function> projectionFunctions = new List<Bpl.Function>();
+ private Dictionary<int, Bpl.Function> arityToNaryIntFunctions = new Dictionary<int, Bpl.Function>();
+ public Bpl.Function FindOrCreateNaryIntFunction(int arity) {
+ Bpl.Function f;
+ if (!this.arityToNaryIntFunctions.TryGetValue(arity, out f)) {
+ Bpl.VariableSeq vseq = new Bpl.VariableSeq();
+ for (int i = 0; i < arity; i++) {
+ vseq.Add(new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "arg" + i, Bpl.Type.Int), true));
+ }
+ f = new Bpl.Function(Bpl.Token.NoToken, "Int" + arity, vseq, new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "result", Bpl.Type.Int), false));
+ this.arityToNaryIntFunctions.Add(arity, f);
+ TranslatedProgram.TopLevelDeclarations.Add(f);
+ if (arity > projectionFunctions.Count) {
+ for (int i = projectionFunctions.Count; i < arity; i++) {
+ Bpl.Variable input = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "in", Bpl.Type.Int), true);
+ Bpl.Variable output = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "out", Bpl.Type.Int), false);
+ Bpl.Function g = new Bpl.Function(Bpl.Token.NoToken, "Proj" + i, new Bpl.VariableSeq(input), output);
+ TranslatedProgram.TopLevelDeclarations.Add(g);
+ projectionFunctions.Add(g);
+ }
+ }
+ Bpl.VariableSeq qvars = new Bpl.VariableSeq();
+ Bpl.ExprSeq exprs = new Bpl.ExprSeq();
+ for (int i = 0; i < arity; i++) {
+ Bpl.Variable v = new Bpl.Constant(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "arg" + i, Bpl.Type.Int));
+ qvars.Add(v);
+ exprs.Add(Bpl.Expr.Ident(v));
+ }
+ Bpl.Expr e = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(f), exprs);
+ for (int i = 0; i < arity; i++) {
+ Bpl.Expr appl = new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(projectionFunctions[i]), new Bpl.ExprSeq(e));
+ Bpl.Expr qexpr = new Bpl.ForallExpr(Bpl.Token.NoToken, new Bpl.TypeVariableSeq(), qvars, null, null, Bpl.Expr.Eq(appl, Bpl.Expr.Ident(qvars[i])));
+ TranslatedProgram.TopLevelDeclarations.Add(new Bpl.Axiom(Bpl.Token.NoToken, qexpr));
+ }
+
+ }
+ return f;
+ }
+
public struct ProcedureInfo {
private Bpl.DeclWithFormals decl;
private Dictionary<IParameterDefinition, MethodParameter> formalMap;
@@ -229,7 +338,6 @@ namespace BytecodeTranslator {
string MethodName = TranslationHelper.CreateUniqueMethodName(method);
- Bpl.Function f;
Bpl.Procedure p;
if (this.initiallyDeclaredProcedures.TryGetValue(MethodName, out p)) return p;
@@ -240,10 +348,9 @@ namespace BytecodeTranslator {
MethodParameter mp;
var formalMap = new Dictionary<IParameterDefinition, MethodParameter>();
foreach (IParameterDefinition formal in method.Parameters) {
-
- mp = new MethodParameter(formal);
+ mp = new MethodParameter(formal, this.CciTypeToBoogie(formal.Type));
if (mp.inParameterCopy != null) in_count++;
- if (mp.outParameterCopy != null && (formal.IsByReference || formal.IsOut))
+ if (mp.outParameterCopy != null && formal.IsByReference)
out_count++;
formalMap.Add(formal, mp);
}
@@ -253,7 +360,7 @@ namespace BytecodeTranslator {
Bpl.Variable savedRetVariable = this.RetVariable;
if (method.Type.TypeCode != PrimitiveTypeCode.Void) {
- Bpl.Type rettype = TranslationHelper.CciTypeToBoogie(method.Type);
+ Bpl.Type rettype = CciTypeToBoogie(method.Type);
out_count++;
this.RetVariable = new Bpl.Formal(method.Token(),
new Bpl.TypedIdent(method.Type.Token(),
@@ -265,13 +372,22 @@ namespace BytecodeTranslator {
#endregion
Bpl.Formal/*?*/ self = null;
+ Bpl.Formal selfOut = null;
#region Create 'this' parameter
if (!method.IsStatic) {
- in_count++;
- Bpl.Type selftype = Bpl.Type.Int;
- self = new Bpl.Formal(method.Token(),
- new Bpl.TypedIdent(method.Type.Token(),
- "this", selftype), true);
+ Bpl.Type selfType = CciTypeToBoogie(method.ContainingType);
+ if (method.ContainingType.ResolvedType.IsStruct) {
+ //selfType = Heap.StructType;
+ in_count++;
+ self = new Bpl.Formal(method.Token(), new Bpl.TypedIdent(method.Type.Token(), "thisIn", selfType), true);
+ out_count++;
+ selfOut = new Bpl.Formal(method.Token(), new Bpl.TypedIdent(method.Type.Token(), "this", selfType), false);
+ }
+ else {
+ in_count++;
+ //selfType = Heap.RefType;
+ self = new Bpl.Formal(method.Token(), new Bpl.TypedIdent(method.Type.Token(), "this", selfType), true);
+ }
}
#endregion
@@ -281,9 +397,11 @@ namespace BytecodeTranslator {
int i = 0;
int j = 0;
- #region Add 'this' parameter as first in parameter
- if (!method.IsStatic)
+ #region Add 'this' parameter as first in parameter and 'thisOut' parameter as first out parameter
+ if (self != null)
invars[i++] = self;
+ if (selfOut != null)
+ outvars[j++] = selfOut;
#endregion
foreach (MethodParameter mparam in formalMap.Values) {
@@ -291,7 +409,7 @@ namespace BytecodeTranslator {
invars[i++] = mparam.inParameterCopy;
}
if (mparam.outParameterCopy != null) {
- if (mparam.underlyingParameter.IsByReference || mparam.underlyingParameter.IsOut)
+ if (mparam.underlyingParameter.IsByReference)
outvars[j++] = mparam.outParameterCopy;
}
}
@@ -387,6 +505,40 @@ namespace BytecodeTranslator {
return procAndFormalMap.Decl;
}
+ /// <summary>
+ /// Struct "creation" (source code that looks like "new S()" for a struct type S) is modeled
+ /// by a call to the nullary "ctor" that initializes all of the structs fields to zero-
+ /// equivalent values. Note that the generated procedure has no contract. So if the struct
+ /// is defined in an assembly that is not being translated, then its behavior is unspecified.
+ /// </summary>
+ /// <param name="structType">A type reference to the value type for which the ctor should be returned.</param>
+ /// <returns>A nullary procedure that returns an initialized value of type <paramref name="structType"/>.</returns>
+ public Bpl.DeclWithFormals FindOrCreateProcedureForDefaultStructCtor(ITypeReference structType) {
+ Contract.Requires(structType.IsValueType);
+
+ ProcedureInfo procAndFormalMap;
+ var key = structType.InternedKey;
+ if (!this.declaredMethods.TryGetValue(key, out procAndFormalMap)) {
+ var typename = TranslationHelper.TurnStringIntoValidIdentifier(TypeHelper.GetTypeName(structType));
+ var tok = structType.Token();
+ var selfType = new Bpl.MapType(Bpl.Token.NoToken, new Bpl.TypeVariableSeq(), new Bpl.TypeSeq(Heap.FieldType), Heap.BoxType);
+ var selfOut = new Bpl.Formal(tok, new Bpl.TypedIdent(tok, "this", selfType), false);
+ var outvars = new Bpl.Formal[]{ selfOut };
+ var proc = new Bpl.Procedure(Bpl.Token.NoToken, typename + ".#default_ctor",
+ new Bpl.TypeVariableSeq(),
+ new Bpl.VariableSeq(), // in
+ new Bpl.VariableSeq(outvars),
+ new Bpl.RequiresSeq(),
+ new Bpl.IdentifierExprSeq(), // modifies
+ new Bpl.EnsuresSeq()
+ );
+ this.TranslatedProgram.TopLevelDeclarations.Add(proc);
+ procAndFormalMap = new ProcedureInfo(proc, new Dictionary<IParameterDefinition, MethodParameter>(), this.RetVariable);
+ this.declaredMethods.Add(key, procAndFormalMap);
+ }
+ return procAndFormalMap.Decl;
+ }
+
// TODO: Fix test to return true iff method is marked with the "real" [Pure] attribute
// also, should it return true for properties and all of the other things the tools
// consider pure?
@@ -423,7 +575,7 @@ namespace BytecodeTranslator {
this.FindOrCreateProcedure(method);
return this.declaredMethods[method.InternedKey];
}
- private static IMethodReference Unspecialize(IMethodReference method) {
+ public static IMethodReference Unspecialize(IMethodReference method) {
IMethodReference result = method;
var gmir = result as IGenericMethodInstanceReference;
if (gmir != null) {
@@ -479,6 +631,7 @@ namespace BytecodeTranslator {
public void BeginMethod() {
this.localVarMap = new Dictionary<ILocalDefinition, Bpl.LocalVariable>();
+ this.localCounter = 0;
}
public Dictionary<ITypeDefinition, HashSet<IMethodDefinition>> delegateTypeToDelegates = new Dictionary<ITypeDefinition, HashSet<IMethodDefinition>>();
@@ -496,7 +649,7 @@ namespace BytecodeTranslator {
}
private Dictionary<IMethodDefinition, Bpl.Constant> delegateMethods = new Dictionary<IMethodDefinition, Bpl.Constant>();
- private IContractAwareHost host;
+ internal IContractAwareHost host;
public Bpl.Constant FindOrAddDelegateMethodConstant(IMethodDefinition defn)
{
diff --git a/BCT/BytecodeTranslator/StatementTraverser.cs b/BCT/BytecodeTranslator/StatementTraverser.cs
index a062fca1..24b4b2ca 100644
--- a/BCT/BytecodeTranslator/StatementTraverser.cs
+++ b/BCT/BytecodeTranslator/StatementTraverser.cs
@@ -28,11 +28,9 @@ namespace BytecodeTranslator
public readonly PdbReader/*?*/ PdbReader;
- private readonly Bpl.Variable ArrayContentsVariable;
- private readonly Bpl.Variable ArrayLengthVariable;
-
public readonly Bpl.StmtListBuilder StmtBuilder = new Bpl.StmtListBuilder();
private bool contractContext;
+ internal readonly Stack<Bpl.Expr> operandStack = new Stack<Bpl.Expr>();
#region Constructors
public StatementTraverser(Sink sink, PdbReader/*?*/ pdbReader, bool contractContext) {
@@ -40,9 +38,6 @@ namespace BytecodeTranslator
this.factory = sink.Factory;
PdbReader = pdbReader;
this.contractContext = contractContext;
-
- ArrayContentsVariable = sink.ArrayContentsVariable;
- ArrayLengthVariable = sink.ArrayLengthVariable;
}
#endregion
@@ -164,6 +159,20 @@ namespace BytecodeTranslator
return;
}
+ public override void Visit(IPushStatement pushStatement) {
+ var tok = pushStatement.Token();
+ var val = pushStatement.ValueToPush;
+ var dup = val as IDupValue;
+ Bpl.Expr e;
+ if (dup != null) {
+ e = this.operandStack.Peek();
+ } else {
+ e = ExpressionFor(val);
+ }
+ this.operandStack.Push(e);
+ return;
+ }
+
/// <summary>
///
/// </summary>
diff --git a/BCT/BytecodeTranslator/TranslationException.cs b/BCT/BytecodeTranslator/TranslationException.cs
index 5aac98af..c62d78c5 100644
--- a/BCT/BytecodeTranslator/TranslationException.cs
+++ b/BCT/BytecodeTranslator/TranslationException.cs
@@ -9,12 +9,19 @@ using System.Linq;
using System.Text;
namespace BytecodeTranslator {
- class TranslationException : Exception {
-
- public TranslationException(string reason) {
+ public enum ExceptionType {
+ UnresolvedMethod,
+ UnresolvedType,
+ };
+
+ public class TranslationException : Exception {
+ public TranslationException(string reason) : base(reason) {
}
+ public TranslationException(ExceptionType eType, string message)
+ : base(eType.ToString() + ": " + message) {
+ }
}
}
diff --git a/BCT/BytecodeTranslator/TranslationHelper.cs b/BCT/BytecodeTranslator/TranslationHelper.cs
index f3b7aa58..54ed1700 100644
--- a/BCT/BytecodeTranslator/TranslationHelper.cs
+++ b/BCT/BytecodeTranslator/TranslationHelper.cs
@@ -36,25 +36,19 @@ namespace BytecodeTranslator {
public IParameterDefinition underlyingParameter;
- public MethodParameter(IParameterDefinition parameterDefinition) {
-
+ public MethodParameter(IParameterDefinition parameterDefinition, Bpl.Type ptype) {
this.underlyingParameter = parameterDefinition;
- Bpl.Type ptype = TranslationHelper.CciTypeToBoogie(parameterDefinition.Type);
-
var parameterToken = parameterDefinition.Token();
var typeToken = parameterDefinition.Type.Token();
var parameterName = parameterDefinition.Name.Value;
- if (!parameterDefinition.IsOut) {
- this.inParameterCopy = new Bpl.Formal(parameterToken, new Bpl.TypedIdent(typeToken, parameterName + "$in", ptype), true);
- }
- if (parameterDefinition.IsByReference || parameterDefinition.IsOut) {
+ this.inParameterCopy = new Bpl.Formal(parameterToken, new Bpl.TypedIdent(typeToken, parameterName + "$in", ptype), true);
+ if (parameterDefinition.IsByReference) {
this.outParameterCopy = new Bpl.Formal(parameterToken, new Bpl.TypedIdent(typeToken, parameterName + "$out", ptype), false);
} else {
this.outParameterCopy = new Bpl.LocalVariable(parameterToken, new Bpl.TypedIdent(typeToken, parameterName, ptype));
}
-
}
public override string ToString() {
@@ -90,20 +84,6 @@ namespace BytecodeTranslator {
public static string CreateUniqueMethodName(IMethodReference method) {
var containingTypeName = TypeHelper.GetTypeName(method.ContainingType, NameFormattingOptions.None);
- /*
- if (containingTypeName == "Poirot.Poirot")
- {
- string name = method.Name.Value;
- if (name == "BeginAtomic")
- return "corral_atomic_begin";
- else if (name == "EndAtomic")
- return "corral_atomic_end";
- else if (name == "CurrentThreadId")
- return "corral_getThreadID";
- else if (name == "Nondet_int" || name == "Nondet_string")
- return "poirot_nondet";
- }
- */
var s = MemberHelper.GetMethodSignature(method, NameFormattingOptions.DocumentationId);
s = s.Substring(2);
s = s.TrimEnd(')');
@@ -112,6 +92,12 @@ namespace BytecodeTranslator {
}
public static string TurnStringIntoValidIdentifier(string s) {
+ s = s.Replace("[0:,0:]", "2DArray"); // TODO: Do this programmatically to handle arbitrary arity
+ s = s.Replace("[0:,0:,0:]", "3DArray");
+ s = s.Replace("[0:,0:,0:,0:]", "4DArray");
+ s = s.Replace("[0:,0:,0:,0:,0:]", "5DArray");
+ s = s.Replace('!', '$');
+ s = s.Replace('*', '$');
s = s.Replace('(', '$');
s = s.Replace(')', '$');
s = s.Replace(',', '$');
@@ -130,32 +116,18 @@ namespace BytecodeTranslator {
s = s.Replace('\\', '$');
s = s.Replace('=', '$');
s = s.Replace('@', '$');
+ s = s.Replace(';', '$');
+ s = s.Replace('%', '$');
+ s = s.Replace('&', '$');
return s;
}
#region Temp Stuff that must be replaced as soon as there is real code to deal with this
- public static Bpl.Type CciTypeToBoogie(ITypeReference type) {
- if (TypeHelper.TypesAreEquivalent(type, type.PlatformType.SystemBoolean))
- return Bpl.Type.Bool;
- else if (TypeHelper.IsPrimitiveInteger(type))
- return Bpl.Type.Int;
- else
- return Bpl.Type.Int; // BUG! This is where we need to return "ref" for a reference type
- }
-
public static Bpl.Variable TempThisVar() {
return new Bpl.GlobalVariable(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "this", Bpl.Type.Int));
}
- public static Bpl.Variable TempArrayContentsVar()
- {
- return new Bpl.GlobalVariable(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "$ArrayContents", Bpl.Type.Int));
- }
- public static Bpl.Variable TempArrayLengthVar()
- {
- return new Bpl.GlobalVariable(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "$ArrayLength", Bpl.Type.Int));
- }
#endregion
}
diff --git a/BCT/BytecodeTranslator/WholeProgram.cs b/BCT/BytecodeTranslator/WholeProgram.cs
index f4cc59af..92154020 100644
--- a/BCT/BytecodeTranslator/WholeProgram.cs
+++ b/BCT/BytecodeTranslator/WholeProgram.cs
@@ -149,13 +149,11 @@ namespace BytecodeTranslator {
Bpl.IToken token = methodCall.Token();
- // TODO: if there is no stmttraverser we are visiting a contract and should use a boogie function instead of procedure!
-
#region Translate Out vars
var outvars = new List<Bpl.IdentifierExpr>();
foreach (KeyValuePair<IParameterDefinition, Bpl.Expr> kvp in p2eMap) {
- if (kvp.Key.IsOut || kvp.Key.IsByReference) {
+ if (kvp.Key.IsByReference) {
Bpl.IdentifierExpr iexp = kvp.Value as Bpl.IdentifierExpr;
if (iexp == null) {
throw new TranslationException("Trying to pass complex expression as out in functioncall");
diff --git a/BCT/RegressionTests/RegressionTestInput/Class1.cs b/BCT/RegressionTests/RegressionTestInput/Class1.cs
index f2918aa7..90fa7b50 100644
--- a/BCT/RegressionTests/RegressionTestInput/Class1.cs
+++ b/BCT/RegressionTests/RegressionTestInput/Class1.cs
@@ -130,4 +130,31 @@ namespace RegressionTestInput {
this.y = this.x;
}
}
+
+ public struct S {
+ public int x;
+ public bool b;
+ }
+
+ public class CreateStruct {
+ public S Create() {
+ var s = new S();
+ Contract.Assert(s.x == 0);
+ Contract.Assert(s.b == false);
+ return s;
+ }
+ S AssignThreeToSDotX(S s) {
+ s.x = 3;
+ Contract.Assert(s.x == 3);
+ return s;
+ }
+
+ }
+
+ public class RefParameters {
+ public static void M(ref int x) {
+ x++;
+ }
+ }
+
}
diff --git a/BCT/RegressionTests/TranslationTest/GeneralHeapInput.txt b/BCT/RegressionTests/TranslationTest/GeneralHeapInput.txt
index 703c908f..98d25303 100644
--- a/BCT/RegressionTests/TranslationTest/GeneralHeapInput.txt
+++ b/BCT/RegressionTests/TranslationTest/GeneralHeapInput.txt
@@ -1,29 +1,21 @@
// Copyright (c) 2010, Microsoft Corp.
// Bytecode Translator prelude
-const null: ref;
+type Struct = [Field]Box;
-type box;
-
-type ref = int;
-
-type HeapType = [ref,Field]box;
+type HeapType = [Ref,Field]Box;
function IsGoodHeap(HeapType) : bool;
-var $ArrayContents: [int][int]int;
-
-var $ArrayLength: [int]int;
-
-var $Alloc: [ref]bool;
+var $Alloc: [Ref]bool;
-procedure {:inline 1} Alloc() returns (x: ref);
+procedure {:inline 1} Alloc() returns (x: Ref);
modifies $Alloc;
free ensures x != null;
-implementation Alloc() returns (x: ref)
+implementation Alloc() returns (x: Ref)
{
assume $Alloc[x] == false;
$Alloc[x] := true;
@@ -31,21 +23,31 @@ implementation Alloc() returns (x: ref)
-procedure DelegateAdd(a: int, b: int) returns (c: int);
+axiom (forall x: Field :: $DefaultStruct[x] == $DefaultBox);
+
+axiom Box2Int($DefaultBox) == 0;
+
+axiom Box2Bool($DefaultBox) == false;
+
+axiom (forall x: int :: { Int2Box(x) } Box2Int(Int2Box(x)) == x);
+
+axiom (forall x: bool :: { Bool2Box(x) } Box2Bool(Bool2Box(x)) == x);
+procedure DelegateAdd(a: Ref, b: Ref) returns (c: Ref);
-implementation DelegateAdd(a: int, b: int) returns (c: int)
+
+implementation DelegateAdd(a: Ref, b: Ref) returns (c: Ref)
{
var m: int;
- var o: int;
+ var o: Ref;
- if (a == 0)
+ if (a == null)
{
c := b;
return;
}
- else if (b == 0)
+ else if (b == null)
{
c := a;
return;
@@ -62,21 +64,21 @@ implementation DelegateAdd(a: int, b: int) returns (c: int)
-procedure DelegateRemove(a: int, b: int) returns (c: int);
+procedure DelegateRemove(a: Ref, b: Ref) returns (c: Ref);
-implementation DelegateRemove(a: int, b: int) returns (c: int)
+implementation DelegateRemove(a: Ref, b: Ref) returns (c: Ref)
{
var m: int;
- var o: int;
+ var o: Ref;
- if (a == 0)
+ if (a == null)
{
- c := 0;
+ c := null;
return;
}
- else if (b == 0)
+ else if (b == null)
{
c := a;
return;
@@ -93,13 +95,13 @@ implementation DelegateRemove(a: int, b: int) returns (c: int)
-procedure GetFirstElement(i: int) returns (m: int, o: int);
+procedure GetFirstElement(i: Ref) returns (m: int, o: Ref);
-implementation GetFirstElement(i: int) returns (m: int, o: int)
+implementation GetFirstElement(i: Ref) returns (m: int, o: Ref)
{
- var first: int;
+ var first: Ref;
first := $Next[i][$Head[i]];
m := $Method[i][first];
@@ -108,16 +110,16 @@ implementation GetFirstElement(i: int) returns (m: int, o: int)
-procedure DelegateAddHelper(oldi: int, m: int, o: int) returns (i: int);
+procedure DelegateAddHelper(oldi: Ref, m: int, o: Ref) returns (i: Ref);
-implementation DelegateAddHelper(oldi: int, m: int, o: int) returns (i: int)
+implementation DelegateAddHelper(oldi: Ref, m: int, o: Ref) returns (i: Ref)
{
- var x: int;
- var h: int;
+ var x: Ref;
+ var h: Ref;
- if (oldi == 0)
+ if (oldi == null)
{
call i := Alloc();
call x := Alloc();
@@ -140,23 +142,23 @@ implementation DelegateAddHelper(oldi: int, m: int, o: int) returns (i: int)
-procedure DelegateRemoveHelper(oldi: int, m: int, o: int) returns (i: int);
+procedure DelegateRemoveHelper(oldi: Ref, m: int, o: Ref) returns (i: Ref);
-implementation DelegateRemoveHelper(oldi: int, m: int, o: int) returns (i: int)
+implementation DelegateRemoveHelper(oldi: Ref, m: int, o: Ref) returns (i: Ref)
{
- var prev: int;
- var iter: int;
- var niter: int;
+ var prev: Ref;
+ var iter: Ref;
+ var niter: Ref;
i := oldi;
- if (i == 0)
+ if (i == null)
{
return;
}
- prev := 0;
+ prev := null;
iter := $Head[i];
while (true)
{
@@ -174,7 +176,7 @@ implementation DelegateRemoveHelper(oldi: int, m: int, o: int) returns (i: int)
iter := niter;
}
- if (prev == 0)
+ if (prev == null)
{
return;
}
@@ -182,51 +184,81 @@ implementation DelegateRemoveHelper(oldi: int, m: int, o: int) returns (i: int)
$Next[i] := $Next[i][prev := $Next[i][$Next[i][prev]]];
if ($Next[i][$Head[i]] == $Head[i])
{
- i := 0;
+ i := null;
}
}
-type Field;
-
var $Heap: HeapType where IsGoodHeap($Heap);
-function Box2Int(box) : int;
-
-function Box2Bool(box) : bool;
-
-function Int2Box(int) : box;
-
-function Bool2Box(bool) : box;
-
-function {:inline true} Read(H: HeapType, o: ref, f: Field) : box
+function {:inline true} Read(H: HeapType, o: Ref, f: Field) : Box
{
H[o, f]
}
-function {:inline true} Write(H: HeapType, o: ref, f: Field, v: box) : HeapType
+function {:inline true} Write(H: HeapType, o: Ref, f: Field, v: Box) : HeapType
{
H[o, f := v]
}
+var $ArrayContents: [Ref][int]Box;
+
+var $ArrayLength: [Ref]int;
+
+type Field;
+
+type Box;
+
+const unique $DefaultBox: Box;
+
+type Ref;
+
+const unique null: Ref;
+
type Type;
-function $DynamicType(ref) : Type;
+const unique $DefaultStruct: Struct;
+
+function Box2Int(Box) : int;
+
+function Box2Bool(Box) : bool;
+
+function Box2Struct(Box) : Struct;
+
+function Box2Ref(Box) : Ref;
+
+function Int2Box(int) : Box;
+
+function Bool2Box(bool) : Box;
+
+function Struct2Box(Struct) : Box;
-function $TypeOf(Type) : ref;
+function Ref2Box(Ref) : Box;
-var $Head: [int]int;
+function Struct2Ref(Struct) : Ref;
-var $Next: [int][int]int;
+function Int2Ref(int) : Ref;
-var $Method: [int][int]int;
+function Bool2Ref(bool) : Ref;
-var $Receiver: [int][int]int;
+function $DynamicType(Ref) : Type;
+
+function $TypeOf(Type) : Ref;
+
+function $As(Ref, Type) : Ref;
+
+var $Head: [Ref]Ref;
+
+var $Next: [Ref][Ref]Ref;
+
+var $Method: [Ref][Ref]int;
+
+var $Receiver: [Ref][Ref]Ref;
const unique RegressionTestInput.ClassWithArrayTypes: Type;
-var RegressionTestInput.ClassWithArrayTypes.s: int;
+var RegressionTestInput.ClassWithArrayTypes.s: Ref;
const unique RegressionTestInput.ClassWithArrayTypes.a: Field;
@@ -236,27 +268,37 @@ procedure RegressionTestInput.ClassWithArrayTypes.Main1();
implementation RegressionTestInput.ClassWithArrayTypes.Main1()
{
- var local_0: int;
- var $tmp0: int;
- var local_1: int;
+ var local_0: Ref;
+ var $tmp0: Ref;
var $tmp1: int;
+ var $tmp2: int;
+ var local_1: Ref;
+ var $tmp3: Ref;
+ var $tmp4: int;
+ var $tmp5: int;
+ var $tmp6: int;
assert {:sourceFile "Class1.cs"} {:sourceLine 86} true;
call $tmp0 := Alloc();
local_0 := $tmp0;
assert {:sourceFile "Class1.cs"} {:sourceLine 87} true;
- $ArrayContents := $ArrayContents[local_0 := $ArrayContents[local_0][0 := 2]];
+ $tmp1 := Box2Int($ArrayContents[local_0][0]);
+ $ArrayContents := $ArrayContents[local_0 := $ArrayContents[local_0][0 := Int2Box(2)]];
assert {:sourceFile "Class1.cs"} {:sourceLine 88} true;
- assert $ArrayContents[local_0][0] == 2;
+ $tmp2 := Box2Int($ArrayContents[local_0][0]);
+ assert $tmp2 == 2;
assert {:sourceFile "Class1.cs"} {:sourceLine 90} true;
- call $tmp1 := Alloc();
- local_1 := $tmp1;
+ call $tmp3 := Alloc();
+ local_1 := $tmp3;
assert {:sourceFile "Class1.cs"} {:sourceLine 91} true;
- $ArrayContents := $ArrayContents[local_1 := $ArrayContents[local_1][0 := 1]];
+ $tmp4 := Box2Int($ArrayContents[local_1][0]);
+ $ArrayContents := $ArrayContents[local_1 := $ArrayContents[local_1][0 := Int2Box(1)]];
assert {:sourceFile "Class1.cs"} {:sourceLine 92} true;
- assert $ArrayContents[local_1][0] == 1;
+ $tmp5 := Box2Int($ArrayContents[local_1][0]);
+ assert $tmp5 == 1;
assert {:sourceFile "Class1.cs"} {:sourceLine 94} true;
- assert $ArrayContents[local_0][0] == 2;
+ $tmp6 := Box2Int($ArrayContents[local_0][0]);
+ assert $tmp6 == 2;
assert {:sourceFile "Class1.cs"} {:sourceLine 95} true;
return;
}
@@ -269,66 +311,104 @@ procedure RegressionTestInput.ClassWithArrayTypes.Main2();
implementation RegressionTestInput.ClassWithArrayTypes.Main2()
{
- var $tmp2: int;
- var local_0: int;
- var $tmp3: int;
+ var $tmp7: Ref;
+ var $tmp8: int;
+ var $tmp9: int;
+ var local_0: Ref;
+ var $tmp10: Ref;
+ var $tmp11: int;
+ var $tmp12: int;
+ var $tmp13: int;
assert {:sourceFile "Class1.cs"} {:sourceLine 100} true;
- call $tmp2 := Alloc();
- RegressionTestInput.ClassWithArrayTypes.s := $tmp2;
+ call $tmp7 := Alloc();
+ RegressionTestInput.ClassWithArrayTypes.s := $tmp7;
assert {:sourceFile "Class1.cs"} {:sourceLine 101} true;
- $ArrayContents := $ArrayContents[RegressionTestInput.ClassWithArrayTypes.s := $ArrayContents[RegressionTestInput.ClassWithArrayTypes.s][0 := 2]];
+ $tmp8 := Box2Int($ArrayContents[RegressionTestInput.ClassWithArrayTypes.s][0]);
+ $ArrayContents := $ArrayContents[RegressionTestInput.ClassWithArrayTypes.s := $ArrayContents[RegressionTestInput.ClassWithArrayTypes.s][0 := Int2Box(2)]];
assert {:sourceFile "Class1.cs"} {:sourceLine 102} true;
- assert $ArrayContents[RegressionTestInput.ClassWithArrayTypes.s][0] == 2;
+ $tmp9 := Box2Int($ArrayContents[RegressionTestInput.ClassWithArrayTypes.s][0]);
+ assert $tmp9 == 2;
assert {:sourceFile "Class1.cs"} {:sourceLine 104} true;
- call $tmp3 := Alloc();
- local_0 := $tmp3;
+ call $tmp10 := Alloc();
+ local_0 := $tmp10;
assert {:sourceFile "Class1.cs"} {:sourceLine 105} true;
- $ArrayContents := $ArrayContents[local_0 := $ArrayContents[local_0][0 := 1]];
+ $tmp11 := Box2Int($ArrayContents[local_0][0]);
+ $ArrayContents := $ArrayContents[local_0 := $ArrayContents[local_0][0 := Int2Box(1)]];
assert {:sourceFile "Class1.cs"} {:sourceLine 106} true;
- assert $ArrayContents[local_0][0] == 1;
+ $tmp12 := Box2Int($ArrayContents[local_0][0]);
+ assert $tmp12 == 1;
assert {:sourceFile "Class1.cs"} {:sourceLine 108} true;
- assert $ArrayContents[RegressionTestInput.ClassWithArrayTypes.s][0] == 2;
+ $tmp13 := Box2Int($ArrayContents[RegressionTestInput.ClassWithArrayTypes.s][0]);
+ assert $tmp13 == 2;
assert {:sourceFile "Class1.cs"} {:sourceLine 109} true;
return;
}
-procedure RegressionTestInput.ClassWithArrayTypes.Main3$System.Int32(this: int, x$in: int);
+procedure RegressionTestInput.ClassWithArrayTypes.Main3$System.Int32(this: Ref, x$in: int);
-implementation RegressionTestInput.ClassWithArrayTypes.Main3$System.Int32(this: int, x$in: int)
+implementation RegressionTestInput.ClassWithArrayTypes.Main3$System.Int32(this: Ref, x$in: int)
{
var x: int;
+ var _loc0: Ref;
+ var $tmp14: Ref;
+ var $tmp15: int;
+ var _loc1: Ref;
+ var $tmp16: Ref;
+ var $tmp17: int;
+ var $tmp18: Ref;
+ var $tmp19: int;
+ var $tmp20: Ref;
+ var $tmp21: int;
x := x$in;
assert {:sourceFile "Class1.cs"} {:sourceLine 114} true;
- $ArrayContents := $ArrayContents[Box2Int(Read($Heap, this, RegressionTestInput.ClassWithArrayTypes.a)) := $ArrayContents[Box2Int(Read($Heap, this, RegressionTestInput.ClassWithArrayTypes.a))][x := 42]];
+ $tmp14 := Box2Ref(Read($Heap, this, RegressionTestInput.ClassWithArrayTypes.a));
+ _loc0 := $tmp14;
+ $tmp15 := Box2Int($ArrayContents[_loc0][x]);
+ $ArrayContents := $ArrayContents[_loc0 := $ArrayContents[_loc0][x := Int2Box(42)]];
assert {:sourceFile "Class1.cs"} {:sourceLine 115} true;
- $ArrayContents := $ArrayContents[Box2Int(Read($Heap, this, RegressionTestInput.ClassWithArrayTypes.a)) := $ArrayContents[Box2Int(Read($Heap, this, RegressionTestInput.ClassWithArrayTypes.a))][x + 1 := 43]];
+ $tmp16 := Box2Ref(Read($Heap, this, RegressionTestInput.ClassWithArrayTypes.a));
+ _loc1 := $tmp16;
+ $tmp17 := Box2Int($ArrayContents[_loc1][x + 1]);
+ $ArrayContents := $ArrayContents[_loc1 := $ArrayContents[_loc1][x + 1 := Int2Box(43)]];
assert {:sourceFile "Class1.cs"} {:sourceLine 116} true;
- assert $ArrayContents[Box2Int(Read($Heap, this, RegressionTestInput.ClassWithArrayTypes.a))][x + 1] == $ArrayContents[Box2Int(Read($Heap, this, RegressionTestInput.ClassWithArrayTypes.a))][x] + 1;
+ $tmp18 := Box2Ref(Read($Heap, this, RegressionTestInput.ClassWithArrayTypes.a));
+ $tmp19 := Box2Int($ArrayContents[$tmp18][x + 1]);
+ $tmp20 := Box2Ref(Read($Heap, this, RegressionTestInput.ClassWithArrayTypes.a));
+ $tmp21 := Box2Int($ArrayContents[$tmp20][x]);
+ assert $tmp19 == $tmp21 + 1;
assert {:sourceFile "Class1.cs"} {:sourceLine 117} true;
return;
}
-procedure RegressionTestInput.ClassWithArrayTypes.Main4$System.Int32array(this: int, xs$in: int);
+procedure RegressionTestInput.ClassWithArrayTypes.Main4$System.Int32array(this: Ref, xs$in: Ref);
-implementation RegressionTestInput.ClassWithArrayTypes.Main4$System.Int32array(this: int, xs$in: int)
+implementation RegressionTestInput.ClassWithArrayTypes.Main4$System.Int32array(this: Ref, xs$in: Ref)
{
- var xs: int;
+ var xs: Ref;
+ var $tmp22: int;
+ var _loc0: Ref;
+ var $tmp23: Ref;
+ var $tmp24: int;
xs := xs$in;
- if (!(if xs != 0 then $ArrayLength[xs] <= 0 else true))
+ if (!(if xs != null then $ArrayLength[xs] <= 0 else true))
{
assert {:sourceFile "Class1.cs"} {:sourceLine 121} true;
- $ArrayContents := $ArrayContents[Box2Int(Read($Heap, this, RegressionTestInput.ClassWithArrayTypes.a)) := $ArrayContents[Box2Int(Read($Heap, this, RegressionTestInput.ClassWithArrayTypes.a))][0 := $ArrayContents[xs][0]]];
+ $tmp22 := Box2Int($ArrayContents[xs][0]);
+ $tmp23 := Box2Ref(Read($Heap, this, RegressionTestInput.ClassWithArrayTypes.a));
+ _loc0 := $tmp23;
+ $tmp24 := Box2Int($ArrayContents[_loc0][0]);
+ $ArrayContents := $ArrayContents[_loc0 := $ArrayContents[_loc0][0 := Int2Box($tmp22)]];
}
else
{
@@ -340,17 +420,17 @@ implementation RegressionTestInput.ClassWithArrayTypes.Main4$System.Int32array(t
-procedure RegressionTestInput.ClassWithArrayTypes.#ctor(this: int);
+procedure RegressionTestInput.ClassWithArrayTypes.#ctor(this: Ref);
-procedure System.Object.#ctor(this: int);
+procedure System.Object.#ctor(this: Ref);
-implementation RegressionTestInput.ClassWithArrayTypes.#ctor(this: int)
+implementation RegressionTestInput.ClassWithArrayTypes.#ctor(this: Ref)
{
- $Heap := Write($Heap, this, RegressionTestInput.ClassWithArrayTypes.a, Int2Box(0));
+ $Heap := Write($Heap, this, RegressionTestInput.ClassWithArrayTypes.a, Ref2Box(null));
call System.Object.#ctor(this);
return;
}
@@ -363,7 +443,46 @@ procedure RegressionTestInput.ClassWithArrayTypes.#cctor();
implementation RegressionTestInput.ClassWithArrayTypes.#cctor()
{
- RegressionTestInput.ClassWithArrayTypes.s := 0;
+ RegressionTestInput.ClassWithArrayTypes.s := null;
+}
+
+
+
+const unique RegressionTestInput.RefParameters: Type;
+
+procedure RegressionTestInput.RefParameters.M$System.Int32$(x$in: int) returns (x$out: int);
+
+
+
+implementation RegressionTestInput.RefParameters.M$System.Int32$(x$in: int) returns (x$out: int)
+{
+ x$out := x$in;
+ assert {:sourceFile "Class1.cs"} {:sourceLine 156} true;
+ x$out := x$out + 1;
+ assert {:sourceFile "Class1.cs"} {:sourceLine 157} true;
+ return;
+}
+
+
+
+procedure RegressionTestInput.RefParameters.#ctor(this: Ref);
+
+
+
+implementation RegressionTestInput.RefParameters.#ctor(this: Ref)
+{
+ call System.Object.#ctor(this);
+ return;
+}
+
+
+
+procedure RegressionTestInput.RefParameters.#cctor();
+
+
+
+implementation RegressionTestInput.RefParameters.#cctor()
+{
}
@@ -388,21 +507,21 @@ implementation RegressionTestInput.Class0.StaticMethod$System.Int32(x$in: int) r
-procedure RegressionTestInput.Class0.M$System.Int32(this: int, x$in: int);
+procedure RegressionTestInput.Class0.M$System.Int32(this: Ref, x$in: int);
-implementation RegressionTestInput.Class0.M$System.Int32(this: int, x$in: int)
+implementation RegressionTestInput.Class0.M$System.Int32(this: Ref, x$in: int)
{
var x: int;
var __temp_1: int;
- var $tmp4: int;
+ var $tmp25: int;
var local_0: int;
x := x$in;
- $tmp4 := x;
- assert $tmp4 != 0;
- __temp_1 := 5 / $tmp4;
+ $tmp25 := x;
+ assert $tmp25 != 0;
+ __temp_1 := 5 / $tmp25;
x := 3;
local_0 := __temp_1 + 3;
assert {:sourceFile "Class1.cs"} {:sourceLine 22} true;
@@ -417,11 +536,11 @@ implementation RegressionTestInput.Class0.M$System.Int32(this: int, x$in: int)
-procedure RegressionTestInput.Class0.M$System.Int32$System.Int32(this: int, x$in: int, y$in: int);
+procedure RegressionTestInput.Class0.M$System.Int32$System.Int32(this: Ref, x$in: int, y$in: int);
-implementation RegressionTestInput.Class0.M$System.Int32$System.Int32(this: int, x$in: int, y$in: int)
+implementation RegressionTestInput.Class0.M$System.Int32$System.Int32(this: Ref, x$in: int, y$in: int)
{
var x: int;
var y: int;
@@ -434,11 +553,11 @@ implementation RegressionTestInput.Class0.M$System.Int32$System.Int32(this: int,
-procedure RegressionTestInput.Class0.M$System.Boolean(this: int, b$in: bool);
+procedure RegressionTestInput.Class0.M$System.Boolean(this: Ref, b$in: bool);
-implementation RegressionTestInput.Class0.M$System.Boolean(this: int, b$in: bool)
+implementation RegressionTestInput.Class0.M$System.Boolean(this: Ref, b$in: bool)
{
var b: bool;
@@ -449,13 +568,13 @@ implementation RegressionTestInput.Class0.M$System.Boolean(this: int, b$in: bool
-procedure RegressionTestInput.Class0.M$RegressionTestInput.Class0(this: int, c$in: int);
+procedure RegressionTestInput.Class0.M$RegressionTestInput.Class0(this: Ref, c$in: Ref);
-implementation RegressionTestInput.Class0.M$RegressionTestInput.Class0(this: int, c$in: int)
+implementation RegressionTestInput.Class0.M$RegressionTestInput.Class0(this: Ref, c$in: Ref)
{
- var c: int;
+ var c: Ref;
c := c$in;
assert {:sourceFile "Class1.cs"} {:sourceLine 30} true;
@@ -464,27 +583,27 @@ implementation RegressionTestInput.Class0.M$RegressionTestInput.Class0(this: int
-procedure RegressionTestInput.Class0.NonVoid(this: int) returns ($result: int);
+procedure RegressionTestInput.Class0.NonVoid(this: Ref) returns ($result: int);
-implementation RegressionTestInput.Class0.NonVoid(this: int) returns ($result: int)
+implementation RegressionTestInput.Class0.NonVoid(this: Ref) returns ($result: int)
{
- var $tmp5: int;
+ var $tmp26: int;
assert {:sourceFile "Class1.cs"} {:sourceLine 34} true;
- call $tmp5 := RegressionTestInput.Class0.StaticMethod$System.Int32(3);
- $result := 3 + RegressionTestInput.Class0.StaticInt + $tmp5;
+ call $tmp26 := RegressionTestInput.Class0.StaticMethod$System.Int32(3);
+ $result := 3 + RegressionTestInput.Class0.StaticInt + $tmp26;
return;
}
-procedure RegressionTestInput.Class0.OutParam$System.Int32$(this: int) returns (x$out: int, $result: int);
+procedure RegressionTestInput.Class0.OutParam$System.Int32$(this: Ref) returns (x$out: int, $result: int);
-implementation RegressionTestInput.Class0.OutParam$System.Int32$(this: int) returns (x$out: int, $result: int)
+implementation RegressionTestInput.Class0.OutParam$System.Int32$(this: Ref) returns (x$out: int, $result: int)
{
assert {:sourceFile "Class1.cs"} {:sourceLine 37} true;
x$out := 3 + RegressionTestInput.Class0.StaticInt;
@@ -495,11 +614,11 @@ implementation RegressionTestInput.Class0.OutParam$System.Int32$(this: int) retu
-procedure RegressionTestInput.Class0.RefParam$System.Int32$(this: int, x$in: int) returns (x$out: int, $result: int);
+procedure RegressionTestInput.Class0.RefParam$System.Int32$(this: Ref, x$in: int) returns (x$out: int, $result: int);
-implementation RegressionTestInput.Class0.RefParam$System.Int32$(this: int, x$in: int) returns (x$out: int, $result: int)
+implementation RegressionTestInput.Class0.RefParam$System.Int32$(this: Ref, x$in: int) returns (x$out: int, $result: int)
{
x$out := x$in;
assert {:sourceFile "Class1.cs"} {:sourceLine 42} true;
@@ -513,11 +632,11 @@ implementation RegressionTestInput.Class0.RefParam$System.Int32$(this: int, x$in
-procedure RegressionTestInput.Class0.AssignToInParam$System.Int32(this: int, x$in: int) returns ($result: int);
+procedure RegressionTestInput.Class0.AssignToInParam$System.Int32(this: Ref, x$in: int) returns ($result: int);
-implementation RegressionTestInput.Class0.AssignToInParam$System.Int32(this: int, x$in: int) returns ($result: int)
+implementation RegressionTestInput.Class0.AssignToInParam$System.Int32(this: Ref, x$in: int) returns ($result: int)
{
var x: int;
@@ -533,11 +652,11 @@ implementation RegressionTestInput.Class0.AssignToInParam$System.Int32(this: int
-procedure {:RegressionTestInput.Async} RegressionTestInput.Class0.MethodThatRepresentsAnAynchronousMethod$System.Int32(this: int, x$in: int) returns ($result: int);
+procedure {:RegressionTestInput.Async} RegressionTestInput.Class0.MethodThatRepresentsAnAynchronousMethod$System.Int32(this: Ref, x$in: int) returns ($result: int);
-implementation RegressionTestInput.Class0.MethodThatRepresentsAnAynchronousMethod$System.Int32(this: int, x$in: int) returns ($result: int)
+implementation RegressionTestInput.Class0.MethodThatRepresentsAnAynchronousMethod$System.Int32(this: Ref, x$in: int) returns ($result: int)
{
var x: int;
@@ -549,29 +668,29 @@ implementation RegressionTestInput.Class0.MethodThatRepresentsAnAynchronousMetho
-procedure RegressionTestInput.Class0.CallAsyncMethod$System.Int32(this: int, y$in: int) returns ($result: int);
+procedure RegressionTestInput.Class0.CallAsyncMethod$System.Int32(this: Ref, y$in: int) returns ($result: int);
-implementation RegressionTestInput.Class0.CallAsyncMethod$System.Int32(this: int, y$in: int) returns ($result: int)
+implementation RegressionTestInput.Class0.CallAsyncMethod$System.Int32(this: Ref, y$in: int) returns ($result: int)
{
var y: int;
- var $tmp6: int;
+ var $tmp27: int;
y := y$in;
assert {:sourceFile "Class1.cs"} {:sourceLine 60} true;
- call {:async} $tmp6 := RegressionTestInput.Class0.MethodThatRepresentsAnAynchronousMethod$System.Int32(this, y);
- $result := $tmp6;
+ call {:async} $tmp27 := RegressionTestInput.Class0.MethodThatRepresentsAnAynchronousMethod$System.Int32(this, y);
+ $result := $tmp27;
return;
}
-procedure RegressionTestInput.Class0.#ctor(this: int);
+procedure RegressionTestInput.Class0.#ctor(this: Ref);
-implementation RegressionTestInput.Class0.#ctor(this: int)
+implementation RegressionTestInput.Class0.#ctor(this: Ref)
{
call System.Object.#ctor(this);
return;
@@ -596,25 +715,28 @@ const unique RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.x: Field;
const unique RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.y: Field;
-procedure RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.M(this: int);
+procedure RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.M(this: Ref);
-implementation RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.M(this: int)
+implementation RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.M(this: Ref)
{
+ var $tmp28: int;
+
assert {:sourceFile "Class1.cs"} {:sourceLine 130} true;
- $Heap := Write($Heap, this, RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.y, Int2Box(Box2Int(Read($Heap, this, RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.x))));
+ $tmp28 := Box2Int(Read($Heap, this, RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.x));
+ $Heap := Write($Heap, this, RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.y, Int2Box($tmp28));
assert {:sourceFile "Class1.cs"} {:sourceLine 131} true;
return;
}
-procedure RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.#ctor(this: int);
+procedure RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.#ctor(this: Ref);
-implementation RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.#ctor(this: int)
+implementation RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.#ctor(this: Ref)
{
$Heap := Write($Heap, this, RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.x, Int2Box(0));
$Heap := Write($Heap, this, RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.y, Int2Box(0));
@@ -658,11 +780,11 @@ implementation RegressionTestInput.ClassWithBoolTypes.M$System.Int32$System.Int3
-procedure RegressionTestInput.ClassWithBoolTypes.#ctor$System.Boolean(this: int, z$in: bool);
+procedure RegressionTestInput.ClassWithBoolTypes.#ctor$System.Boolean(this: Ref, z$in: bool);
-implementation RegressionTestInput.ClassWithBoolTypes.#ctor$System.Boolean(this: int, z$in: bool)
+implementation RegressionTestInput.ClassWithBoolTypes.#ctor$System.Boolean(this: Ref, z$in: bool)
{
var z: bool;
@@ -693,10 +815,10 @@ procedure RegressionTestInput.ClassWithBoolTypes.Main();
implementation RegressionTestInput.ClassWithBoolTypes.Main()
{
- var $tmp7: bool;
+ var $tmp29: bool;
assert {:sourceFile "Class1.cs"} {:sourceLine 78} true;
- call $tmp7 := RegressionTestInput.ClassWithBoolTypes.M$System.Int32$System.Int32(3, 4);
+ call $tmp29 := RegressionTestInput.ClassWithBoolTypes.M$System.Int32$System.Int32(3, 4);
assert {:sourceFile "Class1.cs"} {:sourceLine 79} true;
return;
}
@@ -714,17 +836,23 @@ implementation RegressionTestInput.ClassWithBoolTypes.#cctor()
+const unique RegressionTestInput.S: Type;
+
+const unique RegressionTestInput.S.x: Field;
+
+const unique RegressionTestInput.S.b: Field;
+
const unique RegressionTestInput.AsyncAttribute: Type;
-procedure RegressionTestInput.AsyncAttribute.#ctor(this: int);
+procedure RegressionTestInput.AsyncAttribute.#ctor(this: Ref);
-procedure System.Attribute.#ctor(this: int);
+procedure System.Attribute.#ctor(this: Ref);
-implementation RegressionTestInput.AsyncAttribute.#ctor(this: int)
+implementation RegressionTestInput.AsyncAttribute.#ctor(this: Ref)
{
call System.Attribute.#ctor(this);
return;
@@ -741,3 +869,74 @@ implementation RegressionTestInput.AsyncAttribute.#cctor()
}
+
+const unique RegressionTestInput.CreateStruct: Type;
+
+procedure RegressionTestInput.CreateStruct.Create(this: Ref) returns ($result: [Field]Box);
+
+
+
+implementation RegressionTestInput.CreateStruct.Create(this: Ref) returns ($result: [Field]Box)
+{
+ var local_0: [Field]Box;
+ var $tmp30: int;
+ var $tmp31: bool;
+
+ assert {:sourceFile "Class1.cs"} {:sourceLine 141} true;
+ local_0 := $DefaultStruct;
+ assert {:sourceFile "Class1.cs"} {:sourceLine 142} true;
+ $tmp30 := Box2Int(local_0[RegressionTestInput.S.x]);
+ assert $tmp30 == 0;
+ assert {:sourceFile "Class1.cs"} {:sourceLine 143} true;
+ $tmp31 := Box2Bool(local_0[RegressionTestInput.S.b]);
+ assert !$tmp31;
+ assert {:sourceFile "Class1.cs"} {:sourceLine 145} true;
+ $result := local_0;
+ return;
+}
+
+
+
+procedure RegressionTestInput.CreateStruct.AssignThreeToSDotX$RegressionTestInput.S(this: Ref, s$in: [Field]Box) returns ($result: [Field]Box);
+
+
+
+implementation RegressionTestInput.CreateStruct.AssignThreeToSDotX$RegressionTestInput.S(this: Ref, s$in: [Field]Box) returns ($result: [Field]Box)
+{
+ var s: [Field]Box;
+ var $tmp32: int;
+
+ s := s$in;
+ assert {:sourceFile "Class1.cs"} {:sourceLine 147} true;
+ s := s[RegressionTestInput.S.x := Int2Box(3)];
+ assert {:sourceFile "Class1.cs"} {:sourceLine 148} true;
+ $tmp32 := Box2Int(s[RegressionTestInput.S.x]);
+ assert $tmp32 == 3;
+ assert {:sourceFile "Class1.cs"} {:sourceLine 150} true;
+ $result := s;
+ return;
+}
+
+
+
+procedure RegressionTestInput.CreateStruct.#ctor(this: Ref);
+
+
+
+implementation RegressionTestInput.CreateStruct.#ctor(this: Ref)
+{
+ call System.Object.#ctor(this);
+ return;
+}
+
+
+
+procedure RegressionTestInput.CreateStruct.#cctor();
+
+
+
+implementation RegressionTestInput.CreateStruct.#cctor()
+{
+}
+
+
diff --git a/BCT/RegressionTests/TranslationTest/SplitFieldsHeapInput.txt b/BCT/RegressionTests/TranslationTest/SplitFieldsHeapInput.txt
index 5245bf3d..6e450f38 100644
--- a/BCT/RegressionTests/TranslationTest/SplitFieldsHeapInput.txt
+++ b/BCT/RegressionTests/TranslationTest/SplitFieldsHeapInput.txt
@@ -1,27 +1,23 @@
// Copyright (c) 2010, Microsoft Corp.
// Bytecode Translator prelude
-const null: int;
+type Struct = [Field]Box;
-type HeapType = [int,int]int;
+type HeapType = [Ref,Field]Box;
var $Heap: HeapType where IsGoodHeap($Heap);
function IsGoodHeap(HeapType) : bool;
-var $ArrayContents: [int][int]int;
+var $Alloc: [Ref]bool;
-var $ArrayLength: [int]int;
-
-var $Alloc: [int]bool;
-
-procedure {:inline 1} Alloc() returns (x: int);
+procedure {:inline 1} Alloc() returns (x: Ref);
modifies $Alloc;
- free ensures x != 0;
+ free ensures x != null;
-implementation Alloc() returns (x: int)
+implementation Alloc() returns (x: Ref)
{
assume $Alloc[x] == false;
$Alloc[x] := true;
@@ -29,23 +25,31 @@ implementation Alloc() returns (x: int)
-type ref = int;
+axiom (forall x: Field :: $DefaultStruct[x] == $DefaultBox);
+
+axiom Box2Int($DefaultBox) == 0;
+
+axiom Box2Bool($DefaultBox) == false;
-procedure DelegateAdd(a: int, b: int) returns (c: int);
+axiom (forall x: int :: { Int2Box(x) } Box2Int(Int2Box(x)) == x);
+axiom (forall x: bool :: { Bool2Box(x) } Box2Bool(Bool2Box(x)) == x);
+procedure DelegateAdd(a: Ref, b: Ref) returns (c: Ref);
-implementation DelegateAdd(a: int, b: int) returns (c: int)
+
+
+implementation DelegateAdd(a: Ref, b: Ref) returns (c: Ref)
{
var m: int;
- var o: int;
+ var o: Ref;
- if (a == 0)
+ if (a == null)
{
c := b;
return;
}
- else if (b == 0)
+ else if (b == null)
{
c := a;
return;
@@ -62,21 +66,21 @@ implementation DelegateAdd(a: int, b: int) returns (c: int)
-procedure DelegateRemove(a: int, b: int) returns (c: int);
+procedure DelegateRemove(a: Ref, b: Ref) returns (c: Ref);
-implementation DelegateRemove(a: int, b: int) returns (c: int)
+implementation DelegateRemove(a: Ref, b: Ref) returns (c: Ref)
{
var m: int;
- var o: int;
+ var o: Ref;
- if (a == 0)
+ if (a == null)
{
- c := 0;
+ c := null;
return;
}
- else if (b == 0)
+ else if (b == null)
{
c := a;
return;
@@ -93,13 +97,13 @@ implementation DelegateRemove(a: int, b: int) returns (c: int)
-procedure GetFirstElement(i: int) returns (m: int, o: int);
+procedure GetFirstElement(i: Ref) returns (m: int, o: Ref);
-implementation GetFirstElement(i: int) returns (m: int, o: int)
+implementation GetFirstElement(i: Ref) returns (m: int, o: Ref)
{
- var first: int;
+ var first: Ref;
first := $Next[i][$Head[i]];
m := $Method[i][first];
@@ -108,16 +112,16 @@ implementation GetFirstElement(i: int) returns (m: int, o: int)
-procedure DelegateAddHelper(oldi: int, m: int, o: int) returns (i: int);
+procedure DelegateAddHelper(oldi: Ref, m: int, o: Ref) returns (i: Ref);
-implementation DelegateAddHelper(oldi: int, m: int, o: int) returns (i: int)
+implementation DelegateAddHelper(oldi: Ref, m: int, o: Ref) returns (i: Ref)
{
- var x: int;
- var h: int;
+ var x: Ref;
+ var h: Ref;
- if (oldi == 0)
+ if (oldi == null)
{
call i := Alloc();
call x := Alloc();
@@ -140,23 +144,23 @@ implementation DelegateAddHelper(oldi: int, m: int, o: int) returns (i: int)
-procedure DelegateRemoveHelper(oldi: int, m: int, o: int) returns (i: int);
+procedure DelegateRemoveHelper(oldi: Ref, m: int, o: Ref) returns (i: Ref);
-implementation DelegateRemoveHelper(oldi: int, m: int, o: int) returns (i: int)
+implementation DelegateRemoveHelper(oldi: Ref, m: int, o: Ref) returns (i: Ref)
{
- var prev: int;
- var iter: int;
- var niter: int;
+ var prev: Ref;
+ var iter: Ref;
+ var niter: Ref;
i := oldi;
- if (i == 0)
+ if (i == null)
{
return;
}
- prev := 0;
+ prev := null;
iter := $Head[i];
while (true)
{
@@ -174,7 +178,7 @@ implementation DelegateRemoveHelper(oldi: int, m: int, o: int) returns (i: int)
iter := niter;
}
- if (prev == 0)
+ if (prev == null)
{
return;
}
@@ -182,31 +186,71 @@ implementation DelegateRemoveHelper(oldi: int, m: int, o: int) returns (i: int)
$Next[i] := $Next[i][prev := $Next[i][$Next[i][prev]]];
if ($Next[i][$Head[i]] == $Head[i])
{
- i := 0;
+ i := null;
}
}
+var $ArrayContents: [Ref][int]Box;
+
+var $ArrayLength: [Ref]int;
+
+type Field;
+
+type Box;
+
+const unique $DefaultBox: Box;
+
+type Ref;
+
+const unique null: Ref;
+
type Type;
-function $DynamicType(ref) : Type;
+const unique $DefaultStruct: Struct;
-function $TypeOf(Type) : ref;
+function Box2Int(Box) : int;
-var $Head: [int]int;
+function Box2Bool(Box) : bool;
-var $Next: [int][int]int;
+function Box2Struct(Box) : Struct;
-var $Method: [int][int]int;
+function Box2Ref(Box) : Ref;
-var $Receiver: [int][int]int;
+function Int2Box(int) : Box;
+
+function Bool2Box(bool) : Box;
+
+function Struct2Box(Struct) : Box;
+
+function Ref2Box(Ref) : Box;
+
+function Struct2Ref(Struct) : Ref;
+
+function Int2Ref(int) : Ref;
+
+function Bool2Ref(bool) : Ref;
+
+function $DynamicType(Ref) : Type;
+
+function $TypeOf(Type) : Ref;
+
+function $As(Ref, Type) : Ref;
+
+var $Head: [Ref]Ref;
+
+var $Next: [Ref][Ref]Ref;
+
+var $Method: [Ref][Ref]int;
+
+var $Receiver: [Ref][Ref]Ref;
const unique RegressionTestInput.ClassWithArrayTypes: Type;
-var RegressionTestInput.ClassWithArrayTypes.s: int;
+var RegressionTestInput.ClassWithArrayTypes.s: Ref;
-var RegressionTestInput.ClassWithArrayTypes.a: [int]int;
+var RegressionTestInput.ClassWithArrayTypes.a: [Ref]Ref;
procedure RegressionTestInput.ClassWithArrayTypes.Main1();
@@ -214,27 +258,37 @@ procedure RegressionTestInput.ClassWithArrayTypes.Main1();
implementation RegressionTestInput.ClassWithArrayTypes.Main1()
{
- var local_0: int;
- var $tmp0: int;
- var local_1: int;
+ var local_0: Ref;
+ var $tmp0: Ref;
var $tmp1: int;
+ var $tmp2: int;
+ var local_1: Ref;
+ var $tmp3: Ref;
+ var $tmp4: int;
+ var $tmp5: int;
+ var $tmp6: int;
assert {:sourceFile "Class1.cs"} {:sourceLine 86} true;
call $tmp0 := Alloc();
local_0 := $tmp0;
assert {:sourceFile "Class1.cs"} {:sourceLine 87} true;
+ $tmp1 := $ArrayContents[local_0][0];
$ArrayContents := $ArrayContents[local_0 := $ArrayContents[local_0][0 := 2]];
assert {:sourceFile "Class1.cs"} {:sourceLine 88} true;
- assert $ArrayContents[local_0][0] == 2;
+ $tmp2 := $ArrayContents[local_0][0];
+ assert $tmp2 == 2;
assert {:sourceFile "Class1.cs"} {:sourceLine 90} true;
- call $tmp1 := Alloc();
- local_1 := $tmp1;
+ call $tmp3 := Alloc();
+ local_1 := $tmp3;
assert {:sourceFile "Class1.cs"} {:sourceLine 91} true;
+ $tmp4 := $ArrayContents[local_1][0];
$ArrayContents := $ArrayContents[local_1 := $ArrayContents[local_1][0 := 1]];
assert {:sourceFile "Class1.cs"} {:sourceLine 92} true;
- assert $ArrayContents[local_1][0] == 1;
+ $tmp5 := $ArrayContents[local_1][0];
+ assert $tmp5 == 1;
assert {:sourceFile "Class1.cs"} {:sourceLine 94} true;
- assert $ArrayContents[local_0][0] == 2;
+ $tmp6 := $ArrayContents[local_0][0];
+ assert $tmp6 == 2;
assert {:sourceFile "Class1.cs"} {:sourceLine 95} true;
return;
}
@@ -247,66 +301,104 @@ procedure RegressionTestInput.ClassWithArrayTypes.Main2();
implementation RegressionTestInput.ClassWithArrayTypes.Main2()
{
- var $tmp2: int;
- var local_0: int;
- var $tmp3: int;
+ var $tmp7: Ref;
+ var $tmp8: int;
+ var $tmp9: int;
+ var local_0: Ref;
+ var $tmp10: Ref;
+ var $tmp11: int;
+ var $tmp12: int;
+ var $tmp13: int;
assert {:sourceFile "Class1.cs"} {:sourceLine 100} true;
- call $tmp2 := Alloc();
- RegressionTestInput.ClassWithArrayTypes.s := $tmp2;
+ call $tmp7 := Alloc();
+ RegressionTestInput.ClassWithArrayTypes.s := $tmp7;
assert {:sourceFile "Class1.cs"} {:sourceLine 101} true;
+ $tmp8 := $ArrayContents[RegressionTestInput.ClassWithArrayTypes.s][0];
$ArrayContents := $ArrayContents[RegressionTestInput.ClassWithArrayTypes.s := $ArrayContents[RegressionTestInput.ClassWithArrayTypes.s][0 := 2]];
assert {:sourceFile "Class1.cs"} {:sourceLine 102} true;
- assert $ArrayContents[RegressionTestInput.ClassWithArrayTypes.s][0] == 2;
+ $tmp9 := $ArrayContents[RegressionTestInput.ClassWithArrayTypes.s][0];
+ assert $tmp9 == 2;
assert {:sourceFile "Class1.cs"} {:sourceLine 104} true;
- call $tmp3 := Alloc();
- local_0 := $tmp3;
+ call $tmp10 := Alloc();
+ local_0 := $tmp10;
assert {:sourceFile "Class1.cs"} {:sourceLine 105} true;
+ $tmp11 := $ArrayContents[local_0][0];
$ArrayContents := $ArrayContents[local_0 := $ArrayContents[local_0][0 := 1]];
assert {:sourceFile "Class1.cs"} {:sourceLine 106} true;
- assert $ArrayContents[local_0][0] == 1;
+ $tmp12 := $ArrayContents[local_0][0];
+ assert $tmp12 == 1;
assert {:sourceFile "Class1.cs"} {:sourceLine 108} true;
- assert $ArrayContents[RegressionTestInput.ClassWithArrayTypes.s][0] == 2;
+ $tmp13 := $ArrayContents[RegressionTestInput.ClassWithArrayTypes.s][0];
+ assert $tmp13 == 2;
assert {:sourceFile "Class1.cs"} {:sourceLine 109} true;
return;
}
-procedure RegressionTestInput.ClassWithArrayTypes.Main3$System.Int32(this: int, x$in: int);
+procedure RegressionTestInput.ClassWithArrayTypes.Main3$System.Int32(this: Ref, x$in: int);
-implementation RegressionTestInput.ClassWithArrayTypes.Main3$System.Int32(this: int, x$in: int)
+implementation RegressionTestInput.ClassWithArrayTypes.Main3$System.Int32(this: Ref, x$in: int)
{
var x: int;
+ var _loc0: Ref;
+ var $tmp14: Ref;
+ var $tmp15: int;
+ var _loc1: Ref;
+ var $tmp16: Ref;
+ var $tmp17: int;
+ var $tmp18: Ref;
+ var $tmp19: int;
+ var $tmp20: Ref;
+ var $tmp21: int;
x := x$in;
assert {:sourceFile "Class1.cs"} {:sourceLine 114} true;
- $ArrayContents := $ArrayContents[RegressionTestInput.ClassWithArrayTypes.a[this] := $ArrayContents[RegressionTestInput.ClassWithArrayTypes.a[this]][x := 42]];
+ $tmp14 := RegressionTestInput.ClassWithArrayTypes.a[this];
+ _loc0 := $tmp14;
+ $tmp15 := $ArrayContents[_loc0][x];
+ $ArrayContents := $ArrayContents[_loc0 := $ArrayContents[_loc0][x := 42]];
assert {:sourceFile "Class1.cs"} {:sourceLine 115} true;
- $ArrayContents := $ArrayContents[RegressionTestInput.ClassWithArrayTypes.a[this] := $ArrayContents[RegressionTestInput.ClassWithArrayTypes.a[this]][x + 1 := 43]];
+ $tmp16 := RegressionTestInput.ClassWithArrayTypes.a[this];
+ _loc1 := $tmp16;
+ $tmp17 := $ArrayContents[_loc1][x + 1];
+ $ArrayContents := $ArrayContents[_loc1 := $ArrayContents[_loc1][x + 1 := 43]];
assert {:sourceFile "Class1.cs"} {:sourceLine 116} true;
- assert $ArrayContents[RegressionTestInput.ClassWithArrayTypes.a[this]][x + 1] == $ArrayContents[RegressionTestInput.ClassWithArrayTypes.a[this]][x] + 1;
+ $tmp18 := RegressionTestInput.ClassWithArrayTypes.a[this];
+ $tmp19 := $ArrayContents[$tmp18][x + 1];
+ $tmp20 := RegressionTestInput.ClassWithArrayTypes.a[this];
+ $tmp21 := $ArrayContents[$tmp20][x];
+ assert $tmp19 == $tmp21 + 1;
assert {:sourceFile "Class1.cs"} {:sourceLine 117} true;
return;
}
-procedure RegressionTestInput.ClassWithArrayTypes.Main4$System.Int32array(this: int, xs$in: int);
+procedure RegressionTestInput.ClassWithArrayTypes.Main4$System.Int32array(this: Ref, xs$in: Ref);
-implementation RegressionTestInput.ClassWithArrayTypes.Main4$System.Int32array(this: int, xs$in: int)
+implementation RegressionTestInput.ClassWithArrayTypes.Main4$System.Int32array(this: Ref, xs$in: Ref)
{
- var xs: int;
+ var xs: Ref;
+ var $tmp22: int;
+ var _loc0: Ref;
+ var $tmp23: Ref;
+ var $tmp24: int;
xs := xs$in;
- if (!(if xs != 0 then $ArrayLength[xs] <= 0 else true))
+ if (!(if xs != null then $ArrayLength[xs] <= 0 else true))
{
assert {:sourceFile "Class1.cs"} {:sourceLine 121} true;
- $ArrayContents := $ArrayContents[RegressionTestInput.ClassWithArrayTypes.a[this] := $ArrayContents[RegressionTestInput.ClassWithArrayTypes.a[this]][0 := $ArrayContents[xs][0]]];
+ $tmp22 := $ArrayContents[xs][0];
+ $tmp23 := RegressionTestInput.ClassWithArrayTypes.a[this];
+ _loc0 := $tmp23;
+ $tmp24 := $ArrayContents[_loc0][0];
+ $ArrayContents := $ArrayContents[_loc0 := $ArrayContents[_loc0][0 := $tmp22]];
}
else
{
@@ -318,17 +410,17 @@ implementation RegressionTestInput.ClassWithArrayTypes.Main4$System.Int32array(t
-procedure RegressionTestInput.ClassWithArrayTypes.#ctor(this: int);
+procedure RegressionTestInput.ClassWithArrayTypes.#ctor(this: Ref);
-procedure System.Object.#ctor(this: int);
+procedure System.Object.#ctor(this: Ref);
-implementation RegressionTestInput.ClassWithArrayTypes.#ctor(this: int)
+implementation RegressionTestInput.ClassWithArrayTypes.#ctor(this: Ref)
{
- RegressionTestInput.ClassWithArrayTypes.a[this] := 0;
+ RegressionTestInput.ClassWithArrayTypes.a[this] := null;
call System.Object.#ctor(this);
return;
}
@@ -341,7 +433,46 @@ procedure RegressionTestInput.ClassWithArrayTypes.#cctor();
implementation RegressionTestInput.ClassWithArrayTypes.#cctor()
{
- RegressionTestInput.ClassWithArrayTypes.s := 0;
+ RegressionTestInput.ClassWithArrayTypes.s := null;
+}
+
+
+
+const unique RegressionTestInput.RefParameters: Type;
+
+procedure RegressionTestInput.RefParameters.M$System.Int32$(x$in: int) returns (x$out: int);
+
+
+
+implementation RegressionTestInput.RefParameters.M$System.Int32$(x$in: int) returns (x$out: int)
+{
+ x$out := x$in;
+ assert {:sourceFile "Class1.cs"} {:sourceLine 156} true;
+ x$out := x$out + 1;
+ assert {:sourceFile "Class1.cs"} {:sourceLine 157} true;
+ return;
+}
+
+
+
+procedure RegressionTestInput.RefParameters.#ctor(this: Ref);
+
+
+
+implementation RegressionTestInput.RefParameters.#ctor(this: Ref)
+{
+ call System.Object.#ctor(this);
+ return;
+}
+
+
+
+procedure RegressionTestInput.RefParameters.#cctor();
+
+
+
+implementation RegressionTestInput.RefParameters.#cctor()
+{
}
@@ -366,21 +497,21 @@ implementation RegressionTestInput.Class0.StaticMethod$System.Int32(x$in: int) r
-procedure RegressionTestInput.Class0.M$System.Int32(this: int, x$in: int);
+procedure RegressionTestInput.Class0.M$System.Int32(this: Ref, x$in: int);
-implementation RegressionTestInput.Class0.M$System.Int32(this: int, x$in: int)
+implementation RegressionTestInput.Class0.M$System.Int32(this: Ref, x$in: int)
{
var x: int;
var __temp_1: int;
- var $tmp4: int;
+ var $tmp25: int;
var local_0: int;
x := x$in;
- $tmp4 := x;
- assert $tmp4 != 0;
- __temp_1 := 5 / $tmp4;
+ $tmp25 := x;
+ assert $tmp25 != 0;
+ __temp_1 := 5 / $tmp25;
x := 3;
local_0 := __temp_1 + 3;
assert {:sourceFile "Class1.cs"} {:sourceLine 22} true;
@@ -395,11 +526,11 @@ implementation RegressionTestInput.Class0.M$System.Int32(this: int, x$in: int)
-procedure RegressionTestInput.Class0.M$System.Int32$System.Int32(this: int, x$in: int, y$in: int);
+procedure RegressionTestInput.Class0.M$System.Int32$System.Int32(this: Ref, x$in: int, y$in: int);
-implementation RegressionTestInput.Class0.M$System.Int32$System.Int32(this: int, x$in: int, y$in: int)
+implementation RegressionTestInput.Class0.M$System.Int32$System.Int32(this: Ref, x$in: int, y$in: int)
{
var x: int;
var y: int;
@@ -412,11 +543,11 @@ implementation RegressionTestInput.Class0.M$System.Int32$System.Int32(this: int,
-procedure RegressionTestInput.Class0.M$System.Boolean(this: int, b$in: bool);
+procedure RegressionTestInput.Class0.M$System.Boolean(this: Ref, b$in: bool);
-implementation RegressionTestInput.Class0.M$System.Boolean(this: int, b$in: bool)
+implementation RegressionTestInput.Class0.M$System.Boolean(this: Ref, b$in: bool)
{
var b: bool;
@@ -427,13 +558,13 @@ implementation RegressionTestInput.Class0.M$System.Boolean(this: int, b$in: bool
-procedure RegressionTestInput.Class0.M$RegressionTestInput.Class0(this: int, c$in: int);
+procedure RegressionTestInput.Class0.M$RegressionTestInput.Class0(this: Ref, c$in: Ref);
-implementation RegressionTestInput.Class0.M$RegressionTestInput.Class0(this: int, c$in: int)
+implementation RegressionTestInput.Class0.M$RegressionTestInput.Class0(this: Ref, c$in: Ref)
{
- var c: int;
+ var c: Ref;
c := c$in;
assert {:sourceFile "Class1.cs"} {:sourceLine 30} true;
@@ -442,27 +573,27 @@ implementation RegressionTestInput.Class0.M$RegressionTestInput.Class0(this: int
-procedure RegressionTestInput.Class0.NonVoid(this: int) returns ($result: int);
+procedure RegressionTestInput.Class0.NonVoid(this: Ref) returns ($result: int);
-implementation RegressionTestInput.Class0.NonVoid(this: int) returns ($result: int)
+implementation RegressionTestInput.Class0.NonVoid(this: Ref) returns ($result: int)
{
- var $tmp5: int;
+ var $tmp26: int;
assert {:sourceFile "Class1.cs"} {:sourceLine 34} true;
- call $tmp5 := RegressionTestInput.Class0.StaticMethod$System.Int32(3);
- $result := 3 + RegressionTestInput.Class0.StaticInt + $tmp5;
+ call $tmp26 := RegressionTestInput.Class0.StaticMethod$System.Int32(3);
+ $result := 3 + RegressionTestInput.Class0.StaticInt + $tmp26;
return;
}
-procedure RegressionTestInput.Class0.OutParam$System.Int32$(this: int) returns (x$out: int, $result: int);
+procedure RegressionTestInput.Class0.OutParam$System.Int32$(this: Ref) returns (x$out: int, $result: int);
-implementation RegressionTestInput.Class0.OutParam$System.Int32$(this: int) returns (x$out: int, $result: int)
+implementation RegressionTestInput.Class0.OutParam$System.Int32$(this: Ref) returns (x$out: int, $result: int)
{
assert {:sourceFile "Class1.cs"} {:sourceLine 37} true;
x$out := 3 + RegressionTestInput.Class0.StaticInt;
@@ -473,11 +604,11 @@ implementation RegressionTestInput.Class0.OutParam$System.Int32$(this: int) retu
-procedure RegressionTestInput.Class0.RefParam$System.Int32$(this: int, x$in: int) returns (x$out: int, $result: int);
+procedure RegressionTestInput.Class0.RefParam$System.Int32$(this: Ref, x$in: int) returns (x$out: int, $result: int);
-implementation RegressionTestInput.Class0.RefParam$System.Int32$(this: int, x$in: int) returns (x$out: int, $result: int)
+implementation RegressionTestInput.Class0.RefParam$System.Int32$(this: Ref, x$in: int) returns (x$out: int, $result: int)
{
x$out := x$in;
assert {:sourceFile "Class1.cs"} {:sourceLine 42} true;
@@ -491,11 +622,11 @@ implementation RegressionTestInput.Class0.RefParam$System.Int32$(this: int, x$in
-procedure RegressionTestInput.Class0.AssignToInParam$System.Int32(this: int, x$in: int) returns ($result: int);
+procedure RegressionTestInput.Class0.AssignToInParam$System.Int32(this: Ref, x$in: int) returns ($result: int);
-implementation RegressionTestInput.Class0.AssignToInParam$System.Int32(this: int, x$in: int) returns ($result: int)
+implementation RegressionTestInput.Class0.AssignToInParam$System.Int32(this: Ref, x$in: int) returns ($result: int)
{
var x: int;
@@ -511,11 +642,11 @@ implementation RegressionTestInput.Class0.AssignToInParam$System.Int32(this: int
-procedure {:RegressionTestInput.Async} RegressionTestInput.Class0.MethodThatRepresentsAnAynchronousMethod$System.Int32(this: int, x$in: int) returns ($result: int);
+procedure {:RegressionTestInput.Async} RegressionTestInput.Class0.MethodThatRepresentsAnAynchronousMethod$System.Int32(this: Ref, x$in: int) returns ($result: int);
-implementation RegressionTestInput.Class0.MethodThatRepresentsAnAynchronousMethod$System.Int32(this: int, x$in: int) returns ($result: int)
+implementation RegressionTestInput.Class0.MethodThatRepresentsAnAynchronousMethod$System.Int32(this: Ref, x$in: int) returns ($result: int)
{
var x: int;
@@ -527,29 +658,29 @@ implementation RegressionTestInput.Class0.MethodThatRepresentsAnAynchronousMetho
-procedure RegressionTestInput.Class0.CallAsyncMethod$System.Int32(this: int, y$in: int) returns ($result: int);
+procedure RegressionTestInput.Class0.CallAsyncMethod$System.Int32(this: Ref, y$in: int) returns ($result: int);
-implementation RegressionTestInput.Class0.CallAsyncMethod$System.Int32(this: int, y$in: int) returns ($result: int)
+implementation RegressionTestInput.Class0.CallAsyncMethod$System.Int32(this: Ref, y$in: int) returns ($result: int)
{
var y: int;
- var $tmp6: int;
+ var $tmp27: int;
y := y$in;
assert {:sourceFile "Class1.cs"} {:sourceLine 60} true;
- call {:async} $tmp6 := RegressionTestInput.Class0.MethodThatRepresentsAnAynchronousMethod$System.Int32(this, y);
- $result := $tmp6;
+ call {:async} $tmp27 := RegressionTestInput.Class0.MethodThatRepresentsAnAynchronousMethod$System.Int32(this, y);
+ $result := $tmp27;
return;
}
-procedure RegressionTestInput.Class0.#ctor(this: int);
+procedure RegressionTestInput.Class0.#ctor(this: Ref);
-implementation RegressionTestInput.Class0.#ctor(this: int)
+implementation RegressionTestInput.Class0.#ctor(this: Ref)
{
call System.Object.#ctor(this);
return;
@@ -570,29 +701,32 @@ implementation RegressionTestInput.Class0.#cctor()
const unique RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap: Type;
-var RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.x: [int]int;
+var RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.x: [Ref]int;
-var RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.y: [int]int;
+var RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.y: [Ref]int;
-procedure RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.M(this: int);
+procedure RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.M(this: Ref);
-implementation RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.M(this: int)
+implementation RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.M(this: Ref)
{
+ var $tmp28: int;
+
assert {:sourceFile "Class1.cs"} {:sourceLine 130} true;
- RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.y[this] := RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.x[this];
+ $tmp28 := RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.x[this];
+ RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.y[this] := $tmp28;
assert {:sourceFile "Class1.cs"} {:sourceLine 131} true;
return;
}
-procedure RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.#ctor(this: int);
+procedure RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.#ctor(this: Ref);
-implementation RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.#ctor(this: int)
+implementation RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.#ctor(this: Ref)
{
RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.x[this] := 0;
RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.y[this] := 0;
@@ -616,7 +750,7 @@ const unique RegressionTestInput.ClassWithBoolTypes: Type;
var RegressionTestInput.ClassWithBoolTypes.staticB: bool;
-var RegressionTestInput.ClassWithBoolTypes.b: [int]bool;
+var RegressionTestInput.ClassWithBoolTypes.b: [Ref]bool;
procedure RegressionTestInput.ClassWithBoolTypes.M$System.Int32$System.Int32(x$in: int, y$in: int) returns ($result: bool);
@@ -636,11 +770,11 @@ implementation RegressionTestInput.ClassWithBoolTypes.M$System.Int32$System.Int3
-procedure RegressionTestInput.ClassWithBoolTypes.#ctor$System.Boolean(this: int, z$in: bool);
+procedure RegressionTestInput.ClassWithBoolTypes.#ctor$System.Boolean(this: Ref, z$in: bool);
-implementation RegressionTestInput.ClassWithBoolTypes.#ctor$System.Boolean(this: int, z$in: bool)
+implementation RegressionTestInput.ClassWithBoolTypes.#ctor$System.Boolean(this: Ref, z$in: bool)
{
var z: bool;
@@ -671,10 +805,10 @@ procedure RegressionTestInput.ClassWithBoolTypes.Main();
implementation RegressionTestInput.ClassWithBoolTypes.Main()
{
- var $tmp7: bool;
+ var $tmp29: bool;
assert {:sourceFile "Class1.cs"} {:sourceLine 78} true;
- call $tmp7 := RegressionTestInput.ClassWithBoolTypes.M$System.Int32$System.Int32(3, 4);
+ call $tmp29 := RegressionTestInput.ClassWithBoolTypes.M$System.Int32$System.Int32(3, 4);
assert {:sourceFile "Class1.cs"} {:sourceLine 79} true;
return;
}
@@ -692,17 +826,23 @@ implementation RegressionTestInput.ClassWithBoolTypes.#cctor()
+const unique RegressionTestInput.S: Type;
+
+var RegressionTestInput.S.x: [Ref]int;
+
+var RegressionTestInput.S.b: [Ref]bool;
+
const unique RegressionTestInput.AsyncAttribute: Type;
-procedure RegressionTestInput.AsyncAttribute.#ctor(this: int);
+procedure RegressionTestInput.AsyncAttribute.#ctor(this: Ref);
-procedure System.Attribute.#ctor(this: int);
+procedure System.Attribute.#ctor(this: Ref);
-implementation RegressionTestInput.AsyncAttribute.#ctor(this: int)
+implementation RegressionTestInput.AsyncAttribute.#ctor(this: Ref)
{
call System.Attribute.#ctor(this);
return;
@@ -719,3 +859,74 @@ implementation RegressionTestInput.AsyncAttribute.#cctor()
}
+
+const unique RegressionTestInput.CreateStruct: Type;
+
+procedure RegressionTestInput.CreateStruct.Create(this: Ref) returns ($result: [Field]Box);
+
+
+
+implementation RegressionTestInput.CreateStruct.Create(this: Ref) returns ($result: [Field]Box)
+{
+ var local_0: [Field]Box;
+ var $tmp30: int;
+ var $tmp31: bool;
+
+ assert {:sourceFile "Class1.cs"} {:sourceLine 141} true;
+ local_0 := $DefaultStruct;
+ assert {:sourceFile "Class1.cs"} {:sourceLine 142} true;
+ $tmp30 := local_0[RegressionTestInput.S.x];
+ assert $tmp30 == 0;
+ assert {:sourceFile "Class1.cs"} {:sourceLine 143} true;
+ $tmp31 := local_0[RegressionTestInput.S.b];
+ assert !$tmp31;
+ assert {:sourceFile "Class1.cs"} {:sourceLine 145} true;
+ $result := local_0;
+ return;
+}
+
+
+
+procedure RegressionTestInput.CreateStruct.AssignThreeToSDotX$RegressionTestInput.S(this: Ref, s$in: [Field]Box) returns ($result: [Field]Box);
+
+
+
+implementation RegressionTestInput.CreateStruct.AssignThreeToSDotX$RegressionTestInput.S(this: Ref, s$in: [Field]Box) returns ($result: [Field]Box)
+{
+ var s: [Field]Box;
+ var $tmp32: int;
+
+ s := s$in;
+ assert {:sourceFile "Class1.cs"} {:sourceLine 147} true;
+ s[RegressionTestInput.S.x] := 3;
+ assert {:sourceFile "Class1.cs"} {:sourceLine 148} true;
+ $tmp32 := s[RegressionTestInput.S.x];
+ assert $tmp32 == 3;
+ assert {:sourceFile "Class1.cs"} {:sourceLine 150} true;
+ $result := s;
+ return;
+}
+
+
+
+procedure RegressionTestInput.CreateStruct.#ctor(this: Ref);
+
+
+
+implementation RegressionTestInput.CreateStruct.#ctor(this: Ref)
+{
+ call System.Object.#ctor(this);
+ return;
+}
+
+
+
+procedure RegressionTestInput.CreateStruct.#cctor();
+
+
+
+implementation RegressionTestInput.CreateStruct.#cctor()
+{
+}
+
+
diff --git a/BCT/RegressionTests/TranslationTest/TranslationTest.csproj b/BCT/RegressionTests/TranslationTest/TranslationTest.csproj
index cef103b7..b0dd1907 100644
--- a/BCT/RegressionTests/TranslationTest/TranslationTest.csproj
+++ b/BCT/RegressionTests/TranslationTest/TranslationTest.csproj
@@ -102,15 +102,9 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
- <EmbeddedResource Include="TwoDIntHeapInput.txt" />
- </ItemGroup>
- <ItemGroup>
<EmbeddedResource Include="SplitFieldsHeapInput.txt" />
</ItemGroup>
<ItemGroup>
- <EmbeddedResource Include="TwoDBoxHeapInput.txt" />
- </ItemGroup>
- <ItemGroup>
<EmbeddedResource Include="GeneralHeapInput.txt" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
diff --git a/BCT/RegressionTests/TranslationTest/TwoDBoxHeapInput.txt b/BCT/RegressionTests/TranslationTest/TwoDBoxHeapInput.txt
deleted file mode 100644
index c23df829..00000000
--- a/BCT/RegressionTests/TranslationTest/TwoDBoxHeapInput.txt
+++ /dev/null
@@ -1,729 +0,0 @@
-// Copyright (c) 2010, Microsoft Corp.
-// Bytecode Translator prelude
-
-const null: int;
-
-type box;
-
-type HeapType = [int,int]box;
-
-function IsGoodHeap(HeapType) : bool;
-
-var $ArrayContents: [int][int]int;
-
-var $ArrayLength: [int]int;
-
-var $Alloc: [int]bool;
-
-procedure {:inline 1} Alloc() returns (x: int);
- modifies $Alloc;
- free ensures x != 0;
-
-
-
-implementation Alloc() returns (x: int)
-{
- assume $Alloc[x] == false;
- $Alloc[x] := true;
-}
-
-
-
-procedure DelegateAdd(a: int, b: int) returns (c: int);
-
-
-
-implementation DelegateAdd(a: int, b: int) returns (c: int)
-{
- var m: int;
- var o: int;
-
- if (a == 0)
- {
- c := b;
- return;
- }
- else if (b == 0)
- {
- c := a;
- return;
- }
-
- call m, o := GetFirstElement(b);
- call c := Alloc();
- $Head[c] := $Head[a];
- $Next[c] := $Next[a];
- $Method[c] := $Method[a];
- $Receiver[c] := $Receiver[a];
- call c := DelegateAddHelper(c, m, o);
-}
-
-
-
-procedure DelegateRemove(a: int, b: int) returns (c: int);
-
-
-
-implementation DelegateRemove(a: int, b: int) returns (c: int)
-{
- var m: int;
- var o: int;
-
- if (a == 0)
- {
- c := 0;
- return;
- }
- else if (b == 0)
- {
- c := a;
- return;
- }
-
- call m, o := GetFirstElement(b);
- call c := Alloc();
- $Head[c] := $Head[a];
- $Next[c] := $Next[a];
- $Method[c] := $Method[a];
- $Receiver[c] := $Receiver[a];
- call c := DelegateRemoveHelper(c, m, o);
-}
-
-
-
-procedure GetFirstElement(i: int) returns (m: int, o: int);
-
-
-
-implementation GetFirstElement(i: int) returns (m: int, o: int)
-{
- var first: int;
-
- first := $Next[i][$Head[i]];
- m := $Method[i][first];
- o := $Receiver[i][first];
-}
-
-
-
-procedure DelegateAddHelper(oldi: int, m: int, o: int) returns (i: int);
-
-
-
-implementation DelegateAddHelper(oldi: int, m: int, o: int) returns (i: int)
-{
- var x: int;
- var h: int;
-
- if (oldi == 0)
- {
- call i := Alloc();
- call x := Alloc();
- $Head[i] := x;
- $Next[i] := $Next[i][x := x];
- }
- else
- {
- i := oldi;
- }
-
- h := $Head[i];
- $Method[i] := $Method[i][h := m];
- $Receiver[i] := $Receiver[i][h := o];
- call x := Alloc();
- $Next[i] := $Next[i][x := $Next[i][h]];
- $Next[i] := $Next[i][h := x];
- $Head[i] := x;
-}
-
-
-
-procedure DelegateRemoveHelper(oldi: int, m: int, o: int) returns (i: int);
-
-
-
-implementation DelegateRemoveHelper(oldi: int, m: int, o: int) returns (i: int)
-{
- var prev: int;
- var iter: int;
- var niter: int;
-
- i := oldi;
- if (i == 0)
- {
- return;
- }
-
- prev := 0;
- iter := $Head[i];
- while (true)
- {
- niter := $Next[i][iter];
- if (niter == $Head[i])
- {
- break;
- }
-
- if ($Method[i][niter] == m && $Receiver[i][niter] == o)
- {
- prev := iter;
- }
-
- iter := niter;
- }
-
- if (prev == 0)
- {
- return;
- }
-
- $Next[i] := $Next[i][prev := $Next[i][$Next[i][prev]]];
- if ($Next[i][$Head[i]] == $Head[i])
- {
- i := 0;
- }
-}
-
-
-
-var $Heap: HeapType where IsGoodHeap($Heap);
-
-function Box2Int(box) : int;
-
-function Box2Bool(box) : bool;
-
-function Int2Box(int) : box;
-
-function Bool2Box(bool) : box;
-
-type Type;
-
-function $DynamicType(ref) : Type;
-
-function $TypeOf(Type) : ref;
-
-var $Head: [int]int;
-
-var $Next: [int][int]int;
-
-var $Method: [int][int]int;
-
-var $Receiver: [int][int]int;
-
-const unique RegressionTestInput.ClassWithArrayTypes: Type;
-
-var RegressionTestInput.ClassWithArrayTypes.s: int;
-
-const unique RegressionTestInput.ClassWithArrayTypes.a: int;
-
-procedure RegressionTestInput.ClassWithArrayTypes.Main1();
-
-
-
-implementation RegressionTestInput.ClassWithArrayTypes.Main1()
-{
- var local_0: int;
- var $tmp0: int;
- var local_1: int;
- var $tmp1: int;
-
- assert {:sourceFile "Class1.cs"} {:sourceLine 86} true;
- call $tmp0 := Alloc();
- local_0 := $tmp0;
- assert {:sourceFile "Class1.cs"} {:sourceLine 87} true;
- $ArrayContents := $ArrayContents[local_0 := $ArrayContents[local_0][0 := 2]];
- assert {:sourceFile "Class1.cs"} {:sourceLine 88} true;
- assert $ArrayContents[local_0][0] == 2;
- assert {:sourceFile "Class1.cs"} {:sourceLine 90} true;
- call $tmp1 := Alloc();
- local_1 := $tmp1;
- assert {:sourceFile "Class1.cs"} {:sourceLine 91} true;
- $ArrayContents := $ArrayContents[local_1 := $ArrayContents[local_1][0 := 1]];
- assert {:sourceFile "Class1.cs"} {:sourceLine 92} true;
- assert $ArrayContents[local_1][0] == 1;
- assert {:sourceFile "Class1.cs"} {:sourceLine 94} true;
- assert $ArrayContents[local_0][0] == 2;
- assert {:sourceFile "Class1.cs"} {:sourceLine 95} true;
- return;
-}
-
-
-
-procedure RegressionTestInput.ClassWithArrayTypes.Main2();
-
-
-
-implementation RegressionTestInput.ClassWithArrayTypes.Main2()
-{
- var $tmp2: int;
- var local_0: int;
- var $tmp3: int;
-
- assert {:sourceFile "Class1.cs"} {:sourceLine 100} true;
- call $tmp2 := Alloc();
- RegressionTestInput.ClassWithArrayTypes.s := $tmp2;
- assert {:sourceFile "Class1.cs"} {:sourceLine 101} true;
- $ArrayContents := $ArrayContents[RegressionTestInput.ClassWithArrayTypes.s := $ArrayContents[RegressionTestInput.ClassWithArrayTypes.s][0 := 2]];
- assert {:sourceFile "Class1.cs"} {:sourceLine 102} true;
- assert $ArrayContents[RegressionTestInput.ClassWithArrayTypes.s][0] == 2;
- assert {:sourceFile "Class1.cs"} {:sourceLine 104} true;
- call $tmp3 := Alloc();
- local_0 := $tmp3;
- assert {:sourceFile "Class1.cs"} {:sourceLine 105} true;
- $ArrayContents := $ArrayContents[local_0 := $ArrayContents[local_0][0 := 1]];
- assert {:sourceFile "Class1.cs"} {:sourceLine 106} true;
- assert $ArrayContents[local_0][0] == 1;
- assert {:sourceFile "Class1.cs"} {:sourceLine 108} true;
- assert $ArrayContents[RegressionTestInput.ClassWithArrayTypes.s][0] == 2;
- assert {:sourceFile "Class1.cs"} {:sourceLine 109} true;
- return;
-}
-
-
-
-procedure RegressionTestInput.ClassWithArrayTypes.Main3$System.Int32(this: int, x$in: int);
-
-
-
-implementation RegressionTestInput.ClassWithArrayTypes.Main3$System.Int32(this: int, x$in: int)
-{
- var x: int;
-
- x := x$in;
- assert {:sourceFile "Class1.cs"} {:sourceLine 114} true;
- $ArrayContents := $ArrayContents[Box2Int($Heap[this, RegressionTestInput.ClassWithArrayTypes.a]) := $ArrayContents[Box2Int($Heap[this, RegressionTestInput.ClassWithArrayTypes.a])][x := 42]];
- assert {:sourceFile "Class1.cs"} {:sourceLine 115} true;
- $ArrayContents := $ArrayContents[Box2Int($Heap[this, RegressionTestInput.ClassWithArrayTypes.a]) := $ArrayContents[Box2Int($Heap[this, RegressionTestInput.ClassWithArrayTypes.a])][x + 1 := 43]];
- assert {:sourceFile "Class1.cs"} {:sourceLine 116} true;
- assert $ArrayContents[Box2Int($Heap[this, RegressionTestInput.ClassWithArrayTypes.a])][x + 1] == $ArrayContents[Box2Int($Heap[this, RegressionTestInput.ClassWithArrayTypes.a])][x] + 1;
- assert {:sourceFile "Class1.cs"} {:sourceLine 117} true;
- return;
-}
-
-
-
-procedure RegressionTestInput.ClassWithArrayTypes.Main4$System.Int32array(this: int, xs$in: int);
-
-
-
-implementation RegressionTestInput.ClassWithArrayTypes.Main4$System.Int32array(this: int, xs$in: int)
-{
- var xs: int;
-
- xs := xs$in;
- if (!(if xs != 0 then $ArrayLength[xs] <= 0 else true))
- {
- assert {:sourceFile "Class1.cs"} {:sourceLine 121} true;
- $ArrayContents := $ArrayContents[Box2Int($Heap[this, RegressionTestInput.ClassWithArrayTypes.a]) := $ArrayContents[Box2Int($Heap[this, RegressionTestInput.ClassWithArrayTypes.a])][0 := $ArrayContents[xs][0]]];
- }
- else
- {
- }
-
- assert {:sourceFile "Class1.cs"} {:sourceLine 123} true;
- return;
-}
-
-
-
-procedure RegressionTestInput.ClassWithArrayTypes.#ctor(this: int);
-
-
-
-procedure System.Object.#ctor(this: int);
-
-
-
-implementation RegressionTestInput.ClassWithArrayTypes.#ctor(this: int)
-{
- $Heap[this, RegressionTestInput.ClassWithArrayTypes.a] := Int2Box(0);
- call System.Object.#ctor(this);
- return;
-}
-
-
-
-procedure RegressionTestInput.ClassWithArrayTypes.#cctor();
-
-
-
-implementation RegressionTestInput.ClassWithArrayTypes.#cctor()
-{
- RegressionTestInput.ClassWithArrayTypes.s := 0;
-}
-
-
-
-const unique RegressionTestInput.Class0: Type;
-
-var RegressionTestInput.Class0.StaticInt: int;
-
-procedure RegressionTestInput.Class0.StaticMethod$System.Int32(x$in: int) returns ($result: int);
-
-
-
-implementation RegressionTestInput.Class0.StaticMethod$System.Int32(x$in: int) returns ($result: int)
-{
- var x: int;
-
- x := x$in;
- assert {:sourceFile "Class1.cs"} {:sourceLine 18} true;
- $result := x + 1;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.M$System.Int32(this: int, x$in: int);
-
-
-
-implementation RegressionTestInput.Class0.M$System.Int32(this: int, x$in: int)
-{
- var x: int;
- var __temp_1: int;
- var $tmp4: int;
- var local_0: int;
-
- x := x$in;
- $tmp4 := x;
- assert $tmp4 != 0;
- __temp_1 := 5 / $tmp4;
- x := 3;
- local_0 := __temp_1 + 3;
- assert {:sourceFile "Class1.cs"} {:sourceLine 22} true;
- assert (if x == 3 then local_0 <= 8 else false);
- assert {:sourceFile "Class1.cs"} {:sourceLine 23} true;
- RegressionTestInput.Class0.StaticInt := local_0;
- assert {:sourceFile "Class1.cs"} {:sourceLine 24} true;
- assert local_0 == RegressionTestInput.Class0.StaticInt;
- assert {:sourceFile "Class1.cs"} {:sourceLine 25} true;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.M$System.Int32$System.Int32(this: int, x$in: int, y$in: int);
-
-
-
-implementation RegressionTestInput.Class0.M$System.Int32$System.Int32(this: int, x$in: int, y$in: int)
-{
- var x: int;
- var y: int;
-
- x := x$in;
- y := y$in;
- assert {:sourceFile "Class1.cs"} {:sourceLine 28} true;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.M$System.Boolean(this: int, b$in: bool);
-
-
-
-implementation RegressionTestInput.Class0.M$System.Boolean(this: int, b$in: bool)
-{
- var b: bool;
-
- b := b$in;
- assert {:sourceFile "Class1.cs"} {:sourceLine 29} true;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.M$RegressionTestInput.Class0(this: int, c$in: int);
-
-
-
-implementation RegressionTestInput.Class0.M$RegressionTestInput.Class0(this: int, c$in: int)
-{
- var c: int;
-
- c := c$in;
- assert {:sourceFile "Class1.cs"} {:sourceLine 30} true;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.NonVoid(this: int) returns ($result: int);
-
-
-
-implementation RegressionTestInput.Class0.NonVoid(this: int) returns ($result: int)
-{
- var $tmp5: int;
-
- assert {:sourceFile "Class1.cs"} {:sourceLine 34} true;
- call $tmp5 := RegressionTestInput.Class0.StaticMethod$System.Int32(3);
- $result := 3 + RegressionTestInput.Class0.StaticInt + $tmp5;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.OutParam$System.Int32$(this: int) returns (x$out: int, $result: int);
-
-
-
-implementation RegressionTestInput.Class0.OutParam$System.Int32$(this: int) returns (x$out: int, $result: int)
-{
- assert {:sourceFile "Class1.cs"} {:sourceLine 37} true;
- x$out := 3 + RegressionTestInput.Class0.StaticInt;
- assert {:sourceFile "Class1.cs"} {:sourceLine 39} true;
- $result := x$out;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.RefParam$System.Int32$(this: int, x$in: int) returns (x$out: int, $result: int);
-
-
-
-implementation RegressionTestInput.Class0.RefParam$System.Int32$(this: int, x$in: int) returns (x$out: int, $result: int)
-{
- x$out := x$in;
- assert {:sourceFile "Class1.cs"} {:sourceLine 42} true;
- x$out := x$out + 1;
- assert {:sourceFile "Class1.cs"} {:sourceLine 43} true;
- RegressionTestInput.Class0.StaticInt := x$out;
- assert {:sourceFile "Class1.cs"} {:sourceLine 45} true;
- $result := x$out;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.AssignToInParam$System.Int32(this: int, x$in: int) returns ($result: int);
-
-
-
-implementation RegressionTestInput.Class0.AssignToInParam$System.Int32(this: int, x$in: int) returns ($result: int)
-{
- var x: int;
-
- x := x$in;
- assert {:sourceFile "Class1.cs"} {:sourceLine 48} true;
- x := x + 1;
- assert {:sourceFile "Class1.cs"} {:sourceLine 49} true;
- RegressionTestInput.Class0.StaticInt := x;
- assert {:sourceFile "Class1.cs"} {:sourceLine 51} true;
- $result := x;
- return;
-}
-
-
-
-procedure {:RegressionTestInput.Async} RegressionTestInput.Class0.MethodThatRepresentsAnAynchronousMethod$System.Int32(this: int, x$in: int) returns ($result: int);
-
-
-
-implementation RegressionTestInput.Class0.MethodThatRepresentsAnAynchronousMethod$System.Int32(this: int, x$in: int) returns ($result: int)
-{
- var x: int;
-
- x := x$in;
- assert {:sourceFile "Class1.cs"} {:sourceLine 56} true;
- $result := x;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.CallAsyncMethod$System.Int32(this: int, y$in: int) returns ($result: int);
-
-
-
-implementation RegressionTestInput.Class0.CallAsyncMethod$System.Int32(this: int, y$in: int) returns ($result: int)
-{
- var y: int;
- var $tmp6: int;
-
- y := y$in;
- assert {:sourceFile "Class1.cs"} {:sourceLine 60} true;
- call {:async} $tmp6 := RegressionTestInput.Class0.MethodThatRepresentsAnAynchronousMethod$System.Int32(this, y);
- $result := $tmp6;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.#ctor(this: int);
-
-
-
-implementation RegressionTestInput.Class0.#ctor(this: int)
-{
- call System.Object.#ctor(this);
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.#cctor();
-
-
-
-implementation RegressionTestInput.Class0.#cctor()
-{
- RegressionTestInput.Class0.StaticInt := 0;
-}
-
-
-
-const unique RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap: Type;
-
-const unique RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.x: int;
-
-const unique RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.y: int;
-
-procedure RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.M(this: int);
-
-
-
-implementation RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.M(this: int)
-{
- assert {:sourceFile "Class1.cs"} {:sourceLine 130} true;
- $Heap[this, RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.y] := Int2Box(Box2Int($Heap[this, RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.x]));
- assert {:sourceFile "Class1.cs"} {:sourceLine 131} true;
- return;
-}
-
-
-
-procedure RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.#ctor(this: int);
-
-
-
-implementation RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.#ctor(this: int)
-{
- $Heap[this, RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.x] := Int2Box(0);
- $Heap[this, RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.y] := Int2Box(0);
- call System.Object.#ctor(this);
- return;
-}
-
-
-
-procedure RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.#cctor();
-
-
-
-implementation RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.#cctor()
-{
-}
-
-
-
-const unique RegressionTestInput.ClassWithBoolTypes: Type;
-
-var RegressionTestInput.ClassWithBoolTypes.staticB: bool;
-
-const unique RegressionTestInput.ClassWithBoolTypes.b: bool;
-
-procedure RegressionTestInput.ClassWithBoolTypes.M$System.Int32$System.Int32(x$in: int, y$in: int) returns ($result: bool);
-
-
-
-implementation RegressionTestInput.ClassWithBoolTypes.M$System.Int32$System.Int32(x$in: int, y$in: int) returns ($result: bool)
-{
- var x: int;
- var y: int;
-
- x := x$in;
- y := y$in;
- assert {:sourceFile "Class1.cs"} {:sourceLine 70} true;
- $result := x < y;
- return;
-}
-
-
-
-procedure RegressionTestInput.ClassWithBoolTypes.#ctor$System.Boolean(this: int, z$in: bool);
-
-
-
-implementation RegressionTestInput.ClassWithBoolTypes.#ctor$System.Boolean(this: int, z$in: bool)
-{
- var z: bool;
-
- z := z$in;
- $Heap[this, RegressionTestInput.ClassWithBoolTypes.b] := Bool2Box(false);
- assert {:sourceFile "Class1.cs"} {:sourceLine 72} true;
- call System.Object.#ctor(this);
- assert {:sourceFile "Class1.cs"} {:sourceLine 73} true;
- $Heap[this, RegressionTestInput.ClassWithBoolTypes.b] := Bool2Box(z);
- assert {:sourceFile "Class1.cs"} {:sourceLine 74} true;
- if (z)
- {
- assert {:sourceFile "Class1.cs"} {:sourceLine 74} true;
- RegressionTestInput.ClassWithBoolTypes.staticB := z;
- }
- else
- {
- }
-
- return;
-}
-
-
-
-procedure RegressionTestInput.ClassWithBoolTypes.Main();
-
-
-
-implementation RegressionTestInput.ClassWithBoolTypes.Main()
-{
- var $tmp7: bool;
-
- assert {:sourceFile "Class1.cs"} {:sourceLine 78} true;
- call $tmp7 := RegressionTestInput.ClassWithBoolTypes.M$System.Int32$System.Int32(3, 4);
- assert {:sourceFile "Class1.cs"} {:sourceLine 79} true;
- return;
-}
-
-
-
-procedure RegressionTestInput.ClassWithBoolTypes.#cctor();
-
-
-
-implementation RegressionTestInput.ClassWithBoolTypes.#cctor()
-{
- RegressionTestInput.ClassWithBoolTypes.staticB := false;
-}
-
-
-
-const unique RegressionTestInput.AsyncAttribute: Type;
-
-procedure RegressionTestInput.AsyncAttribute.#ctor(this: int);
-
-
-
-procedure System.Attribute.#ctor(this: int);
-
-
-
-implementation RegressionTestInput.AsyncAttribute.#ctor(this: int)
-{
- call System.Attribute.#ctor(this);
- return;
-}
-
-
-
-procedure RegressionTestInput.AsyncAttribute.#cctor();
-
-
-
-implementation RegressionTestInput.AsyncAttribute.#cctor()
-{
-}
-
-
diff --git a/BCT/RegressionTests/TranslationTest/TwoDIntHeapInput.txt b/BCT/RegressionTests/TranslationTest/TwoDIntHeapInput.txt
deleted file mode 100644
index 262958c0..00000000
--- a/BCT/RegressionTests/TranslationTest/TwoDIntHeapInput.txt
+++ /dev/null
@@ -1,719 +0,0 @@
-// Copyright (c) 2010, Microsoft Corp.
-// Bytecode Translator prelude
-
-const null: int;
-
-type HeapType = [int,int]int;
-
-function IsGoodHeap(HeapType) : bool;
-
-var $ArrayContents: [int][int]int;
-
-var $ArrayLength: [int]int;
-
-var $Alloc: [int]bool;
-
-procedure {:inline 1} Alloc() returns (x: int);
- modifies $Alloc;
- free ensures x != 0;
-
-
-
-implementation Alloc() returns (x: int)
-{
- assume $Alloc[x] == false;
- $Alloc[x] := true;
-}
-
-
-
-procedure DelegateAdd(a: int, b: int) returns (c: int);
-
-
-
-implementation DelegateAdd(a: int, b: int) returns (c: int)
-{
- var m: int;
- var o: int;
-
- if (a == 0)
- {
- c := b;
- return;
- }
- else if (b == 0)
- {
- c := a;
- return;
- }
-
- call m, o := GetFirstElement(b);
- call c := Alloc();
- $Head[c] := $Head[a];
- $Next[c] := $Next[a];
- $Method[c] := $Method[a];
- $Receiver[c] := $Receiver[a];
- call c := DelegateAddHelper(c, m, o);
-}
-
-
-
-procedure DelegateRemove(a: int, b: int) returns (c: int);
-
-
-
-implementation DelegateRemove(a: int, b: int) returns (c: int)
-{
- var m: int;
- var o: int;
-
- if (a == 0)
- {
- c := 0;
- return;
- }
- else if (b == 0)
- {
- c := a;
- return;
- }
-
- call m, o := GetFirstElement(b);
- call c := Alloc();
- $Head[c] := $Head[a];
- $Next[c] := $Next[a];
- $Method[c] := $Method[a];
- $Receiver[c] := $Receiver[a];
- call c := DelegateRemoveHelper(c, m, o);
-}
-
-
-
-procedure GetFirstElement(i: int) returns (m: int, o: int);
-
-
-
-implementation GetFirstElement(i: int) returns (m: int, o: int)
-{
- var first: int;
-
- first := $Next[i][$Head[i]];
- m := $Method[i][first];
- o := $Receiver[i][first];
-}
-
-
-
-procedure DelegateAddHelper(oldi: int, m: int, o: int) returns (i: int);
-
-
-
-implementation DelegateAddHelper(oldi: int, m: int, o: int) returns (i: int)
-{
- var x: int;
- var h: int;
-
- if (oldi == 0)
- {
- call i := Alloc();
- call x := Alloc();
- $Head[i] := x;
- $Next[i] := $Next[i][x := x];
- }
- else
- {
- i := oldi;
- }
-
- h := $Head[i];
- $Method[i] := $Method[i][h := m];
- $Receiver[i] := $Receiver[i][h := o];
- call x := Alloc();
- $Next[i] := $Next[i][x := $Next[i][h]];
- $Next[i] := $Next[i][h := x];
- $Head[i] := x;
-}
-
-
-
-procedure DelegateRemoveHelper(oldi: int, m: int, o: int) returns (i: int);
-
-
-
-implementation DelegateRemoveHelper(oldi: int, m: int, o: int) returns (i: int)
-{
- var prev: int;
- var iter: int;
- var niter: int;
-
- i := oldi;
- if (i == 0)
- {
- return;
- }
-
- prev := 0;
- iter := $Head[i];
- while (true)
- {
- niter := $Next[i][iter];
- if (niter == $Head[i])
- {
- break;
- }
-
- if ($Method[i][niter] == m && $Receiver[i][niter] == o)
- {
- prev := iter;
- }
-
- iter := niter;
- }
-
- if (prev == 0)
- {
- return;
- }
-
- $Next[i] := $Next[i][prev := $Next[i][$Next[i][prev]]];
- if ($Next[i][$Head[i]] == $Head[i])
- {
- i := 0;
- }
-}
-
-
-
-var $Heap: HeapType where IsGoodHeap($Heap);
-
-type Type;
-
-function $DynamicType(ref) : Type;
-
-function $TypeOf(Type) : ref;
-
-var $Head: [int]int;
-
-var $Next: [int][int]int;
-
-var $Method: [int][int]int;
-
-var $Receiver: [int][int]int;
-
-const unique RegressionTestInput.ClassWithArrayTypes: Type;
-
-var RegressionTestInput.ClassWithArrayTypes.s: int;
-
-const unique RegressionTestInput.ClassWithArrayTypes.a: int;
-
-procedure RegressionTestInput.ClassWithArrayTypes.Main1();
-
-
-
-implementation RegressionTestInput.ClassWithArrayTypes.Main1()
-{
- var local_0: int;
- var $tmp0: int;
- var local_1: int;
- var $tmp1: int;
-
- assert {:sourceFile "Class1.cs"} {:sourceLine 86} true;
- call $tmp0 := Alloc();
- local_0 := $tmp0;
- assert {:sourceFile "Class1.cs"} {:sourceLine 87} true;
- $ArrayContents := $ArrayContents[local_0 := $ArrayContents[local_0][0 := 2]];
- assert {:sourceFile "Class1.cs"} {:sourceLine 88} true;
- assert $ArrayContents[local_0][0] == 2;
- assert {:sourceFile "Class1.cs"} {:sourceLine 90} true;
- call $tmp1 := Alloc();
- local_1 := $tmp1;
- assert {:sourceFile "Class1.cs"} {:sourceLine 91} true;
- $ArrayContents := $ArrayContents[local_1 := $ArrayContents[local_1][0 := 1]];
- assert {:sourceFile "Class1.cs"} {:sourceLine 92} true;
- assert $ArrayContents[local_1][0] == 1;
- assert {:sourceFile "Class1.cs"} {:sourceLine 94} true;
- assert $ArrayContents[local_0][0] == 2;
- assert {:sourceFile "Class1.cs"} {:sourceLine 95} true;
- return;
-}
-
-
-
-procedure RegressionTestInput.ClassWithArrayTypes.Main2();
-
-
-
-implementation RegressionTestInput.ClassWithArrayTypes.Main2()
-{
- var $tmp2: int;
- var local_0: int;
- var $tmp3: int;
-
- assert {:sourceFile "Class1.cs"} {:sourceLine 100} true;
- call $tmp2 := Alloc();
- RegressionTestInput.ClassWithArrayTypes.s := $tmp2;
- assert {:sourceFile "Class1.cs"} {:sourceLine 101} true;
- $ArrayContents := $ArrayContents[RegressionTestInput.ClassWithArrayTypes.s := $ArrayContents[RegressionTestInput.ClassWithArrayTypes.s][0 := 2]];
- assert {:sourceFile "Class1.cs"} {:sourceLine 102} true;
- assert $ArrayContents[RegressionTestInput.ClassWithArrayTypes.s][0] == 2;
- assert {:sourceFile "Class1.cs"} {:sourceLine 104} true;
- call $tmp3 := Alloc();
- local_0 := $tmp3;
- assert {:sourceFile "Class1.cs"} {:sourceLine 105} true;
- $ArrayContents := $ArrayContents[local_0 := $ArrayContents[local_0][0 := 1]];
- assert {:sourceFile "Class1.cs"} {:sourceLine 106} true;
- assert $ArrayContents[local_0][0] == 1;
- assert {:sourceFile "Class1.cs"} {:sourceLine 108} true;
- assert $ArrayContents[RegressionTestInput.ClassWithArrayTypes.s][0] == 2;
- assert {:sourceFile "Class1.cs"} {:sourceLine 109} true;
- return;
-}
-
-
-
-procedure RegressionTestInput.ClassWithArrayTypes.Main3$System.Int32(this: int, x$in: int);
-
-
-
-implementation RegressionTestInput.ClassWithArrayTypes.Main3$System.Int32(this: int, x$in: int)
-{
- var x: int;
-
- x := x$in;
- assert {:sourceFile "Class1.cs"} {:sourceLine 114} true;
- $ArrayContents := $ArrayContents[$Heap[this, RegressionTestInput.ClassWithArrayTypes.a] := $ArrayContents[$Heap[this, RegressionTestInput.ClassWithArrayTypes.a]][x := 42]];
- assert {:sourceFile "Class1.cs"} {:sourceLine 115} true;
- $ArrayContents := $ArrayContents[$Heap[this, RegressionTestInput.ClassWithArrayTypes.a] := $ArrayContents[$Heap[this, RegressionTestInput.ClassWithArrayTypes.a]][x + 1 := 43]];
- assert {:sourceFile "Class1.cs"} {:sourceLine 116} true;
- assert $ArrayContents[$Heap[this, RegressionTestInput.ClassWithArrayTypes.a]][x + 1] == $ArrayContents[$Heap[this, RegressionTestInput.ClassWithArrayTypes.a]][x] + 1;
- assert {:sourceFile "Class1.cs"} {:sourceLine 117} true;
- return;
-}
-
-
-
-procedure RegressionTestInput.ClassWithArrayTypes.Main4$System.Int32array(this: int, xs$in: int);
-
-
-
-implementation RegressionTestInput.ClassWithArrayTypes.Main4$System.Int32array(this: int, xs$in: int)
-{
- var xs: int;
-
- xs := xs$in;
- if (!(if xs != 0 then $ArrayLength[xs] <= 0 else true))
- {
- assert {:sourceFile "Class1.cs"} {:sourceLine 121} true;
- $ArrayContents := $ArrayContents[$Heap[this, RegressionTestInput.ClassWithArrayTypes.a] := $ArrayContents[$Heap[this, RegressionTestInput.ClassWithArrayTypes.a]][0 := $ArrayContents[xs][0]]];
- }
- else
- {
- }
-
- assert {:sourceFile "Class1.cs"} {:sourceLine 123} true;
- return;
-}
-
-
-
-procedure RegressionTestInput.ClassWithArrayTypes.#ctor(this: int);
-
-
-
-procedure System.Object.#ctor(this: int);
-
-
-
-implementation RegressionTestInput.ClassWithArrayTypes.#ctor(this: int)
-{
- $Heap[this, RegressionTestInput.ClassWithArrayTypes.a] := 0;
- call System.Object.#ctor(this);
- return;
-}
-
-
-
-procedure RegressionTestInput.ClassWithArrayTypes.#cctor();
-
-
-
-implementation RegressionTestInput.ClassWithArrayTypes.#cctor()
-{
- RegressionTestInput.ClassWithArrayTypes.s := 0;
-}
-
-
-
-const unique RegressionTestInput.Class0: Type;
-
-var RegressionTestInput.Class0.StaticInt: int;
-
-procedure RegressionTestInput.Class0.StaticMethod$System.Int32(x$in: int) returns ($result: int);
-
-
-
-implementation RegressionTestInput.Class0.StaticMethod$System.Int32(x$in: int) returns ($result: int)
-{
- var x: int;
-
- x := x$in;
- assert {:sourceFile "Class1.cs"} {:sourceLine 18} true;
- $result := x + 1;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.M$System.Int32(this: int, x$in: int);
-
-
-
-implementation RegressionTestInput.Class0.M$System.Int32(this: int, x$in: int)
-{
- var x: int;
- var __temp_1: int;
- var $tmp4: int;
- var local_0: int;
-
- x := x$in;
- $tmp4 := x;
- assert $tmp4 != 0;
- __temp_1 := 5 / $tmp4;
- x := 3;
- local_0 := __temp_1 + 3;
- assert {:sourceFile "Class1.cs"} {:sourceLine 22} true;
- assert (if x == 3 then local_0 <= 8 else false);
- assert {:sourceFile "Class1.cs"} {:sourceLine 23} true;
- RegressionTestInput.Class0.StaticInt := local_0;
- assert {:sourceFile "Class1.cs"} {:sourceLine 24} true;
- assert local_0 == RegressionTestInput.Class0.StaticInt;
- assert {:sourceFile "Class1.cs"} {:sourceLine 25} true;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.M$System.Int32$System.Int32(this: int, x$in: int, y$in: int);
-
-
-
-implementation RegressionTestInput.Class0.M$System.Int32$System.Int32(this: int, x$in: int, y$in: int)
-{
- var x: int;
- var y: int;
-
- x := x$in;
- y := y$in;
- assert {:sourceFile "Class1.cs"} {:sourceLine 28} true;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.M$System.Boolean(this: int, b$in: bool);
-
-
-
-implementation RegressionTestInput.Class0.M$System.Boolean(this: int, b$in: bool)
-{
- var b: bool;
-
- b := b$in;
- assert {:sourceFile "Class1.cs"} {:sourceLine 29} true;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.M$RegressionTestInput.Class0(this: int, c$in: int);
-
-
-
-implementation RegressionTestInput.Class0.M$RegressionTestInput.Class0(this: int, c$in: int)
-{
- var c: int;
-
- c := c$in;
- assert {:sourceFile "Class1.cs"} {:sourceLine 30} true;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.NonVoid(this: int) returns ($result: int);
-
-
-
-implementation RegressionTestInput.Class0.NonVoid(this: int) returns ($result: int)
-{
- var $tmp5: int;
-
- assert {:sourceFile "Class1.cs"} {:sourceLine 34} true;
- call $tmp5 := RegressionTestInput.Class0.StaticMethod$System.Int32(3);
- $result := 3 + RegressionTestInput.Class0.StaticInt + $tmp5;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.OutParam$System.Int32$(this: int) returns (x$out: int, $result: int);
-
-
-
-implementation RegressionTestInput.Class0.OutParam$System.Int32$(this: int) returns (x$out: int, $result: int)
-{
- assert {:sourceFile "Class1.cs"} {:sourceLine 37} true;
- x$out := 3 + RegressionTestInput.Class0.StaticInt;
- assert {:sourceFile "Class1.cs"} {:sourceLine 39} true;
- $result := x$out;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.RefParam$System.Int32$(this: int, x$in: int) returns (x$out: int, $result: int);
-
-
-
-implementation RegressionTestInput.Class0.RefParam$System.Int32$(this: int, x$in: int) returns (x$out: int, $result: int)
-{
- x$out := x$in;
- assert {:sourceFile "Class1.cs"} {:sourceLine 42} true;
- x$out := x$out + 1;
- assert {:sourceFile "Class1.cs"} {:sourceLine 43} true;
- RegressionTestInput.Class0.StaticInt := x$out;
- assert {:sourceFile "Class1.cs"} {:sourceLine 45} true;
- $result := x$out;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.AssignToInParam$System.Int32(this: int, x$in: int) returns ($result: int);
-
-
-
-implementation RegressionTestInput.Class0.AssignToInParam$System.Int32(this: int, x$in: int) returns ($result: int)
-{
- var x: int;
-
- x := x$in;
- assert {:sourceFile "Class1.cs"} {:sourceLine 48} true;
- x := x + 1;
- assert {:sourceFile "Class1.cs"} {:sourceLine 49} true;
- RegressionTestInput.Class0.StaticInt := x;
- assert {:sourceFile "Class1.cs"} {:sourceLine 51} true;
- $result := x;
- return;
-}
-
-
-
-procedure {:RegressionTestInput.Async} RegressionTestInput.Class0.MethodThatRepresentsAnAynchronousMethod$System.Int32(this: int, x$in: int) returns ($result: int);
-
-
-
-implementation RegressionTestInput.Class0.MethodThatRepresentsAnAynchronousMethod$System.Int32(this: int, x$in: int) returns ($result: int)
-{
- var x: int;
-
- x := x$in;
- assert {:sourceFile "Class1.cs"} {:sourceLine 56} true;
- $result := x;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.CallAsyncMethod$System.Int32(this: int, y$in: int) returns ($result: int);
-
-
-
-implementation RegressionTestInput.Class0.CallAsyncMethod$System.Int32(this: int, y$in: int) returns ($result: int)
-{
- var y: int;
- var $tmp6: int;
-
- y := y$in;
- assert {:sourceFile "Class1.cs"} {:sourceLine 60} true;
- call {:async} $tmp6 := RegressionTestInput.Class0.MethodThatRepresentsAnAynchronousMethod$System.Int32(this, y);
- $result := $tmp6;
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.#ctor(this: int);
-
-
-
-implementation RegressionTestInput.Class0.#ctor(this: int)
-{
- call System.Object.#ctor(this);
- return;
-}
-
-
-
-procedure RegressionTestInput.Class0.#cctor();
-
-
-
-implementation RegressionTestInput.Class0.#cctor()
-{
- RegressionTestInput.Class0.StaticInt := 0;
-}
-
-
-
-const unique RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap: Type;
-
-const unique RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.x: int;
-
-const unique RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.y: int;
-
-procedure RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.M(this: int);
-
-
-
-implementation RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.M(this: int)
-{
- assert {:sourceFile "Class1.cs"} {:sourceLine 130} true;
- $Heap[this, RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.y] := $Heap[this, RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.x];
- assert {:sourceFile "Class1.cs"} {:sourceLine 131} true;
- return;
-}
-
-
-
-procedure RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.#ctor(this: int);
-
-
-
-implementation RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.#ctor(this: int)
-{
- $Heap[this, RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.x] := 0;
- $Heap[this, RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.y] := 0;
- call System.Object.#ctor(this);
- return;
-}
-
-
-
-procedure RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.#cctor();
-
-
-
-implementation RegressionTestInput.WriteToTheHeapAValueReadFromTheHeap.#cctor()
-{
-}
-
-
-
-const unique RegressionTestInput.ClassWithBoolTypes: Type;
-
-var RegressionTestInput.ClassWithBoolTypes.staticB: bool;
-
-const unique RegressionTestInput.ClassWithBoolTypes.b: bool;
-
-procedure RegressionTestInput.ClassWithBoolTypes.M$System.Int32$System.Int32(x$in: int, y$in: int) returns ($result: bool);
-
-
-
-implementation RegressionTestInput.ClassWithBoolTypes.M$System.Int32$System.Int32(x$in: int, y$in: int) returns ($result: bool)
-{
- var x: int;
- var y: int;
-
- x := x$in;
- y := y$in;
- assert {:sourceFile "Class1.cs"} {:sourceLine 70} true;
- $result := x < y;
- return;
-}
-
-
-
-procedure RegressionTestInput.ClassWithBoolTypes.#ctor$System.Boolean(this: int, z$in: bool);
-
-
-
-implementation RegressionTestInput.ClassWithBoolTypes.#ctor$System.Boolean(this: int, z$in: bool)
-{
- var z: bool;
-
- z := z$in;
- $Heap[this, RegressionTestInput.ClassWithBoolTypes.b] := false;
- assert {:sourceFile "Class1.cs"} {:sourceLine 72} true;
- call System.Object.#ctor(this);
- assert {:sourceFile "Class1.cs"} {:sourceLine 73} true;
- $Heap[this, RegressionTestInput.ClassWithBoolTypes.b] := z;
- assert {:sourceFile "Class1.cs"} {:sourceLine 74} true;
- if (z)
- {
- assert {:sourceFile "Class1.cs"} {:sourceLine 74} true;
- RegressionTestInput.ClassWithBoolTypes.staticB := z;
- }
- else
- {
- }
-
- return;
-}
-
-
-
-procedure RegressionTestInput.ClassWithBoolTypes.Main();
-
-
-
-implementation RegressionTestInput.ClassWithBoolTypes.Main()
-{
- var $tmp7: bool;
-
- assert {:sourceFile "Class1.cs"} {:sourceLine 78} true;
- call $tmp7 := RegressionTestInput.ClassWithBoolTypes.M$System.Int32$System.Int32(3, 4);
- assert {:sourceFile "Class1.cs"} {:sourceLine 79} true;
- return;
-}
-
-
-
-procedure RegressionTestInput.ClassWithBoolTypes.#cctor();
-
-
-
-implementation RegressionTestInput.ClassWithBoolTypes.#cctor()
-{
- RegressionTestInput.ClassWithBoolTypes.staticB := false;
-}
-
-
-
-const unique RegressionTestInput.AsyncAttribute: Type;
-
-procedure RegressionTestInput.AsyncAttribute.#ctor(this: int);
-
-
-
-procedure System.Attribute.#ctor(this: int);
-
-
-
-implementation RegressionTestInput.AsyncAttribute.#ctor(this: int)
-{
- call System.Attribute.#ctor(this);
- return;
-}
-
-
-
-procedure RegressionTestInput.AsyncAttribute.#cctor();
-
-
-
-implementation RegressionTestInput.AsyncAttribute.#cctor()
-{
-}
-
-
diff --git a/BCT/RegressionTests/TranslationTest/UnitTest0.cs b/BCT/RegressionTests/TranslationTest/UnitTest0.cs
index dadeb4e5..99b6e680 100644
--- a/BCT/RegressionTests/TranslationTest/UnitTest0.cs
+++ b/BCT/RegressionTests/TranslationTest/UnitTest0.cs
@@ -68,21 +68,6 @@ namespace TranslationTest {
}
[TestMethod]
- public void TwoDIntHeap() {
- string dir = TestContext.DeploymentDirectory;
- var fullPath = Path.Combine(dir, "RegressionTestInput.dll");
- Stream resource = typeof(UnitTest0).Assembly.GetManifestResourceStream("TranslationTest.TwoDIntHeapInput.txt");
- StreamReader reader = new StreamReader(resource);
- string expected = reader.ReadToEnd();
- var result = ExecuteTest(fullPath, new TwoDIntHeap());
- if (result != expected) {
- string resultFile = Path.GetFullPath("TwoDIntHeapOutput.txt");
- File.WriteAllText(resultFile, result);
- Assert.Fail("Output didn't match TwoDIntHeapInput.txt: " + resultFile);
- }
- }
-
- [TestMethod]
public void SplitFieldsHeap() {
string dir = TestContext.DeploymentDirectory;
var fullPath = Path.Combine(dir, "RegressionTestInput.dll");
@@ -98,21 +83,6 @@ namespace TranslationTest {
}
[TestMethod]
- public void TwoDBoxHeap() {
- string dir = TestContext.DeploymentDirectory;
- var fullPath = Path.Combine(dir, "RegressionTestInput.dll");
- Stream resource = typeof(UnitTest0).Assembly.GetManifestResourceStream("TranslationTest.TwoDBoxHeapInput.txt");
- StreamReader reader = new StreamReader(resource);
- string expected = reader.ReadToEnd();
- var result = ExecuteTest(fullPath, new TwoDBoxHeap());
- if (result != expected) {
- string resultFile = Path.GetFullPath("TwoDBoxHeapOutput.txt");
- File.WriteAllText(resultFile, result);
- Assert.Fail("Output didn't match TwoDBoxHeapInput.txt: " + resultFile);
- }
- }
-
- [TestMethod]
public void GeneralHeap() {
string dir = TestContext.DeploymentDirectory;
var fullPath = Path.Combine(dir, "RegressionTestInput.dll");
diff --git a/BCT/Samples/CodeCounter/codecounter.sln b/BCT/Samples/CodeCounter/codecounter.sln
new file mode 100644
index 00000000..8869bd4f
--- /dev/null
+++ b/BCT/Samples/CodeCounter/codecounter.sln
@@ -0,0 +1,51 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCounter", "console\CodeCounter.csproj", "{7A901DC8-19B3-4F4C-9C2D-2088A30CB5D4}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "codecounterlibrary", "library\codecounterlibrary.csproj", "{A055DCC3-3C6A-123C-82F8-AD10A8B313F7}"
+EndProject
+Global
+ GlobalSection(TeamFoundationVersionControl) = preSolution
+ SccNumberOfProjects = 4
+ SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
+ SccTeamFoundationServer = https://tfs.codeplex.com/tfs/tfs09
+ SccLocalPath0 = .
+ SccProjectUniqueName1 = console\\CodeCounter.csproj
+ SccProjectName1 = console
+ SccLocalPath1 = console
+ SccProjectUniqueName2 = library\\codecounterlibrary.csproj
+ SccProjectName2 = library
+ SccLocalPath2 = library
+ SccProjectUniqueName3 = Extensions\\vbcounter\\VBCodeCountingLogic\\VBCodeCountingLogic.vbproj
+ SccProjectName3 = Extensions/vbcounter/VBCodeCountingLogic
+ SccLocalPath3 = Extensions\\vbcounter\\VBCodeCountingLogic
+ EndGlobalSection
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ DEBUG ALL|Any CPU = DEBUG ALL|Any CPU
+ Debug|Any CPU = Debug|Any CPU
+ RELEASE ALL|Any CPU = RELEASE ALL|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {7A901DC8-19B3-4F4C-9C2D-2088A30CB5D4}.DEBUG ALL|Any CPU.ActiveCfg = Debug|Any CPU
+ {7A901DC8-19B3-4F4C-9C2D-2088A30CB5D4}.DEBUG ALL|Any CPU.Build.0 = Debug|Any CPU
+ {7A901DC8-19B3-4F4C-9C2D-2088A30CB5D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7A901DC8-19B3-4F4C-9C2D-2088A30CB5D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7A901DC8-19B3-4F4C-9C2D-2088A30CB5D4}.RELEASE ALL|Any CPU.ActiveCfg = Release|Any CPU
+ {7A901DC8-19B3-4F4C-9C2D-2088A30CB5D4}.RELEASE ALL|Any CPU.Build.0 = Release|Any CPU
+ {7A901DC8-19B3-4F4C-9C2D-2088A30CB5D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7A901DC8-19B3-4F4C-9C2D-2088A30CB5D4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A055DCC3-3C6A-123C-82F8-AD10A8B313F7}.DEBUG ALL|Any CPU.ActiveCfg = DEBUG ALL|Any CPU
+ {A055DCC3-3C6A-123C-82F8-AD10A8B313F7}.DEBUG ALL|Any CPU.Build.0 = DEBUG ALL|Any CPU
+ {A055DCC3-3C6A-123C-82F8-AD10A8B313F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A055DCC3-3C6A-123C-82F8-AD10A8B313F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A055DCC3-3C6A-123C-82F8-AD10A8B313F7}.RELEASE ALL|Any CPU.ActiveCfg = RELEASE ALL|Any CPU
+ {A055DCC3-3C6A-123C-82F8-AD10A8B313F7}.RELEASE ALL|Any CPU.Build.0 = RELEASE ALL|Any CPU
+ {A055DCC3-3C6A-123C-82F8-AD10A8B313F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A055DCC3-3C6A-123C-82F8-AD10A8B313F7}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/BCT/Samples/CodeCounter/codecounter.suo b/BCT/Samples/CodeCounter/codecounter.suo
new file mode 100644
index 00000000..84ae5e2a
--- /dev/null
+++ b/BCT/Samples/CodeCounter/codecounter.suo
Binary files differ
diff --git a/BCT/Samples/CodeCounter/codecounter.vssscc b/BCT/Samples/CodeCounter/codecounter.vssscc
new file mode 100644
index 00000000..794f014c
--- /dev/null
+++ b/BCT/Samples/CodeCounter/codecounter.vssscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROJECT"
+}
diff --git a/BCT/Samples/CodeCounter/console/App.config b/BCT/Samples/CodeCounter/console/App.config
new file mode 100644
index 00000000..5f8ec848
--- /dev/null
+++ b/BCT/Samples/CodeCounter/console/App.config
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+ <configSections>
+ <section
+ name="codeCounters"
+ type="CodeCounter.Library.CodeCounterTypesConfigurationSection, CodeCounter.Library"
+ requirePermission="false"
+ />
+ </configSections>
+ <codeCounters>
+ <counterImplementations>
+ <logic key="CS"
+ assemblyInformation="CSharpCodeCounterLogic, CodeCounter.Library.CSharpCodeCounterLogic, CodeCounter.Library.dll"/>
+ <logic key="MSSQL" assemblyInformation="SqlCodeCounterLogic, CodeCounter.Library.SqlCodeCounterLogic, CodeCounter.Library.dll"/>
+ <logic key="XAML" assemblyInformation="XamlCodeCounterLogic, CodeCounter.Library.XamlCodeCounterLogic, CodeCounter.Library.dll"/>
+ </counterImplementations>
+ </codeCounters>
+</configuration> \ No newline at end of file
diff --git a/BCT/Samples/CodeCounter/console/CodeCounter.csproj b/BCT/Samples/CodeCounter/console/CodeCounter.csproj
new file mode 100644
index 00000000..d8accbbd
--- /dev/null
+++ b/BCT/Samples/CodeCounter/console/CodeCounter.csproj
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{7A901DC8-19B3-4F4C-9C2D-2088A30CB5D4}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>CodeCounter</RootNamespace>
+ <AssemblyName>CodeCounter</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <SccProjectName>SAK</SccProjectName>
+ <SccLocalPath>SAK</SccLocalPath>
+ <SccAuxPath>SAK</SccAuxPath>
+ <SccProvider>SAK</SccProvider>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ <OldToolsVersion>3.5</OldToolsVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Big Woo.NET, Version=3.0.3287.30089, Culture=neutral, PublicKeyToken=b8a13bcc86eb719e, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\dependencies\Big Woo.NET.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.configuration" />
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Xml.Linq">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data.DataSetExtensions">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="CodeCounterEngine.cs" />
+ <Compile Include="CountCounterEvents.cs" />
+ <Compile Include="FileTypes.cs" />
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\library\codecounterlibrary.csproj">
+ <Project>{A055DCC3-3C6A-123C-82F8-AD10A8B313F7}</Project>
+ <Name>codecounterlibrary</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="App.config" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/BCT/Samples/CodeCounter/console/CodeCounter.csproj.user b/BCT/Samples/CodeCounter/console/CodeCounter.csproj.user
new file mode 100644
index 00000000..f83e497d
--- /dev/null
+++ b/BCT/Samples/CodeCounter/console/CodeCounter.csproj.user
@@ -0,0 +1,6 @@
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <StartArguments>-about</StartArguments>
+ <StartWorkingDirectory>C:\src\toolkit\CodeCounter\library\</StartWorkingDirectory>
+ </PropertyGroup>
+</Project> \ No newline at end of file
diff --git a/BCT/Samples/CodeCounter/console/CodeCounter.csproj.vspscc b/BCT/Samples/CodeCounter/console/CodeCounter.csproj.vspscc
new file mode 100644
index 00000000..bfa5cf9c
--- /dev/null
+++ b/BCT/Samples/CodeCounter/console/CodeCounter.csproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = "relative:toolkit\\CodeCounter"
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
diff --git a/BCT/Samples/CodeCounter/console/CodeCounterEngine.cs b/BCT/Samples/CodeCounter/console/CodeCounterEngine.cs
new file mode 100644
index 00000000..2cf1748f
--- /dev/null
+++ b/BCT/Samples/CodeCounter/console/CodeCounterEngine.cs
@@ -0,0 +1,270 @@
+/*
+ ******************************************************************************
+ This file is part of BigWoo.NET.
+
+ BigWoo.NET is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BigWoo.NET is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with BigWoo.NET; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ architected and written by
+ matt raffel
+ matt.raffel@mindspring.com
+
+ copyright (c) 2008 by matt raffel unless noted otherwise
+
+ ******************************************************************************
+*/
+#region using statements
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.IO;
+using System.Security.AccessControl;
+using CodeCounter.Library;
+#endregion
+
+namespace CodeCounter
+{
+ /// <summary>
+ /// This is the class that processes a file. If manages the "conversation" with the
+ /// ICodeCounterLogic implementation occuring during reading through the file.
+ /// </summary>
+ public class CodeCounterEngine
+ {
+ #region private data
+ private FileInfo _fileInfo = null;
+ private long _statementLines = 0L;
+ private long _totalLines = 0L;
+ private long _codeLines = 0L;
+ private long _commentLines = 0L;
+ private long _errors = 0L;
+ private CodeCounterLogicImplementerList _implementerList = null;
+ #endregion
+
+ #region properties
+ /// <summary>
+ /// FileInfo instance of the file we want to count code.
+ /// </summary>
+ public FileInfo File
+ {
+ get { return _fileInfo; }
+ set { _fileInfo = value; }
+ }
+ #endregion
+
+ #region event firing helpers
+ /// <summary>
+ /// Fires the OnStartEvent if there are listeners. This
+ /// event is fired once per file.
+ /// </summary>
+ /// <param name="startArgs">CodeCounterUpdateEventArgs</param>
+ private void FireOnStartEvent(CodeCounterUpdateEventArgs startArgs)
+ {
+ if (null != OnStart)
+ {
+ OnStart(this, startArgs);
+ }
+ }
+
+ /// <summary>
+ /// Fires OnUpdate event if there are listeners. This event
+ /// is fired approx every 250 lines read in the file.
+ /// </summary>
+ /// <param name="updateArgs">CodeCounterUpdateEventArgs</param>
+ private void FireOnUpdateEvent(CodeCounterUpdateEventArgs updateArgs)
+ {
+ if (null != OnUpdate)
+ OnUpdate(this, updateArgs);
+ }
+
+ /// <summary>
+ /// Fires OnFinish event if there are listeners. This event
+ /// is fired once per file
+ /// </summary>
+ /// <param name="finishedArgs">CodeCounterFinishedEventArgs</param>
+ private void FireOnFinishedEvent(CodeCounterFinishedEventArgs finishedArgs)
+ {
+ if (null != OnFinish)
+ OnFinish(this, finishedArgs);
+ }
+ #endregion
+
+ #region private methods
+ /// <summary>
+ /// Find the ICodeCounterLogic implementation that can work with the file type we
+ /// have found.
+ /// </summary>
+ /// <exception cref="FileTypeNotSupportedException">Thrown if no logic is found for the given file type</exception>
+ /// <exception cref="ConfigurationFileException">Thrown if no logic is defined in the config file</exception>
+ /// <returns>ICodeCounterLogic</returns>
+ private ICodeCounterLogic GetFileProcessor(FileInfo info)
+ {
+ if (null == _implementerList)
+ {
+ _implementerList = CodeCounterLogicImplementerList.LoadFromConfigFile();
+ if (0 == _implementerList.Count)
+ throw new ConfigurationFileException("No code counter logic found.");
+ }
+
+ ICodeCounterLogic handler = null;
+
+ foreach (CodeCounterLogicImplementer implementer in _implementerList)
+ {
+ ICodeCounterLogic potentialHandler = implementer.Implementer;
+
+ if (true == potentialHandler.CanProcessFile(info.Name))
+ {
+ handler = potentialHandler;
+ break;
+ }
+ }
+
+ if (null == handler)
+ throw FileTypeNotSupportedException.CreateException(info);
+
+ return handler;
+ }
+
+ /// <summary>
+ /// Each count is file specific. It is up to the consumer to process
+ /// those values
+ /// </summary>
+ private void InitializeCounters()
+ {
+ _statementLines = 0L;
+ _totalLines = 0L;
+ _codeLines = 0L;
+ _commentLines = 0L;
+ _errors = 0L;
+ }
+ #endregion
+
+ #region public methods
+ /// <summary>
+ /// The heart of the counting of lines
+ /// </summary>
+ public void Count()
+ {
+ // nothing to process if we have no file name
+ if (null == _fileInfo)
+ return;
+
+ // ensures member data is reset to default
+ InitializeCounters();
+ long linesRead = 0L;
+
+ // event arg initialization
+ CodeCounterFinishedEventArgs finishedArgs = new CodeCounterFinishedEventArgs(_fileInfo, CodeCounterFunctionTypes.Error);
+ CodeCounterUpdateEventArgs startArgs = new CodeCounterUpdateEventArgs(_fileInfo, CodeCounterFunctionTypes.ProcessingFiles);
+ CodeCounterUpdateEventArgs updateEventArg = new CodeCounterUpdateEventArgs(_fileInfo, CodeCounterFunctionTypes.ProcessingFiles);
+
+ try
+ {
+ // let console know we found a file
+ FireOnStartEvent(startArgs);
+
+ // find the appropriate handler for the type
+ ICodeCounterLogic processor = GetFileProcessor(_fileInfo);
+ bool _processorDeterminesEmpty = processor.EngineCanDetermineBlankLines();
+
+ // allow the ICodeCounterLogic implementation a chance to
+ // do something with the file
+ processor.PrefileProcessing(_fileInfo.FullName);
+
+ // now we can read through each line and count what it contains
+ using (TextReader fileReader = _fileInfo.OpenText())
+ {
+ string line = "";
+
+ while (null != (line = fileReader.ReadLine()))
+ {
+ linesRead++;
+
+ long mod = (linesRead % 250L);
+
+ if (0L == mod)
+ {
+ updateEventArg.Lines = linesRead;
+ FireOnUpdateEvent(updateEventArg);
+ }
+
+ string trimmed = line.Trim();
+
+ // when the processor does not know or care how empty lines are determined
+ // we will do it by testing for null or empty line.
+ if ((true == _processorDeterminesEmpty) && (true == string.IsNullOrEmpty(trimmed)))
+ continue;
+
+ // now we are ready to let the implemention decide what the line is
+ CodeCounterLineType lineType = processor.LineType(trimmed);
+
+ switch (lineType)
+ {
+ case CodeCounterLineType.Statement:
+ case CodeCounterLineType.Code:
+ _codeLines++;
+ break;
+ case CodeCounterLineType.StatementAndComment:
+ case CodeCounterLineType.CodeAndComment:
+ _codeLines++;
+ _commentLines++;
+ break;
+ case CodeCounterLineType.CommentOnly:
+ _commentLines++;
+ break;
+ default:
+ break;
+ }
+
+ if (CodeCounterLineType.EmptyLine != lineType)
+ _totalLines++;
+ }
+
+ // yay we are done
+ fileReader.Close();
+
+ // allow the counter implemenation any final moments
+ processor.PostfileProcessing(_fileInfo.FullName);
+
+ finishedArgs.Function = CodeCounterFunctionTypes.Summarizing;
+ }
+ }
+ catch (Exception ex)
+ {
+ System.Diagnostics.Debug.WriteLine(ex.Message);
+ finishedArgs.Function = CodeCounterFunctionTypes.Error;
+ finishedArgs.AdditionalData = ex;
+ }
+ finally
+ {
+ finishedArgs.FileInfo = _fileInfo;
+ finishedArgs.CodeLines = _codeLines;
+ finishedArgs.CommentLines = _commentLines;
+ finishedArgs.StatementLines = _statementLines;
+ finishedArgs.Lines = _totalLines;
+ _fileInfo = null;
+
+ FireOnFinishedEvent(finishedArgs);
+ }
+ }
+ #endregion
+
+ #region event member delcaration
+ public event CodeCounterUpdateEvent OnStart;
+ public event CodeCounterUpdateEvent OnUpdate;
+ public event CodeCounterFinishedEvent OnFinish;
+ #endregion
+ }
+}
diff --git a/BCT/Samples/CodeCounter/console/CountCounterEvents.cs b/BCT/Samples/CodeCounter/console/CountCounterEvents.cs
new file mode 100644
index 00000000..5bc24136
--- /dev/null
+++ b/BCT/Samples/CodeCounter/console/CountCounterEvents.cs
@@ -0,0 +1,169 @@
+/*
+ ******************************************************************************
+ This file is part of BigWoo.NET.
+
+ BigWoo.NET is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BigWoo.NET is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with BigWoo.NET; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ architected and written by
+ matt raffel
+ matt.raffel@mindspring.com
+
+ copyright (c) 2008 by matt raffel unless noted otherwise
+
+ ******************************************************************************
+*/
+#region using statements
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.IO;
+#endregion
+
+namespace CodeCounter
+{
+ #region CodeCounterFunctionTypes enumeration
+ /// <summary>
+ ///
+ /// </summary>
+ public enum CodeCounterFunctionTypes
+ {
+ NA,
+ ListingFiles,
+ ProcessingFiles,
+ Summarizing,
+ Error
+ }
+ #endregion
+
+ #region base Event Arg class
+ /// <summary>
+ ///
+ /// </summary>
+ public class BaseCodeCounterEventArgs : EventArgs
+ {
+ private FileInfo _fileInfo = null;
+
+ public FileInfo FileInfo
+ {
+ get { return _fileInfo; }
+ set { _fileInfo = value; }
+ }
+
+ protected BaseCodeCounterEventArgs() { }
+
+ protected BaseCodeCounterEventArgs(FileInfo fileInfo)
+ {
+ _fileInfo = fileInfo;
+ }
+ }
+ #endregion
+
+ #region CodeCounterUpdateEventArgs implementation
+ /// <summary>
+ ///
+ /// </summary>
+ public class CodeCounterUpdateEventArgs : BaseCodeCounterEventArgs
+ {
+ private CodeCounterFunctionTypes _function = CodeCounterFunctionTypes.NA;
+ private long _lines = 0;
+
+ public long Lines
+ {
+ get { return _lines; }
+ set { _lines = value; }
+ }
+
+ public CodeCounterFunctionTypes Function
+ {
+ get { return _function; }
+ set { _function = value; }
+ }
+
+ protected CodeCounterUpdateEventArgs() { }
+
+ public CodeCounterUpdateEventArgs(FileInfo fileInfo, CodeCounterFunctionTypes function)
+ : base(fileInfo)
+ {
+ _function = function;
+ }
+ }
+ #endregion
+
+ #region CodeCounterFinishedEventArgs declaration
+ /// <summary>
+ ///
+ /// </summary>
+ public class CodeCounterFinishedEventArgs : BaseCodeCounterEventArgs
+ {
+ private CodeCounterFunctionTypes _function = CodeCounterFunctionTypes.NA;
+ private long _totalLines = 0L;
+ private long _codeLines = 0L;
+ private long _commentLines = 0L;
+ private long _statementLines = 0L;
+ private object _additionalData = null;
+
+ public object AdditionalData
+ {
+ get { return _additionalData; }
+ set { _additionalData = value; }
+ }
+
+ public CodeCounterFunctionTypes Function
+ {
+ get { return _function; }
+ set { _function = value; }
+ }
+
+ public long StatementLines
+ {
+ get { return _statementLines; }
+ set { _statementLines = value; }
+ }
+
+ public long Lines
+ {
+ get { return _totalLines; }
+ set { _totalLines = value; }
+ }
+
+ public long CodeLines
+ {
+ get { return _codeLines; }
+ set { _codeLines = value; }
+ }
+
+ public long CommentLines
+ {
+ get { return _commentLines; }
+ set { _commentLines = value; }
+ }
+
+ public CodeCounterFinishedEventArgs(FileInfo fileInfo, CodeCounterFunctionTypes function)
+ : base(fileInfo)
+ {
+ _function = function;
+ }
+
+ }
+ #endregion
+
+ #region event declarations
+ public delegate void CodeCounterUpdateEvent(object sender, CodeCounterUpdateEventArgs args);
+ public delegate void CodeCounterFinishedEvent(object sender, CodeCounterFinishedEventArgs args);
+ #endregion
+
+}
diff --git a/BCT/Samples/CodeCounter/console/FileTypes.cs b/BCT/Samples/CodeCounter/console/FileTypes.cs
new file mode 100644
index 00000000..3b614eb0
--- /dev/null
+++ b/BCT/Samples/CodeCounter/console/FileTypes.cs
@@ -0,0 +1,47 @@
+/*
+ ******************************************************************************
+ This file is part of BigWoo.NET.
+
+ BigWoo.NET is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BigWoo.NET is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with BigWoo.NET; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ architected and written by
+ matt raffel
+ matt.raffel@mindspring.com
+
+ copyright (c) 2008 by matt raffel unless noted otherwise
+
+ ******************************************************************************
+*/
+#region using statements
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.IO;
+#endregion
+
+namespace CodeCounter
+{
+ /// <summary>
+ ///
+ /// </summary>
+ public interface IFileType
+ {
+ string Extension { get; }
+ bool HandlesFile(File file);
+ string[] Comments { get; }
+ }
+}
diff --git a/BCT/Samples/CodeCounter/console/MSSCCPRJ.SCC b/BCT/Samples/CodeCounter/console/MSSCCPRJ.SCC
new file mode 100644
index 00000000..ec58105e
--- /dev/null
+++ b/BCT/Samples/CodeCounter/console/MSSCCPRJ.SCC
@@ -0,0 +1,5 @@
+SCC = This is a source code control file
+
+[CodeCounter.csproj]
+SCC_Aux_Path = "P4SCC#bigwoo:1666##matt##MediumWoo"
+SCC_Project_Name = Perforce Project
diff --git a/BCT/Samples/CodeCounter/console/Program.cs b/BCT/Samples/CodeCounter/console/Program.cs
new file mode 100644
index 00000000..1815170c
--- /dev/null
+++ b/BCT/Samples/CodeCounter/console/Program.cs
@@ -0,0 +1,642 @@
+/*
+ ******************************************************************************
+ This file is part of BigWoo.NET.
+
+ BigWoo.NET is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BigWoo.NET is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with BigWoo.NET; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ architected and written by
+ matt raffel
+ matt.raffel@mindspring.com
+
+ copyright (c) 2008 by matt raffel unless noted otherwise
+
+ ******************************************************************************
+*/
+#region using statements
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using BigWoo.NET.ApplicationSupport;
+using BigWoo.NET.Utility;
+using System.IO;
+using BigWoo.Utility;
+using CodeCounter.Library;
+#endregion
+
+namespace CodeCounter
+{
+ /// <summary>
+ /// The main control loop for the code counter program. Evaulates command line arguments
+ /// spins up file searches and code counting implmentations to count the code in the file
+ /// </summary>
+ class Program
+ {
+ private class PrintHelpException : Exception { }
+
+ private class ShowAboutWebPageException : Exception { }
+
+ #region private data
+
+ private const string COMMAND_VERBOSE = "-verbose";
+ private const string COMMAND_RECURSE = "-recurse";
+ private const string COMMAND_SUPPORTED = "-supportedTypes";
+ private const string COMMAND_SHOWABOUTWEBPAGE = "-about";
+
+ private const string WEBSITE = "www.mattraffel.com/aboutme.aspx";
+
+ private char[] _spinner = new char[] { '|', '/', '-', '\\', '|', '/', '-', '\\' };
+ private char[] _osWildCards = new char[] { '*', '?' };
+ private object _lockObject = new object();
+
+ private List<string> _fileArgs = new List<string>();
+ private ScanResultsList _listOfFiles = new ScanResultsList();
+ private ScanForFiles _fileScanner = new ScanForFiles();
+
+ private bool _quiet = true;
+ private bool _recursive = false;
+ private bool _detailedHelp = false;
+
+ private AutoResetEvent _eventReset = null;
+ private int _erasableTextLengh = 0;
+ private int _spinnerPosition = 0;
+ private string _lastDirectoryProcessed = string.Empty;
+
+ private long _filesCounted = 0L;
+ private long _totalLines = 0L;
+ private long _codeLines = 0L;
+ private long _commentLines = 0L;
+ private long _statementLines = 0L;
+ private long _errors = 0L;
+ #endregion
+
+ #region private methods
+ /// <summary>
+ /// Draws what might appear to some as a spinner in the console window to
+ /// show that the program is functioning and not hung
+ /// </summary>
+ private void DrawSpinner()
+ {
+ // move cursor back to starting position, ignoring if we muck up
+ ConsoleBackspace(_erasableTextLengh);
+
+ if (_spinnerPosition >= _spinner.Length)
+ _spinnerPosition = 0;
+
+ string outputText = string.Format("{0}", _spinner[_spinnerPosition]);
+ Console.Write(outputText);
+
+ _erasableTextLengh = outputText.Length;
+
+ _spinnerPosition++;
+
+ }
+
+ /// <summary>
+ /// Erases "spaces" by moving the cursor left by "spaces"
+ /// Exceptions are ignored
+ /// </summary>
+ /// <param name="spaces">int, the number of spaces to backspace</param>
+ private void ConsoleBackspace(int spaces)
+ {
+ try
+ {
+ if (0 < spaces)
+ {
+ int move = spaces;
+
+ if (spaces > Console.CursorLeft)
+ move = Console.CursorLeft;
+
+ Console.CursorLeft -= move;
+ }
+ }
+ catch(Exception ex)
+ {
+ System.Diagnostics.Debug.WriteLine(ex.Message);
+ }
+ }
+
+ /// <summary>
+ /// processes the command line arguments. We expect no more than
+ /// -quiet
+ /// -recurse
+ /// -help
+ /// -supportedTypes
+ /// {filename}
+ ///
+ /// FileName can be full filename or partial with wild card
+ /// </summary>
+ /// <param name="args">string[]</param>
+ private void ProcessCommandLineArgs(string[] args)
+ {
+ foreach (string arg in args)
+ {
+ if (('-' == arg[0]) || (('/' == arg[0])))
+ {
+ if (0 == arg.CompareTo(COMMAND_VERBOSE))
+ _quiet = false;
+ else if (0 == arg.CompareTo(COMMAND_RECURSE))
+ _recursive = true;
+ else if (0 == arg.CompareTo(COMMAND_SUPPORTED))
+ {
+ _detailedHelp = true;
+ throw new PrintHelpException();
+ }
+ else if (0 == arg.CompareTo(COMMAND_SHOWABOUTWEBPAGE))
+ throw new ShowAboutWebPageException();
+ else
+ throw new PrintHelpException();
+ }
+ else
+ _fileArgs.Add(arg);
+ }
+
+ if (0 == _fileArgs.Count)
+ throw new PrintHelpException();
+ }
+
+ /// <summary>
+ /// Using a mask, look for files matching the mask, digging recursively
+ /// into sub-directories if recursive is true. While this code can work
+ /// for files without a wildcard, for performance reasons the expectation
+ /// is this method is only called when fileMask has a wildcard in it,
+ /// or recursive is true.
+ /// </summary>
+ /// <param name="fileMask">string</param>
+ private void BuildFileListForMask(string fileMask)
+ {
+ Console.Write(string.Format("scanning for {0}.", fileMask));
+
+ _fileScanner.FilesList = new ScanResultsList();
+ _fileScanner.IsRecursive = _recursive;
+ _fileScanner.RootDir = Environment.CurrentDirectory;
+ _fileScanner.FileMask = fileMask;
+ _fileScanner.Scan();
+
+ _listOfFiles.AddRange(_fileScanner.FilesList.ToArray());
+
+ ConsoleBackspace(_erasableTextLengh);
+ _erasableTextLengh = 0;
+
+ if (false == _quiet)
+ Console.WriteLine("..done");
+ else
+ Console.WriteLine("");
+
+ }
+
+ /// <summary>
+ /// Called when recursive is true, scan for all matches in fileMask
+ /// input received from the commandline
+ /// </summary>
+ private void BuildFileListViaScanner()
+ {
+ // for each input that "appears" to be a file mask (either a file name or a file wildcard)
+ // gather the file names)
+ foreach (string fileMask in _fileArgs)
+ {
+ BuildFileListForMask(fileMask);
+ }
+ }
+
+ /// <summary>
+ /// Called when recursive is false, evaluates the input to see if search is really
+ /// required or not, only using the file scanner when a wildcard is present in the
+ /// input
+ /// </summary>
+ private void BuildFileListIntelligently()
+ {
+ // for each input that "appears" to be a file mask (either a file name or a file wildcard)
+ // gather the file names)
+ foreach (string fileMask in _fileArgs)
+ {
+ if (-1 < fileMask.IndexOfAny(_osWildCards))
+ {
+ BuildFileListForMask(fileMask);
+ }
+ else
+ {
+ DefaultScanForFilesData nextFile = new DefaultScanForFilesData();
+ nextFile.FileInfo = new FileInfo(fileMask);
+ _listOfFiles.Add(nextFile);
+ }
+ }
+ }
+
+ /// <summary>
+ /// optimized building of the file list....if recursive is not true
+ /// additional code checks the input and determines how to add files
+ /// to the list
+ /// </summary>
+ private void BuildFileList()
+ {
+ _listOfFiles.Clear();
+
+ // go ahead and hook up the event handler for file found
+ // in case we do end up using the scanner
+ _fileScanner.OnFileFound += new FileFoundEvent(OnFileFound);
+ _fileScanner.OnDirectoryFound += new ScanningDirectoryEvent(OnDirectoryFound);
+
+ // since recursive is true, it really doesnt matter if
+ // a wild card is in the input, just start scanning
+ if (true == _recursive)
+ {
+ BuildFileListViaScanner();
+ }
+ else
+ {
+ BuildFileListIntelligently();
+ }
+ }
+
+ /// <summary>
+ /// File list has been built, now its time to crack open each file
+ /// and count the code
+ /// </summary>
+ private void ProcessFileList()
+ {
+ // now we are ready to count the files
+ CodeCounterEngine codeCounterEngine = new CodeCounterEngine();
+ _eventReset = new AutoResetEvent(false);
+ object lockObject = new object();
+
+ // hook up finished even handler (required)
+ codeCounterEngine.OnFinish += new CodeCounterFinishedEvent(OnCodeCountingFinished);
+
+ if (0 < _listOfFiles.Count)
+ Console.WriteLine(string.Format("counting {0} possible files", _listOfFiles.Count));
+
+ // only add these event handlers if the user wanted output
+ if (false == _quiet)
+ {
+ codeCounterEngine.OnStart += new CodeCounterUpdateEvent(OnCodeCountingStart);
+ codeCounterEngine.OnUpdate += new CodeCounterUpdateEvent(OnCodeCountingUpdate);
+ }
+
+ // for each file in the array
+ foreach (IScanForFilesData file in _listOfFiles)
+ {
+ try
+ {
+ codeCounterEngine.File = file.FileInfo;
+
+ // clean everything up
+ while (true == Console.KeyAvailable)
+ Console.Read();
+
+ _spinnerPosition = 0;
+ _erasableTextLengh = 0;
+ _eventReset.Reset();
+
+ // make erasure execute on a separate thread
+ ThreadStart codeCountThreadStart = new ThreadStart(codeCounterEngine.Count);
+ Thread codeCountThread = new Thread(codeCountThreadStart);
+ codeCountThread.Name = "codeCountingThread worker";
+ codeCountThread.Start();
+
+ _eventReset.WaitOne();
+ }
+ catch (Exception ex)
+ {
+ System.Diagnostics.Debug.WriteLine(ex.Message);
+ Console.WriteLine(ex.Message);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Prints help to console
+ /// </summary>
+ private void PrintHelp()
+ {
+ Console.WriteLine("");
+ Console.WriteLine("\t-verbose");
+ Console.WriteLine("\t-recurse");
+ Console.WriteLine("\t-supportedTypes");
+ Console.WriteLine("\t-help");
+ Console.WriteLine("\t-about (opens www.mattraffel.com)");
+ Console.WriteLine("\t{filename}");
+ Console.WriteLine("");
+ Console.WriteLine("FileName can be full filename or partial with wild card");
+
+ // _detailedHelp is set to true when -supportedTypes is found in the command line
+ // this means we show information from each of the code counter implmentations
+ if (true == _detailedHelp)
+ {
+ Console.WriteLine("");
+ CodeCounterLogicImplementerList list = CodeCounterLogicImplementerList.LoadFromConfigFile();
+ if (0 == list.Count)
+ {
+ Console.WriteLine("No code types supported. Check the config file.");
+ return;
+ }
+
+ Console.WriteLine("File formats supported:");
+
+ foreach (CodeCounterLogicImplementer implementor in list)
+ {
+ string[] fileTypeList = implementor.Implementer.FileTypesHandled();
+ foreach (string fileType in fileTypeList)
+ {
+ // most file types are short so we will make a fair assumption
+ // that it is ok to right justify fileType by 10 chars....
+ string details = string.Format("{0,10} by {1}", fileType, implementor.ImplementerType.Name);
+ Console.WriteLine(details);
+ }
+ }
+
+ }
+ }
+
+ /// <summary>
+ /// Prints the results of counting code lines
+ /// </summary>
+ private void PrintSummaryReport()
+ {
+ if (false == _quiet)
+ Console.WriteLine("");
+
+ Console.WriteLine(string.Format("Files {0,10:#,##0}", _filesCounted));
+ if (0 < _codeLines)
+ Console.WriteLine(string.Format("Code Lines {0,10:#,##0}", _codeLines));
+
+ if (0 < _statementLines)
+ Console.WriteLine(string.Format("Statment Lines {0,10:#,##0}", _statementLines));
+
+ Console.WriteLine(string.Format("Comment Lines {0,10:#,##0}", _commentLines));
+
+ if (0 < _filesCounted)
+ Console.WriteLine(string.Format("Avg Lines/File {0,10:#,##0}", _totalLines / _filesCounted));
+
+ if (0 < _errors)
+ {
+ Console.WriteLine(string.Format("Error Files {0,10:#,##0}", _errors));
+ if (true == _quiet)
+ Console.WriteLine(" ==> to see details about the errors run with -verbose");
+ }
+
+ Console.WriteLine("");
+ }
+
+ /// <summary>
+ /// A little extra self boasting.....
+ /// </summary>
+ private void ShowAboutWebPage()
+ {
+ try
+ {
+ Console.WriteLine("");
+ Console.WriteLine(string.Format("ok to open {0} in your browser (Y/n)?", WEBSITE));
+ ConsoleKeyInfo keyInfo = Console.ReadKey();
+ char input = keyInfo.KeyChar;
+
+ if (('y' == input) || ('Y' == input) || ('\r' == input))
+ System.Diagnostics.Process.Start(string.Format("http://{0}", WEBSITE));
+
+ //if ('y' != input)
+ // System.Diagnostics.Process.Start(string.Format("http://{0}", WEBSITE));
+ }
+ catch
+ {
+ Console.WriteLine(string.Format("Error trying to open url. Please visit http://{0} when you have a moment.", WEBSITE));
+ }
+ }
+
+ /// <summary>
+ /// Prints a standard bit of header information every time
+ /// </summary>
+ private void PrintHeader()
+ {
+ Console.WriteLine("CodeCounter by matt raffel");
+ Console.WriteLine("(c) 2009 - matt.raffel@mindspring.com");
+ }
+
+ /// <summary>
+ /// This is the main function of this class
+ /// it runs through the command line parameters
+ /// sets up the FileErasure object and lets it do
+ /// its business
+ /// </summary>
+ /// <param name="args">string[], command line arguments</param>
+ private void Run(string[] args)
+ {
+ PrintHeader();
+
+ try
+ {
+ // process input
+ ProcessCommandLineArgs(args);
+
+ // now we should know what files to count or what mask to use
+ // to get the files to count so build a definitive list
+ // of files
+ BuildFileList();
+
+ // now count the code
+ ProcessFileList();
+
+ // and print out the results
+ PrintSummaryReport();
+ }
+ catch (PrintHelpException)
+ {
+ PrintHelp();
+ }
+ catch (ShowAboutWebPageException)
+ {
+ ShowAboutWebPage();
+ }
+ catch (Exception error)
+ {
+ Console.WriteLine("");
+ Console.WriteLine("Application Exception:");
+ Console.WriteLine(error.Message);
+ Console.WriteLine(error.StackTrace);
+ }
+ finally
+ {
+ }
+ }
+ #endregion
+
+ #region event methods
+ /// <summary>
+ /// Provide simple UI updates on scanning
+ /// </summary>
+ /// <param name="directoryName">string</param>
+ private void OnDirectoryFound(string directoryName)
+ {
+ if (false == _quiet)
+ DrawSpinner();
+ }
+
+ /// <summary>
+ /// Provide simple UI updates on scanning
+ /// </summary>
+ /// <param name="fileData">string</param>
+ private void OnFileFound(IScanForFilesData fileData)
+ {
+ if (false == _quiet)
+ DrawSpinner();
+ }
+
+ /// <summary>
+ /// Finished counting lines in a file, now its time to note it
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="counterFinishedArgs">CodeCounterFinishedEventArgs</param>
+ private void OnCodeCountingFinished(object sender, CodeCounterFinishedEventArgs counterFinishedArgs)
+ {
+ lock (_lockObject)
+ {
+ try
+ {
+
+ if (CodeCounterFunctionTypes.Summarizing == counterFinishedArgs.Function)
+ {
+ if (false == _quiet)
+ {
+ // move cursor back to starting position, ignoring if we muck up
+ ConsoleBackspace(_erasableTextLengh);
+ string spaces = new string(' ', _erasableTextLengh);
+ Console.Write(spaces);
+ Console.WriteLine("");
+ }
+
+ // only files we succeeding in counting are part of the file count
+ // error files are not included in the value
+ _filesCounted++;
+
+ _codeLines += counterFinishedArgs.CodeLines;
+ _totalLines += counterFinishedArgs.Lines;
+ _commentLines += counterFinishedArgs.CommentLines;
+ _statementLines += counterFinishedArgs.StatementLines;
+
+ }
+ else
+ {
+ _errors++;
+
+ if ((counterFinishedArgs.AdditionalData is ConfigurationFileException) ||
+ (counterFinishedArgs.AdditionalData is FileTypeNotSupportedException))
+ {
+ if (false == _quiet)
+ {
+ // move cursor back to starting position, ignoring if we muck up
+ ConsoleBackspace(_erasableTextLengh);
+ Console.Write("...file type not supported");
+ Console.WriteLine("");
+ }
+ }
+ }
+
+ }
+ catch (Exception ex)
+ {
+ System.Diagnostics.Debug.WriteLine(ex.Message);
+ }
+ finally
+ {
+ _spinnerPosition = 0;
+ _erasableTextLengh = 0;
+ _eventReset.Set();
+
+ }
+ }
+ }
+
+ /// <summary>
+ /// Updates from the code counter as it evaluates a file
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="erasureArgs">CodeCounterUpdateEventArgs</param>
+ private void OnCodeCountingUpdate(object sender, CodeCounterUpdateEventArgs erasureArgs)
+ {
+ lock (_lockObject)
+ {
+ try
+ {
+ // move cursor back to starting position, ignoring if we muck up
+ DrawSpinner();
+ }
+ catch (Exception ex)
+ {
+ System.Diagnostics.Debug.WriteLine(ex.Message);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Indicates a file has been found that matches our criteria for counting the lines
+ /// of code in the file
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="startArgs">CodeCounterUpdateEventArgs</param>
+ private void OnCodeCountingStart(object sender, CodeCounterUpdateEventArgs startArgs)
+ {
+ try
+ {
+ System.Diagnostics.Debug.Assert(0 == _erasableTextLengh);
+
+ if (0 != _lastDirectoryProcessed.CompareTo(startArgs.FileInfo.DirectoryName))
+ {
+ _lastDirectoryProcessed = startArgs.FileInfo.DirectoryName;
+ string directory = string.Format("{0}:", _lastDirectoryProcessed);
+ Console.WriteLine(directory);
+ }
+
+ _spinnerPosition = 0;
+ _erasableTextLengh = 0;
+ string fileName = string.Format("\t{0}: ", startArgs.FileInfo.Name);
+ Console.Write(fileName);
+ }
+ catch (Exception ex)
+ {
+ System.Diagnostics.Debug.WriteLine(ex.Message);
+ }
+ }
+ #endregion
+
+ #region ctor
+ /// <summary>
+ ///
+ /// </summary>
+ internal Program()
+ {
+ }
+ #endregion
+
+ #region startup entry method
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="args">string[]</param>
+ static void Main(string[] args)
+ {
+ Program go = new Program();
+ go.Run(args);
+
+ if (true == System.Diagnostics.Debugger.IsAttached)
+ {
+ Console.WriteLine("press a key....");
+ Console.Read();
+ }
+ }
+ #endregion
+ }
+}
diff --git a/BCT/Samples/CodeCounter/console/Properties/AssemblyInfo.cs b/BCT/Samples/CodeCounter/console/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..10081080
--- /dev/null
+++ b/BCT/Samples/CodeCounter/console/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("CodeCounter")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("CodeCounter")]
+[assembly: AssemblyCopyright("Copyright © 2008")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("d6e0a218-ddd1-436c-8405-4be8d7616bfb")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/BCT/Samples/CodeCounter/dependencies/Big Woo.NET.dll b/BCT/Samples/CodeCounter/dependencies/Big Woo.NET.dll
new file mode 100644
index 00000000..9110f2cb
--- /dev/null
+++ b/BCT/Samples/CodeCounter/dependencies/Big Woo.NET.dll
Binary files differ
diff --git a/BCT/Samples/CodeCounter/library/CSharpCodeCounterLogic.cs b/BCT/Samples/CodeCounter/library/CSharpCodeCounterLogic.cs
new file mode 100644
index 00000000..83f90d9a
--- /dev/null
+++ b/BCT/Samples/CodeCounter/library/CSharpCodeCounterLogic.cs
@@ -0,0 +1,177 @@
+/*
+ ******************************************************************************
+ This file is part of BigWoo.NET.
+
+ BigWoo.NET is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BigWoo.NET is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with BigWoo.NET; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ architected and written by
+ matt raffel
+ matt.raffel@mindspring.com
+
+ copyright (c) 2008 by matt raffel unless noted otherwise
+
+ ******************************************************************************
+*/
+#region using statements
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Configuration;
+using System.IO;
+#endregion
+
+namespace CodeCounter.Library
+{
+ /// <summary>
+ /// Provides the logic for counting lines of code and comments
+ /// </summary>
+ public class CSharpCodeCounterLogic : ICodeCounterLogic
+ {
+ private bool _isInComment = false;
+
+ /// <summary>
+ /// Performs all the evaluations while are stepping through
+ /// a multi line comment
+ /// </summary>
+ /// <param name="line">string</param>
+ /// <returns>CodeCounterLineType</returns>
+ private CodeCounterLineType EvaluateWhileInComment(string line)
+ {
+ if (false == string.IsNullOrEmpty(line))
+ {
+ if (true == line.Contains("*/"))
+ {
+ _isInComment = false;
+
+ int endOfCommentIndex = line.IndexOf("*/");
+
+ endOfCommentIndex += 2;
+
+ if (endOfCommentIndex < line.Length)
+ return CodeCounterLineType.CodeAndComment;
+ }
+ }
+
+ return CodeCounterLineType.CommentOnly;
+ }
+
+ /// <summary>
+ /// Evaluates a line
+ /// </summary>
+ /// <param name="line">string</param>
+ /// <returns>CodeCounterLineType</returns>
+ private CodeCounterLineType Evaluate(string line)
+ {
+ // this one is real simple a line starts with // so
+ // know there is no code after and we know the next line
+ // could be anything
+ if (true == line.StartsWith("//"))
+ return CodeCounterLineType.CommentOnly;
+
+ if (true == line.StartsWith("/*"))
+ {
+ _isInComment = true;
+
+ // because it is possible the comment terminates
+ // in this same line and to ensure that we count code after the comment
+ // terminates, use our EvaluateWhileInComment to determine
+ // return value
+ return EvaluateWhileInComment(line);
+ }
+
+ if (true == line.Contains("//"))
+ return CodeCounterLineType.CodeAndComment;
+
+ if (true == line.Contains("/*"))
+ {
+ _isInComment = true;
+
+ // because it is possible the comment terminates
+ // in this same line and to ensure that we count code after the comment
+ // terminates, use our EvaluateWhileInComment to determine
+ // if the comment has finished. we will ignore its return
+ // value as the only possible legal value for this case is
+ // CodeCounterLineType.CodeAndComment
+ EvaluateWhileInComment(line);
+
+ return CodeCounterLineType.CodeAndComment;
+ }
+
+ return CodeCounterLineType.Code;
+ }
+
+ #region ICodeCounterLogic Members
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="line"></param>
+ /// <returns></returns>
+ public CodeCounterLineType LineType(string line)
+ {
+ if (true == string.IsNullOrEmpty(line))
+ return CodeCounterLineType.EmptyLine;
+
+ string trimmed = line.Trim();
+
+ if (true == string.IsNullOrEmpty(line))
+ return CodeCounterLineType.EmptyLine;
+
+ if (true == _isInComment)
+ return EvaluateWhileInComment(trimmed);
+ else
+ return Evaluate(trimmed);
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <returns></returns>
+ public bool EngineCanDetermineBlankLines()
+ {
+ return true;
+ }
+
+ /// <summary>
+ /// should return something like cs or vb or sql etc
+ /// </summary>
+ /// <returns>string[]</returns>
+ public string[] FileTypesHandled()
+ {
+ return new string[] {"cs"};
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="fileName"></param>
+ /// <returns></returns>
+ public bool CanProcessFile(string file)
+ {
+ FileInfo info = new FileInfo(file);
+ string fileExtension = info.Extension.ToLower();
+ if (".cs" == fileExtension)
+ return true;
+
+ return false;
+ }
+
+ public void PrefileProcessing(string fileName) {}
+
+ public void PostfileProcessing(string fileName) {}
+
+ #endregion
+ }
+}
diff --git a/BCT/Samples/CodeCounter/library/CodeCounterLogicImplementers.cs b/BCT/Samples/CodeCounter/library/CodeCounterLogicImplementers.cs
new file mode 100644
index 00000000..245571d3
--- /dev/null
+++ b/BCT/Samples/CodeCounter/library/CodeCounterLogicImplementers.cs
@@ -0,0 +1,136 @@
+/*
+ ******************************************************************************
+ This file is part of BigWoo.NET.
+
+ BigWoo.NET is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BigWoo.NET is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with BigWoo.NET; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ architected and written by
+ matt raffel
+ matt.raffel@mindspring.com
+
+ copyright (c) 2008 by matt raffel unless noted otherwise
+
+ ******************************************************************************
+*/
+#region using statements
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Configuration;
+using System.IO;
+using BigWoo.Utility;
+#endregion
+
+namespace CodeCounter.Library
+{
+ /// <summary>
+ ///
+ /// </summary>
+ public class CodeCounterLogicImplementer
+ {
+ private string _className = string.Empty;
+ private string _fullClassName = string.Empty;
+ private string _assemblyName = "CodeCounter.Library.dll";
+ private Type _implementer = null;
+ private ICodeCounterLogic _logic = null;
+
+ private Type GetImplementerTypeInstance()
+ {
+ if (null == _implementer)
+ {
+ if (true == string.IsNullOrEmpty(_assemblyName))
+ throw new ConfigurationFileException("codeCounters not configured correctly");
+
+ if (true == string.IsNullOrEmpty(_fullClassName))
+ throw new ConfigurationFileException("codeCounters not configured correctly");
+
+ _implementer = AssemblyUtility.GetTypeFromFile(_assemblyName, _fullClassName);
+
+ if (false == AssemblyUtility.HasInterface(typeof(ICodeCounterLogic), _implementer))
+ throw new ConfigurationFileException("codeCounters not implemented correctly");
+ }
+
+ return _implementer;
+ }
+
+ private ICodeCounterLogic GetImplementerInstance()
+ {
+ if (null == _logic)
+ {
+ _logic = AssemblyUtility.InvokeDefaultCtor(ImplementerType) as ICodeCounterLogic;
+ }
+
+ return _logic;
+ }
+
+ public Type ImplementerType
+ {
+ get { return GetImplementerTypeInstance(); }
+ }
+
+ public ICodeCounterLogic Implementer
+ {
+ get { return GetImplementerInstance(); }
+ }
+
+ protected CodeCounterLogicImplementer() { }
+
+ public static CodeCounterLogicImplementer FromConfigElement(CodeCounterLogicElement element)
+ {
+ CodeCounterLogicImplementer implementer = new CodeCounterLogicImplementer();
+ string[] typeParts = element.AssemblyInformation.Split(new char[] { ',' });
+
+ if (null != typeParts)
+ {
+ if (1 <= typeParts.Length)
+ implementer._className = typeParts[0].Trim();
+
+ if (2 <= typeParts.Length)
+ implementer._fullClassName = typeParts[1].Trim();
+
+ if (3 <= typeParts.Length)
+ implementer._assemblyName = typeParts[2].Trim();
+ }
+ return implementer;
+ }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public class CodeCounterLogicImplementerList : List<CodeCounterLogicImplementer>
+ {
+ protected CodeCounterLogicImplementerList() { }
+
+ public static CodeCounterLogicImplementerList LoadFromConfigFile()
+ {
+ CodeCounterLogicImplementerList list = new CodeCounterLogicImplementerList();
+
+ CodeCounterTypesConfigurationSection section = ConfigurationManager.GetSection("codeCounters") as CodeCounterTypesConfigurationSection;
+
+ if (null == section)
+ throw new ConfigurationFileException("codeCounters section is missing");
+
+ foreach (CodeCounterLogicElement element in section.CounterImplementations)
+ {
+ CodeCounterLogicImplementer implementer = CodeCounterLogicImplementer.FromConfigElement(element);
+ list.Add(implementer);
+ }
+
+ return list;
+ }
+ }
+}
diff --git a/BCT/Samples/CodeCounter/library/ConfigFileSections.cs b/BCT/Samples/CodeCounter/library/ConfigFileSections.cs
new file mode 100644
index 00000000..70bc5917
--- /dev/null
+++ b/BCT/Samples/CodeCounter/library/ConfigFileSections.cs
@@ -0,0 +1,122 @@
+/*
+ ******************************************************************************
+ This file is part of BigWoo.NET.
+
+ BigWoo.NET is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BigWoo.NET is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with BigWoo.NET; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ architected and written by
+ matt raffel
+ matt.raffel@mindspring.com
+
+ copyright (c) 2008 by matt raffel unless noted otherwise
+
+ ******************************************************************************
+*/
+#region using statements
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Configuration;
+#endregion
+
+namespace CodeCounter.Library
+{
+ /// <summary>
+ ///
+ /// </summary>
+ public class CodeCounterTypesConfigurationSection : ConfigurationSection
+ {
+ [ConfigurationProperty("counterImplementations")]
+ public CodeCounterLogicCollection CounterImplementations
+ {
+ get { return ((CodeCounterLogicCollection)(base["counterImplementations"])); }
+ }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ [ConfigurationCollection(typeof(CodeCounterLogicElement), AddItemName = "logic")]
+ public class CodeCounterLogicCollection : ConfigurationElementCollection
+ {
+ /// <summary>
+ /// for creating new elements
+ /// </summary>
+ /// <returns>AssemblyElement</returns>
+ protected override ConfigurationElement CreateNewElement()
+ {
+ return new CodeCounterLogicElement();
+ }
+
+ /// <summary>
+ /// searchs the collection for a given AssemblyElement based on its key
+ /// </summary>
+ /// <param name="element">AssemblyElement</param>
+ /// <returns>CodeCounterType</returns>
+ protected override object GetElementKey(ConfigurationElement element)
+ {
+ return (element as CodeCounterLogicElement).AssemblyInformation;
+ }
+
+ /// <summary>
+ /// Indexor into the array
+ /// </summary>
+ /// <param name="idx">int</param>
+ /// <returns>CodeCounterType</returns>
+ public CodeCounterLogicElement this[int idx]
+ {
+ get
+ {
+ return BaseGet(idx) as CodeCounterLogicElement;
+ }
+ }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public class CodeCounterLogicElement : ConfigurationElement
+ {
+ [ConfigurationProperty("assemblyInformation", IsKey = false, IsRequired = true)]
+ public string AssemblyInformation
+ {
+ get
+ {
+ // assemblyInformation="CSharpCodeCounterLogic, CodeCounter.Library.CSharpCodeCounterLogic, CodeCounter.Library.dll"
+ string assemblyInformation = (string) base["assemblyInformation"];
+ return assemblyInformation;
+ }
+
+ set
+ {
+ base["assemblyInformation"] = value;
+ }
+ }
+
+ [ConfigurationProperty("key", IsKey = true, IsRequired = true)]
+ public string Key
+ {
+ get
+ {
+ string key = (string) base["key"];
+ return key;
+ }
+ set { base["key"] = value; }
+ }
+ }
+
+
+}
diff --git a/BCT/Samples/CodeCounter/library/CustomExceptions.cs b/BCT/Samples/CodeCounter/library/CustomExceptions.cs
new file mode 100644
index 00000000..b4ee7100
--- /dev/null
+++ b/BCT/Samples/CodeCounter/library/CustomExceptions.cs
@@ -0,0 +1,60 @@
+/*
+ ******************************************************************************
+ This file is part of BigWoo.NET.
+
+ BigWoo.NET is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BigWoo.NET is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with BigWoo.NET; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ architected and written by
+ matt raffel
+ matt.raffel@mindspring.com
+
+ copyright (c) 2008 by matt raffel unless noted otherwise
+
+ ******************************************************************************
+*/
+#region using statements
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Configuration;
+using System.IO;
+#endregion
+
+
+namespace CodeCounter.Library
+{
+ /// <summary>
+ ///
+ /// </summary>
+ public class ConfigurationFileException : Exception
+ {
+ public ConfigurationFileException(string msg) : base(msg) { }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public class FileTypeNotSupportedException : Exception
+ {
+ public FileTypeNotSupportedException(string msg) : base(msg) { }
+
+ public static FileTypeNotSupportedException CreateException(FileInfo info)
+ {
+ string msg = string.Format("{0} was not counted as no implemention for type {1} was found", info.Name, info.Extension);
+ return new FileTypeNotSupportedException(msg);
+ }
+ }
+}
diff --git a/BCT/Samples/CodeCounter/library/ICodeCounterLogic.cs b/BCT/Samples/CodeCounter/library/ICodeCounterLogic.cs
new file mode 100644
index 00000000..9e37ed59
--- /dev/null
+++ b/BCT/Samples/CodeCounter/library/ICodeCounterLogic.cs
@@ -0,0 +1,120 @@
+/*
+ ******************************************************************************
+ This file is part of BigWoo.NET.
+
+ BigWoo.NET is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BigWoo.NET is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with BigWoo.NET; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ architected and written by
+ matt raffel
+ matt.raffel@mindspring.com
+
+ copyright (c) 2008 by matt raffel unless noted otherwise
+
+ ******************************************************************************
+*/
+#region using statements
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+#endregion
+
+namespace CodeCounter.Library
+{
+ /// <summary>
+ /// Used by ICodeCounterLogic implementations to inform the the code counting engine
+ /// the type of line read.
+ /// </summary>
+ public enum CodeCounterLineType
+ {
+ /// <summary>
+ /// a blank line
+ /// </summary>
+ EmptyLine,
+ /// <summary>
+ /// this line contains code only
+ /// </summary>
+ Code,
+ /// <summary>
+ /// this line contains code and comments
+ /// </summary>
+ CodeAndComment,
+ /// <summary>
+ /// line line is part of a comment and no code
+ /// </summary>
+ CommentOnly,
+ /// <summary>
+ /// a complete code statement (like in cs a statement ends with ;)
+ /// </summary>
+ Statement,
+ /// <summary>
+ /// this line contains a completed code statement and comments
+ /// </summary>
+ StatementAndComment,
+ }
+
+ /// <summary>
+ /// Interface that defines the methods required by implementtions that provide
+ /// the code counting functions
+ /// </summary>
+ public interface ICodeCounterLogic
+ {
+ /// <summary>
+ /// Evaluates input and determines what the line contains: nothing,
+ /// code, code and comments or comment only, statement etc...
+ /// </summary>
+ /// <param name="line">string, typically one line a source file</param>
+ /// <returns>CodeCounterLineType</returns>
+ CodeCounterLineType LineType(string line);
+
+ /// <summary>
+ /// should return something like cs or vb or sql etc. No need to return .cs just cs
+ /// Typically used to display the supported types during command line help command
+ /// </summary>
+ /// <returns>string[]</returns>
+ string[] FileTypesHandled();
+
+ /// <summary>
+ /// Called by the engine to ask the implementation if it can count the lines in the file
+ /// </summary>
+ /// <param name="fileName"></param>
+ /// <returns>bool, true if the file can be processed</returns>
+ bool CanProcessFile(string file);
+
+ /// <summary>
+ /// Determines who is responsible for identifying an empty line. An empty line
+ /// being a line that contains no comments and no code. (Currently unused)
+ /// </summary>
+ /// <returns>true, the engine will determine what constitues a blank line
+ /// other wise the ICodeCounterLogic Implmentation makes that decision</returns>
+ bool EngineCanDetermineBlankLines();
+
+ /// <summary>
+ /// opportunity to do some processing prior to counting. If your code
+ /// grabs a system handle to this file, make sure you release it before
+ /// the function terminates or counting fails.
+ /// </summary>
+ /// <param name="fileName">string, full path to the file</param>
+ void PrefileProcessing(string fileName);
+
+ /// <summary>
+ /// opportunity to do some processing after counting
+ /// </summary>
+ /// <param name="fileName">string, full path to the file</param>
+ void PostfileProcessing(string fileName);
+
+ }
+}
diff --git a/BCT/Samples/CodeCounter/library/MSSCCPRJ.SCC b/BCT/Samples/CodeCounter/library/MSSCCPRJ.SCC
new file mode 100644
index 00000000..76e63471
--- /dev/null
+++ b/BCT/Samples/CodeCounter/library/MSSCCPRJ.SCC
@@ -0,0 +1,5 @@
+SCC = This is a source code control file
+
+[codecounterlibrary.csproj]
+SCC_Aux_Path = "P4SCC#bigwoo:1666##matt##MediumWoo"
+SCC_Project_Name = Perforce Project
diff --git a/BCT/Samples/CodeCounter/library/Properties/AssemblyInfo.cs b/BCT/Samples/CodeCounter/library/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..6df524f7
--- /dev/null
+++ b/BCT/Samples/CodeCounter/library/Properties/AssemblyInfo.cs
@@ -0,0 +1,57 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+//
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+//
+[assembly: AssemblyTitle("CodeCounterLib")]
+[assembly: AssemblyDescription("Assortment of Mananged utilities")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("mattraffel.com")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("See GNU license included")]
+[assembly: AssemblyTrademark("See GNU license included")]
+[assembly: AssemblyCulture("")]
+
+//
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+
+[assembly: AssemblyVersion("1.0.*")]
+
+//
+// In order to sign your assembly you must specify a key to use. Refer to the
+// Microsoft .NET Framework documentation for more information on assembly signing.
+//
+// Use the attributes below to control which key is used for signing.
+//
+// Notes:
+// (*) If no key is specified, the assembly is not signed.
+// (*) KeyName refers to a key that has been installed in the Crypto Service
+// Provider (CSP) on your machine. KeyFile refers to a file which contains
+// a key.
+// (*) If the KeyFile and the KeyName values are both specified, the
+// following processing occurs:
+// (1) If the KeyName can be found in the CSP, that key is used.
+// (2) If the KeyName does not exist and the KeyFile does exist, the key
+// in the KeyFile is installed into the CSP and used.
+// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
+// When specifying the KeyFile, the location of the KeyFile should be
+// relative to the project output directory which is
+// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
+// located in the project directory, you would specify the AssemblyKeyFile
+// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
+// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
+// documentation for more information on this.
+//
+[assembly: AssemblyDelaySign(false)]
+
diff --git a/BCT/Samples/CodeCounter/library/SqlCodeCounterLogic.cs b/BCT/Samples/CodeCounter/library/SqlCodeCounterLogic.cs
new file mode 100644
index 00000000..e8581fee
--- /dev/null
+++ b/BCT/Samples/CodeCounter/library/SqlCodeCounterLogic.cs
@@ -0,0 +1,169 @@
+/*
+ ******************************************************************************
+ This file is part of BigWoo.NET.
+
+ BigWoo.NET is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BigWoo.NET is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with BigWoo.NET; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ architected and written by
+ matt raffel
+ matt.raffel@mindspring.com
+
+ copyright (c) 2008 by matt raffel unless noted otherwise
+
+ ******************************************************************************
+*/
+#region using statements
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Configuration;
+using System.IO;
+#endregion
+
+namespace CodeCounter.Library
+{
+ /// <summary>
+ ///
+ /// </summary>
+ public class SqlCodeCounterLogic : ICodeCounterLogic
+ {
+ private bool _isInComment = false;
+
+ /// <summary>
+ /// Performs all the evaluations while are stepping through
+ /// a multi line comment
+ /// </summary>
+ /// <param name="line">string</param>
+ /// <returns>CodeCounterLineType</returns>
+ private CodeCounterLineType EvaluateWhileInComment(string line)
+ {
+ if (false == string.IsNullOrEmpty(line))
+ {
+ if (true == line.Contains("*/"))
+ {
+ _isInComment = false;
+
+ int endOfCommentIndex = line.IndexOf("*/");
+
+ endOfCommentIndex += 2;
+
+ if (endOfCommentIndex < line.Length)
+ return CodeCounterLineType.CodeAndComment;
+ }
+ }
+
+ return CodeCounterLineType.CommentOnly;
+ }
+
+ /// <summary>
+ /// Evaluates a line
+ /// </summary>
+ /// <param name="line">string</param>
+ /// <returns>CodeCounterLineType</returns>
+ private CodeCounterLineType Evaluate(string line)
+ {
+ // this one is real simple a line starts with // so
+ // know there is no code after and we know the next line
+ // could be anything
+ if (true == line.StartsWith("--"))
+ return CodeCounterLineType.CommentOnly;
+
+ if (true == line.StartsWith("/*"))
+ {
+ _isInComment = true;
+
+ // because it is possible the comment terminates
+ // in this same line and to ensure that we count code after the comment
+ // terminates, use our EvaluateWhileInComment to determine
+ // return value
+ return EvaluateWhileInComment(line);
+ }
+
+ if (true == line.Contains("--"))
+ return CodeCounterLineType.CodeAndComment;
+
+ if (true == line.Contains("/*"))
+ {
+ _isInComment = true;
+
+ // because it is possible the comment terminates
+ // in this same line and to ensure that we count code after the comment
+ // terminates, use our EvaluateWhileInComment to determine
+ // if the comment has finished. we will ignore its return
+ // value as the only possible legal value for this case is
+ // CodeCounterLineType.CodeAndComment
+ EvaluateWhileInComment(line);
+
+ return CodeCounterLineType.CodeAndComment;
+ }
+
+ return CodeCounterLineType.Code;
+ }
+
+ #region ICodeCounterLogic Members
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="line"></param>
+ /// <returns></returns>
+ public CodeCounterLineType LineType(string line)
+ {
+ if (true == string.IsNullOrEmpty(line))
+ return CodeCounterLineType.EmptyLine;
+
+ string trimmed = line.Trim();
+
+ if (true == string.IsNullOrEmpty(line))
+ return CodeCounterLineType.EmptyLine;
+
+ if (true == _isInComment)
+ return EvaluateWhileInComment(trimmed);
+ else
+ return Evaluate(trimmed);
+ }
+
+ /// <summary>
+ /// should return something like cs or vb or sql etc
+ /// </summary>
+ /// <returns>string[]</returns>
+ public string[] FileTypesHandled()
+ {
+ return new string[] { "sql" };
+ }
+
+
+ public bool CanProcessFile(string file)
+ {
+ FileInfo info = new FileInfo(file);
+ string fileExtension = info.Extension.ToLower();
+ if (".sql" == fileExtension)
+ return true;
+
+ return false;
+ }
+
+ public bool EngineCanDetermineBlankLines()
+ {
+ return true;
+ }
+
+ public void PrefileProcessing(string fileName) { }
+
+ public void PostfileProcessing(string fileName) {}
+
+ #endregion
+ }
+}
diff --git a/BCT/Samples/CodeCounter/library/XamlCodeCounterLogic.cs b/BCT/Samples/CodeCounter/library/XamlCodeCounterLogic.cs
new file mode 100644
index 00000000..60ece6fb
--- /dev/null
+++ b/BCT/Samples/CodeCounter/library/XamlCodeCounterLogic.cs
@@ -0,0 +1,161 @@
+/*
+ ******************************************************************************
+ This file is part of BigWoo.NET.
+
+ BigWoo.NET is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BigWoo.NET is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with BigWoo.NET; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ architected and written by
+ matt raffel
+ matt.raffel@mindspring.com
+
+ copyright (c) 2008 by matt raffel unless noted otherwise
+
+ ******************************************************************************
+*/
+#region using statements
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Configuration;
+using System.IO;
+#endregion
+
+namespace CodeCounter.Library
+{
+ /// <summary>
+ /// XamlCodeCounterLogic
+ /// </summary>
+ public class XamlCodeCounterLogic : ICodeCounterLogic
+ {
+ private bool _isInComment = false;
+
+ /// <summary>
+ /// Performs all the evaluations while are stepping through
+ /// a multi line comment
+ /// </summary>
+ /// <param name="line">string</param>
+ /// <returns>CodeCounterLineType</returns>
+ private CodeCounterLineType EvaluateWhileInComment(string line)
+ {
+ if (false == string.IsNullOrEmpty(line))
+ {
+ if (true == line.Contains("-->"))
+ {
+ _isInComment = false;
+
+ int endOfCommentIndex = line.IndexOf("-->");
+
+ endOfCommentIndex += 3;
+
+ if (endOfCommentIndex < line.Length)
+ return CodeCounterLineType.CodeAndComment;
+ }
+ }
+
+ return CodeCounterLineType.CommentOnly;
+ }
+
+ /// <summary>
+ /// Evaluates a line
+ /// </summary>
+ /// <param name="line">string</param>
+ /// <returns>CodeCounterLineType</returns>
+ private CodeCounterLineType Evaluate(string line)
+ {
+ if (true == line.StartsWith("<!--"))
+ {
+ _isInComment = true;
+
+ // because it is possible the comment terminates
+ // in this same line and to ensure that we count code after the comment
+ // terminates, use our EvaluateWhileInComment to determine
+ // return value
+ return EvaluateWhileInComment(line);
+ }
+
+ if (true == line.Contains("<!--"))
+ {
+ _isInComment = true;
+
+ // because it is possible the comment terminates
+ // in this same line and to ensure that we count code after the comment
+ // terminates, use our EvaluateWhileInComment to determine
+ // if the comment has finished. we will ignore its return
+ // value as the only possible legal value for this case is
+ // CodeCounterLineType.CodeAndComment
+ EvaluateWhileInComment(line);
+
+ return CodeCounterLineType.CodeAndComment;
+ }
+
+ return CodeCounterLineType.Code;
+ }
+
+ #region ICodeCounterLogic Members
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="line"></param>
+ /// <returns></returns>
+ public CodeCounterLineType LineType(string line)
+ {
+ if (true == string.IsNullOrEmpty(line))
+ return CodeCounterLineType.EmptyLine;
+
+ string trimmed = line.Trim();
+
+ if (true == string.IsNullOrEmpty(line))
+ return CodeCounterLineType.EmptyLine;
+
+ if (true == _isInComment)
+ return EvaluateWhileInComment(trimmed);
+ else
+ return Evaluate(trimmed);
+ }
+
+ /// <summary>
+ /// should return something like cs or vb or sql etc
+ /// </summary>
+ /// <returns>string[]</returns>
+ public string[] FileTypesHandled()
+ {
+ return new string[] { "xaml" };
+ }
+
+
+ public bool CanProcessFile(string file)
+ {
+ FileInfo info = new FileInfo(file);
+ string fileExtension = info.Extension.ToLower();
+ if (".xaml" == fileExtension)
+ return true;
+
+ return false;
+ }
+
+ public bool EngineCanDetermineBlankLines()
+ {
+ return true;
+ }
+
+ public void PrefileProcessing(string fileName) { }
+
+ public void PostfileProcessing(string fileName) { }
+
+ #endregion
+ }
+
+}
diff --git a/BCT/Samples/CodeCounter/library/codecounterlibrary.csproj b/BCT/Samples/CodeCounter/library/codecounterlibrary.csproj
new file mode 100644
index 00000000..53193b57
--- /dev/null
+++ b/BCT/Samples/CodeCounter/library/codecounterlibrary.csproj
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+ <PropertyGroup>
+ <ProjectType>Local</ProjectType>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{A055DCC3-3C6A-123C-82F8-AD10A8B313F7}</ProjectGuid>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>CodeCounter.Library</AssemblyName>
+ <DefaultClientScript>JScript</DefaultClientScript>
+ <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
+ <DefaultTargetSchema>IE50</DefaultTargetSchema>
+ <DelaySign>false</DelaySign>
+ <OutputType>Library</OutputType>
+ <RootNamespace>CodeCounter.Library</RootNamespace>
+ <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ <OldToolsVersion>3.5</OldToolsVersion>
+ <SccProjectName>SAK</SccProjectName>
+ <SccLocalPath>SAK</SccLocalPath>
+ <SccAuxPath>SAK</SccAuxPath>
+ <SccProvider>SAK</SccProvider>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <OutputPath>bin\dll\Debug\</OutputPath>
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+ <BaseAddress>285212672</BaseAddress>
+ <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugSymbols>true</DebugSymbols>
+ <FileAlignment>4096</FileAlignment>
+ <NoStdLib>false</NoStdLib>
+ <Optimize>false</Optimize>
+ <RegisterForComInterop>false</RegisterForComInterop>
+ <RemoveIntegerChecks>false</RemoveIntegerChecks>
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+ <WarningLevel>4</WarningLevel>
+ <DebugType>full</DebugType>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <OutputPath>bin\dll\release\</OutputPath>
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+ <BaseAddress>285212672</BaseAddress>
+ <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+ <DefineConstants>TRACE</DefineConstants>
+ <DebugSymbols>false</DebugSymbols>
+ <FileAlignment>4096</FileAlignment>
+ <NoStdLib>false</NoStdLib>
+ <Optimize>true</Optimize>
+ <RegisterForComInterop>false</RegisterForComInterop>
+ <RemoveIntegerChecks>false</RemoveIntegerChecks>
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+ <WarningLevel>4</WarningLevel>
+ <DebugType>none</DebugType>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DEBUG ALL|AnyCPU' ">
+ <OutputPath>bin\DEBUG ALL\</OutputPath>
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+ <BaseAddress>285212672</BaseAddress>
+ <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+ <DebugSymbols>true</DebugSymbols>
+ <FileAlignment>4096</FileAlignment>
+ <NoStdLib>false</NoStdLib>
+ <Optimize>false</Optimize>
+ <RegisterForComInterop>false</RegisterForComInterop>
+ <RemoveIntegerChecks>false</RemoveIntegerChecks>
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+ <WarningLevel>1</WarningLevel>
+ <DebugType>full</DebugType>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'RELEASE ALL|AnyCPU' ">
+ <OutputPath>bin\dll\release\</OutputPath>
+ <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+ <BaseAddress>285212672</BaseAddress>
+ <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+ <DefineConstants>TRACE</DefineConstants>
+ <DebugSymbols>false</DebugSymbols>
+ <FileAlignment>4096</FileAlignment>
+ <NoStdLib>false</NoStdLib>
+ <Optimize>true</Optimize>
+ <RegisterForComInterop>false</RegisterForComInterop>
+ <RemoveIntegerChecks>false</RemoveIntegerChecks>
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+ <WarningLevel>4</WarningLevel>
+ <DebugType>none</DebugType>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Big Woo.NET, Version=3.0.3287.30089, Culture=neutral, PublicKeyToken=b8a13bcc86eb719e, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\dependencies\Big Woo.NET.dll</HintPath>
+ </Reference>
+ <Reference Include="System">
+ <Name>System</Name>
+ </Reference>
+ <Reference Include="System.configuration" />
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data">
+ <Name>System.Data</Name>
+ </Reference>
+ <Reference Include="System.Drawing">
+ <Name>System.Drawing</Name>
+ </Reference>
+ <Reference Include="System.Security">
+ <Name>System.Security</Name>
+ </Reference>
+ <Reference Include="System.Windows.Forms">
+ <Name>System.Windows.Forms</Name>
+ </Reference>
+ <Reference Include="System.Xml">
+ <Name>System.XML</Name>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="CodeCounterLogicImplementers.cs" />
+ <Compile Include="ConfigFileSections.cs" />
+ <Compile Include="CSharpCodeCounterLogic.cs" />
+ <Compile Include="CustomExceptions.cs" />
+ <Compile Include="ICodeCounterLogic.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="SqlCodeCounterLogic.cs" />
+ <Compile Include="XamlCodeCounterLogic.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+</Project> \ No newline at end of file
diff --git a/BCT/Samples/CodeCounter/library/codecounterlibrary.csproj.vspscc b/BCT/Samples/CodeCounter/library/codecounterlibrary.csproj.vspscc
new file mode 100644
index 00000000..feffdeca
--- /dev/null
+++ b/BCT/Samples/CodeCounter/library/codecounterlibrary.csproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
diff --git a/BCT/Samples/Generics/GenericsExample.cs b/BCT/Samples/Generics/GenericsExample.cs
new file mode 100644
index 00000000..c7016ceb
--- /dev/null
+++ b/BCT/Samples/Generics/GenericsExample.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.Contracts;
+using System.Linq;
+using System.Text;
+
+/* Simple example of generics/dictionary support needed by Poirot */
+class GenericsExample
+{
+ public static void Main()
+ {
+ Dictionary<String, String> dict = new Dictionary<String, String>();
+ dict["foo"] = "bar";
+ Contract.Assert(dict.ContainsKey("foo"));
+ Contract.Assert(dict.ContainsValue("bar"));
+ Contract.Assert(dict["foo"] == "bar");
+ dict.Remove("foo");
+ Contract.Assert(dict["foo"] == "bar"); // should fail
+ }
+} \ No newline at end of file
diff --git a/BCT/Samples/Strings/StringsExample.cs b/BCT/Samples/Strings/StringsExample.cs
new file mode 100644
index 00000000..a04fc9a0
--- /dev/null
+++ b/BCT/Samples/Strings/StringsExample.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.Contracts;
+using System.Linq;
+using System.Text;
+
+/* Example of string functionality needed by Poirot: concatenation and equality */
+class StringsExample
+{
+ public static void Main()
+ {
+ string foo = "delicious";
+ string bar = "cake";
+ Contract.Assert(!foo.Equals(bar));
+ string foo_bar = foo + bar;
+ Contract.Assert(foo_bar.Equals("deliciouscake"));
+ string delish = "delicious";
+ Contract.Assert(foo.Equals(delish));
+ }
+} \ No newline at end of file
diff --git a/Binaries/DafnyRuntime.cs b/Binaries/DafnyRuntime.cs
index 63cca64a..b10aeac9 100644
--- a/Binaries/DafnyRuntime.cs
+++ b/Binaries/DafnyRuntime.cs
@@ -122,6 +122,7 @@ namespace Dafny
// return the first one
return t;
}
+ return default(T);
}
}
public class Sequence<T>
diff --git a/Binaries/UnivBackPred2.smt2 b/Binaries/UnivBackPred2.smt2
index 06b307fe..97c052c9 100644
--- a/Binaries/UnivBackPred2.smt2
+++ b/Binaries/UnivBackPred2.smt2
@@ -1,7 +1,6 @@
; Boogie universal background predicate
; Copyright (c) 2004-2010, Microsoft Corp.
(set-info :category "industrial")
-(set-logic UFNIA)
(declare-sort |T@U| 0)
(declare-sort |T@T| 0)
(declare-fun int_div (Int Int) Int)
diff --git a/Source/BoogieDriver/BoogieDriver.cs b/Source/BoogieDriver/BoogieDriver.cs
index 3929e237..dcc007fe 100644
--- a/Source/BoogieDriver/BoogieDriver.cs
+++ b/Source/BoogieDriver/BoogieDriver.cs
@@ -261,7 +261,8 @@ namespace Microsoft.Boogie {
//BoogiePL.Errors.count = 0;
Program program = null;
bool okay = true;
- foreach (string bplFileName in fileNames) {
+ for (int fileId = 0; fileId < fileNames.Count; fileId++) {
+ string bplFileName = fileNames[fileId];
if (!suppressTraceOutput) {
if (CommandLineOptions.Clo.XmlSink != null) {
CommandLineOptions.Clo.XmlSink.WriteFileFragment(bplFileName);
@@ -274,7 +275,8 @@ namespace Microsoft.Boogie {
Program programSnippet;
int errorCount;
try {
- errorCount = BoogiePL.Parser.Parse(bplFileName, null, out programSnippet);
+ var defines = new List<string>() { "FILE_" + fileId };
+ errorCount = BoogiePL.Parser.Parse(bplFileName, defines, out programSnippet);
if (programSnippet == null || errorCount != 0) {
Console.WriteLine("{0} parse errors detected in {1}", errorCount, bplFileName);
okay = false;
diff --git a/Source/Core/Absy.cs b/Source/Core/Absy.cs
index cde8fc3f..67500c88 100644
--- a/Source/Core/Absy.cs
+++ b/Source/Core/Absy.cs
@@ -235,30 +235,26 @@ namespace Microsoft.Boogie {
ResolveTypes(rc);
- List<Declaration/*!*/> prunedTopLevelDecls = CommandLineOptions.Clo.OverlookBoogieTypeErrors ? new List<Declaration/*!*/>() : null;
-
+ var prunedTopLevelDecls = new List<Declaration/*!*/>();
foreach (Declaration d in TopLevelDeclarations) {
+ if (QKeyValue.FindBoolAttribute(d.Attributes, "ignore")) {
+ continue;
+ }
// resolve all the non-type-declarations
if (d is TypeCtorDecl || d is TypeSynonymDecl) {
- if (prunedTopLevelDecls != null)
- prunedTopLevelDecls.Add(d);
} else {
int e = rc.ErrorCount;
d.Resolve(rc);
- if (prunedTopLevelDecls != null) {
- if (rc.ErrorCount != e && d is Implementation) {
- // ignore this implementation
- System.Console.WriteLine("Warning: Ignoring implementation {0} because of translation resolution errors", ((Implementation)d).Name);
- rc.ErrorCount = e;
- } else {
- prunedTopLevelDecls.Add(d);
- }
+ if (CommandLineOptions.Clo.OverlookBoogieTypeErrors && rc.ErrorCount != e && d is Implementation) {
+ // ignore this implementation
+ System.Console.WriteLine("Warning: Ignoring implementation {0} because of translation resolution errors", ((Implementation)d).Name);
+ rc.ErrorCount = e;
+ continue;
}
}
+ prunedTopLevelDecls.Add(d);
}
- if (prunedTopLevelDecls != null) {
- TopLevelDeclarations = prunedTopLevelDecls;
- }
+ TopLevelDeclarations = prunedTopLevelDecls;
foreach (Declaration d in TopLevelDeclarations) {
Variable v = d as Variable;
diff --git a/Source/Core/AbsyCmd.cs b/Source/Core/AbsyCmd.cs
index c6184e63..87b48740 100644
--- a/Source/Core/AbsyCmd.cs
+++ b/Source/Core/AbsyCmd.cs
@@ -247,7 +247,9 @@ namespace Microsoft.Boogie {
private void ComputeAllLabels(StmtList stmts) {
if (stmts == null) return;
foreach (BigBlock bb in stmts.BigBlocks) {
- allLabels.Add(bb.LabelName);
+ if (bb.LabelName != null) {
+ allLabels.Add(bb.LabelName);
+ }
ComputeAllLabels(bb.ec);
}
}
diff --git a/Source/Core/CommandLineOptions.cs b/Source/Core/CommandLineOptions.cs
index 5094fb9e..84ecce6d 100644
--- a/Source/Core/CommandLineOptions.cs
+++ b/Source/Core/CommandLineOptions.cs
@@ -1875,6 +1875,21 @@ namespace Microsoft.Boogie {
Console.WriteLine(
@"Boogie: The following attributes are supported by this implementation.
+ ---- On top-level declarations ---------------------------------------------
+
+ {:ignore}
+ Ignore the declaration (after checking for duplicate names).
+ See also below for more options when :ignore is used with axioms.
+
+ {:extern}
+ If two top-level declarations introduce the same name (for example, two
+ constants with the same name or two procedures with the same name), then
+ Boogie usually produces an error message. However, if at least one of
+ the declarations is declared with :extern, one of the declarations is
+ ignored. If both declarations are :extern, Boogie arbitrarily chooses
+ one of them to keep; otherwise, Boogie ignore the :extern declaration
+ and keeps the other.
+
---- On axioms -------------------------------------------------------------
{:inline true}
diff --git a/Source/Core/DeadVarElim.cs b/Source/Core/DeadVarElim.cs
index c1270eab..3c2b9a42 100644
--- a/Source/Core/DeadVarElim.cs
+++ b/Source/Core/DeadVarElim.cs
@@ -332,7 +332,7 @@ namespace Microsoft.Boogie {
List<Block/*!*/> newBlocks = new List<Block/*!*/>();
foreach (Block/*!*/ b in impl.Blocks) {
Contract.Assert(b != null);
- if (!removedBlocks.Contains(b)) {
+ if (visitedBlocks.Contains(b) && !removedBlocks.Contains(b)) {
newBlocks.Add(b);
}
}
diff --git a/Source/Core/ResolutionContext.cs b/Source/Core/ResolutionContext.cs
index d4b353ef..803b1f8b 100644
--- a/Source/Core/ResolutionContext.cs
+++ b/Source/Core/ResolutionContext.cs
@@ -170,15 +170,22 @@ namespace Microsoft.Boogie {
public void AddType(NamedDeclaration td) {
Contract.Requires(td != null);
Contract.Assert((td is TypeCtorDecl) || (td is TypeSynonymDecl));
+ Contract.Requires(td.Name != null);
- string name = cce.NonNull(td.Name);
+ string name = td.Name;
if (CheckBvNameClashes(td, name))
return; // error has already been reported
- if (types[name] != null) {
- Error(td, "more than one declaration of type name: {0}", name);
- } else {
+ var previous = (NamedDeclaration)types[name];
+ if (previous == null) {
types.Add(name, td);
+ } else {
+ var r = (NamedDeclaration)SelectNonExtern(td, previous);
+ if (r == null) {
+ Error(td, "more than one declaration of type name: {0}", name);
+ } else {
+ types[name] = r;
+ }
}
}
@@ -247,79 +254,6 @@ namespace Microsoft.Boogie {
return null; // not present
}
- // ------------------------------ Types ------------------------------
-
- // user-defined types
- // Hashtable /*string->TypeDecl*/! types = new Hashtable /*string->TypeDecl*/ ();
- /*
- public void AddType(TypeDecl td){
- Contract.Requires(td != null);
- string! name = (!)td.Name;
-
- if (name.StartsWith("bv") && name.Length > 2) {
- bool isBv = true;
- for (int i = 2; i < name.Length; ++i)
- if (!char.IsDigit(name[i])) isBv = false;
- if (isBv)
- Error(td, "type name: {0} is registered for bitvectors", name);
- }
-
- if (types[name] != null)
- {
- Error(td, "more than one declaration of type name: {0}", name);
- }
- else
- {
- types.Add(name, td);
- }
- }
- */
- /// <summary>
- /// Returns the declaration of the named type, or null if
- /// no such type is declared.
- /// </summary>
- /// <param name="name"></param>
- /// <returns></returns>
- /* public TypeDecl LookUpType(string name){
-Contract.Requires(name != null);
- return (TypeDecl)types[name];
- }
- */
- // ------------------------------ Type Binders ------------------------------
- /*
- List<TypeBinderDecl!>! typeBinders = new List<TypeBinderDecl!>(5);
-
- public void AddTypeBinder(TypeBinderDecl td){
- Contract.Requires(td != null);
- for (int i = 0; i < typeBinders.Count; i++) {
- if (typeBinders[i].Name == td.Name) {
- Error(td, "more than one declaration of type binder name: {0}", td.Name);
- return;
- }
- }
- typeBinders.Add(td);
- }
-
- public int TypeBinderState {
- get { return typeBinders.Count; }
- set { typeBinders.RemoveRange(value, typeBinders.Count - value); }
- }
-
- /// <summary>
- /// Returns the declaration of the named type binder, or null if
- /// no such binder is declared.
- /// </summary>
- public TypeDecl LookUpTypeBinder(string name){
- Contract.Requires(name != null);
- for (int i = typeBinders.Count; 0 <= --i; ) {
- TypeBinderDecl td = typeBinders[i];
- if (td.Name == name) {
- return td;
- }
- }
- return null; // not present
- }
- */
// ------------------------------ Variables ------------------------------
class VarContextNode {
@@ -365,10 +299,16 @@ Contract.Requires(name != null);
public void AddVariable(Variable var, bool global) {
Contract.Requires(var != null);
- if (FindVariable(cce.NonNull(var.Name), !global) != null) {
- Error(var, "more than one declaration of variable name: {0}", var.Name);
- } else {
+ var previous = FindVariable(cce.NonNull(var.Name), !global);
+ if (previous == null) {
varContext.VarSymbols.Add(var.Name, var);
+ } else {
+ var r = (Variable)SelectNonExtern(var, previous);
+ if (r == null) {
+ Error(var, "more than one declaration of variable name: {0}", var.Name);
+ } else {
+ varContext.VarSymbols[var.Name] = r;
+ }
}
}
@@ -417,11 +357,47 @@ Contract.Requires(name != null);
public void AddProcedure(DeclWithFormals proc) {
Contract.Requires(proc != null);
- if (funcdures[cce.NonNull(proc.Name)] != null) {
- Error(proc, "more than one declaration of function/procedure name: {0}", proc.Name);
+ Contract.Requires(proc.Name != null);
+
+ string name = proc.Name;
+ var previous = (DeclWithFormals)funcdures[name];
+ if (previous == null) {
+ funcdures.Add(name, proc);
+ } else {
+ var r = (DeclWithFormals)SelectNonExtern(proc, previous);
+ if (r == null) {
+ Error(proc, "more than one declaration of function/procedure name: {0}", name);
+ } else {
+ funcdures[name] = r;
+ }
+ }
+ }
+
+ /// <summary>
+ /// If both "a" and "b" have an ":extern" attribute, returns either one.
+ /// If one of "a" and "b" has an ":extern" attribute, returns that one.
+ /// If neither of "a" and "b" has an ":extern" attribute, returns null.
+ /// If a non-value value is returned, this method also adds the ":ignore"
+ /// attribute to the declaration NOT returned.
+ /// </summary>
+ Declaration SelectNonExtern(Declaration a, Declaration b) {
+ Contract.Requires(a != null);
+ Contract.Requires(b != null);
+ Contract.Ensures(Contract.Result<Declaration>() == null || Contract.Result<Declaration>() == a || Contract.Result<Declaration>() == b);
+
+ Declaration ignore, keep;
+ if (QKeyValue.FindBoolAttribute(a.Attributes, "extern")) {
+ ignore = a;
+ keep = b;
+ } else if (QKeyValue.FindBoolAttribute(b.Attributes, "extern")) {
+ ignore = b;
+ keep = a;
} else {
- funcdures.Add(proc.Name, proc);
+ return null;
}
+ // prepend :ignore attribute
+ ignore.Attributes = new QKeyValue(ignore.tok, "ignore", new List<object/*!*/>(), ignore.Attributes);
+ return keep;
}
/// <summary>
diff --git a/Source/Dafny/Compiler.cs b/Source/Dafny/Compiler.cs
index 62270067..9495d64e 100644
--- a/Source/Dafny/Compiler.cs
+++ b/Source/Dafny/Compiler.cs
@@ -66,7 +66,7 @@ namespace Microsoft.Dafny {
foreach (ModuleDecl m in program.Modules) {
int indent = 0;
if (!m.IsDefaultModule) {
- wr.WriteLine("namespace {0} {{", m.Name);
+ wr.WriteLine("namespace @{0} {{", m.Name);
indent += IndentAmount;
}
foreach (TopLevelDecl d in m.TopLevelDecls) {
@@ -84,7 +84,7 @@ namespace Microsoft.Dafny {
} else {
ClassDecl cl = (ClassDecl)d;
Indent(indent);
- wr.Write("public class {0}", cl.Name);
+ wr.Write("public class @{0}", cl.Name);
if (cl.TypeArgs.Count != 0) {
wr.Write("<{0}>", TypeParameters(cl.TypeArgs));
}
@@ -199,17 +199,17 @@ namespace Microsoft.Dafny {
wr.Write(">");
}
wr.Write(" : Base_{0}", dt.Name);
- wr.WriteLine(" {");
if (dt.TypeArgs.Count != 0) {
wr.Write("<{0}>", TypeParameters(dt.TypeArgs));
}
+ wr.WriteLine(" {");
int ind = indent + IndentAmount;
int i = 0;
foreach (Formal arg in ctor.Formals) {
if (!arg.IsGhost) {
Indent(ind);
- wr.WriteLine("public readonly {0} {1};", TypeName(arg.Type), FormalName(arg, i));
+ wr.WriteLine("public readonly {0} @{1};", TypeName(arg.Type), FormalName(arg, i));
i++;
}
}
@@ -222,7 +222,7 @@ namespace Microsoft.Dafny {
foreach (Formal arg in ctor.Formals) {
if (!arg.IsGhost) {
Indent(ind + IndentAmount);
- wr.WriteLine("this.{0} = {0};", FormalName(arg, i));
+ wr.WriteLine("this.@{0} = @{0};", FormalName(arg, i));
i++;
}
}
@@ -232,10 +232,12 @@ namespace Microsoft.Dafny {
}
}
- void CompileDatatypeStruct(DatatypeDecl dt, int indent) {Contract.Requires(dt != null);
+ void CompileDatatypeStruct(DatatypeDecl dt, int indent) {
+ Contract.Requires(dt != null);
+
// public struct Dt<T> {
// Base_Dt<T> d;
- // public Base_Dt<T> D {
+ // public Base_Dt<T> _D {
// get { if (d == null) { d = Default; } return d; }
// }
// public Dt(Base_Dt<T> d) { this.d = d; }
@@ -243,9 +245,9 @@ namespace Microsoft.Dafny {
// get { return ...; }
// }
// public override bool Equals(object other) {
- // return other is Dt<T> && D.Equals(((Dt<T>)other).D);
+ // return other is Dt<T> && _D.Equals(((Dt<T>)other)._D);
// }
- // public override int GetHashCode() { return D.GetHashCode(); }
+ // public override int GetHashCode() { return _D.GetHashCode(); }
// }
string DtT = dt.Name;
if (dt.TypeArgs.Count != 0) {
@@ -253,27 +255,29 @@ namespace Microsoft.Dafny {
}
Indent(indent);
- wr.WriteLine("public struct {0} {{", DtT);
+ wr.WriteLine("public struct @{0} {{", DtT);
int ind = indent + IndentAmount;
Indent(ind);
wr.WriteLine("Base_{0} d;", DtT);
Indent(ind);
- wr.WriteLine("public Base_{0} D {{", DtT);
+ wr.WriteLine("public Base_{0} _D {{", DtT);
Indent(ind + IndentAmount);
wr.WriteLine("get { if (d == null) { d = Default; } return d; }");
Indent(ind); wr.WriteLine("}");
Indent(ind);
- wr.WriteLine("public {0}(Base_{1} d) {{ this.d = d; }}", dt.Name, DtT);
+ wr.WriteLine("public @{0}(Base_{1} d) {{ this.d = d; }}", dt.Name, DtT);
Indent(ind);
wr.WriteLine("public static Base_{0} Default {{", DtT);
Indent(ind + IndentAmount);
wr.Write("get { return ");
wr.Write("new {0}", DtCtorName(cce.NonNull(dt.DefaultCtor)));
- // todo: type parameters
+ if (dt.TypeArgs.Count != 0) {
+ wr.Write("<{0}>", TypeParameters(dt.TypeArgs));
+ }
wr.Write("(");
string sep = "";
foreach (Formal f in dt.DefaultCtor.Formals) {
@@ -288,11 +292,11 @@ namespace Microsoft.Dafny {
Indent(ind); wr.WriteLine("public override bool Equals(object other) {");
Indent(ind + IndentAmount);
- wr.WriteLine("return other is {0} && D.Equals((({0})other).D);", DtT);
+ wr.WriteLine("return other is @{0} && _D.Equals(((@{0})other)._D);", DtT);
Indent(ind); wr.WriteLine("}");
Indent(ind);
- wr.WriteLine("public override int GetHashCode() { return D.GetHashCode(); }");
+ wr.WriteLine("public override int GetHashCode() { return _D.GetHashCode(); }");
Indent(indent);
wr.WriteLine("}");
@@ -306,7 +310,7 @@ namespace Microsoft.Dafny {
foreach (Formal arg in formals) {
if (!arg.IsGhost) {
string name = FormalName(arg, i);
- wr.Write("{0}{1}{2} {3}", sep, arg.InParam ? "" : "out ", TypeName(arg.Type), name);
+ wr.Write("{0}{1}{2} @{3}", sep, arg.InParam ? "" : "out ", TypeName(arg.Type), name);
sep = ", ";
i++;
}
@@ -314,7 +318,8 @@ namespace Microsoft.Dafny {
}
string FormalName(Formal formal, int i) {
- Contract.Requires(formal != null);Contract.Ensures(Contract.Result<string>() != null);
+ Contract.Requires(formal != null);
+ Contract.Ensures(Contract.Result<string>() != null);
return formal.Name.StartsWith("#") ? "a" + i : formal.Name;
}
@@ -333,7 +338,7 @@ namespace Microsoft.Dafny {
Field f = (Field)member;
if (!f.IsGhost) {
Indent(indent);
- wr.WriteLine("public {0} {1} = {2};", TypeName(f.Type), f.Name, DefaultValue(f.Type));
+ wr.WriteLine("public {0} @{1} = {2};", TypeName(f.Type), f.Name, DefaultValue(f.Type));
}
} else if (member is Function) {
@@ -344,7 +349,7 @@ namespace Microsoft.Dafny {
Error("Function {0} has no body", f.FullName);
} else {
Indent(indent);
- wr.Write("public {0}{1} {2}", f.IsStatic ? "static " : "", TypeName(f.ResultType), f.Name);
+ wr.Write("public {0}{1} @{2}", f.IsStatic ? "static " : "", TypeName(f.ResultType), f.Name);
if (f.TypeArgs.Count != 0) {
wr.Write("<{0}>", TypeParameters(f.TypeArgs));
}
@@ -354,8 +359,8 @@ namespace Microsoft.Dafny {
if (f.Body is MatchExpr) {
MatchExpr me = (MatchExpr)f.Body;
// Type source = e;
- // if (source.D is Dt_Ctor0) {
- // FormalType f0 = ((Dt_Ctor0)source.D).a0;
+ // if (source._D is Dt_Ctor0) {
+ // FormalType f0 = ((Dt_Ctor0)source._D).a0;
// ...
// return Body0;
// } else if (...) {
@@ -397,7 +402,7 @@ namespace Microsoft.Dafny {
Method m = (Method)member;
if (!m.IsGhost) {
Indent(indent);
- wr.Write("public {0}void {1}", m.IsStatic ? "static " : "", m.Name);
+ wr.Write("public {0}void @{1}", m.IsStatic ? "static " : "", m.Name);
if (m.TypeArgs.Count != 0) {
wr.Write("<{0}>", TypeParameters(m.TypeArgs));
}
@@ -412,7 +417,7 @@ namespace Microsoft.Dafny {
foreach (Formal p in m.Outs) {
if (!p.IsGhost) {
Indent(indent + IndentAmount);
- wr.WriteLine("{0} = {1};", p.Name, DefaultValue(p.Type));
+ wr.WriteLine("@{0} = {1};", p.Name, DefaultValue(p.Type));
}
}
if (m.Body == null) {
@@ -428,7 +433,7 @@ namespace Microsoft.Dafny {
wr.WriteLine("public static void Main(string[] args) {");
ClassDecl cl = cce.NonNull(m.EnclosingClass);
Indent(indent + IndentAmount);
- wr.Write("{0} b = new {0}", cl.Name);
+ wr.Write("@{0} b = new @{0}", cl.Name);
if (cl.TypeArgs.Count != 0) {
// instantiate every parameter, it doesn't particularly matter how
wr.Write("<");
@@ -493,7 +498,7 @@ namespace Microsoft.Dafny {
return name + "]";
} else if (type is UserDefinedType) {
UserDefinedType udt = (UserDefinedType)type;
- string s = udt.Name;
+ string s = "@" + udt.Name;
if (udt.TypeArgs.Count != 0) {
if (Contract.Exists(udt.TypeArgs, argType =>argType is ObjectType)) {
Error("compilation does not support type 'object' as a type parameter; consider introducing a ghost");
@@ -538,7 +543,7 @@ namespace Microsoft.Dafny {
string s = "";
string sep = "";
foreach (TypeParameter tp in targs) {
- s += sep + tp.Name;
+ s += sep + "@" + tp.Name;
sep = ",";
}
return s;
@@ -569,14 +574,14 @@ namespace Microsoft.Dafny {
return "null";
} else if (type.IsDatatype) {
UserDefinedType udt = (UserDefinedType)type;
- string s = udt.Name;
+ string s = "@" + udt.Name;
if (udt.TypeArgs.Count != 0) {
s += "<" + TypeNames(udt.TypeArgs) + ">";
}
- return s + ".Default";
+ return string.Format("new {0}({0}.Default)", s);
} else if (type.IsTypeParameter) {
UserDefinedType udt = (UserDefinedType)type;
- return "default(" + udt.Name + ")";
+ return "default(@" + udt.Name + ")";
} else if (type is SetType) {
return DafnySetClass + "<" + TypeName(((SetType)type).Arg) + ">.Empty";
} else if (type is SeqType) {
@@ -667,12 +672,10 @@ namespace Microsoft.Dafny {
string nw = "_nw" + tmpVarCount;
tmpVarCount++;
Indent(indent);
- wr.Write("{0} = ", nw);
+ wr.Write("var {0} = ", nw);
TrAssignmentRhs(s.Rhs);
wr.WriteLine(";");
- Indent(indent);
TrCallStmt(tRhs.InitCall, nw, indent);
- wr.WriteLine(";");
Indent(indent);
TrExpr(s.Lhs);
wr.WriteLine(" = {0};", nw);
@@ -709,7 +712,7 @@ namespace Microsoft.Dafny {
}
TrStmt(s.Thn, indent);
- if (s.Els != null) {
+ if (s.Els != null && s.Guard != null) {
Indent(indent); wr.WriteLine("else");
TrStmt(s.Els, indent);
}
@@ -749,7 +752,7 @@ namespace Microsoft.Dafny {
wr.WriteLine("List<Pair<{0},{1}>> {2} = new List<Pair<{0},{1}>>();", TType, RhsType, pu);
Indent(indent);
- wr.Write("foreach ({0} {1} in (", TType, s.BoundVar.Name);
+ wr.Write("foreach ({0} @{1} in (", TType, s.BoundVar.Name);
TrExpr(s.Collection);
wr.WriteLine(").Elements) {");
@@ -762,7 +765,7 @@ namespace Microsoft.Dafny {
TrStmt(p, indent + 2*IndentAmount);
}
Indent(indent + 2*IndentAmount);
- wr.Write("{0}.Add(new Pair<{1},{2}>({3}, ", pu, TType, RhsType, s.BoundVar.Name);
+ wr.Write("{0}.Add(new Pair<{1},{2}>(@{3}, ", pu, TType, RhsType, s.BoundVar.Name);
ExprRhs rhsExpr = s.BodyAssign.Rhs as ExprRhs;
if (rhsExpr != null) {
TrExpr(rhsExpr.Expr);
@@ -783,8 +786,8 @@ namespace Microsoft.Dafny {
} else if (stmt is MatchStmt) {
MatchStmt s = (MatchStmt)stmt;
// Type source = e;
- // if (source.D is Dt_Ctor0) {
- // FormalType f0 = ((Dt_Ctor0)source.D).a0;
+ // if (source._D is Dt_Ctor0) {
+ // FormalType f0 = ((Dt_Ctor0)source._D).a0;
// ...
// Body0;
// } else if (...) {
@@ -823,13 +826,13 @@ namespace Microsoft.Dafny {
Contract.Assert(s.Method != null); // follows from the fact that stmt has been successfully resolved
Indent(indent);
if (receiverReplacement != null) {
- wr.Write(receiverReplacement);
+ wr.Write("@" + receiverReplacement);
} else if (s.Method.IsStatic) {
wr.Write(TypeName(cce.NonNull(s.Receiver.Type)));
} else {
TrParenExpr(s.Receiver);
}
- wr.Write(".{0}(", s.Method.Name);
+ wr.Write(".@{0}(", s.Method.Name);
string sep = "";
for (int i = 0; i < s.Method.Ins.Count; i++) {
@@ -921,8 +924,13 @@ namespace Microsoft.Dafny {
void TrVarDecl(VarDecl s, bool alwaysInitialize, int indent) {
Contract.Requires(s != null);
+ if (s.IsGhost) {
+ // only emit non-ghosts (we get here only for local variables introduced implicitly by call statements)
+ return;
+ }
+
Indent(indent);
- wr.Write("{0} {1}", TypeName(s.Type), s.Name);
+ wr.Write("{0} @{1}", TypeName(s.Type), s.Name);
if (s.Rhs != null) {
wr.Write(" = ");
TrAssignmentRhs(s.Rhs);
@@ -943,15 +951,15 @@ namespace Microsoft.Dafny {
Contract.Requires(source != null);
Contract.Requires(ctor != null);
Contract.Requires(cce.NonNullElements(arguments));
- // if (source.D is Dt_Ctor0) {
- // FormalType f0 = ((Dt_Ctor0)source.D).a0;
+ // if (source._D is Dt_Ctor0) {
+ // FormalType f0 = ((Dt_Ctor0)source._D).a0;
// ...
Indent(indent);
wr.Write("{0}if (", caseIndex == 0 ? "" : "} else ");
if (caseIndex == caseCount - 1) {
wr.Write("true");
} else {
- wr.Write("{0}.D is {1}", source, DtCtorName(ctor));
+ wr.Write("{0}._D is {1}", source, DtCtorName(ctor));
}
wr.WriteLine(") {");
@@ -960,9 +968,9 @@ namespace Microsoft.Dafny {
Formal arg = ctor.Formals[m];
if (!arg.IsGhost) {
BoundVar bv = arguments[m];
- // FormalType f0 = ((Dt_Ctor0)source.D).a0;
+ // FormalType f0 = ((Dt_Ctor0)source._D).a0;
Indent(indent + IndentAmount);
- wr.WriteLine("{0} {1} = (({2}){3}.D).{4};",
+ wr.WriteLine("{0} @{1} = (({2}){3}._D).@{4};",
TypeName(bv.Type), bv.Name, DtCtorName(ctor), source, FormalName(arg, k));
k++;
}
@@ -1022,7 +1030,7 @@ namespace Microsoft.Dafny {
} else if (expr is IdentifierExpr) {
IdentifierExpr e = (IdentifierExpr)expr;
- wr.Write(cce.NonNull(e.Var).Name);
+ wr.Write("@" + e.Var.Name);
} else if (expr is SetDisplayExpr) {
SetDisplayExpr e = (SetDisplayExpr)expr;
@@ -1050,7 +1058,7 @@ namespace Microsoft.Dafny {
}
} else {
TrParenExpr(e.Obj);
- wr.Write(".{0}", e.Field.Name);
+ wr.Write(".@{0}", e.Field.Name);
}
} else if (expr is SeqSelectExpr) {
@@ -1103,7 +1111,7 @@ namespace Microsoft.Dafny {
} else {
TrParenExpr(e.Receiver);
}
- wr.Write(".{0}", f.Name);
+ wr.Write(".@{0}", f.Name);
wr.Write("(");
string sep = "";
for (int i = 0; i < e.Args.Count; i++) {
@@ -1325,7 +1333,7 @@ namespace Microsoft.Dafny {
Contract.Assert(false); throw new cce.UnreachableException(); // unexpected BoundedPool type
}
wr.Write("{0}, ", expr is ForallExpr ? "true" : "false");
- wr.Write("{0} => ", bv.Name);
+ wr.Write("@{0} => ", bv.Name);
}
TrExpr(e.Body);
for (int i = 0; i < n; i++) {
diff --git a/Source/Dafny/Dafny.atg b/Source/Dafny/Dafny.atg
index c630d67e..780d35ea 100644
--- a/Source/Dafny/Dafny.atg
+++ b/Source/Dafny/Dafny.atg
@@ -1312,6 +1312,8 @@ SelectOrCallSuffix<ref Expression/*!*/ e>
)
(. if (multipleIndices != null) {
e = new MultiSelectExpr(x, e, multipleIndices);
+ // make sure an array class with this dimensionality exists
+ UserDefinedType tmp = theBuiltIns.ArrayType(multipleIndices.Count, new IntType(), true);
} else {
if (!anyDots && e0 == null) {
/* a parsing error occurred */
diff --git a/Source/Dafny/Parser.cs b/Source/Dafny/Parser.cs
index e2a45ceb..26cb7fbb 100644
--- a/Source/Dafny/Parser.cs
+++ b/Source/Dafny/Parser.cs
@@ -25,7 +25,7 @@ public class Parser {
const bool T = true;
const bool x = false;
const int minErrDist = 2;
-
+
public Scanner/*!*/ scanner;
public Errors/*!*/ errors;
@@ -161,10 +161,10 @@ public static int Parse (string/*!*/ s, string/*!*/ filename, List<ModuleDecl/*!
if (errDist >= minErrDist) errors.SemErr(t, msg);
errDist = 0;
}
-
- public void SemErr(IToken/*!*/ tok, string/*!*/ msg) {
- Contract.Requires(tok != null);
- Contract.Requires(msg != null);
+
+ public void SemErr(IToken/*!*/ tok, string/*!*/ msg) {
+ Contract.Requires(tok != null);
+ Contract.Requires(msg != null);
errors.SemErr(tok, msg);
}
@@ -177,15 +177,15 @@ public static int Parse (string/*!*/ s, string/*!*/ filename, List<ModuleDecl/*!
la = t;
}
}
-
+
void Expect (int n) {
if (la.kind==n) Get(); else { SynErr(n); }
}
-
+
bool StartOf (int s) {
return set[s, la.kind];
}
-
+
void ExpectWeak (int n, int follow) {
if (la.kind == n) Get();
else {
@@ -209,7 +209,7 @@ public static int Parse (string/*!*/ s, string/*!*/ filename, List<ModuleDecl/*!
}
}
-
+
void Dafny() {
ClassDecl/*!*/ c; DatatypeDecl/*!*/ dt;
Attributes attrs; IToken/*!*/ id; List<string/*!*/> theImports;
@@ -2047,6 +2047,8 @@ List<Expression/*!*/>/*!*/ decreases) {
} else SynErr(144);
if (multipleIndices != null) {
e = new MultiSelectExpr(x, e, multipleIndices);
+ // make sure an array class with this dimensionality exists
+ UserDefinedType tmp = theBuiltIns.ArrayType(multipleIndices.Count, new IntType(), true);
} else {
if (!anyDots && e0 == null) {
/* a parsing error occurred */
@@ -2131,13 +2133,13 @@ List<Expression/*!*/>/*!*/ decreases) {
public void Parse() {
la = new Token();
- la.val = "";
+ la.val = "";
Get();
Dafny();
- Expect(0);
+ Expect(0);
}
-
+
static readonly bool[,]/*!*/ set = {
{T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
{x,x,x,x, x,T,x,x, x,T,T,T, T,T,T,x, x,x,T,x, T,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
@@ -2164,20 +2166,18 @@ List<Expression/*!*/>/*!*/ decreases) {
public class Errors {
public int count = 0; // number of errors detected
public System.IO.TextWriter/*!*/ errorStream = Console.Out; // error messages go to this stream
- public string errMsgFormat = "{0}({1},{2}): error: {3}"; // 0=filename, 1=line, 2=column, 3=text
- public string warningMsgFormat = "{0}({1},{2}): warning: {3}"; // 0=filename, 1=line, 2=column, 3=text
-
+ public string errMsgFormat = "{0}({1},{2}): error: {3}"; // 0=filename, 1=line, 2=column, 3=text
+ public string warningMsgFormat = "{0}({1},{2}): warning: {3}"; // 0=filename, 1=line, 2=column, 3=text
+
public void SynErr(string filename, int line, int col, int n) {
- SynErr(filename, line, col, GetSyntaxErrorString(n));
- }
-
- public virtual void SynErr(string filename, int line, int col, string/*!*/ msg) {
- Contract.Requires(msg != null);
+ SynErr(filename, line, col, GetSyntaxErrorString(n));
+ }
+ public virtual void SynErr(string filename, int line, int col, string msg) {
+ Contract.Requires(msg != null);
errorStream.WriteLine(errMsgFormat, filename, line, col, msg);
count++;
- }
-
- string GetSyntaxErrorString(int n) {
+ }
+ string GetSyntaxErrorString(int n) {
string s;
switch (n) {
case 0: s = "EOF expected"; break;
@@ -2333,7 +2333,7 @@ public class Errors {
default: s = "error " + n; break;
}
- return s;
+ return s;
}
public void SemErr(IToken/*!*/ tok, string/*!*/ msg) { // semantic errors
@@ -2341,9 +2341,8 @@ public class Errors {
Contract.Requires(msg != null);
SemErr(tok.filename, tok.line, tok.col, msg);
}
-
public virtual void SemErr(string filename, int line, int col, string/*!*/ msg) {
- Contract.Requires(msg != null);
+ Contract.Requires(msg != null);
errorStream.WriteLine(errMsgFormat, filename, line, col, msg);
count++;
}
diff --git a/Source/Dafny/Resolver.cs b/Source/Dafny/Resolver.cs
index ba28d531..37b80894 100644
--- a/Source/Dafny/Resolver.cs
+++ b/Source/Dafny/Resolver.cs
@@ -964,7 +964,7 @@ namespace Microsoft.Dafny {
if (!UnifyTypes(iProxy.Arg, ((SeqType)t).Arg)) {
return false;
}
- } else if (t.IsArrayType) {
+ } else if (t.IsArrayType && (t.AsArrayType).Dims == 1) {
Type elType = UserDefinedType.ArrayElementType(t);
if (!UnifyTypes(iProxy.Arg, elType)) {
return false;
@@ -1320,7 +1320,7 @@ namespace Microsoft.Dafny {
} else if (stmt is WhileStmt) {
WhileStmt s = (WhileStmt)stmt;
- bool bodyIsSpecOnly = specContextOnly;
+ bool bodyMustBeSpecOnly = specContextOnly;
if (s.Guard != null) {
int prevErrorCount = ErrorCount;
ResolveExpression(s.Guard, true, true);
@@ -1330,7 +1330,7 @@ namespace Microsoft.Dafny {
Error(s.Guard, "condition is expected to be of type {0}, but is {1}", Type.Bool, s.Guard.Type);
}
if (!specContextOnly && successfullyResolved) {
- bodyIsSpecOnly = UsesSpecFeatures(s.Guard);
+ bodyMustBeSpecOnly = UsesSpecFeatures(s.Guard);
}
}
foreach (MaybeFreeExpression inv in s.Invariants) {
@@ -1342,10 +1342,13 @@ namespace Microsoft.Dafny {
}
foreach (Expression e in s.Decreases) {
ResolveExpression(e, true, true);
+ if (bodyMustBeSpecOnly && e is WildcardExpr) {
+ Error(e, "'decreases *' is not allowed on ghost loops");
+ }
// any type is fine
}
- s.IsGhost = bodyIsSpecOnly;
- ResolveStatement(s.Body, bodyIsSpecOnly, method);
+ s.IsGhost = bodyMustBeSpecOnly;
+ ResolveStatement(s.Body, bodyMustBeSpecOnly, method);
} else if (stmt is ForeachStmt) {
ForeachStmt s = (ForeachStmt)stmt;
@@ -1910,7 +1913,7 @@ namespace Microsoft.Dafny {
Contract.Assert(e.Array.Type != null); // follows from postcondition of ResolveExpression
Type elementType = new InferredTypeProxy();
if (!UnifyTypes(e.Array.Type, builtIns.ArrayType(e.Indices.Count, elementType))) {
- Error(e.Array, "array selection requires an array (got {0})", e.Array.Type);
+ Error(e.Array, "array selection requires an array{0} (got {1})", e.Indices.Count, e.Array.Type);
}
int i = 0;
foreach (Expression idx in e.Indices) {
diff --git a/Source/Dafny/Scanner.cs b/Source/Dafny/Scanner.cs
index 817df6cd..0af254f3 100644
--- a/Source/Dafny/Scanner.cs
+++ b/Source/Dafny/Scanner.cs
@@ -19,7 +19,7 @@ public class Buffer {
// a) whole stream in buffer
// b) part of stream in buffer
// 2) non seekable stream (network, console)
-
+
public const int EOF = 65535 + 1; // char.MaxValue + 1;
const int MIN_BUFFER_LENGTH = 1024; // 1KB
const int MAX_BUFFER_LENGTH = MIN_BUFFER_LENGTH * 64; // 64KB
@@ -31,17 +31,15 @@ public class Buffer {
Stream/*!*/ stream; // input stream (seekable)
bool isUserStream; // was the stream opened by the user?
- [ContractInvariantMethod]
- void ObjectInvariant(){
- Contract.Invariant(buf != null);
- Contract.Invariant(stream != null);
- }
-
-// [NotDelayed]
- public Buffer (Stream/*!*/ s, bool isUserStream) : base() {
+[ContractInvariantMethod]
+void ObjectInvariant(){
+ Contract.Invariant(buf != null);
+ Contract.Invariant(stream != null);}
+ [NotDelayed]
+ public Buffer (Stream/*!*/ s, bool isUserStream) :base() {
Contract.Requires(s != null);
stream = s; this.isUserStream = isUserStream;
-
+
int fl, bl;
if (s.CanSeek) {
fl = (int) s.Length;
@@ -53,12 +51,12 @@ public class Buffer {
buf = new byte[(bl>0) ? bl : MIN_BUFFER_LENGTH];
fileLen = fl; bufLen = bl;
-
+
if (fileLen > 0) Pos = 0; // setup buffer to position 0 (start)
else bufPos = 0; // index 0 is already after the file, thus Pos = 0 is invalid
if (bufLen == fileLen && s.CanSeek) Close();
}
-
+
protected Buffer(Buffer/*!*/ b) { // called in UTF8Buffer constructor
Contract.Requires(b != null);
buf = b.buf;
@@ -75,14 +73,14 @@ public class Buffer {
}
~Buffer() { Close(); }
-
+
protected void Close() {
if (!isUserStream && stream != null) {
stream.Close();
//stream = null;
}
}
-
+
public virtual int Read () {
if (bufPos < bufLen) {
return buf[bufPos++];
@@ -102,7 +100,7 @@ public class Buffer {
Pos = curPos;
return ch;
}
-
+
public string/*!*/ GetString (int beg, int end) {
Contract.Ensures(Contract.Result<string>() != null);
int len = 0;
@@ -141,7 +139,7 @@ public class Buffer {
}
}
}
-
+
// Read the next chunk of bytes from the stream, increases the buffer
// if needed and updates the fields fileLen and bufLen.
// Returns the number of bytes read.
@@ -215,20 +213,19 @@ public class Scanner {
const int noSym = 107;
- [ContractInvariantMethod]
- void objectInvariant(){
- Contract.Invariant(buffer!=null);
- Contract.Invariant(t != null);
- Contract.Invariant(start != null);
- Contract.Invariant(tokens != null);
- Contract.Invariant(pt != null);
- Contract.Invariant(tval != null);
- Contract.Invariant(Filename != null);
- Contract.Invariant(errorHandler != null);
- }
-
+[ContractInvariantMethod]
+void objectInvariant(){
+ Contract.Invariant(buffer!=null);
+ Contract.Invariant(t != null);
+ Contract.Invariant(start != null);
+ Contract.Invariant(tokens != null);
+ Contract.Invariant(pt != null);
+ Contract.Invariant(tval != null);
+ Contract.Invariant(Filename != null);
+ Contract.Invariant(errorHandler != null);
+}
public Buffer/*!*/ buffer; // scanner buffer
-
+
Token/*!*/ t; // current token
int ch; // current input character
int pos; // byte position of current character
@@ -239,13 +236,13 @@ public class Scanner {
Token/*!*/ tokens; // list of tokens already peeked (first token is a dummy)
Token/*!*/ pt; // current peek token
-
+
char[]/*!*/ tval = new char[128]; // text of current token
int tlen; // length of current token
-
+
private string/*!*/ Filename;
private Errors/*!*/ errorHandler;
-
+
static Scanner() {
start = new Hashtable(128);
for (int i = 39; i <= 39; ++i) start[i] = 1;
@@ -294,9 +291,9 @@ public class Scanner {
start[Buffer.EOF] = -1;
}
-
-// [NotDelayed]
- public Scanner (string/*!*/ fileName, Errors/*!*/ errorHandler) : base() {
+
+ [NotDelayed]
+ public Scanner (string/*!*/ fileName, Errors/*!*/ errorHandler) :base(){
Contract.Requires(fileName != null);
Contract.Requires(errorHandler != null);
this.errorHandler = errorHandler;
@@ -306,14 +303,15 @@ public class Scanner {
Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
buffer = new Buffer(stream, false);
Filename = fileName;
+
Init();
} catch (IOException) {
throw new FatalError("Cannot open file " + fileName);
}
}
-
-// [NotDelayed]
- public Scanner (Stream/*!*/ s, Errors/*!*/ errorHandler, string/*!*/ fileName) : base() {
+
+ [NotDelayed]
+ public Scanner (Stream/*!*/ s, Errors/*!*/ errorHandler, string/*!*/ fileName) :base(){
Contract.Requires(s != null);
Contract.Requires(errorHandler != null);
Contract.Requires(fileName != null);
@@ -322,9 +320,10 @@ public class Scanner {
buffer = new Buffer(s, true);
this.errorHandler = errorHandler;
this.Filename = fileName;
+
Init();
}
-
+
void Init() {
pos = -1; line = 1; col = 0;
oldEols = 0;
@@ -345,11 +344,11 @@ public class Scanner {
Contract.Ensures(Contract.Result<string>() != null);
int p = buffer.Pos;
int ch = buffer.Read();
- // replace isolated '\r' by '\n' in order to make
+ // replace isolated '\r' by '\n' in order to make
// eol handling uniform across Windows, Unix and Mac
if (ch == '\r' && buffer.Peek() != '\n') ch = EOL;
while (ch != EOL && ch != Buffer.EOF){
- ch = buffer.Read();
+ ch = buffer.Read();
// replace isolated '\r' by '\n' in order to make
// eol handling uniform across Windows, Unix and Mac
if (ch == '\r' && buffer.Peek() != '\n') ch = EOL;
@@ -360,7 +359,7 @@ public class Scanner {
}
void NextCh() {
- if (oldEols > 0) { ch = EOL; oldEols--; }
+ if (oldEols > 0) { ch = EOL; oldEols--; }
else {
// pos = buffer.Pos;
// ch = buffer.Read(); col++;
@@ -368,9 +367,9 @@ public class Scanner {
// // eol handling uniform across Windows, Unix and Mac
// if (ch == '\r' && buffer.Peek() != '\n') ch = EOL;
// if (ch == EOL) { line++; col = 0; }
-
+
while (true) {
- pos = buffer.Pos;
+ pos = buffer.Pos;
ch = buffer.Read(); col++;
// replace isolated '\r' by '\n' in order to make
// eol handling uniform across Windows, Unix and Mac
@@ -420,7 +419,7 @@ public class Scanner {
return;
}
-
+
}
}
@@ -559,13 +558,10 @@ public class Scanner {
t.pos = pos; t.col = col; t.line = line;
t.filename = this.Filename;
int state;
- if (start.ContainsKey(ch)) {
- Contract.Assert(start[ch] != null);
- state = (int) start[ch];
- }
+ if (start.ContainsKey(ch)) { state = (int) cce.NonNull( start[ch]); }
else { state = 0; }
tlen = 0; AddCh();
-
+
switch (state) {
case -1: { t.kind = eofSym; break; } // NextCh already done
case 0: {
@@ -773,14 +769,14 @@ public class Scanner {
t.val = new String(tval, 0, tlen);
return t;
}
-
+
private void SetScannerBehindT() {
buffer.Pos = t.pos;
NextCh();
line = t.line; col = t.col;
for (int i = 0; i < tlen; i++) NextCh();
}
-
+
// get the next token (possibly a token already seen during peeking)
public Token/*!*/ Scan () {
Contract.Ensures(Contract.Result<Token>() != null);
@@ -801,7 +797,7 @@ public class Scanner {
}
pt = pt.next;
} while (pt.kind > maxT); // skip pragmas
-
+
return pt;
}
diff --git a/Source/ModelViewer/bvdicon.design b/Source/ModelViewer/bvdicon.design
new file mode 100644
index 00000000..c71ca9a6
--- /dev/null
+++ b/Source/ModelViewer/bvdicon.design
Binary files differ
diff --git a/Source/Provers/SMTLib/ProverInterface.cs b/Source/Provers/SMTLib/ProverInterface.cs
index f1a00873..42cf89ab 100644
--- a/Source/Provers/SMTLib/ProverInterface.cs
+++ b/Source/Provers/SMTLib/ProverInterface.cs
@@ -151,6 +151,13 @@ namespace Microsoft.Boogie.SMTLib
foreach (var opt in options.SmtOptions) {
SendCommon("(set-option :" + opt.Option + " " + opt.Value + ")");
}
+
+ if (CommandLineOptions.Clo.UseArrayTheory) {
+ SendCommon("; skipping logic setting (using arrays)");
+ } else {
+ SendCommon("(set-logic UFNIA)");
+ }
+
SendCommon("; done setting options\n");
SendCommon(_backgroundPredicates);
}
@@ -359,7 +366,7 @@ namespace Microsoft.Boogie.SMTLib
{
SendThisVC("(labels)");
if (options.ExpectingModel())
- SendThisVC("(model)");
+ SendThisVC("(get-model)");
Process.Ping();
List<string> labelNums = null;
@@ -371,26 +378,36 @@ namespace Microsoft.Boogie.SMTLib
if (resp == null || Process.IsPong(resp))
break;
if (resp.Name == "labels" && resp.ArgCount >= 1) {
- var labels = resp[0].Arguments.Select(a => a.Name.Replace("|", "")).ToArray();
+ var labels = resp.Arguments.Select(a => a.Name.Replace("|", "")).ToArray();
res = labels;
if (labelNums != null) HandleProverError("Got multiple :labels responses");
labelNums = labels.Select(a => a.Replace("@", "").Replace("+", "")).ToList();
- } else if (resp.Name == "model" && resp.ArgCount >= 1) {
- var modelStr = resp[0].Name;
- List<Model> models = null;
- try {
- models = Model.ParseModels(new StringReader("Z3 error model: \n" + modelStr));
- } catch (ArgumentException exn) {
- HandleProverError("Model parsing error: " + exn.Message);
+ } else {
+ string modelStr = null;
+ if (resp.Name == "model" && resp.ArgCount >= 1) {
+ modelStr = resp[0].Name;
+ } else if (resp.ArgCount == 0 && resp.Name.Contains("->")) {
+ modelStr = resp.Name;
}
- if (models != null) {
- if (models.Count == 0) HandleProverError("Could not parse any models");
- else {
- if (models.Count > 1) HandleProverError("Expecting only one model, got multiple");
- if (theModel != null) HandleProverError("Got multiple :model responses");
- theModel = models[0];
+ if (modelStr != null) {
+ List<Model> models = null;
+ try {
+ models = Model.ParseModels(new StringReader("Z3 error model: \n" + modelStr));
+ } catch (ArgumentException exn) {
+ HandleProverError("Model parsing error: " + exn.Message);
}
+
+ if (models != null) {
+ if (models.Count == 0) HandleProverError("Could not parse any models");
+ else {
+ if (models.Count > 1) HandleProverError("Expecting only one model, got multiple");
+ if (theModel != null) HandleProverError("Got multiple :model responses");
+ theModel = models[0];
+ }
+ }
+ } else {
+ HandleProverError("Unexpected prover response (getting labels/model): " + resp.ToString());
}
}
}
@@ -435,10 +452,7 @@ namespace Microsoft.Boogie.SMTLib
}
if (wasUnknown) {
- if (options.UseZ3)
- SendThisVC("(get-info :last-failure)");
- else
- SendThisVC("(get-info :reason-unknown)");
+ SendThisVC("(get-info :reason-unknown)");
Process.Ping();
while (true) {
@@ -446,7 +460,7 @@ namespace Microsoft.Boogie.SMTLib
if (resp == null || Process.IsPong(resp))
break;
- if (resp.ArgCount == 1 && (resp.Name == ":reason-unknown" || resp.Name == ":last-failure")) {
+ if (resp.ArgCount == 1 && resp.Name == ":reason-unknown") {
switch (resp[0].Name) {
case "memout":
result = Outcome.OutOfMemory;
diff --git a/Source/Provers/SMTLib/SMTLibLineariser.cs b/Source/Provers/SMTLib/SMTLibLineariser.cs
index d06cba3b..3e8a3fc8 100644
--- a/Source/Provers/SMTLib/SMTLibLineariser.cs
+++ b/Source/Provers/SMTLib/SMTLibLineariser.cs
@@ -266,7 +266,7 @@ namespace Microsoft.Boogie.SMTLib
if (weight != 1)
wr.Write(" :weight {0}\n", weight);
if (infos.uniqueId != -1)
- wr.Write(" :skolemid {0}\n", infos.uniqueId);
+ wr.Write(" :skolemid |{0}|\n", infos.uniqueId);
WriteTriggers(node.Triggers, options);
wr.Write(")");
diff --git a/Source/Provers/SMTLib/Z3.cs b/Source/Provers/SMTLib/Z3.cs
index 27d86915..54742802 100644
--- a/Source/Provers/SMTLib/Z3.cs
+++ b/Source/Provers/SMTLib/Z3.cs
@@ -124,7 +124,7 @@ namespace Microsoft.Boogie.SMTLib
options.AddWeakSmtOption("ARITH_RANDOM_INITIAL_VALUE", "true");
// The left-to-right structural case-splitting strategy.
- options.AddWeakSmtOption("SORT_AND_OR", "false");
+ //options.AddWeakSmtOption("SORT_AND_OR", "false"); // always false now
options.AddWeakSmtOption("CASE_SPLIT", "3");
// In addition delay adding unit conflicts.
diff --git a/Source/VCGeneration/VC.cs b/Source/VCGeneration/VC.cs
index 8c8b17a0..11db59b0 100644
--- a/Source/VCGeneration/VC.cs
+++ b/Source/VCGeneration/VC.cs
@@ -3621,7 +3621,6 @@ namespace VC {
Hashtable/*<int, Absy!>*/ label2absy,
ProverContext proverCtxt) {
Contract.Requires(startBlock != null);
- Contract.Requires(label2absy != null);
Contract.Requires(proverCtxt != null);
Contract.Ensures(Contract.Result<VCExpr>() != null);
@@ -3640,7 +3639,6 @@ namespace VC {
ProverContext proverCtxt)
{
Contract.Requires(block != null);
- Contract.Requires(label2absy != null);
Contract.Requires(blockVariables!= null);
Contract.Requires(cce.NonNullElements(bindings));
Contract.Requires(proverCtxt != null);
diff --git a/Source/VCGeneration/Wlp.cs b/Source/VCGeneration/Wlp.cs
index 23be6082..f5469ebf 100644
--- a/Source/VCGeneration/Wlp.cs
+++ b/Source/VCGeneration/Wlp.cs
@@ -17,7 +17,6 @@ namespace VC {
[ContractInvariantMethod]
void ObjectInvariant()
{
- Contract.Invariant(Label2absy!=null);
Contract.Invariant(Ctxt != null);
}
@@ -27,7 +26,6 @@ namespace VC {
public VCContext(Hashtable/*<int, Absy!>*/ label2absy, ProverContext ctxt)
{
- Contract.Requires(label2absy != null);
Contract.Requires(ctxt != null);
this.Label2absy = label2absy;
this.Ctxt = ctxt;
@@ -36,7 +34,6 @@ namespace VC {
public VCContext(Hashtable/*<int, Absy!>*/ label2absy, ProverContext ctxt, Variable controlFlowVariable)
{
- Contract.Requires(label2absy != null);
Contract.Requires(ctxt != null);
this.Label2absy = label2absy;
this.Ctxt = ctxt;
diff --git a/Test/VSComp2010/runtest.bat b/Test/VSComp2010/runtest.bat
index e39abe7d..e16eda13 100644
--- a/Test/VSComp2010/runtest.bat
+++ b/Test/VSComp2010/runtest.bat
@@ -4,7 +4,7 @@ setlocal
set BOOGIEDIR=..\..\Binaries
set DAFNY_EXE=%BOOGIEDIR%\Dafny.exe
set BPLEXE=%BOOGIEDIR%\Boogie.exe
-
+set CSC=c:/Windows/Microsoft.NET/Framework/v4.0.30319/csc.exe
for %%f in (Problem1-SumMax.dfy Problem2-Invert.dfy
Problem3-FindZero.dfy Problem4-Queens.dfy
@@ -12,4 +12,6 @@ for %%f in (Problem1-SumMax.dfy Problem2-Invert.dfy
echo.
echo -------------------- %%f --------------------
%DAFNY_EXE% %* %%f
+
+ IF NOT "%COMPILEDAFNY%"=="" %CSC% /nologo /debug /t:library /out:out.dll /r:System.Numerics.dll out.cs
)
diff --git a/Test/VSI-Benchmarks/runtest.bat b/Test/VSI-Benchmarks/runtest.bat
index 0cd898c4..a733a1c0 100644
--- a/Test/VSI-Benchmarks/runtest.bat
+++ b/Test/VSI-Benchmarks/runtest.bat
@@ -4,12 +4,16 @@ setlocal
set BOOGIEDIR=..\..\Binaries
set DAFNY_EXE=%BOOGIEDIR%\Dafny.exe
set BPLEXE=%BOOGIEDIR%\Boogie.exe
+set CSC=c:/Windows/Microsoft.NET/Framework/v4.0.30319/csc.exe
-
-
-for %%f in ( b1.dfy b2.dfy b3.dfy b4.dfy b5.dfy b6.dfy b7.dfy
- b8.dfy ) do (
+for %%f in (b1.dfy b2.dfy b3.dfy b4.dfy b5.dfy b6.dfy b7.dfy b8.dfy) do (
echo.
echo -------------------- %%f --------------------
- %DAFNY_EXE% /compile:0 %* %%f
+
+ REM The following line will just run the verifier
+ IF "%COMPILEDAFNY%"=="" %DAFNY_EXE% /compile:0 %* %%f
+
+ REM Alternatively, the following lines also produce C# code and compile it
+ IF NOT "%COMPILEDAFNY%"=="" %DAFNY_EXE% %* %%f
+ IF NOT "%COMPILEDAFNY%"=="" %CSC% /nologo /debug /t:library /out:out.dll /r:System.Numerics.dll out.cs
)
diff --git a/Test/dafny0/Answer b/Test/dafny0/Answer
index afa88a47..4bdea760 100644
--- a/Test/dafny0/Answer
+++ b/Test/dafny0/Answer
@@ -391,6 +391,13 @@ Execution trace:
Dafny program verifier finished with 3 verified, 3 errors
+-------------------- ResolutionErrors.dfy --------------------
+ResolutionErrors.dfy(10,16): Error: 'decreases *' is not allowed on ghost loops
+ResolutionErrors.dfy(22,11): Error: array selection requires an array2 (got array3<T>)
+ResolutionErrors.dfy(23,12): Error: sequence/array selection requires a sequence or array (got array3<T>)
+ResolutionErrors.dfy(24,11): Error: array selection requires an array4 (got array<T>)
+4 resolution/type errors detected in ResolutionErrors.dfy
+
-------------------- Array.dfy --------------------
Array.dfy(10,12): Error: assignment may update an array element not in the enclosing method's modifies clause
Execution trace:
diff --git a/Test/dafny0/ResolutionErrors.dfy b/Test/dafny0/ResolutionErrors.dfy
new file mode 100644
index 00000000..5ec0cc4c
--- /dev/null
+++ b/Test/dafny0/ResolutionErrors.dfy
@@ -0,0 +1,25 @@
+
+//Should not verify, as ghost loops should not be allowed to diverge.
+method GhostDivergentLoop()
+{
+ var a := new int [2];
+ a[0] := 1;
+ a[1] := -1;
+ ghost var i := 0;
+ while (i < 2)
+ decreases *; // error: not allowed on a ghost loop
+ invariant i <= 2;
+ invariant (forall j :: 0 <= j && j < i ==> a[j] > 0);
+ {
+ i := 0;
+ }
+ assert a[1] != a[1]; // ...for then this would incorrectly verify
+}
+
+method M<T>(a: array3<T>, b: array<T>, m: int, n: int)
+{
+ // the following invalid expressions were once incorrectly resolved:
+ var x := a[m, n]; // error
+ var y := a[m]; // error
+ var z := b[m, n, m, n]; // error
+}
diff --git a/Test/dafny0/runtest.bat b/Test/dafny0/runtest.bat
index 491b7b75..12d9bcf4 100644
--- a/Test/dafny0/runtest.bat
+++ b/Test/dafny0/runtest.bat
@@ -11,8 +11,8 @@ for %%f in (Simple.dfy) do (
%DAFNY_EXE% %* /dprint:- /env:0 /noVerify %%f
)
-for %%f in (TypeTests.dfy NatTypes.dfy SmallTests.dfy Definedness.dfy
- FunctionSpecifications.dfy
+for %%f in (TypeTests.dfy NatTypes.dfy SmallTests.dfy Definedness.dfy
+ FunctionSpecifications.dfy ResolutionErrors.dfy
Array.dfy MultiDimArray.dfy NonGhostQuantifiers.dfy AdvancedLHS.dfy
Modules0.dfy Modules1.dfy BadFunction.dfy
Termination.dfy Use.dfy DTypes.dfy
diff --git a/Test/dafny1/runtest.bat b/Test/dafny1/runtest.bat
index cab18ddb..57ac97e3 100644
--- a/Test/dafny1/runtest.bat
+++ b/Test/dafny1/runtest.bat
@@ -4,6 +4,7 @@ setlocal
set BOOGIEDIR=..\..\Binaries
set DAFNY_EXE=%BOOGIEDIR%\Dafny.exe
set BPLEXE=%BOOGIEDIR%\Boogie.exe
+set CSC=c:/Windows/Microsoft.NET/Framework/v4.0.30319/csc.exe
for %%f in (BQueue.bpl) do (
echo.
@@ -25,5 +26,11 @@ for %%f in (Queue.dfy PriorityQueue.dfy ExtensibleArray.dfy
UltraFilter.dfy) do (
echo.
echo -------------------- %%f --------------------
- %DAFNY_EXE% /compile:0 %* %%f
+
+ REM The following line will just run the verifier
+ IF "%COMPILEDAFNY%"=="" %DAFNY_EXE% /compile:0 %* %%f
+
+ REM Alternatively, the following lines also produce C# code and compile it
+ IF NOT "%COMPILEDAFNY%"=="" %DAFNY_EXE% %* %%f
+ IF NOT "%COMPILEDAFNY%"=="" %CSC% /nologo /debug /t:library /out:out.dll /r:System.Numerics.dll out.cs
)
diff --git a/Test/test0/Answer b/Test/test0/Answer
index 0441b69b..d434a8ca 100644
--- a/Test/test0/Answer
+++ b/Test/test0/Answer
@@ -247,3 +247,16 @@ BadQuantifier.bpl(3,15): error: invalid QuantifierBody
EmptyCallArgs.bpl(31,2): Error: type variable must occur in types of given arguments: a
EmptyCallArgs.bpl(32,2): Error: type variable must occur in types of given arguments: a
2 name resolution errors detected in EmptyCallArgs.bpl
+----- SeparateVerification0.bpl
+SeparateVerification0.bpl(13,6): Error: undeclared identifier: y
+1 name resolution errors detected in SeparateVerification0.bpl
+----- SeparateVerification1.bpl SeparateVerification0.bpl
+SeparateVerification1.bpl(4,6): Error: undeclared identifier: x
+SeparateVerification0.bpl(10,6): Error: undeclared identifier: x
+2 name resolution errors detected in SeparateVerification0.bpl
+----- SeparateVerification0.bpl SeparateVerification0.bpl
+
+Boogie program verifier finished with 0 verified, 0 errors
+----- SeparateVerification0.bpl SeparateVerification0.bpl SeparateVerification1.bpl
+
+Boogie program verifier finished with 0 verified, 0 errors
diff --git a/Test/test0/SeparateVerification0.bpl b/Test/test0/SeparateVerification0.bpl
new file mode 100644
index 00000000..5a8ef283
--- /dev/null
+++ b/Test/test0/SeparateVerification0.bpl
@@ -0,0 +1,21 @@
+// need to include this file twice for it to include all necessary declarations
+
+#if FILE_0
+const x: int;
+#else
+const y: int;
+#endif
+
+#if FILE_1
+axiom x == 12;
+procedure Q();
+#else
+axiom y == 7;
+#endif
+
+// duplicates of :extern's are fine (Boogie keeps the non-:extern or chooses arbitrarily among the :extern's)
+type {:extern} T;
+const {:extern} C: int;
+function {:extern} F(): int;
+var {:extern} n: int;
+procedure {:extern} P(inconsistentParameterButThatIsOkayBecauseTheExternIsIgnored: int);
diff --git a/Test/test0/SeparateVerification1.bpl b/Test/test0/SeparateVerification1.bpl
new file mode 100644
index 00000000..0e3e7926
--- /dev/null
+++ b/Test/test0/SeparateVerification1.bpl
@@ -0,0 +1,19 @@
+// to be used with SeparateVerification0.bpl
+
+// x and y are declared in SeparateVerification0.bpl
+axiom x + y <= 100;
+
+// these are declared as :extern as SeparateVerification0.bpl
+type T;
+const C: int;
+function F(): int;
+var n: int;
+procedure P();
+procedure {:extern} Q(x: int);
+
+procedure Main() {
+ call P(); // note, calling the parameter-less non-extern P (an extern and a non-extern
+ // declaration of the same name are usually mostly identical declarations,
+ // but Boogie allows them to be different, because it ignores the extern ones)
+ call Q(); // ditto
+}
diff --git a/Test/test0/runtest.bat b/Test/test0/runtest.bat
index c7c6ee3d..5ecc22dc 100644
--- a/Test/test0/runtest.bat
+++ b/Test/test0/runtest.bat
@@ -31,3 +31,12 @@ rem set BGEXE=mono ..\..\Binaries\Boogie.exe
%BGEXE% %* /noVerify Orderings.bpl
%BGEXE% %* /noVerify BadQuantifier.bpl
%BGEXE% %* /noVerify EmptyCallArgs.bpl
+
+echo ----- SeparateVerification0.bpl
+%BGEXE% %* /noVerify SeparateVerification0.bpl
+echo ----- SeparateVerification1.bpl SeparateVerification0.bpl
+%BGEXE% %* /noVerify SeparateVerification1.bpl SeparateVerification0.bpl
+echo ----- SeparateVerification0.bpl SeparateVerification0.bpl
+%BGEXE% %* /noVerify SeparateVerification0.bpl SeparateVerification0.bpl
+echo ----- SeparateVerification0.bpl SeparateVerification0.bpl SeparateVerification1.bpl
+%BGEXE% %* /noVerify SeparateVerification0.bpl SeparateVerification0.bpl SeparateVerification1.bpl
diff --git a/Test/vacid0/runtest.bat b/Test/vacid0/runtest.bat
index d6af7b71..32c6a984 100644
--- a/Test/vacid0/runtest.bat
+++ b/Test/vacid0/runtest.bat
@@ -4,9 +4,16 @@ setlocal
set BOOGIEDIR=..\..\Binaries
set DAFNY_EXE=%BOOGIEDIR%\Dafny.exe
set BPLEXE=%BOOGIEDIR%\Boogie.exe
+set CSC=c:/Windows/Microsoft.NET/Framework/v4.0.30319/csc.exe
for %%f in (LazyInitArray.dfy SparseArray.dfy Composite.dfy) do (
echo.
echo -------------------- %%f --------------------
- %DAFNY_EXE% /compile:0 %* %%f
+
+ REM The following line will just run the verifier
+ IF "%COMPILEDAFNY%"=="" %DAFNY_EXE% /compile:0 %* %%f
+
+ REM Alternatively, the following lines also produce C# code and compile it
+ IF NOT "%COMPILEDAFNY%"=="" %DAFNY_EXE% %* %%f
+ IF NOT "%COMPILEDAFNY%"=="" %CSC% /nologo /debug /t:library /out:out.dll /r:System.Numerics.dll out.cs
)
diff --git a/_admin/Boogie/aste/summary.log b/_admin/Boogie/aste/summary.log
index d0d8b4ce..d5fb6585 100644
--- a/_admin/Boogie/aste/summary.log
+++ b/_admin/Boogie/aste/summary.log
@@ -1,9 +1,9 @@
-# Aste started: 2011-04-16 07:00:19
+# Aste started: 2011-05-04 07:00:19
# Host id: Boogiebox
-# [2011-04-16 07:02:49] SpecSharp revision: 9e70f4df4f12
-# [2011-04-16 07:02:49] SscBoogie revision: 9e70f4df4f12
-# [2011-04-16 07:04:04] Boogie revision: 36bd84e75a0f
-[2011-04-16 07:06:47] C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.com Boogie.sln /Rebuild Checked
+# [2011-05-04 07:02:49] SpecSharp revision: 6e9f7e851bd3
+# [2011-05-04 07:02:49] SscBoogie revision: 6e9f7e851bd3
+# [2011-05-04 07:04:02] Boogie revision: e7280be476fa
+[2011-05-04 07:06:38] C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.com Boogie.sln /Rebuild Checked
D:\Temp\aste\Boogie\Source\Core\AbsyType.cs(823,16): warning CS0659: 'Microsoft.Boogie.BasicType' overrides Object.Equals(object o) but does not override Object.GetHashCode()
D:\Temp\aste\Boogie\Source\Core\AbsyType.cs(2802,16): warning CS0659: 'Microsoft.Boogie.CtorType' overrides Object.Equals(object o) but does not override Object.GetHashCode()
@@ -31,6 +31,5 @@
warning CS0162: Unreachable code detected
warning CS0162: Unreachable code detected
warning CC1032: Method 'VC.StratifiedVCGen+NormalChecker.CheckVC' overrides 'VC.StratifiedVCGen+StratifiedCheckerInterface.CheckVC', thus cannot add Requires.
-[2011-04-16 07:48:44] 1 out of 30 test(s) in D:\Temp\aste\Boogie\Test\alltests.txt failed
-['lazyinline']
-# [2011-04-16 07:49:46] Released nightly of Boogie
+[2011-05-04 07:48:22] 0 out of 30 test(s) in D:\Temp\aste\Boogie\Test\alltests.txt failed
+# [2011-05-04 07:49:23] Released nightly of Boogie