private DataTypeSymbol ProcessDataType(Symbol scope, DatatypeDecl dataTypeDeclaration) { var dataTypeSymbol = new DataTypeSymbol(scope, dataTypeDeclaration); ProcessAndAddAllMembers(dataTypeSymbol, dataTypeDeclaration); return(dataTypeSymbol); }
public void DeclareProgram(Program program) { foreach (ModuleDefinition mod in program.Modules) { foreach (TopLevelDecl top in mod.TopLevelDecls) { ClassDecl cls = top as ClassDecl; DatatypeDecl dataDecl = top as DatatypeDecl; if (cls != null) { foreach (MemberDecl member in cls.Members) { Method method = member as Method; Function function = member as Function; if (method != null && !allMethods.ContainsKey(method.Name)) { allMethods[method.Name] = method; } if (function != null && !allFunctions.ContainsKey(function.Name)) { allFunctions[function.Name] = function; } } } if (dataDecl != null && !allDatatypes.ContainsKey(dataDecl.Name)) { allDatatypes[dataDecl.Name] = dataDecl; } } } }
public virtual void Visit(DatatypeDecl dataTypeDeclaration) { foreach (var member in dataTypeDeclaration.Members) { Visit(member); } }
/// <summary> /// /// </summary> /// <param name="line"></param> /// <param name="ns"></param> /// <param name="datatype"></param> /// <param name="fL"></param>a function list which contains a function to generate stetment list with given line number /// <returns></returns> private MatchStmt GenerateMatchStmt(int line, NameSegment ns, DatatypeDecl datatype, List <Func <int, List <Statement> > > fL) { Contract.Requires(ns != null); Contract.Requires(datatype != null); Contract.Ensures(Contract.Result <MatchStmt>() != null); List <MatchCaseStmt> cases = new List <MatchCaseStmt>(); int index = TacnyDriver.TacticCodeTokLine;//line + 1; for (int j = 0; j < datatype.Ctors.Count; j++) { var dc = datatype.Ctors[j]; Func <int, List <Statement> > f = _ => new List <Statement>(); if (j < fL.Count) { f = fL[j]; } MatchCaseStmt mcs = GenerateMatchCaseStmt(index, dc, f); cases.Add(mcs); line += mcs.Body.Count + 1; } return(new MatchStmt(new Token(index, 0) { val = "match" }, new Token(index, 0) { val = "=>" }, ns, cases, false)); }
private void InitCtorFlags(DatatypeDecl datatype, out bool[] flags, bool value = false) { flags = new bool[datatype.Ctors.Count]; for (int i = 0; i < flags.Length; i++) { flags[i] = value; } }
public TypeApply Compile_SeqType(SeqType t) { Dictionary <TypeParameter, Type> typeArgs = new Dictionary <TypeParameter, Type>(); DatatypeDecl decl = FindDatatype("Seq"); return(Compile_Datatype(new UserDefinedType(Bpl.Token.NoToken, "Seq", decl, new List <Type> { t.Arg }))); }
private static LiteralExpr IsInductive(string datatypeName, DatatypeDecl datatype) { LiteralExpr lit = new LiteralExpr(datatype.tok, false); foreach (var ctor in datatype.Ctors) { foreach (var formal in ctor.Formals) { if (formal.Type.ToString() == datatypeName) { return new LiteralExpr(datatype.tok, true); } } } return lit; }
private void Init() { DebugDataList = new List <DebugData>(); TopLevelClasses = new List <TopLevelClassDeclaration>(); Globals = new List <DatatypeDecl>(); foreach (var item in DafnyProgram.DefaultModuleDef.TopLevelDecls) { ClassDecl curDecl = item as ClassDecl; if (curDecl != null) { var temp = new TopLevelClassDeclaration(); foreach (var member in curDecl.Members) { Tactic tac = member as Tactic; if (tac != null) { try { temp.Tactics.Add(tac.Name, tac); } catch (ArgumentException) { Contract.Assert(false, $"tactic {tac.Name} is already declared in the current context"); } } else { var tacFun = member as TacticFunction; if (tacFun != null) { temp.Tactics.Add(tacFun.Name, tacFun); } else { temp.Members.Add(member.Name, member); } } } TopLevelClasses.Add(temp); } else { DatatypeDecl dd = item as DatatypeDecl; if (dd != null) { Globals.Add(dd); } } } }
private static LiteralExpr IsInductive(string datatypeName, DatatypeDecl datatype) { LiteralExpr lit = new LiteralExpr(datatype.tok, false); foreach (var ctor in datatype.Ctors) { foreach (var formal in ctor.Formals) { if (formal.Type.ToString() == datatypeName) { return(new LiteralExpr(datatype.tok, true)); } } } return(lit); }
public IEnumerable <Solution> Resolve(Statement st, Solution solution) { List <Expression> call_arguments = null; IVariable lv = null; DatatypeDecl datatype = null; InitArgs(st, out lv, out call_arguments); Contract.Assert(tcce.OfSize(call_arguments, 1), Error.MkErr(st, 0, 1, call_arguments.Count)); string argType = GetArgumentType(call_arguments[0] as NameSegment); foreach (var result in ResolveExpression(call_arguments[0])) { if (argType == "Element") { var ns = result as NameSegment; IVariable originalDecl = StaticContext.GetGlobalVariable(ns.Name); Contract.Assert(originalDecl != null, Error.MkErr(st, 9, ((NameSegment)call_arguments[0]).Name)); var datatypeName = originalDecl.Type.ToString(); datatype = StaticContext.GetGlobal(datatypeName); var lit = IsInductive(datatypeName, datatype); yield return(AddNewLocal(lv, lit)); } else { var ctor = result as DatatypeCtor; Contract.Assert(ctor != null, Error.MkErr(st, 1, "Datatype constructor")); var datatypeName = ctor.EnclosingDatatype.Name; LiteralExpr lit = new LiteralExpr(st.Tok, false); foreach (var formal in ctor.Formals) { if (formal.Type.ToString() == datatypeName) { lit = new LiteralExpr(st.Tok, true); break; } } yield return(AddNewLocal(lv, lit)); } } }
private MatchStmt GenerateMatchStmt(int index, NameSegment ns, DatatypeDecl datatype, List <Solution> body) { Contract.Requires(ns != null); Contract.Requires(datatype != null); Contract.Ensures(Contract.Result <MatchStmt>() != null); List <MatchCaseStmt> cases = new List <MatchCaseStmt>(); int line = index + 1; int i = 0; foreach (DatatypeCtor dc in datatype.Ctors) { MatchCaseStmt mcs; GenerateMatchCaseStmt(line, dc, body[i], out mcs); cases.Add(mcs); line += mcs.Body.Count + 1; i++; } return(new MatchStmt(CreateToken("match", index, 0), CreateToken("=>", index, 0), ns, cases, false)); }
private DatatypeNode ToDatatypeNode(DatatypeDecl dt) { Console.WriteLine("Datatype: " + dt.Name); var dc = new DocComment(dt.DocComment); var ctors = new List <CtorNode>(); foreach (var ctor in dt.Ctors) { Console.WriteLine("Constructor: " + ctor.Name); ctors.Add(new CtorNode { Name = ctor.Name, ValueParams = ctor.Formals.Select(f => ToValueParamNode(f, null, false)).ToList(), Token = ToTokenNode(ctor.tok), }); } return(new DatatypeNode { Name = dt.Name, IsCodata = dt is CoDatatypeDecl, TypeParams = dt.TypeArgs.Select(tp => ToTypeParamNode(tp, dc)).ToList(), Ctors = ctors, UserDoc = dc.MainBody, }); }
/// <summary> /// TODO: Resolve the bodies lazily /// </summary> /// <param name="datatype"></param> /// <param name="casesGuard"></param> /// <param name="st"></param> /// <returns></returns> private IEnumerable <Solution> GenerateStmt(DatatypeDecl datatype, NameSegment casesGuard, TacnyCasesBlockStmt st) { List <List <Solution> > allCtorBodies = Repeated(new List <Solution>(), datatype.Ctors.Count); int ctor = 0; foreach (var list in allCtorBodies) { list.Add(null); RegisterLocals(datatype, ctor); foreach (var result in ResolveBody(st.Body)) { list.Add(result); } RemoveLocals(datatype, ctor); ctor++; } foreach (var stmt in GenerateAllMatchStmt(DynamicContext.tac_call.Tok.line, 0, Util.Copy.CopyNameSegment(casesGuard), datatype, allCtorBodies, new List <Solution>())) { yield return(CreateSolution(this, stmt)); } }
string DtName(DatatypeDecl decl) { var d = (TopLevelDecl)decl; while (DafnyOptions.O.IronDafny && d.ClonedFrom != null) { d = (TopLevelDecl)d.ClonedFrom; } return d.FullName; }
// Returns true if the DataTypeDecl was compiled as a DTypeVariant (an // enum), or false if a struct. bool CompileDatatypeStruct(DatatypeDecl dt) { Contract.Requires(dt != null); if (ShouldBeEnum(dt)) { WriteToken(dt.tok); using (WriteArray()) { j.WriteValue(KremlinAst.DTypeVariant); // (lident * branches_t) using (WriteArray()) { WriteLident(dt.FullName); using (WriteArray()) { // branches_t = (ident * fields_t) list foreach (DatatypeCtor ctor in dt.Ctors) { using (WriteArray()) { j.WriteValue(ctor.Name); using (WriteArray()) { // No fields } } } } } } return true; } else { foreach (DatatypeCtor ctor in dt.Ctors) { WriteToken(ctor.tok); using (WriteArray()) { j.WriteValue(KremlinAst.DTypeFlat); // of (lident * (ident * typ) list) using (WriteArray()) { WriteLident(dt.FullName); // lident using (WriteArray()) { // list int i = 0; foreach (Formal arg in ctor.Formals) { if (arg.IsGhost) { continue; } Formatting old = j.Formatting; j.Formatting = Formatting.None; using (WriteArray()) { // (ident * (typ * bool)) j.WriteValue(FormalName(arg, i)); using (WriteArray()) { WriteTypeName(arg.Type); // bugbug: for buffer/array types, how should this specify the length? j.WriteValue(true); // mutable } i++; j.Formatting = old; } } } } } } return false; } }
void CompileDatatypeConstructors(DatatypeDecl dt) { Contract.Requires(dt != null); if (dt is CoDatatypeDecl) { WriteEAbort("BUGBUG: CoDatatypeDecl not supported"); // bugbug: implement } // For Kremlin, generate a constructor only: There are no .NET base // object methods such as Equals() or GetHashCode() so no code-gen is // needed here, to support them. // public Dt_Ctor(arguments) { // Fields = arguments; // } UserDefinedType thisType = UserDefinedType.FromTopLevelDecl(dt.tok, dt); foreach (DatatypeCtor ctor in dt.Ctors) { VarTracker.Clear(); var pThis = new BoundVar(ctor.tok, ThisName, thisType); using (WriteArray()) { j.WriteValue(KremlinAst.DFunction); using (WriteArray()) { // of (CallingConvention.t option * flag list * typ * lident * binder list * expr) WriteDefaultCallingConvention(); using (WriteArray()) { } WriteTypeName(thisType); // returns type of 'this' WriteLident(ctor.FullName); using (WriteArray()) { // start of binder list WriteFormals(ctor.Formals); } using (WriteArray()) { j.WriteValue(KremlinAst.ESequence); // Do not emit EPushFrame/EPopFrame, as we want the allocation // of pThis to be inlined into the calling function. using (WriteArray()) { // ELet pThis = DefaultValueOfType in ESequence... using (WriteArray()) { j.WriteValue(KremlinAst.ELet); using (WriteArray()) { // of (binder * expr * expr) WriteBinder(pThis, ThisName, true); VarTracker.Push(pThis); WriteDefaultValue(thisType); using (WriteArray()) { j.WriteValue(KremlinAst.ESequence); using (WriteArray()) { // of expr list foreach (Formal arg in ctor.Formals) { if (arg.IsGhost) { continue; } // EAssign (EField of (EBufRead this.arg 0)) = EBound of Formal using (WriteArray()) { Formatting old = j.Formatting; j.Formatting = Formatting.None; j.WriteValue(KremlinAst.EAssign); using (WriteArray()) { // of (expr * expr) // First expr: EField of EBufRead('this',0) to write into using (WriteArray()) { j.WriteValue(KremlinAst.EField); using (WriteArray()) { // of (lident * expr * ident) WriteLident(pThis.Type); // lident using (WriteArray()) { j.WriteValue(KremlinAst.EBufRead); using (WriteArray()) { WriteEBound(pThis); WriteConstant(0u); } } j.WriteValue(arg.Name); } } // Second expr: // EBound of formal WriteEBound(arg); } j.Formatting = old; } } WriteEBound(pThis); // and return the pThis expression from the constructor } } VarTracker.Pop(pThis); } } } } } } enclosingThis = null; } }
void DatatypeDecl(ModuleDefinition/*!*/ module, out DatatypeDecl/*!*/ dt) { Contract.Requires(module != null); Contract.Ensures(Contract.ValueAtReturn(out dt)!=null); IToken/*!*/ id; Attributes attrs = null; List<TypeParameter/*!*/> typeArgs = new List<TypeParameter/*!*/>(); List<DatatypeCtor/*!*/> ctors = new List<DatatypeCtor/*!*/>(); IToken bodyStart = Token.NoToken; // dummy assignment bool co = false; while (!(la.kind == 0 || la.kind == 76 || la.kind == 77)) {SynErr(142); Get();} if (la.kind == 76) { Get(); } else if (la.kind == 77) { Get(); co = true; } else SynErr(143); while (la.kind == 46) { Attribute(ref attrs); } NoUSIdent(out id); if (la.kind == 52) { GenericParameters(typeArgs); } Expect(67); bodyStart = t; DatatypeMemberDecl(ctors); while (la.kind == 23) { Get(); DatatypeMemberDecl(ctors); } if (la.kind == 28) { while (!(la.kind == 0 || la.kind == 28)) {SynErr(144); Get();} Get(); errors.Warning(t, "the semi-colon that used to terminate a (co)datatype declaration has been deprecated; in the new syntax, just leave off the semi-colon"); } if (co) { dt = new CoDatatypeDecl(id, id.val, module, typeArgs, ctors, attrs); } else { dt = new IndDatatypeDecl(id, id.val, module, typeArgs, ctors, attrs); } dt.BodyStartTok = bodyStart; dt.BodyEndTok = t; }
public void PrintDatatype(DatatypeDecl dt, int indent) { Contract.Requires(dt != null); Indent(indent); PrintClassMethodHelper(dt is IndDatatypeDecl ? "datatype" : "codatatype", dt.Attributes, dt.Name, dt.TypeArgs); wr.Write(" ="); string sep = ""; foreach (DatatypeCtor ctor in dt.Ctors) { wr.Write(sep); PrintClassMethodHelper("", ctor.Attributes, ctor.Name, new List<TypeParameter>()); if (ctor.Formals.Count != 0) { PrintFormals(ctor.Formals); } sep = " |"; } wr.WriteLine(); }
protected override void DeclareDatatype(DatatypeDecl dt, TargetWriter wr) { // $module.Dt = class Dt { // constructor(tag) { // this.$tag = tag; // } // static create_Ctor0(field0, field1, ...) { // let $dt = new Dt(0); // $dt.field0 = field0; // $dt.field1 = field1; // ... // return $dt; // } // static create_Ctor1(...) { // let $dt = new Dt(1); // ... // } // ... // // get is_Ctor0 { return this.$tag == 0; } // get is_Ctor1 { return this.$tag == 1; } // ... // // toString() { // ... // } // equals(other) { // ... // } // } // TODO: need Default member (also for co-datatypes) // TODO: if HasFinitePossibleValues, need enumerator of values string DtT = dt.CompileName; string DtT_protected = IdProtect(DtT); wr.Indent(); // from here on, write everything into the new block created here: wr = wr.NewNamedBlock("$module.{0} = class {0}", DtT_protected); wr.Indent(); wr.WriteLine("constructor(tag) { this.$tag = tag; }"); // query properties var i = 0; foreach (var ctor in dt.Ctors) { // collect the names of non-ghost arguments var argNames = new List <string>(); var k = 0; foreach (var formal in ctor.Formals) { if (!formal.IsGhost) { argNames.Add(FormalName(formal, k)); k++; } } // static create_Ctor0(params) { return {$tag:0, p0: pararms0, p1: params1, ...}; } wr.Indent(); wr.Write("static create_{0}(", ctor.CompileName); wr.Write(Util.Comma(argNames, nm => nm)); var w = wr.NewBlock(")"); w.Indent(); w.WriteLine("let $dt = new {0}({1});", DtT_protected, i); foreach (var arg in argNames) { w.Indent(); w.WriteLine("$dt.{0} = {0};", arg); } w.Indent(); w.WriteLine("return $dt;"); i++; } // query properties i = 0; foreach (var ctor in dt.Ctors) { // get is_Ctor0() { return _D is Dt_Ctor0; } wr.Indent(); wr.WriteLine("get is_{0}() {{ return this.$tag === {1}; }}", ctor.CompileName, i); i++; } if (dt is IndDatatypeDecl && !(dt is TupleTypeDecl)) { // toString method wr.Indent(); var w = wr.NewBlock("toString()"); i = 0; foreach (var ctor in dt.Ctors) { var cw = EmitIf(string.Format("this.$tag == {0}", i), true, w); cw.Indent(); cw.Write("return \"{0}.{1}\"", dt.Name, ctor.Name); var sep = " + \"(\" + "; var anyFormals = false; var k = 0; foreach (var arg in ctor.Formals) { if (!arg.IsGhost) { anyFormals = true; cw.Write("{0}this.{1}.toString()", sep, FormalName(arg, k)); sep = " + \", \" + "; k++; } } if (anyFormals) { cw.Write(" + \")\""); } cw.WriteLine(";"); i++; } w = w.NewBlock(""); w.Indent(); w.WriteLine("return \"<unexpected>\";"); } // equals method wr.Indent(); using (var w = wr.NewBlock("equals(other)")) { using (var thn = EmitIf("this === other", true, w)) { EmitReturnExpr("true", thn); } i = 0; foreach (var ctor in dt.Ctors) { var thn = EmitIf(string.Format("this.$tag == {0}", i), true, w); using (var guard = new TargetWriter()) { guard.Write("other.$tag == {0}", i); var k = 0; foreach (Formal arg in ctor.Formals) { if (!arg.IsGhost) { string nm = FormalName(arg, k); if (IsDirectlyComparable(arg.Type)) { guard.Write(" && this.{0} === oth.{0}", nm); } else { guard.Write(" && _dafny.areEqual(this.{0}, other.{0})", nm); } k++; } } EmitReturnExpr(guard.ToString(), thn); } i++; } using (var els = w.NewBlock("")) { els.Indent(); els.WriteLine("return false; // unexpected"); } } }
private Solution GenerateVerifiedStmt(DatatypeDecl datatype, NameSegment casesGuard, TacnyCasesBlockStmt st) { bool[] ctorFlags; int ctor; // current active match case InitCtorFlags(datatype, out ctorFlags); List <Solution> ctorBodies = RepeatedDefault <Solution>(datatype.Ctors.Count); // find the first failing case MatchStmt ms = GenerateMatchStmt(DynamicContext.tac_call.Tok.line, Util.Copy.CopyNameSegment(casesGuard), datatype, ctorBodies); Solution solution = CreateSolution(this, ms); if (!ResolveAndVerify(solution)) { ctor = 0; } else { ctor = GetErrorIndex(StaticContext.program.GetErrorToken(), ms); // the error is occuring outside the match stmt if (ctor == -1) { ms = GenerateMatchStmt(DynamicContext.tac_call.Tok.line, Util.Copy.CopyNameSegment(casesGuard), datatype, ctorBodies); return(CreateSolution(this, ms)); } ctorFlags[ctor] = true; _oldToken = StaticContext.program.GetErrorToken(); } while (ctor < datatype.Ctors.Count) { if (!StaticContext.program.HasError()) { break; } RegisterLocals(datatype, ctor, _ctorTypes); // if nothing was generated for the cases body move on to the next one foreach (var result in ResolveBody(st.Body)) { ctorBodies[ctor] = result; ms = GenerateMatchStmt(DynamicContext.tac_call.Tok.line, Util.Copy.CopyNameSegment(casesGuard), datatype, ctorBodies); solution = CreateSolution(this, ms); // if the program fails tro resolve skip if (!ResolveAndVerify(solution)) { continue; } if (!StaticContext.program.HasError()) { break; } if (CheckError(ms, ref ctorFlags, ctor)) { // if the ctor does not require a body null the value if (!ctorFlags[ctor]) { ctorBodies[ctor] = null; } break; } } // clear local var RemoveLocals(datatype, ctor); ctor++; } ms = GenerateMatchStmt(DynamicContext.tac_call.Tok.line, Util.Copy.CopyNameSegment(casesGuard), datatype, ctorBodies); return(CreateSolution(this, ms)); }
void CompileDatatypeStruct(DatatypeDecl dt, int indent, TextWriter wr) { Contract.Requires(dt != null); // public struct Dt<T> : IDatatype{ // Base_Dt<T> _d; // public Base_Dt<T> _D { // get { // if (_d == null) { // _d = Default; // } else if (_d is Dt__Lazy<T>) { // co-datatypes only // _d = ((Dt__Lazy<T>)_d).Get(); // co-datatypes only // } // return _d; // } // } // public Dt(Base_Dt<T> d) { this._d = d; } // static Base_Dt<T> theDefault; // public static Base_Dt<T> Default { // get { // if (theDefault == null) { // theDefault = ...; // } // return theDefault; // } // } // 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 override string ToString() { return _D.ToString(); } // only for inductive datatypes // // public bool is_Ctor0 { get { return _D is Dt_Ctor0; } } // ... // // public T0 dtor_Dtor0 { get { return ((DT_Ctor)_D).@Dtor0; } } // ... // } string DtT = dt.CompileName; string DtT_TypeArgs = ""; if (dt.TypeArgs.Count != 0) { DtT_TypeArgs = "<" + TypeParameters(dt.TypeArgs) + ">"; DtT += DtT_TypeArgs; } Indent(indent, wr); wr.WriteLine("public struct @{0} {{", DtT); int ind = indent + IndentAmount; Indent(ind, wr); wr.WriteLine("Base_{0} _d;", DtT); Indent(ind, wr); wr.WriteLine("public Base_{0} _D {{", DtT); Indent(ind + IndentAmount, wr); wr.WriteLine("get {"); Indent(ind + 2 * IndentAmount, wr); wr.WriteLine("if (_d == null) {"); Indent(ind + 3 * IndentAmount, wr); wr.WriteLine("_d = Default;"); if (dt is CoDatatypeDecl) { string typeParams = dt.TypeArgs.Count == 0 ? "" : string.Format("<{0}>", TypeParameters(dt.TypeArgs)); Indent(ind + 2 * IndentAmount, wr); wr.WriteLine("}} else if (_d is {0}__Lazy{1}) {{", dt.CompileName, typeParams); Indent(ind + 3 * IndentAmount, wr); wr.WriteLine("_d = (({0}__Lazy{1})_d).Get();", dt.CompileName, typeParams); } Indent(ind + 2 * IndentAmount, wr); wr.WriteLine("}"); Indent(ind + 2 * IndentAmount, wr); wr.WriteLine("return _d;"); Indent(ind + IndentAmount, wr); wr.WriteLine("}"); Indent(ind, wr); wr.WriteLine("}"); Indent(ind, wr); wr.WriteLine("public @{0}(Base_{1} d) {{ this._d = d; }}", dt.CompileName, DtT); Indent(ind, wr); wr.WriteLine("static Base_{0} theDefault;", DtT); Indent(ind, wr); wr.WriteLine("public static Base_{0} Default {{", DtT); Indent(ind + IndentAmount, wr); wr.WriteLine("get {"); Indent(ind + 2 * IndentAmount, wr); wr.WriteLine("if (theDefault == null) {"); Indent(ind + 3 * IndentAmount, wr); wr.Write("theDefault = "); DatatypeCtor defaultCtor; if (dt is IndDatatypeDecl) { defaultCtor = ((IndDatatypeDecl)dt).DefaultCtor; } else { defaultCtor = ((CoDatatypeDecl)dt).Ctors[0]; // pick any one of them } wr.Write("new {0}", DtCtorName(defaultCtor, dt.TypeArgs)); wr.Write("("); string sep = ""; foreach (Formal f in defaultCtor.Formals) { if (!f.IsGhost) { wr.Write("{0}{1}", sep, DefaultValue(f.Type, wr)); sep = ", "; } } wr.Write(")"); wr.WriteLine(";"); Indent(ind + 2 * IndentAmount, wr); wr.WriteLine("}"); Indent(ind + 2 * IndentAmount, wr); wr.WriteLine("return theDefault;"); Indent(ind + IndentAmount, wr); wr.WriteLine("}"); Indent(ind, wr); wr.WriteLine("}"); Indent(ind, wr); wr.WriteLine("public override bool Equals(object other) {"); Indent(ind + IndentAmount, wr); wr.WriteLine("return other is @{0} && _D.Equals(((@{0})other)._D);", DtT); Indent(ind, wr); wr.WriteLine("}"); Indent(ind, wr); wr.WriteLine("public override int GetHashCode() { return _D.GetHashCode(); }"); if (dt is IndDatatypeDecl) { Indent(ind, wr); wr.WriteLine("public override string ToString() { return _D.ToString(); }"); } // query properties foreach (var ctor in dt.Ctors) { // public bool is_Ctor0 { get { return _D is Dt_Ctor0; } } Indent(ind, wr); wr.WriteLine("public bool is_{0} {{ get {{ return _D is {1}_{0}{2}; }} }}", ctor.CompileName, dt.CompileName, DtT_TypeArgs); } if (dt.HasFinitePossibleValues) { Indent(ind, wr); wr.WriteLine("public static System.Collections.Generic.IEnumerable<@{0}> AllSingletonConstructors {{", DtT); Indent(ind + IndentAmount, wr); wr.WriteLine("get {"); foreach (var ctr in dt.Ctors) { if (ctr.Formals.Count == 0) { Indent(ind + IndentAmount + IndentAmount, wr); wr.WriteLine("yield return new @{0}(new {2}_{1}());", DtT, ctr.CompileName, dt.CompileName); } } Indent(ind + IndentAmount + IndentAmount, wr); wr.WriteLine("yield break;"); Indent(ind + IndentAmount, wr); wr.WriteLine("}"); Indent(ind, wr); wr.WriteLine("}"); } // destructors foreach (var ctor in dt.Ctors) { foreach (var arg in ctor.Formals) { if (!arg.IsGhost && arg.HasName) { // public T0 @Dtor0 { get { return ((DT_Ctor)_D).@Dtor0; } } Indent(ind, wr); wr.WriteLine("public {0} dtor_{1} {{ get {{ return (({2}_{3}{4})_D).@{1}; }} }}", TypeName(arg.Type, wr), arg.CompileName, dt.CompileName, ctor.CompileName, DtT_TypeArgs); } } } Indent(indent, wr); wr.WriteLine("}"); }
bool ShouldBeEnum(DatatypeDecl dt) { foreach (DatatypeCtor ctor in dt.Ctors) { foreach (Formal arg in ctor.Formals) { return false; } } // Returns true only if all Ctors have zero formals, ghost or otherwise return true; }
/// <summary> /// /// </summary> /// <param name="line"></param> /// <param name="ns"></param> /// <param name="datatype"></param> /// <param name="f"></param>a function list which contains a function to generate stetment list with given line number /// <returns></returns> private MatchStmt GenerateMatchStmt (int line, NameSegment ns, DatatypeDecl datatype, List<Func<int, List<Statement>>> fL) { Contract.Requires(ns != null); Contract.Requires(datatype != null); Contract.Ensures(Contract.Result<MatchStmt>() != null); List<MatchCaseStmt> cases = new List<MatchCaseStmt>(); int index = Interpreter.TACNY_CODE_TOK_LINE;//line + 1; int i = 0; for (int j = 0; j < datatype.Ctors.Count; j++){ var dc = datatype.Ctors[j]; Func<int, List<Statement>> f = _=> new List<Statement>(); if (j < fL.Count) f = fL[j]; MatchCaseStmt mcs = GenerateMatchCaseStmt(index, dc, f); cases.Add(mcs); line += mcs.Body.Count + 1; i++; } return new MatchStmt(new Token(index, 0) { val = "match" }, new Token(index, 0) { val = "=>"}, ns, cases, false); }
private static void InitCtorFlags(DatatypeDecl datatype, out bool[] flags, bool value = false) { flags = new bool[datatype.Ctors.Count]; for(int i = 0; i < flags.Length; i++) { flags[i] = value; } }
void DatatypeDecl(DeclModifierData dmod, ModuleDefinition/*!*/ module, out DatatypeDecl/*!*/ dt) { Contract.Requires(module != null); Contract.Ensures(Contract.ValueAtReturn(out dt)!=null); IToken/*!*/ id; Attributes attrs = null; List<TypeParameter/*!*/> typeArgs = new List<TypeParameter/*!*/>(); List<DatatypeCtor/*!*/> ctors = new List<DatatypeCtor/*!*/>(); IToken bodyStart = Token.NoToken; // dummy assignment bool co = false; CheckDeclModifiers(dmod, "Datatypes or codatatypes", AllowedDeclModifiers.None); while (!(la.kind == 0 || la.kind == 81 || la.kind == 82)) {SynErr(156); Get();} if (la.kind == 81) { Get(); } else if (la.kind == 82) { Get(); co = true; } else SynErr(157); while (la.kind == 50) { Attribute(ref attrs); } NoUSIdent(out id); if (la.kind == 56) { GenericParameters(typeArgs); } Expect(74); bodyStart = t; DatatypeMemberDecl(ctors); while (la.kind == 24) { Get(); DatatypeMemberDecl(ctors); } if (la.kind == 30) { while (!(la.kind == 0 || la.kind == 30)) {SynErr(158); Get();} Get(); errors.Deprecated(t, "the semi-colon that used to terminate a (co)datatype declaration has been deprecated; in the new syntax, just leave off the semi-colon"); } if (co) { dt = new CoDatatypeDecl(id, id.val, module, typeArgs, ctors, attrs); } else { dt = new IndDatatypeDecl(id, id.val, module, typeArgs, ctors, attrs); } dt.BodyStartTok = bodyStart; dt.BodyEndTok = t; }
void CompileDatatypeConstructors(DatatypeDecl dt, int indent, TextWriter wr) { Contract.Requires(dt != null); string typeParams = dt.TypeArgs.Count == 0 ? "" : string.Format("<{0}>", TypeParameters(dt.TypeArgs)); if (dt is CoDatatypeDecl) { // public class Dt__Lazy<T> : Base_Dt<T> { // public delegate Base_Dt<T> Computer(); // public delegate Computer ComputerComputer(); // Computer c; // public Dt__Lazy(Computer c) { this.c = c; } // public Base_Dt<T> Get() { return c(); } // } Indent(indent, wr); wr.WriteLine("public class {0}__Lazy{1} : Base_{0}{1} {{", dt.CompileName, typeParams); int ind = indent + IndentAmount; Indent(ind, wr); wr.WriteLine("public delegate Base_{0}{1} Computer();", dt.CompileName, typeParams); Indent(ind, wr); wr.WriteLine("public delegate Computer ComputerComputer();"); Indent(ind, wr); wr.WriteLine("Computer c;"); Indent(ind, wr); wr.WriteLine("public {0}__Lazy(Computer c) {{ this.c = c; }}", dt.CompileName); Indent(ind, wr); wr.WriteLine("public Base_{0}{1} Get() {{ return c(); }}", dt.CompileName, typeParams); Indent(indent, wr); wr.WriteLine("}"); } int constructorIndex = 0; // used to give each constructor a different 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 // } // public override string ToString() { // only for inductive datatypes // // ... // } // } Indent(indent, wr); wr.Write("public class {0}", DtCtorDeclarationName(ctor, dt.TypeArgs)); wr.WriteLine(" : Base_{0}{1} {{", dt.CompileName, typeParams); int ind = indent + IndentAmount; int i = 0; foreach (Formal arg in ctor.Formals) { if (!arg.IsGhost) { Indent(ind, wr); wr.WriteLine("public readonly {0} @{1};", TypeName(arg.Type, wr), FormalName(arg, i)); i++; } } Indent(ind, wr); wr.Write("public {0}(", DtCtorDeclartionName(ctor)); WriteFormals("", ctor.Formals, wr); wr.WriteLine(") {"); i = 0; foreach (Formal arg in ctor.Formals) { if (!arg.IsGhost) { Indent(ind + IndentAmount, wr); wr.WriteLine("this.@{0} = @{0};", FormalName(arg, i)); i++; } } Indent(ind, wr); wr.WriteLine("}"); // Equals method Indent(ind, wr); wr.WriteLine("public override bool Equals(object other) {"); Indent(ind + IndentAmount, wr); wr.Write("var oth = other as {0}", DtCtorName(ctor, dt.TypeArgs)); wr.WriteLine(";"); Indent(ind + IndentAmount, wr); 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 || arg.Type.SupportsEquality) { wr.Write(" && this.@{0}.Equals(oth.@{0})", nm); } else { wr.Write(" && this.@{0} == oth.@{0}", nm); } i++; } } wr.WriteLine(";"); Indent(ind, wr); wr.WriteLine("}"); // GetHashCode method (Uses the djb2 algorithm) Indent(ind, wr); wr.WriteLine("public override int GetHashCode() {"); Indent(ind + IndentAmount, wr); wr.WriteLine("ulong hash = 5381;"); Indent(ind + IndentAmount, wr); wr.WriteLine("hash = ((hash << 5) + hash) + {0};", constructorIndex); i = 0; foreach (Formal arg in ctor.Formals) { if (!arg.IsGhost) { string nm = FormalName(arg, i); Indent(ind + IndentAmount, wr); wr.WriteLine("hash = ((hash << 5) + hash) + ((ulong)this.@{0}.GetHashCode());", nm); i++; } } Indent(ind + IndentAmount, wr); wr.WriteLine("return (int) hash;"); Indent(ind, wr); wr.WriteLine("}"); if (dt is IndDatatypeDecl) { Indent(ind, wr); wr.WriteLine("public override string ToString() {"); string nm; if (dt is TupleTypeDecl) { nm = ""; } else { nm = (dt.Module.IsDefaultModule ? "" : dt.Module.CompileName + ".") + dt.CompileName + "." + ctor.CompileName; } var tempVar = GenVarName("s", ctor.Formals); Indent(ind + IndentAmount, wr); wr.WriteLine("string {0} = \"{1}\";", tempVar, nm); if (ctor.Formals.Count != 0) { Indent(ind + IndentAmount, wr); wr.WriteLine("{0} += \"(\";", tempVar); i = 0; foreach (var arg in ctor.Formals) { if (!arg.IsGhost) { if (i != 0) { Indent(ind + IndentAmount, wr); wr.WriteLine("{0} += \", \";", tempVar); } Indent(ind + IndentAmount, wr); wr.WriteLine("{0} += @{1}.ToString();", tempVar,FormalName(arg, i)); i++; } } Indent(ind + IndentAmount, wr); wr.WriteLine("{0} += \")\";", tempVar); } Indent(ind + IndentAmount, wr); wr.WriteLine("return {0};", tempVar); Indent(ind, wr); wr.WriteLine("}"); } Indent(indent, wr); wr.WriteLine("}"); } constructorIndex++; }
private void CheckDatatypesAreRefinements(DatatypeDecl dd, DatatypeDecl nn) { CheckAgreement_TypeParameters(nn.tok, dd.TypeArgs, nn.TypeArgs, dd.Name, "datatype", false); if (dd.Ctors.Count != nn.Ctors.Count) { reporter.Error(MessageSource.RefinementTransformer, nn.tok, "a refining datatype must have the same number of constructors"); } else { var map = new Dictionary<string, DatatypeCtor>(); foreach (var ctor in nn.Ctors) { map.Add(ctor.Name, ctor); } foreach (var ctor in dd.Ctors) { DatatypeCtor newCtor; if (map.TryGetValue(ctor.Name, out newCtor)) { if (newCtor.Formals.Count != ctor.Formals.Count) { reporter.Error(MessageSource.RefinementTransformer, newCtor, "the constructor ({0}) must have the same number of formals as in the refined module", newCtor.Name); } else { for (int i = 0; i < newCtor.Formals.Count; i++) { var a = ctor.Formals[i]; var b = newCtor.Formals[i]; if (a.HasName) { if (!b.HasName || a.Name != b.Name) reporter.Error(MessageSource.RefinementTransformer, b, "formal argument {0} in constructor {1} does not have the same name as in the refined module (should be {2})", i, ctor.Name, a.Name); } if (!ResolvedTypesAreTheSame(a.Type, b.Type)) { reporter.Error(MessageSource.RefinementTransformer, b, "formal argument {0} in constructor {1} does not have the same type as in the refined module (should be {2}, not {3})", i, ctor.Name, a.Type.ToString(), b.Type.ToString()); } } } } else { reporter.Error(MessageSource.RefinementTransformer, nn, "the constructor {0} must be present in the refining datatype", ctor.Name); } } } }
string DtName(DatatypeDecl decl) { var d = (TopLevelDecl)decl; while (DafnyOptions.O.IronDafny && d.ClonedFrom != null) { d = (TopLevelDecl)d.ClonedFrom; } return d.Module.IsDefaultModule ? d.CompileName : d.FullCompileName; }
private IEnumerable <MatchStmt> GenerateAllMatchStmt(int line_index, int depth, NameSegment ns, DatatypeDecl datatype, List <List <Solution> > bodies, List <Solution> curBody) { if (bodies.Count == 0) { yield break; } if (depth == bodies.Count) { MatchStmt ms = GenerateMatchStmt(line_index, Util.Copy.CopyNameSegment(ns), datatype, curBody); yield return(ms); yield break; } for (int i = 0; i < bodies[depth].Count; ++i) { List <Solution> tmp = new List <Solution>(); tmp.AddRange(curBody); tmp.Add(bodies[depth][i]); foreach (var item in GenerateAllMatchStmt(line_index, depth + 1, ns, datatype, bodies, tmp)) { yield return(item); } } }
public static void Resolve(Resolver resolver, Program program) { try { foreach (ModuleDefinition module in program.Modules) { foreach (TopLevelDecl decl in module.TopLevelDecls) { DatatypeDecl data = decl as DatatypeDecl; if (data != null) { foreach (var ctor in data.Ctors) { resolver.PushGhost(); data.TypeArgs.ForEach(p => resolver.PushTypeParam(p)); ctor.Formals.ForEach(f => f.Resolve(resolver)); data.TypeArgs.ForEach(p => resolver.PopTypeParam(p)); resolver.PopGhost(); } } } } foreach (MemberDecl member in ClassDecl.TheClass.Members) { Field field = member as Field; Function fun = member as Function; Method method = member as Method; if (field != null) { if (field.IsGhost) { resolver.PushGhost(); } field.Type.Resolve(resolver); if (field.IsGhost) { resolver.PopGhost(); } } if (fun != null) { resolver.currentFunction = fun; resolver.PushGhost(); fun.TypeArgs.ForEach(p => resolver.PushTypeParam(p)); fun.Formals.ForEach(x => { x.Resolve(resolver); }); fun.ResultType.Resolve(resolver); fun.TypeArgs.ForEach(p => resolver.PopTypeParam(p)); resolver.PopGhost(); resolver.currentFunction = null; } if (method != null) { resolver.currentMethod = method; if (method.IsGhost) { resolver.PushGhost(); } method.TypeArgs.ForEach(p => resolver.PushTypeParam(p)); method.Formals.ForEach(x => { x.Resolve(resolver); }); method.Outs.ForEach(x => { x.Resolve(resolver); }); method.TypeArgs.ForEach(p => resolver.PopTypeParam(p)); if (method.IsGhost) { resolver.PopGhost(); } resolver.currentMethod = null; } } foreach (MemberDecl member in ClassDecl.TheClass.Members) { Function fun = member as Function; Method method = member as Method; if (fun != null) { resolver.currentFunction = fun; resolver.PushGhost(); fun.TypeArgs.ForEach(p => resolver.PushTypeParam(p)); fun.Formals.ForEach(x => { resolver.PushVar(x.Name, x.Type, true); }); fun.ResultType.Resolve(resolver); fun.Req = fun.Req.ConvertAll(e => e.Resolve(resolver, Type.Bool)); fun.Ens = fun.Ens.ConvertAll(e => e.Resolve(resolver, Type.Bool)); fun.Decreases.Resolve(resolver); if (fun.Body != null) { fun.Body = fun.Body.Resolve(resolver, fun.ResultType); } if (fun.IsRecursive && fun.Decreases.Expressions.Count == 0) { fun.Decreases.Expressions.Add(new IdentifierExpr(Token.NoToken, fun.Formals[0].Name)); fun.Decreases.Resolve(resolver); } fun.Formals.ForEach(x => resolver.PopVar(x.Name)); fun.TypeArgs.ForEach(p => resolver.PopTypeParam(p)); resolver.PopGhost(); resolver.currentFunction = null; } if (method != null) { resolver.currentMethod = method; if (method.IsGhost) { resolver.PushGhost(); } method.TypeArgs.ForEach(p => resolver.PushTypeParam(p)); method.Formals.ForEach(x => { resolver.PushVar(x.Name, x.Type, true); }); method.Req.ForEach(e => e.Resolve(resolver)); method.Outs.ForEach(x => { resolver.PushVar(x.Name, x.Type, true); }); method.Ens.ForEach(e => e.Resolve(resolver)); method.Decreases.Resolve(resolver); method.Outs.ForEach(x => resolver.PopVar(x.Name)); method.Formals.ForEach(x => resolver.PopVar(x.Name)); method.TypeArgs.ForEach(p => resolver.PopTypeParam(p)); if (method.IsGhost) { resolver.PopGhost(); } resolver.currentMethod = null; } } } catch (Exception e) { string ctxt = (resolver.currentMethod != null) ? "in method " + resolver.currentMethod.Name + ": ": (resolver.currentFunction != null) ? "in function " + resolver.currentFunction.Name + ": ": ""; throw new Exception(ctxt, e); } }
public override void Visit(DatatypeDecl datatypeDeclaration) { VisitTopLevelDeclarationWithMembers(datatypeDeclaration, () => base.Visit(datatypeDeclaration)); }