/// <summary>
        /// Pushes the parameters of a new declaration site into a new scope in the symbol table.
        /// </summary>
        /// <param name="parameters">Parameters of the declaration site.</param>
        protected override void Push(IEnumerable <ParameterExpression> parameters)
        {
            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }

            _symbolTable.Push();

            foreach (var parameter in parameters)
            {
                _symbolTable.Add(parameter, GetState(parameter));
            }
        }
        private void PushCore(IEnumerable <KeyValuePair <ParameterExpression, TState> > scope)
        {
            _symbolTable.Push();

            foreach (var entry in scope)
            {
                _symbolTable.Add(entry.Key, entry.Value);
            }
        }
Ejemplo n.º 3
0
        public void ScopedSymbolTable_Basics()
        {
            var res = default(Indexed <Indexed <string> >);

            var sst = new ScopedSymbolTable <string, string>
            {
                { "glb", "val" }
            };

            var assertGlobal = new Action(() =>
            {
                Assert.IsTrue(sst.TryLookup("glb", out res));
                Assert.AreEqual(-1, res.Index);
                Assert.AreEqual(0, res.Value.Index);
                Assert.AreEqual("val", res.Value.Value);

                Assert.IsFalse(sst.TryLookup("blg", out res));
            });

            assertGlobal();

            AssertPushPop(sst,
                          () =>
            {
                assertGlobal();

                Assert.IsFalse(sst.TryLookup("bar", out res));
            },
                          () =>
            {
                sst.Add("bar", "foo");
                sst.Add("baz", "qux");

                AssertPushPop(sst,
                              () =>
                {
                    assertGlobal();

                    Assert.IsTrue(sst.TryLookup("bar", out res));
                    Assert.AreEqual(0, res.Index);
                    Assert.AreEqual(0, res.Value.Index);
                    Assert.AreEqual("foo", res.Value.Value);

                    Assert.IsTrue(sst.TryLookup("baz", out res));
                    Assert.AreEqual(0, res.Index);
                    Assert.AreEqual(1, res.Value.Index);
                    Assert.AreEqual("qux", res.Value.Value);
                },
                              () =>
                {
                    sst.Add("foo", "bar");
                    sst.Add("bar", "qux");

                    AssertPushPop(sst,
                                  () =>
                    {
                        assertGlobal();

                        Assert.IsTrue(sst.TryLookup("foo", out res));
                        Assert.AreEqual(0, res.Index);
                        Assert.AreEqual(0, res.Value.Index);
                        Assert.AreEqual("bar", res.Value.Value);

                        Assert.IsTrue(sst.TryLookup("bar", out res));
                        Assert.AreEqual(0, res.Index);
                        Assert.AreEqual(1, res.Value.Index);
                        Assert.AreEqual("qux", res.Value.Value);

                        Assert.IsTrue(sst.TryLookup("baz", out res));
                        Assert.AreEqual(1, res.Index);
                        Assert.AreEqual(1, res.Value.Index);
                        Assert.AreEqual("qux", res.Value.Value);
                    },
                                  () =>
                    {
                        sst.Add("qux", "baz");

                        AssertPushPop(sst,
                                      () =>
                        {
                            assertGlobal();

                            Assert.IsTrue(sst.TryLookup("qux", out res));
                            Assert.AreEqual(0, res.Index);
                            Assert.AreEqual(0, res.Value.Index);
                            Assert.AreEqual("baz", res.Value.Value);

                            Assert.IsTrue(sst.TryLookup("foo", out res));
                            Assert.AreEqual(1, res.Index);
                            Assert.AreEqual(0, res.Value.Index);
                            Assert.AreEqual("bar", res.Value.Value);

                            Assert.IsTrue(sst.TryLookup("bar", out res));
                            Assert.AreEqual(1, res.Index);
                            Assert.AreEqual(1, res.Value.Index);
                            Assert.AreEqual("qux", res.Value.Value);

                            Assert.IsTrue(sst.TryLookup("baz", out res));
                            Assert.AreEqual(2, res.Index);
                            Assert.AreEqual(1, res.Value.Index);
                            Assert.AreEqual("qux", res.Value.Value);
                        },
                                      () =>
                        {
                            // NOTE: The test method pushes a frame before entering, so we're off by 1 for the outer indices.

                            Assert.IsNotNull(((IEnumerable)sst).GetEnumerator());

                            var symbols = sst.SelectMany(ist => ist.Value, (o, i) => (Outer: o.Index, Inner: i.Index, Symbol: i.Value.Key, i.Value.Value)).ToArray();

                            Assert.IsTrue(symbols.SequenceEqual(new[]
                            {
                                (Outer: 1, Inner: 0, Symbol: "qux", Value: "baz"),
                                (Outer: 2, Inner: 0, Symbol: "foo", Value: "bar"),
                                (Outer: 2, Inner: 1, Symbol: "bar", Value: "qux"),
                                (Outer: 3, Inner: 0, Symbol: "bar", Value: "foo"),
                                (Outer: 3, Inner: 1, Symbol: "baz", Value: "qux"),
                                (Outer: -1, Inner: 0, Symbol: "glb", Value: "val"),
                            }));