/Source/Dafny/Compiler.cs
C# | 1811 lines | 1518 code | 128 blank | 165 comment | 458 complexity | eb503766fce7457a6e4c4ed70bd06a20 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- //-----------------------------------------------------------------------------
- //
- // Copyright (C) Microsoft Corporation. All Rights Reserved.
- //
- //-----------------------------------------------------------------------------
- using System;
- using System.Collections.Generic;
- using System.Numerics;
- using System.IO;
- using System.Diagnostics.Contracts;
- using Bpl = Microsoft.Boogie;
- using System.Text;
-
- namespace Microsoft.Dafny {
- public class Compiler {
- public Compiler(TextWriter wr) {
- Contract.Requires(wr != null);
- this.wr = wr;
- }
-
- [ContractInvariantMethod]
- void ObjectInvariant()
- {
- Contract.Invariant(wr!=null);
- }
-
- TextWriter wr;
-
- public int ErrorCount;
- void Error(string msg, params object[] args) {
- Contract.Requires(msg != null);
- Contract.Requires(args != null);
-
- string s = string.Format("Compilation error: " + msg, args);
- Console.WriteLine(s);
- wr.WriteLine("/* {0} */", s);
- ErrorCount++;
- }
-
- void ReadRuntimeSystem() {
- string codebase = cce.NonNull( System.IO.Path.GetDirectoryName(cce.NonNull(System.Reflection.Assembly.GetExecutingAssembly().Location)));
- string path = System.IO.Path.Combine(codebase, "DafnyRuntime.cs");
- using (TextReader rd = new StreamReader(new FileStream(path, System.IO.FileMode.Open, System.IO.FileAccess.Read)))
- {
- while (true) {
- string s = rd.ReadLine();
- if (s == null)
- return;
- wr.WriteLine(s);
- }
- }
- }
-
- readonly int IndentAmount = 2;
- void Indent(int ind) {
- string spaces = " ";
- for (; spaces.Length < ind; ind -= spaces.Length) {
- wr.Write(spaces);
- }
- wr.Write(spaces.Substring(0, ind));
- }
-
- public void Compile(Program program) {Contract.Requires(program != null);
- wr.WriteLine("// Dafny program {0} compiled into C#", program.Name);
- wr.WriteLine();
- ReadRuntimeSystem();
- CompileBuiltIns(program.BuiltIns);
-
- foreach (ModuleDecl m in program.Modules) {
- if (m.IsGhost) {
- // the purpose of a ghost module is to skip compilation
- continue;
- }
- int indent = 0;
- if (!m.IsDefaultModule) {
- wr.WriteLine("namespace @{0} {{", m.Name);
- indent += IndentAmount;
- }
- foreach (TopLevelDecl d in m.TopLevelDecls) {
- wr.WriteLine();
- if (d is ArbitraryTypeDecl) {
- var at = (ArbitraryTypeDecl)d;
- Error("Arbitrary type ('{0}') cannot be compiled", at.Name);
- } else if (d is DatatypeDecl) {
- DatatypeDecl dt = (DatatypeDecl)d;
- Indent(indent);
- wr.Write("public abstract class Base_{0}", dt.Name);
- if (dt.TypeArgs.Count != 0) {
- wr.Write("<{0}>", TypeParameters(dt.TypeArgs));
- }
- wr.WriteLine(" { }");
- CompileDatatypeConstructors(dt, indent);
- CompileDatatypeStruct(dt, indent);
- } else {
- ClassDecl cl = (ClassDecl)d;
- Indent(indent);
- wr.Write("public class @{0}", cl.Name);
- if (cl.TypeArgs.Count != 0) {
- wr.Write("<{0}>", TypeParameters(cl.TypeArgs));
- }
- wr.WriteLine(" {");
- CompileClassMembers(cl, indent+IndentAmount);
- Indent(indent); wr.WriteLine("}");
- }
- }
- if (!m.IsDefaultModule) {
- wr.WriteLine("}} // end of namespace {0}", m.Name);
- }
- }
- }
-
- void CompileBuiltIns(BuiltIns builtIns) {
- wr.WriteLine("namespace Dafny {");
- Indent(IndentAmount);
- wr.WriteLine("public partial class Helpers {");
- foreach (var decl in builtIns.SystemModule.TopLevelDecls) {
- if (decl is ArrayClassDecl) {
- int dims = ((ArrayClassDecl)decl).Dims;
- // public static T[,] InitNewArray2<T>(BigInteger size0, BigInteger size1) {
- Indent(3 * IndentAmount);
- wr.Write("public static T[");
- RepeatWrite(wr, dims, "", ",");
- wr.Write("] InitNewArray{0}<T>(", dims);
- RepeatWrite(wr, dims, "BigInteger size{0}", ", ");
- wr.WriteLine(") {");
- // int s0 = (int)size0;
- for (int i = 0; i < dims; i++) {
- Indent(4 * IndentAmount);
- wr.WriteLine("int s{0} = (int)size{0};", i);
- }
- // T[,] a = new T[s0, s1];
- Indent(4 * IndentAmount);
- wr.Write("T[");
- RepeatWrite(wr, dims, "", ",");
- wr.Write("] a = new T[");
- RepeatWrite(wr, dims, "s{0}", ",");
- wr.WriteLine("];");
- // BigInteger[,] b = a as BigInteger[,];
- Indent(4 * IndentAmount);
- wr.Write("BigInteger[");
- RepeatWrite(wr, dims, "", ",");
- wr.Write("] b = a as BigInteger[");
- RepeatWrite(wr, dims, "", ",");
- wr.WriteLine("];");
- // if (b != null) {
- Indent(4 * IndentAmount);
- wr.WriteLine("if (b != null) {");
- // BigInteger z = new BigInteger(0);
- Indent(5 * IndentAmount);
- wr.WriteLine("BigInteger z = new BigInteger(0);");
- // for (int i0 = 0; i0 < s0; i0++)
- // for (int i1 = 0; i1 < s1; i1++)
- for (int i = 0; i < dims; i++) {
- Indent((5+i) * IndentAmount);
- wr.WriteLine("for (int i{0} = 0; i{0} < s{0}; i{0}++)", i);
- }
- // b[i0,i1] = z;
- Indent((5+dims) * IndentAmount);
- wr.Write("b[");
- RepeatWrite(wr, dims, "i{0}", ",");
- wr.WriteLine("] = z;");
- // }
- Indent(4 * IndentAmount);
- wr.WriteLine("}");
- // return a;
- Indent(4 * IndentAmount);
- wr.WriteLine("return a;");
- // }
- Indent(3 * IndentAmount);
- wr.WriteLine("}"); // end of method
- }
- }
- Indent(IndentAmount);
- wr.WriteLine("}"); // end of class Helpers
- wr.WriteLine("}"); // end of namespace
- }
-
- static void RepeatWrite(TextWriter wr, int times, string template, string separator) {
- Contract.Requires(1 <= times);
- string s = "";
- for (int i = 0; i < times; i++) {
- wr.Write(s);
- wr.Write(template, i);
- s = separator;
- }
- }
-
- void CompileDatatypeConstructors(DatatypeDecl dt, int indent)
- {Contract.Requires(dt != null);
- foreach (DatatypeCtor ctor in dt.Ctors) {
- // class Dt_Ctor<T,U> : Base_Dt<T> {
- // Fields;
- // public Dt_Ctor(arguments) {
- // Fields = arguments;
- // }
- // public override bool Equals(object other) {
- // var oth = other as Dt_Dtor;
- // return oth != null && equals(_field0, oth._field0) && ... ;
- // }
- // public override int GetHashCode() {
- // return base.GetHashCode(); // surely this can be improved
- // }
- // }
- Indent(indent);
- wr.Write("public class {0}", DtCtorName(ctor));
- if (dt.TypeArgs.Count != 0) {
- wr.Write("<{0}>", TypeParameters(dt.TypeArgs));
- }
- wr.Write(" : Base_{0}", dt.Name);
- 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));
- i++;
- }
- }
-
- Indent(ind);
- wr.Write("public {0}(", DtCtorName(ctor));
- WriteFormals("", ctor.Formals);
- wr.WriteLine(") {");
- i = 0;
- foreach (Formal arg in ctor.Formals) {
- if (!arg.IsGhost) {
- Indent(ind + IndentAmount);
- wr.WriteLine("this.@{0} = @{0};", FormalName(arg, i));
- i++;
- }
- }
- Indent(ind); wr.WriteLine("}");
-
- // Equals method
- Indent(ind); wr.WriteLine("public override bool Equals(object other) {");
- Indent(ind + IndentAmount);
- wr.Write("var oth = other as {0}", DtCtorName(ctor));
- if (dt.TypeArgs.Count != 0) {
- wr.Write("<{0}>", TypeParameters(dt.TypeArgs));
- }
- wr.WriteLine(";");
- Indent(ind + IndentAmount);
- wr.Write("return oth != null");
- i = 0;
- foreach (Formal arg in ctor.Formals) {
- if (!arg.IsGhost) {
- string nm = FormalName(arg, i);
- if (arg.Type.IsDatatype || arg.Type.IsTypeParameter) {
- wr.Write(" && this.@{0}.Equals(oth.@{0})", nm);
- } else {
- wr.Write(" && this.@{0} == oth.@{0}", nm);
- }
- i++;
- }
- }
- wr.WriteLine(";");
- Indent(ind); wr.WriteLine("}");
-
- // GetHashCode method
- Indent(ind); wr.WriteLine("public override int GetHashCode() {");
- Indent(ind + IndentAmount); wr.WriteLine("return base.GetHashCode(); // surely this can be improved");
- Indent(ind); wr.WriteLine("}");
-
- Indent(indent); wr.WriteLine("}");
- }
- }
-
- void CompileDatatypeStruct(DatatypeDecl dt, int indent) {
- Contract.Requires(dt != null);
-
- // public struct Dt<T> {
- // 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; }
- // public static Base_Dt<T> Default {
- // get { return ...; }
- // }
- // public override bool Equals(object other) {
- // return other is Dt<T> && _D.Equals(((Dt<T>)other)._D);
- // }
- // public override int GetHashCode() { return _D.GetHashCode(); }
- //
- // public bool _Ctor0 { get { return _D is Dt_Ctor0; } }
- // ...
- //
- // public T0 dtor_Dtor0 { get { return ((DT_Ctor)_D).@Dtor0; } }
- // ...
- // }
- string DtT = dt.Name;
- string DtT_TypeArgs = "";
- if (dt.TypeArgs.Count != 0) {
- DtT_TypeArgs = "<" + TypeParameters(dt.TypeArgs) + ">";
- DtT += DtT_TypeArgs;
- }
-
- Indent(indent);
- 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);
- 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);
-
- 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)));
- if (dt.TypeArgs.Count != 0) {
- wr.Write("<{0}>", TypeParameters(dt.TypeArgs));
- }
- wr.Write("(");
- string sep = "";
- foreach (Formal f in dt.DefaultCtor.Formals) {
- if (!f.IsGhost) {
- wr.Write("{0}{1}", sep, DefaultValue(f.Type));
- sep = ", ";
- }
- }
- wr.Write(")");
- wr.WriteLine("; }");
- Indent(ind); wr.WriteLine("}");
-
- 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);
- Indent(ind); wr.WriteLine("}");
-
- Indent(ind);
- wr.WriteLine("public override int GetHashCode() { return _D.GetHashCode(); }");
-
- // query properties
- foreach (var ctor in dt.Ctors) {
- // public bool _Ctor0 { get { return _D is Dt_Ctor0; } }
- Indent(ind);
- wr.WriteLine("public bool _{0} {{ get {{ return _D is {1}_{0}{2}; }} }}", ctor.Name, dt.Name, DtT_TypeArgs);
- }
-
- // destructors
- foreach (var ctor in dt.Ctors) {
- foreach (var arg in ctor.Formals) {
- if (arg.HasName) {
- // public T0 @Dtor0 { get { return ((DT_Ctor)_D).@Dtor0; } }
- Indent(ind);
- wr.WriteLine("public {0} dtor_{1} {{ get {{ return (({2}_{3}{4})_D).@{1}; }} }}", TypeName(arg.Type), arg.Name, dt.Name, ctor.Name, DtT_TypeArgs);
- }
- }
- }
-
- Indent(indent);
- wr.WriteLine("}");
- }
-
- int WriteFormals(string sep, List<Formal/*!*/>/*!*/ formals)
- {
- Contract.Requires(sep != null);
- Contract.Requires(cce.NonNullElements(formals));
- int i = 0;
- 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);
- sep = ", ";
- i++;
- }
- }
- return i; // the number of formals written
- }
-
- string FormalName(Formal formal, int i) {
- Contract.Requires(formal != null);
- Contract.Ensures(Contract.Result<string>() != null);
-
- return formal.HasName ? formal.Name : "_a" + i;
- }
-
- string DtCtorName(DatatypeCtor ctor) {
- Contract.Requires(ctor != null);Contract.Ensures(Contract.Result<string>() != null);
-
- return cce.NonNull(ctor.EnclosingDatatype).Name + "_" + ctor.Name;
- }
-
- public bool HasMain(Program program) {
- foreach (var module in program.Modules) {
- foreach (var decl in module.TopLevelDecls) {
- var c = decl as ClassDecl;
- if (c != null) {
- foreach (var member in c.Members) {
- var m = member as Method;
- if (m != null) {
- if (!m.IsGhost && m.Name == "Main" && m.Ins.Count == 0 && m.Outs.Count == 0) {
- return true;
- }
- }
- }
- }
- }
- }
- return false;
- }
-
- void CompileClassMembers(ClassDecl c, int indent)
- {
- Contract.Requires(c != null);
- foreach (MemberDecl member in c.Members) {
- if (member is Field) {
- Field f = (Field)member;
- if (!f.IsGhost) {
- Indent(indent);
- wr.WriteLine("public {0} @{1} = {2};", TypeName(f.Type), f.Name, DefaultValue(f.Type));
- }
-
- } else if (member is Function) {
- Function f = (Function)member;
- if (f.IsGhost) {
- // nothing to compile
- } else if (f.Body == null) {
- 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);
- if (f.TypeArgs.Count != 0) {
- wr.Write("<{0}>", TypeParameters(f.TypeArgs));
- }
- wr.Write("(");
- WriteFormals("", f.Formals);
- wr.WriteLine(") {");
- CompileReturnBody(f.Body, indent + IndentAmount);
- Indent(indent); wr.WriteLine("}");
- }
-
- } else if (member is Method) {
- Method m = (Method)member;
- if (!m.IsGhost) {
- Indent(indent);
- wr.Write("public {0}void @{1}", m.IsStatic ? "static " : "", m.Name);
- if (m.TypeArgs.Count != 0) {
- wr.Write("<{0}>", TypeParameters(m.TypeArgs));
- }
- wr.Write("(");
- int nIns = WriteFormals("", m.Ins);
- WriteFormals(nIns == 0 ? "" : ", ", m.Outs);
- wr.WriteLine(")");
- Indent(indent); wr.WriteLine("{");
- foreach (Formal p in m.Outs) {
- if (!p.IsGhost) {
- Indent(indent + IndentAmount);
- wr.WriteLine("@{0} = {1};", p.Name, DefaultValue(p.Type));
- }
- }
- if (m.Body == null) {
- Error("Method {0} has no body", m.FullName);
- } else {
- TrStmtList(m.Body.Body, indent);
- }
- Indent(indent); wr.WriteLine("}");
-
- // allow the Main method to be an instance method
- if (m.Name == "Main" && m.Ins.Count == 0 && m.Outs.Count == 0) {
- Indent(indent);
- wr.WriteLine("public static void Main(string[] args) {");
- Contract.Assert(m.EnclosingClass == c);
- Indent(indent + IndentAmount);
- wr.Write("@{0} b = new @{0}", c.Name);
- if (c.TypeArgs.Count != 0) {
- // instantiate every parameter, it doesn't particularly matter how
- wr.Write("<");
- string sep = "";
- for (int i = 0; i < c.TypeArgs.Count; i++) {
- wr.Write("{0}int", sep);
- sep = ", ";
- }
- wr.Write(">");
- }
- wr.WriteLine("();");
- Indent(indent + IndentAmount); wr.WriteLine("b.Main();");
- Indent(indent); wr.WriteLine("}");
- }
- }
-
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected member
- }
- }
- }
-
- void CompileReturnBody(Expression body, int indent) {
- body = body.Resolved;
- if (body is MatchExpr) {
- MatchExpr me = (MatchExpr)body;
- // Type source = e;
- // if (source._D is Dt_Ctor0) {
- // FormalType f0 = ((Dt_Ctor0)source._D).a0;
- // ...
- // return Body0;
- // } else if (...) {
- // ...
- // } else if (true) {
- // ...
- // }
-
- SpillLetVariableDecls(me.Source, indent);
- string source = "_source" + tmpVarCount;
- tmpVarCount++;
- Indent(indent);
- wr.Write("{0} {1} = ", TypeName(cce.NonNull(me.Source.Type)), source);
- TrExpr(me.Source);
- wr.WriteLine(";");
-
- if (me.Cases.Count == 0) {
- // the verifier would have proved we never get here; still, we need some code that will compile
- Indent(indent);
- wr.WriteLine("throw new System.Exception();");
- } else {
- int i = 0;
- foreach (MatchCaseExpr mc in me.Cases) {
- MatchCasePrelude(source, cce.NonNull(mc.Ctor), mc.Arguments, i, me.Cases.Count, indent + IndentAmount);
- CompileReturnBody(mc.Body, indent + IndentAmount);
- i++;
- }
- Indent(indent); wr.WriteLine("}");
- }
-
- } else {
- SpillLetVariableDecls(body, indent);
- Indent(indent);
- wr.Write("return ");
- TrExpr(body);
- wr.WriteLine(";");
- }
- }
-
- void SpillLetVariableDecls(Expression expr, int indent) {
- Contract.Requires(0 <= indent);
- if (expr == null) {
- // allow "null" as an argument; nothing to do
- return;
- }
- if (expr is LetExpr) {
- var e = (LetExpr)expr;
- foreach (var v in e.Vars) {
- Indent(indent);
- wr.WriteLine("{0} @{1};", TypeName(v.Type), v.Name);
- }
- }
- foreach (var ee in expr.SubExpressions) {
- SpillLetVariableDecls(ee, indent);
- }
- }
-
- // ----- Type ---------------------------------------------------------------------------------
-
- readonly string DafnySetClass = "Dafny.Set";
- readonly string DafnyMultiSetClass = "Dafny.MultiSet";
- readonly string DafnySeqClass = "Dafny.Sequence";
-
- string TypeName(Type type)
- {
- Contract.Requires(type != null);
- Contract.Ensures(Contract.Result<string>() != null);
-
- while (true) {
- TypeProxy tp = type as TypeProxy;
- if (tp == null) {
- break;
- } else if (tp.T == null) {
- // unresolved proxy; just treat as ref, since no particular type information is apparently needed for this type
- return "object";
- } else {
- type = tp.T;
- }
- }
-
- if (type is BoolType) {
- return "bool";
- } else if (type is IntType) {
- return "BigInteger";
- } else if (type is ObjectType) {
- return "object";
- } else if (type.IsArrayType) {
- ArrayClassDecl at = type.AsArrayType;
- Contract.Assert(at != null); // follows from type.IsArrayType
- Type elType = UserDefinedType.ArrayElementType(type);
- string name = TypeName(elType) + "[";
- for (int i = 1; i < at.Dims; i++) {
- name += ",";
- }
- return name + "]";
- } else if (type is UserDefinedType) {
- UserDefinedType udt = (UserDefinedType)type;
- string s = "@" + udt.FullName;
- 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");
- }
- s += "<" + TypeNames(udt.TypeArgs) + ">";
- }
- return s;
- } else if (type is SetType) {
- Type argType = ((SetType)type).Arg;
- if (argType is ObjectType) {
- Error("compilation of set<object> is not supported; consider introducing a ghost");
- }
- return DafnySetClass + "<" + TypeName(argType) + ">";
- } else if (type is SeqType) {
- Type argType = ((SeqType)type).Arg;
- if (argType is ObjectType) {
- Error("compilation of seq<object> is not supported; consider introducing a ghost");
- }
- return DafnySeqClass + "<" + TypeName(argType) + ">";
- } else if (type is MultiSetType) {
- Type argType = ((MultiSetType)type).Arg;
- if (argType is ObjectType) {
- Error("compilation of seq<object> is not supported; consider introducing a ghost");
- }
- return DafnyMultiSetClass + "<" + TypeName(argType) + ">";
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected type
- }
- }
-
- string/*!*/ TypeNames(List<Type/*!*/>/*!*/ types) {
- Contract.Requires(cce.NonNullElements(types));
- Contract.Ensures(Contract.Result<string>() != null);
-
- string s = "";
- string sep = "";
- foreach (Type t in types) {
- s += sep + TypeName(t);
- sep = ",";
- }
- return s;
- }
-
- string/*!*/ TypeParameters(List<TypeParameter/*!*/>/*!*/ targs) {
- Contract.Requires(cce.NonNullElements(targs));
- Contract.Ensures(Contract.Result<string>() != null);
-
- string s = "";
- string sep = "";
- foreach (TypeParameter tp in targs) {
- s += sep + "@" + tp.Name;
- sep = ",";
- }
- return s;
- }
-
- string DefaultValue(Type type)
- {
- Contract.Requires(type != null);
- Contract.Ensures(Contract.Result<string>() != null);
-
- while (true) {
- TypeProxy tp = type as TypeProxy;
- if (tp == null) {
- break;
- } else if (tp.T == null) {
- // unresolved proxy; just treat as ref, since no particular type information is apparently needed for this type
- return "null";
- } else {
- type = tp.T;
- }
- }
-
- if (type is BoolType) {
- return "false";
- } else if (type is IntType) {
- return "new BigInteger(0)";
- } else if (type.IsRefType) {
- return string.Format("({0})null", TypeName(type));
- } else if (type.IsDatatype) {
- UserDefinedType udt = (UserDefinedType)type;
- string s = "@" + udt.Name;
- if (udt.TypeArgs.Count != 0) {
- s += "<" + TypeNames(udt.TypeArgs) + ">";
- }
- return string.Format("new {0}({0}.Default)", s);
- } else if (type.IsTypeParameter) {
- UserDefinedType udt = (UserDefinedType)type;
- return "default(@" + udt.Name + ")";
- } else if (type is SetType) {
- return DafnySetClass + "<" + TypeName(((SetType)type).Arg) + ">.Empty";
- } else if (type is MultiSetType) {
- return DafnyMultiSetClass + "<" + TypeName(((MultiSetType)type).Arg) + ">.Empty";
- } else if (type is SeqType) {
- return DafnySeqClass + "<" + TypeName(((SeqType)type).Arg) + ">.Empty";
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected type
- }
- }
-
- // ----- Stmt ---------------------------------------------------------------------------------
-
- void CheckHasNoAssumes(Statement stmt) {
- Contract.Requires(stmt != null);
- if (stmt is AssumeStmt) {
- Error("an assume statement cannot be compiled (line {0})", stmt.Tok.line);
- } else if (stmt is BlockStmt) {
- foreach (Statement s in ((BlockStmt)stmt).Body) {
- CheckHasNoAssumes(s);
- }
- } else if (stmt is IfStmt) {
- IfStmt s = (IfStmt)stmt;
- CheckHasNoAssumes(s.Thn);
- if (s.Els != null) {
- CheckHasNoAssumes(s.Els);
- }
- } else if (stmt is AlternativeStmt) {
- foreach (var alternative in ((AlternativeStmt)stmt).Alternatives) {
- foreach (Statement s in alternative.Body) {
- CheckHasNoAssumes(s);
- }
- }
- } else if (stmt is WhileStmt) {
- WhileStmt s = (WhileStmt)stmt;
- CheckHasNoAssumes(s.Body);
- } else if (stmt is AlternativeLoopStmt) {
- foreach (var alternative in ((AlternativeLoopStmt)stmt).Alternatives) {
- foreach (Statement s in alternative.Body) {
- CheckHasNoAssumes(s);
- }
- }
- } else if (stmt is ParallelStmt) {
- var s = (ParallelStmt)stmt;
- CheckHasNoAssumes(s.Body);
- } else if (stmt is MatchStmt) {
- MatchStmt s = (MatchStmt)stmt;
- foreach (MatchCaseStmt mc in s.Cases) {
- foreach (Statement bs in mc.Body) {
- CheckHasNoAssumes(bs);
- }
- }
- }
- }
-
- void TrStmt(Statement stmt, int indent)
- {
- Contract.Requires(stmt != null);
- if (stmt.IsGhost) {
- CheckHasNoAssumes(stmt);
- return;
- }
-
- if (stmt is PrintStmt) {
- PrintStmt s = (PrintStmt)stmt;
- foreach (Attributes.Argument arg in s.Args) {
- SpillLetVariableDecls(arg.E, indent);
- Indent(indent);
- wr.Write("System.Console.Write(");
- if (arg.S != null) {
- wr.Write("\"{0}\"", arg.S);
- } else {
- Contract.Assert(arg.E != null);
- TrExpr(arg.E);
- }
- wr.WriteLine(");");
- }
- } else if (stmt is BreakStmt) {
- var s = (BreakStmt)stmt;
- Indent(indent);
- wr.WriteLine("goto after_{0};", s.TargetStmt.Labels.UniqueId);
- } else if (stmt is ReturnStmt) {
- var s = (ReturnStmt)stmt;
- if (s.hiddenUpdate != null)
- TrStmt(s.hiddenUpdate, indent);
- Indent(indent); wr.WriteLine("return;");
- } else if (stmt is UpdateStmt) {
- var s = (UpdateStmt)stmt;
- var resolved = s.ResolvedStatements;
- if (resolved.Count == 1) {
- TrStmt(resolved[0], indent);
- } else {
- // multi-assignment
- Contract.Assert(s.Lhss.Count == resolved.Count);
- Contract.Assert(s.Rhss.Count == resolved.Count);
- var lvalues = new List<string>();
- var rhss = new List<string>();
- for (int i = 0; i < resolved.Count; i++) {
- if (!resolved[i].IsGhost) {
- var lhs = s.Lhss[i];
- var rhs = s.Rhss[i];
- if (!(rhs is HavocRhs)) {
- lvalues.Add(CreateLvalue(lhs, indent));
-
- string target = "_rhs" + tmpVarCount;
- tmpVarCount++;
- rhss.Add(target);
- TrRhs("var " + target, null, rhs, indent);
- }
- }
- }
- Contract.Assert(lvalues.Count == rhss.Count);
- for (int i = 0; i < lvalues.Count; i++) {
- Indent(indent);
- wr.WriteLine("{0} = {1};", lvalues[i], rhss[i]);
- }
- }
-
- } else if (stmt is AssignStmt) {
- AssignStmt s = (AssignStmt)stmt;
- Contract.Assert(!(s.Lhs is SeqSelectExpr) || ((SeqSelectExpr)s.Lhs).SelectOne); // multi-element array assignments are not allowed
- TrRhs(null, s.Lhs, s.Rhs, indent);
-
- } else if (stmt is VarDecl) {
- TrVarDecl((VarDecl)stmt, true, indent);
-
- } else if (stmt is CallStmt) {
- CallStmt s = (CallStmt)stmt;
- TrCallStmt(s, null, indent);
-
- } else if (stmt is BlockStmt) {
- Indent(indent); wr.WriteLine("{");
- TrStmtList(((BlockStmt)stmt).Body, indent);
- Indent(indent); wr.WriteLine("}");
-
- } else if (stmt is IfStmt) {
- IfStmt s = (IfStmt)stmt;
- if (s.Guard == null) {
- // we can compile the branch of our choice
- if (s.Els == null) {
- // let's compile the "else" branch, since that involves no work
- // (still, let's leave a marker in the source code to indicate that this is what we did)
- Indent(indent);
- wr.WriteLine("if (!false) { }");
- } else {
- // let's compile the "then" branch
- Indent(indent);
- wr.WriteLine("if (true)");
- TrStmt(s.Thn, indent);
- }
- } else {
- SpillLetVariableDecls(s.Guard, indent);
- Indent(indent); wr.Write("if (");
- TrExpr(s.Guard);
- wr.WriteLine(")");
-
- TrStmt(s.Thn, indent);
- if (s.Els != null) {
- Indent(indent); wr.WriteLine("else");
- TrStmt(s.Els, indent);
- }
- }
-
- } else if (stmt is AlternativeStmt) {
- var s = (AlternativeStmt)stmt;
- foreach (var alternative in s.Alternatives) {
- SpillLetVariableDecls(alternative.Guard, indent);
- }
- Indent(indent);
- foreach (var alternative in s.Alternatives) {
- wr.Write("if (");
- TrExpr(alternative.Guard);
- wr.WriteLine(") {");
- TrStmtList(alternative.Body, indent);
- Indent(indent);
- wr.Write("} else ");
- }
- wr.WriteLine("{ /*unreachable alternative*/ }");
-
- } else if (stmt is WhileStmt) {
- WhileStmt s = (WhileStmt)stmt;
- if (s.Guard == null) {
- Indent(indent);
- wr.WriteLine("while (false) { }");
- } else {
- SpillLetVariableDecls(s.Guard, indent);
- Indent(indent);
- wr.Write("while (");
- TrExpr(s.Guard);
- wr.WriteLine(")");
- TrStmt(s.Body, indent);
- }
-
- } else if (stmt is AlternativeLoopStmt) {
- var s = (AlternativeLoopStmt)stmt;
- if (s.Alternatives.Count != 0) {
- Indent(indent);
- wr.WriteLine("while (true) {");
- int ind = indent + IndentAmount;
- foreach (var alternative in s.Alternatives) {
- SpillLetVariableDecls(alternative.Guard, ind);
- }
- Indent(ind);
- foreach (var alternative in s.Alternatives) {
- wr.Write("if (");
- TrExpr(alternative.Guard);
- wr.WriteLine(") {");
- TrStmtList(alternative.Body, ind);
- Indent(ind);
- wr.Write("} else ");
- }
- wr.WriteLine("{ break; }");
- Indent(indent);
- wr.WriteLine("}");
- }
-
- } else if (stmt is ParallelStmt) {
- var s = (ParallelStmt)stmt;
- if (s.Kind != ParallelStmt.ParBodyKind.Assign) {
- // Call and Proof have no side effects, so they can simply be optimized away.
- return;
- } else if (s.BoundVars.Count == 0) {
- // the bound variables just spell out a single point, so the parallel statement is equivalent to one execution of the body
- TrStmt(s.Body, indent);
- return;
- }
- var s0 = (AssignStmt)s.S0;
- if (s0.Rhs is HavocRhs) {
- // The parallel statement says to havoc a bunch of things. This can be efficiently compiled
- // into doing nothing.
- return;
- }
- var rhs = ((ExprRhs)s0.Rhs).Expr;
-
- // Compile:
- // parallel (w,x,y,z | Range(w,x,y,z)) {
- // LHS(w,x,y,z) := RHS(w,x,y,z);
- // }
- // where w,x,y,z have types seq<W>,set<X>,int,bool and LHS has L-1 top-level subexpressions
- // (that is, L denotes the number of top-level subexpressions of LHS plus 1),
- // into:
- // var ingredients = new List< L-Tuple >();
- // foreach (W w in sq.UniqueElements) {
- // foreach (X x in st.Elements) {
- // for (BigInteger y = Lo; j < Hi; j++) {
- // for (bool z in Helper.AllBooleans) {
- // if (Range(w,x,y,z)) {
- // ingredients.Add(new L-Tuple( LHS0(w,x,y,z), LHS1(w,x,y,z), ..., RHS(w,x,y,z) ));
- // }
- // }
- // }
- // }
- // }
- // foreach (L-Tuple l in ingredients) {
- // LHS[ l0, l1, l2, ..., l(L-2) ] = l(L-1);
- // }
- //
- // Note, because the .NET Tuple class only supports up to 8 components, the compiler implementation
- // here supports arrays only up to 6 dimensions. This does not seem like a serious practical limitation.
- // However, it may be more noticeable if the parallel statement supported parallel assignments in its
- // body. To support cases where tuples would need more than 8 components, .NET Tuple's would have to
- // be nested.
-
- // Temporary names
- string ingredients = "_ingredients" + tmpVarCount;
- string tup = "_tup" + tmpVarCount;
- tmpVarCount++;
-
- // Compute L
- int L;
- string tupleTypeArgs;
- if (s0.Lhs is FieldSelectExpr) {
- var lhs = (FieldSelectExpr)s0.Lhs;
- L = 2;
- tupleTypeArgs = TypeName(lhs.Obj.Type);
- } else if (s0.Lhs is SeqSelectExpr) {
- var lhs = (SeqSelectExpr)s0.Lhs;
- L = 3;
- // note, we might as well do the BigInteger-to-int cast for array indices here, before putting things into the Tuple rather than when they are extracted from the Tuple
- tupleTypeArgs = TypeName(lhs.Seq.Type) + ",int";
- } else {
- var lhs = (MultiSelectExpr)s0.Lhs;
- L = 2 + lhs.Indices.Count;
- if (8 < L) {
- Error("compiler currently does not support assignments to more-than-6-dimensional arrays in parallel statements");
- return;
- }
- tupleTypeArgs = TypeName(lhs.Array.Type);
- for (int i = 0; i < lhs.Indices.Count; i++) {
- // note, we might as well do the BigInteger-to-int cast for array indices here, before putting things into the Tuple rather than when they are extracted from the Tuple
- tupleTypeArgs += ",int";
- }
- }
- tupleTypeArgs += "," + TypeName(rhs.Type);
-
- // declare and construct "ingredients"
- Indent(indent);
- wr.WriteLine("var {0} = new List<System.Tuple<{1}>>();", ingredients, tupleTypeArgs);
-
- var n = s.BoundVars.Count;
- Contract.Assert(s.Bounds.Count == n);
- for (int i = 0; i < n; i++) {
- var ind = indent + i * IndentAmount;
- var bound = s.Bounds[i];
- var bv = s.BoundVars[i];
- if (bound is QuantifierExpr.BoolBoundedPool) {
- Indent(ind);
- wr.Write("foreach (var @{0} in Dafny.Helpers.AllBooleans) {{ ", bv.Name);
- } else if (bound is QuantifierExpr.IntBoundedPool) {
- var b = (QuantifierExpr.IntBoundedPool)bound;
- SpillLetVariableDecls(b.LowerBound, ind);
- SpillLetVariableDecls(b.UpperBound, ind);
- Indent(ind);
- wr.Write("for (var @{0} = ", bv.Name);
- TrExpr(b.LowerBound);
- wr.Write("; @{0} < ", bv.Name);
- TrExpr(b.UpperBound);
- wr.Write("; @{0}++) {{ ", bv.Name);
- } else if (bound is QuantifierExpr.SetBoundedPool) {
- var b = (QuantifierExpr.SetBoundedPool)bound;
- SpillLetVariableDecls(b.Set, ind);
- Indent(ind);
- wr.Write("foreach (var @{0} in (", bv.Name);
- TrExpr(b.Set);
- wr.Write(").Elements) { ");
- } else if (bound is QuantifierExpr.SeqBoundedPool) {
- var b = (QuantifierExpr.SeqBoundedPool)bound;
- SpillLetVariableDecls(b.Seq, ind);
- Indent(ind);
- wr.Write("foreach (var @{0} in (", bv.Name);
- TrExpr(b.Seq);
- wr.Write(").UniqueElements) { ");
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected BoundedPool type
- }
- wr.WriteLine();
- }
-
- // if (range) {
- // ingredients.Add(new L-Tuple( LHS0(w,x,y,z), LHS1(w,x,y,z), ..., RHS(w,x,y,z) ));
- // }
- SpillLetVariableDecls(s.Range, indent + n * IndentAmount);
- Indent(indent + n * IndentAmount);
- wr.Write("if ");
- TrParenExpr(s.Range);
- wr.WriteLine(" {");
-
- var indFinal = indent + (n + 1) * IndentAmount;
- SpillLetVariableDecls(s0.Lhs, indFinal);
- SpillLetVariableDecls(rhs, indFinal);
- Indent(indFinal);
- wr.Write("{0}.Add(new System.Tuple<{1}>(", ingredients, tupleTypeArgs);
- if (s0.Lhs is FieldSelectExpr) {
- var lhs = (FieldSelectExpr)s0.Lhs;
- TrExpr(lhs.Obj);
- } else if (s0.Lhs is SeqSelectExpr) {
- var lhs = (SeqSelectExpr)s0.Lhs;
- TrExpr(lhs.Seq);
- wr.Write(", (int)(");
- TrExpr(lhs.E0);
- wr.Write(")");
- } else {
- var lhs = (MultiSelectExpr)s0.Lhs;
- TrExpr(lhs.Array);
- for (int i = 0; i < lhs.Indices.Count; i++) {
- wr.Write(", (int)(");
- TrExpr(lhs.Indices[i]);
- wr.Write(")");
- }
- wr.WriteLine("] = {0}.Item{1};", tup, L);
- }
- wr.Write(", ");
- TrExpr(rhs);
- wr.WriteLine("));");
-
- Indent(indent + n * IndentAmount);
- wr.WriteLine("}");
-
- for (int i = n; 0 <= --i; ) {
- Indent(indent + i * IndentAmount);
- wr.WriteLine("}");
- }
-
- // foreach (L-Tuple l in ingredients) {
- // LHS[ l0, l1, l2, ..., l(L-2) ] = l(L-1);
- // }
- Indent(indent);
- wr.WriteLine("foreach (var {0} in {1}) {{", tup, ingredients);
- Indent(indent + IndentAmount);
- if (s0.Lhs is FieldSelectExpr) {
- var lhs = (FieldSelectExpr)s0.Lhs;
- wr.WriteLine("{0}.Item1.@{1} = {0}.Item2;", tup, lhs.FieldName);
- } else if (s0.Lhs is SeqSelectExpr) {
- var lhs = (SeqSelectExpr)s0.Lhs;
- wr.WriteLine("{0}.Item1[{0}.Item2] = {0}.Item3;", tup);
- } else {
- var lhs = (MultiSelectExpr)s0.Lhs;
- wr.Write("{0}.Item1[");
- string sep = "";
- for (int i = 0; i < lhs.Indices.Count; i++) {
- wr.Write("{0}{1}.Item{2}", sep, tup, i + 2);
- sep = ", ";
- }
- wr.WriteLine("] = {0}.Item{1};", tup, L);
- }
- Indent(indent);
- wr.WriteLine("}");
-
- } 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;
- // ...
- // Body0;
- // } else if (...) {
- // ...
- // } else if (true) {
- // ...
- // }
- if (s.Cases.Count != 0) {
- SpillLetVariableDecls(s.Source, indent);
- string source = "_source" + tmpVarCount;
- tmpVarCount++;
- Indent(indent);
- wr.Write("{0} {1} = ", TypeName(cce.NonNull(s.Source.Type)), source);
- TrExpr(s.Source);
- wr.WriteLine(";");
-
- int i = 0;
- foreach (MatchCaseStmt mc in s.Cases) {
- MatchCasePrelude(source, cce.NonNull(mc.Ctor), mc.Arguments, i, s.Cases.Count, indent);
- TrStmtList(mc.Body, indent);
- i++;
- }
- Indent(indent); wr.WriteLine("}");
- }
-
- } else if (stmt is ConcreteSyntaxStatement) {
- var s = (ConcreteSyntaxStatement)stmt;
- foreach (var ss in s.ResolvedStatements) {
- TrStmt(ss, indent);
- }
-
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected statement
- }
- }
-
- string CreateLvalue(Expression lhs, int indent) {
- lhs = lhs.Resolved;
- SpillLetVariableDecls(lhs, indent);
- if (lhs is IdentifierExpr) {
- var ll = (IdentifierExpr)lhs;
- return "@" + ll.Var.Name;
- } else if (lhs is FieldSelectExpr) {
- var ll = (FieldSelectExpr)lhs;
- string obj = "_obj" + tmpVarCount;
- tmpVarCount++;
- Indent(indent);
- wr.Write("var {0} = ", obj);
- TrExpr(ll.Obj);
- wr.WriteLine(";");
- return string.Format("{0}.@{1}", obj, ll.Field.Name);
- } else if (lhs is SeqSelectExpr) {
- var ll = (SeqSelectExpr)lhs;
- string arr = "_arr" + tmpVarCount;
- string index = "_index" + tmpVarCount;
- tmpVarCount++;
- Indent(indent);
- wr.Write("var {0} = ", arr);
- TrExpr(ll.Seq);
- wr.WriteLine(";");
- Indent(indent);
- wr.Write("var {0} = ", index);
- TrExpr(ll.E0);
- wr.WriteLine(";");
- return string.Format("{0}[(int){1}]", arr, index);
- } else {
- var ll = (MultiSelectExpr)lhs;
- string arr = "_arr" + tmpVarCount;
- Indent(indent);
- wr.Write("var {0} = ", arr);
- TrExpr(ll.Array);
- wr.WriteLine(";");
- string fullString = arr + "[";
- string sep = "";
- int i = 0;
- foreach (var idx in ll.Indices) {
- string index = "_index" + i + "_" + tmpVarCount;
- Indent(indent);
- wr.Write("var {0} = ", index);
- TrExpr(idx);
- wr.WriteLine(";");
- fullString += sep + "(int)" + index;
- sep = ", ";
- i++;
- }
- tmpVarCount++;
- return fullString + "]";
- }
- }
-
- void TrRhs(string target, Expression targetExpr, AssignmentRhs rhs, int indent) {
- Contract.Requires((target == null) != (targetExpr == null));
- SpillLetVariableDecls(targetExpr, indent);
- var tRhs = rhs as TypeRhs;
- if (tRhs != null && tRhs.InitCall != null) {
- string nw = "_nw" + tmpVarCount;
- tmpVarCount++;
- Indent(indent);
- wr.Write("var {0} = ", nw);
- TrAssignmentRhs(rhs); // in this case, this call will not require us to spill any let variables first
- wr.WriteLine(";");
- TrCallStmt(tRhs.InitCall, nw, indent);
- Indent(indent);
- if (target != null) {
- wr.Write(target);
- } else {
- TrExpr(targetExpr);
- }
- wr.WriteLine(" = {0};", nw);
- } else if (rhs is HavocRhs) {
- // do nothing
- } else {
- if (rhs is ExprRhs) {
- SpillLetVariableDecls(((ExprRhs)rhs).Expr, indent);
- } else if (tRhs != null && tRhs.ArrayDimensions != null) {
- foreach (Expression dim in tRhs.ArrayDimensions) {
- SpillLetVariableDecls(dim, indent);
- }
- }
- Indent(indent);
- if (target != null) {
- wr.Write(target);
- } else {
- TrExpr(targetExpr);
- }
- wr.Write(" = ");
- TrAssignmentRhs(rhs);
- wr.WriteLine(";");
- }
- }
-
- void TrCallStmt(CallStmt s, string receiverReplacement, int indent) {
- Contract.Requires(s != null);
- Contract.Assert(s.Method != null); // follows from the fact that stmt has been successfully resolved
-
- var lvalues = new List<string>();
- Contract.Assert(s.Lhs.Count == s.Method.Outs.Count);
- for (int i = 0; i < s.Method.Outs.Count; i++) {
- Formal p = s.Method.Outs[i];
- if (!p.IsGhost) {
- lvalues.Add(CreateLvalue(s.Lhs[i], indent));
- }
- }
- var outTmps = new List<string>();
- for (int i = 0; i < s.Method.Outs.Count; i++) {
- Formal p = s.Method.Outs[i];
- if (!p.IsGhost) {
- string target = "_out" + tmpVarCount;
- tmpVarCount++;
- outTmps.Add(target);
- Indent(indent);
- wr.WriteLine("{0} {1};", TypeName(s.Lhs[i].Type), target);
- }
- }
- Contract.Assert(lvalues.Count == outTmps.Count);
-
- for (int i = 0; i < s.Method.Ins.Count; i++) {
- Formal p = s.Method.Ins[i];
- if (!p.IsGhost) {
- SpillLetVariableDecls(s.Args[i], indent);
- }
- }
- if (receiverReplacement != null) {
- Indent(indent);
- wr.Write("@" + receiverReplacement);
- } else if (s.Method.IsStatic) {
- Indent(indent);
- wr.Write(TypeName(cce.NonNull(s.Receiver.Type)));
- } else {
- SpillLetVariableDecls(s.Receiver, indent);
- Indent(indent);
- TrParenExpr(s.Receiver);
- }
- wr.Write(".@{0}(", s.Method.Name);
-
- string sep = "";
- for (int i = 0; i < s.Method.Ins.Count; i++) {
- Formal p = s.Method.Ins[i];
- if (!p.IsGhost) {
- wr.Write(sep);
- TrExpr(s.Args[i]);
- sep = ", ";
- }
- }
-
- foreach (var outTmp in outTmps) {
- wr.Write("{0}out {1}", sep, outTmp);
- sep = ", ";
- }
- wr.WriteLine(");");
-
- // assign to the actual LHSs
- for (int j = 0; j < lvalues.Count; j++) {
- Indent(indent);
- wr.WriteLine("{0} = {1};", lvalues[j], outTmps[j]);
- }
- }
-
- int tmpVarCount = 0;
-
- /// <summary>
- /// Before calling TrAssignmentRhs(rhs), the caller must have spilled the let variables declared in "rhs".
- /// </summary>
- void TrAssignmentRhs(AssignmentRhs rhs) {
- Contract.Requires(rhs != null);
- Contract.Requires(!(rhs is HavocRhs));
- if (rhs is ExprRhs) {
- ExprRhs e = (ExprRhs)rhs;
- TrExpr(e.Expr);
-
- } else {
- TypeRhs tp = (TypeRhs)rhs;
- if (tp.ArrayDimensions == null) {
- wr.Write("new {0}()", TypeName(tp.EType));
- } else {
- if (tp.EType is IntType || tp.EType.IsTypeParameter) {
- // Because the default constructor for BigInteger does not generate a valid BigInteger, we have
- // to excplicitly initialize the elements of an integer array. This is all done in a helper routine.
- wr.Write("Dafny.Helpers.InitNewArray{0}<{1}>", tp.ArrayDimensions.Count, TypeName(tp.EType));
- string prefix = "(";
- foreach (Expression dim in tp.ArrayDimensions) {
- wr.Write(prefix);
- TrExpr(dim);
- prefix = ", ";
- }
- wr.Write(")");
- } else {
- wr.Write("new {0}", TypeName(tp.EType));
- string prefix = "[";
- foreach (Expression dim in tp.ArrayDimensions) {
- wr.Write("{0}(int)", prefix);
- TrExpr(dim);
- prefix = ", ";
- }
- wr.Write("]");
- }
- }
- }
- }
-
- void TrStmtList(List<Statement/*!*/>/*!*/ stmts, int indent) {Contract.Requires(cce.NonNullElements(stmts));
- foreach (Statement ss in stmts) {
- TrStmt(ss, indent + IndentAmount);
- if (ss.Labels != null) {
- Indent(indent); // labels are not indented as much as the statements
- wr.WriteLine("after_{0}: ;", ss.Labels.UniqueId);
- }
- }
- }
-
- 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);
- if (alwaysInitialize) {
- // produce a default value
- wr.WriteLine(" = {0};", DefaultValue(s.Type));
- } else {
- wr.WriteLine(";");
- }
- }
-
- void MatchCasePrelude(string source, DatatypeCtor ctor, List<BoundVar/*!*/>/*!*/ arguments, int caseIndex, int caseCount, int indent) {
- 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;
- // ...
- 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.WriteLine(") {");
-
- int k = 0; // number of processe…
Large files files are truncated, but you can click here to view the full file