예제 #1
0
    public void TestTokenProperties()
    {
        IdentifierToken  host   = new IdentifierToken("KeyedAccess");
        KeyedAccessToken result = new KeyedAccessToken(0, host);

        Assert.AreEqual(host, result.Host);
    }
예제 #2
0
    public override bool Equals(object other, bool includeChildren)
    {
        if (!base.Equals(other, includeChildren))
        {
            return(false);
        }

        KeyedAccessToken otherToken = (KeyedAccessToken)other;

        if (Host != null)
        {
            return(Host.Equals(otherToken.Host));
        }
        else
        {
            return(otherToken.Host == null);
        }
    }
예제 #3
0
    public void TestValidStartKeyedAccess()
    {
        InitCompiler("host['fred']", 4);
        IdentifierToken host = new IdentifierToken("host", 0);

        compiler.Parent.AddChild(host);

        Assert.IsTrue(parser.Parse(compiler));

        Assert.AreEqual(12, compiler.Pos);
        Assert.AreEqual(1, root.Children.Count);

        KeyedAccessToken expected = new KeyedAccessToken(4, host);

        expected.AddChild(new StringToken("fred", 5));
        Assert.AreEqual(expected, root.Children[0]);

        Assert.AreSame(root, compiler.Parent);
    }
예제 #4
0
    public void TestValidStartMemberKeyedAccess()
    {
        InitCompiler("host.property[123]", 13);
        PropertyAccessToken propertyAccess = new PropertyAccessToken(4,
                                                                     new IdentifierToken("host", 0),
                                                                     new IdentifierToken("property", 5));

        compiler.Parent.AddChild(propertyAccess);

        Assert.IsTrue(parser.Parse(compiler));

        Assert.AreEqual(18, compiler.Pos);
        Assert.AreEqual(1, root.Children.Count);

        KeyedAccessToken expected = new KeyedAccessToken(13, propertyAccess);

        expected.AddChild(new IntegerToken(123, 14));
        Assert.AreEqual(expected, root.Children[0]);

        Assert.AreSame(root, compiler.Parent);
    }
예제 #5
0
    public override bool Parse(ExpressionCompiler compiler)
    {
        int symbolPos = compiler.Pos;

        if (!base.Parse(compiler))
        {
            return(false);
        }

        // Must have a left-hand side...
        if (compiler.Parent.Children.Count == 0)
        {
            // Reset the compiler position
            compiler.Pos = symbolPos;
            throw new ParserException("keyedAccess", symbolPos, "Missing left-hand operand");
        }
        TokenImpl lhs = compiler.Parent.PopChild();

        // See if we can handle the lhs
        KeyedAccessToken keyedAccess = null;

        if (lhs is HostSupport)
        {
            keyedAccess = new KeyedAccessToken(symbolPos, lhs);
            compiler.Parent.AddChild(keyedAccess);
        }
        else if (lhs is BinaryToken)
        {
            // If the RHS of the binary token is token which allows Hosting we can join to and replace it
            BinaryToken binaryLhs = (BinaryToken)lhs;
            TokenImpl   lhsRhs    = binaryLhs.Rhs;

            if (lhsRhs is HostSupport)
            {
                // We can join it
                keyedAccess   = new KeyedAccessToken(symbolPos, lhsRhs);
                binaryLhs.Rhs = keyedAccess;

                compiler.Parent.AddChild(binaryLhs);
            }
        }
        else if (lhs is UnaryToken)
        {
            // If the RHS of the unary token is which which allows Hosting we can join to and replace it
            UnaryToken unaryLhs = (UnaryToken)lhs;
            TokenImpl  lhsRhs   = unaryLhs.Rhs;

            if (lhsRhs is HostSupport)
            {
                // We can join it
                keyedAccess  = new KeyedAccessToken(symbolPos, lhsRhs);
                unaryLhs.Rhs = keyedAccess;

                compiler.Parent.AddChild(unaryLhs);
            }
        }

        // Throw an exception if we couldn't cope with the lhs.
        if (keyedAccess == null)
        {
            // Restore the lhs and position
            compiler.Parent.AddChild(lhs);
            compiler.Pos = symbolPos;

            throw new ParserException("keyedAccess", symbolPos, $"Left-hand side of a keyed access token cannot be: {lhs.Name}");
        }

        // The keyed access becomes the new parent token
        compiler.ParentTokens.Push(keyedAccess);

        // Keep parsing until we are closed
        while (!keyedAccess.IsClosed)
        {
            if (!compiler.ParseNextToken())
            {
                throw new ParserException(keyedAccess, "Unclosed keyed access");
            }
        }

        return(true);
    }