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 void DeclareLocalVar(string name, Type /*?*/ type, Bpl.IToken /*?*/ tok, Expression rhs, bool inLetExprBody, TargetWriter wr) { wr.Indent(); wr.Write("let {0} = ", name); TrExpr(rhs, wr, inLetExprBody); wr.WriteLine(";"); }
// ----- Statements ------------------------------------------------------------- protected override void EmitPrintStmt(TargetWriter wr, Expression arg) { wr.Indent(); wr.Write("process.stdout.write("); TrParenExpr(arg, wr, false); wr.WriteLine(".toString());"); }
protected override BlockTargetWriter CreateForLoop(string indexVar, string bound, TargetWriter wr) { wr.Indent(); var w = wr.NewNamedBlock("for (let {0} = 0; {0} < {1}; {0}++)", indexVar, bound); 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); }
// ----- Statements ------------------------------------------------------------- protected override void EmitPrintStmt(TargetWriter wr, Expression arg) { wr.Indent(); wr.Write("console.log("); TrExpr(arg, wr, false); wr.WriteLine(");"); }
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); }
// ----- Declarations ------------------------------------------------------------- protected override void DeclareField(string name, bool isStatic, bool isConst, Type type, Bpl.IToken tok, string rhs, TargetWriter wr) { wr.Indent(); if (isStatic) { var w = wr.NewNamedBlock("static get {0}()", name); EmitReturnExpr(rhs, w); } else { wr.WriteLine("this.{0} = {1};", name, rhs); } }
protected override void EmitOutParameterSplits(string outCollector, List <string> actualOutParamNames, TargetWriter wr) { if (actualOutParamNames.Count == 1) { EmitAssignment(actualOutParamNames[0], outCollector, wr); } else { for (var i = 0; i < actualOutParamNames.Count; i++) { wr.Indent(); wr.WriteLine("{0} = {1}[{2}];", actualOutParamNames[i], outCollector, i); } } }
protected override void EmitReturn(List <Formal> outParams, TargetWriter wr) { wr.Indent(); if (outParams.Count == 0) { wr.WriteLine("return;"); } else if (outParams.Count == 1) { wr.WriteLine("return {0};", IdName(outParams[0])); } else { wr.WriteLine("return [{0}];", Util.Comma(outParams, IdName)); } }
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 void DeclareLocalVar(string name, Type /*?*/ type, Bpl.IToken /*?*/ tok, bool leaveRoomForRhs, string /*?*/ rhs, TargetWriter wr) { wr.Indent(); wr.Write("let {0}", name); if (leaveRoomForRhs) { Contract.Assert(rhs == null); // follows from precondition } else if (rhs != null) { wr.WriteLine(" = {0};", rhs); } else { wr.WriteLine(";"); } }
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 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"); } } }
protected override void EmitJumpToTailCallStart(TargetWriter wr) { wr.Indent(); wr.WriteLine("continue TAIL_CALL_START;"); }
protected override void EmitAbsurd(TargetWriter wr) { wr.Indent(); wr.WriteLine("throw new Error('unexpected control point');"); }
protected override void EmitYield(TargetWriter wr) { wr.Indent(); wr.WriteLine("yield null;"); }
protected override void EmitBreak(string label, TargetWriter wr) { wr.Indent(); wr.WriteLine("break {0};", label); }