示例#1
0
        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);
        }
示例#2
0
        protected override TargetWriter CreateIIFE(string source, Type sourceType, Bpl.IToken sourceTok, Type resultType, Bpl.IToken resultTok, string bvName, TargetWriter wr)
        {
            var w = wr.NewNamedBlock("function ({0})", bvName);

            w.SetBraceStyle(BlockTargetWriter.BraceStyle.Space, BlockTargetWriter.BraceStyle.Nothing);
            w.Indent();
            w.Write("return ");
            w.BodySuffix = ";" + w.NewLine;

            wr.Write("({0})", source);
            return(w);
        }
示例#3
0
        // ----- 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);
            }
        }
示例#4
0
        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");
                }
            }
        }