protected override BlockTargetWriter /*?*/ CreateGetterSetter(string name, Type resultType, Bpl.IToken tok, bool isStatic, bool createBody, out TargetWriter setterWriter, TargetWriter wr) { if (createBody) { wr.Indent(); wr.Write("{0}get {1}()", isStatic ? "static " : "", name); var wGet = wr.NewBlock("", ";"); if (!isStatic) { wGet.Indent(); wGet.WriteLine("let _this = this;"); } wr.Indent(); wr.Write("{0}set {1}(value)", isStatic ? "static " : "", name); var wSet = wr.NewBlock("", ";"); if (!isStatic) { wSet.Indent(); wSet.WriteLine("let _this = this;"); } setterWriter = wSet; return(wGet); } else { setterWriter = null; return(null); } }
protected override BlockTargetWriter CreateInternalClass(TargetWriter wr, string className) { var w = wr.NewBlock("{0}:", className); w.Footer = ","; return(w); }
protected override BlockTargetWriter /*?*/ CreateMethod(Method m, bool createBody, TargetWriter wr) { if (!createBody) { return(null); } wr.Indent(); wr.Write("{0}{1}(", m.IsStatic ? "static " : "", IdName(m)); int nIns = WriteFormals("", m.Ins, wr); var w = wr.NewBlock(")"); if (!m.IsStatic) { w.Indent(); w.WriteLine("let _this = this;"); } if (m.IsTailRecursive) { w.Indent(); w = w.NewBlock("TAIL_CALL_START: while (true)"); } var r = new TargetWriter(w.IndentLevel); EmitReturn(m.Outs, r); w.BodySuffix = r.ToString(); return(w); }
protected override BlockTargetWriter CreateMethod(TargetWriter wrx, Method m) { var wr = wrx.NewBlock(""); wr.SetBraceStyle(BlockTargetWriter.BraceStyle.Newline, BlockTargetWriter.BraceStyle.Newline); var dllSw = new StringWriter(); var hasDllImportAttribute = ProcessDllImport(m, dllSw); wr.AppendHeader(dllSw.ToString()); string targetReturnTypeReplacement = null; if (hasDllImportAttribute) { wr.AppendHeader(wrx.IndentString); foreach (var p in m.Outs) { if (!p.IsGhost) { if (targetReturnTypeReplacement == null) { targetReturnTypeReplacement = TypeName(p.Type, wr, p.tok); } else if (targetReturnTypeReplacement != null) { // there's more than one out-parameter, so bail targetReturnTypeReplacement = null; break; } } } } var sw = new StringWriter(); sw.Write("public {0}{1}{3} @{2}", m.IsStatic ? "static " : "", hasDllImportAttribute ? "extern " : "", m.CompileName, targetReturnTypeReplacement ?? "void"); if (m.TypeArgs.Count != 0) { sw.Write("<{0}>", TypeParameters(m.TypeArgs)); } sw.Write("("); int nIns = WriteFormals("", m.Ins, sw); if (targetReturnTypeReplacement == null) { WriteFormals(nIns == 0 ? "" : ", ", m.Outs, sw); } sw.Write(")"); wr.AppendHeader(sw.ToString()); if (hasDllImportAttribute) { wr.DropBody(); wr.SetBraceStyle(BlockTargetWriter.BraceStyle.Nothing, BlockTargetWriter.BraceStyle.Newline); } return(wr); }
protected override BlockTargetWriter CreateClass(string name, List <TypeParameter> /*?*/ typeParameters, List <Type> /*?*/ superClasses, Bpl.IToken tok, out TargetWriter instanceFieldsWriter, TargetWriter wr) { wr.Indent(); var w = wr.NewBlock(string.Format("$module.{0} = class {0}", name), ";"); w.Indent(); instanceFieldsWriter = w.NewBlock("constructor ()"); return(w); }
protected override BlockTargetWriter CreateTrait(string name, List <Type> /*?*/ superClasses, Bpl.IToken tok, out TargetWriter instanceFieldsWriter, out TargetWriter staticMemberWriter, TargetWriter wr) { wr.Indent(); var w = wr.NewBlock(string.Format("$module.{0} = class {0}", IdProtect(name)), ";"); w.Indent(); instanceFieldsWriter = w.NewBlock("constructor ()"); staticMemberWriter = w; return(w); }
protected override BlockTargetWriter CreateLambda(List <Type> inTypes, Bpl.IToken tok, List <string> inNames, Type resultType, TargetWriter wr) { wr.Write("function ("); Contract.Assert(inTypes.Count == inNames.Count); // guaranteed by precondition for (var i = 0; i < inNames.Count; i++) { wr.Write("{0}{1}", i == 0 ? "" : ", ", inNames[i]); } var w = wr.NewBlock(")"); w.SetBraceStyle(BlockTargetWriter.BraceStyle.Space, BlockTargetWriter.BraceStyle.Nothing); return(w); }
protected override BlockTargetWriter CreateClass(TargetWriter wr, ClassDecl cl) { var w = wr.NewBlock("public partial class @{0}", cl.CompileName); if (cl.TypeArgs.Count != 0) { w.AppendHeader("<{0}>", TypeParameters(cl.TypeArgs)); } string sep = " : "; foreach (var trait in cl.TraitsTyp) { w.AppendHeader("{0}{1}", sep, TypeName(trait, w, cl.tok)); sep = ", "; } return(w); }
protected override BlockTargetWriter /*?*/ CreateFunction(string name, List <TypeParameter> /*?*/ typeArgs, List <Formal> formals, Type resultType, Bpl.IToken tok, bool isStatic, bool createBody, MemberDecl member, TargetWriter wr) { if (!createBody) { return(null); } wr.Indent(); wr.Write("{0}{1}(", isStatic ? "static " : "", name); int nIns = WriteFormals("", formals, wr); var w = wr.NewBlock(")", ";"); if (!isStatic) { w.Indent(); w.WriteLine("let _this = this;"); } return(w); }
protected override BlockTargetWriter /*?*/ CreateGetter(string name, Type resultType, Bpl.IToken tok, bool isStatic, bool createBody, TargetWriter wr) { if (createBody) { wr.Indent(); wr.Write("{0}get {1}()", isStatic ? "static " : "", name); var w = wr.NewBlock("", ";"); if (!isStatic) { w.Indent(); w.WriteLine("let _this = this;"); } return(w); } else { return(null); } }
protected override BlockTargetWriter CreateInternalClass(TargetWriter wr, string className) { var w = wr.NewBlock("internal class {0}", className); return(w); }
protected override BlockTargetWriter CreateMethod(TargetWriter wr, Method m) { return(wr.NewBlock("{0}: function()", m.CompileName)); }
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"); } } }