public TruDef(string name, TruExpr body)
 {
     this.name = name; this.body = body;
 }
 public TruLambda(string[] parameters, TruExpr body)
 {
     this.parameters = parameters;
     this.body       = body;
 }
        public Environment env; // closures.

        public TruFunc(string[] parameters, TruExpr body, Environment env)
        {
            this.parameters = parameters;
            this.body       = body;
            this.env        = env;
        }
 public TruCall(TruExpr func, TruExpr[] args)
 {
     this.func = func; this.args = args;
 }
        public void TestTruEquals()
        {
            Assert.IsTrue(new TruBool(true).Equals(new TruBool(true)));
            Assert.IsFalse(new TruBool(true).Equals(new TruBool(false)));
            Assert.IsFalse(new TruBool(true).Equals(null));

            Assert.IsTrue(new TruId("x").Equals(new TruId("x")));
            Assert.IsFalse(new TruId("x").Equals(new TruId("t")));

            Assert.IsTrue(TruLibrary.Library.Find("and").Equals(TruLibrary.Library.Find("and")));
            Assert.IsFalse(TruLibrary.Library.Find("and").Equals(TruLibrary.Library.Find("or")));

            TruLambda lamb0 = new TruLambda(new string[] { "x" }, new TruId("x"));
            TruLambda lamb1 = new TruLambda(new string[] { "x" }, new TruId("x"));
            TruLambda lamb2 = new TruLambda(new string[] {}, new TruId("x"));
            TruLambda lamb3 = new TruLambda(new string[] { "y" }, new TruId("x"));
            TruLambda lamb4 = new TruLambda(new string[] { "x" }, new TruId("y"));

            Assert.IsTrue(lamb0.Equals(lamb1));
            Assert.IsFalse(lamb0.Equals(lamb2));
            Assert.IsFalse(lamb0.Equals(lamb3));
            Assert.IsFalse(lamb0.Equals(lamb4));


            TruCall call0 = new TruCall(new TruId("and"), new TruExpr[] {
                new TruBool(true),
                new TruCall(new TruId("not"), new TruExpr[] {
                    new TruBool(false)
                })
            });
            TruCall call1 = new TruCall(new TruId("and"), new TruExpr[] {
                new TruBool(true),
                new TruCall(new TruId("not"), new TruExpr[] {
                    new TruBool(false)
                })
            });
            TruCall call2 = new TruCall(new TruId("and"), new TruExpr[] {
                new TruBool(true),
                new TruCall(new TruId("not"), new TruExpr[] {
                    new TruBool(true)
                })
            });
            TruCall call3 = new TruCall(new TruId("nand"), new TruExpr[] {
                new TruBool(true),
                new TruCall(new TruId("not"), new TruExpr[] {
                    new TruBool(false)
                })
            });

            Assert.IsTrue(call0.Equals(call1));
            Assert.IsFalse(call0.Equals(call2));
            Assert.IsFalse(call0.Equals(call3));

            TruExpr let0 = TruExpr.Parse("{let {[a false]} a}");
            TruExpr let1 = TruExpr.Parse("{let {[a false]} a}");
            TruExpr let2 = TruExpr.Parse("{let {} true}");

            Assert.IsTrue(let0.Equals(let1));
            Assert.IsFalse(let0.Equals(let2));

            TruStatement def0 = TruStatement.Parse("{define x true}");
            TruStatement def1 = TruStatement.Parse("{define x true}");
            TruStatement def2 = TruStatement.Parse("{define x false}");

            Assert.IsTrue(def0.Equals(def1));
            Assert.IsFalse(def0.Equals(def2));
        }