protected override TokenImpl CreateToken(ExpressionCompiler compiler, int symbolPos, TokenImpl lhs, TokenImpl rhs) { if (!(rhs is IdentifierToken)) { throw new ParserException(Name, symbolPos, "Right-hand side of a property access token must be an identifier"); } // The lhs must be a token which supports Hosting. If it's not see if we can do anything if (lhs is HostSupport) { return(new PropertyAccessToken(symbolPos, lhs, (IdentifierToken)rhs)); } else if (lhs is BinaryToken) { // If the RHS of the binary token is a token which allows hosting we can join to it BinaryToken binaryLhs = (BinaryToken)lhs; TokenImpl lhsRhs = binaryLhs.Rhs; if (lhsRhs is HostSupport) { // We can join... binaryLhs.Rhs = new PropertyAccessToken(symbolPos, lhsRhs, (IdentifierToken)rhs); return(binaryLhs); } } else if (lhs is UnaryToken) { // If the RHS of the unary token is a token 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 unaryLhs.Rhs = new PropertyAccessToken(symbolPos, lhsRhs, (IdentifierToken)rhs); return(unaryLhs); } } // Can't work with the lhs throw new ParserException(Name, symbolPos, $"Left-hand side of a property access token cannot be: {lhs.Name}"); }
public override bool Equals(object obj, bool includeChildren) { if (!base.Equals(obj, includeChildren)) { return(false); } UnaryToken other = (UnaryToken)obj; if (Rhs != null) { if (!Rhs.Equals(other.Rhs)) { return(false); } } else if (other.Rhs != null) { return(false); } return(true); }
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; // We don't throw an exception so the compiler will then check to see // if the symbol represents a group instead return(false); } TokenImpl lhs = compiler.Parent.PopChild(); FunctionToken function = null; if (lhs is HostSupport) { function = new FunctionToken(symbolPos, lhs); compiler.Parent.AddChild(function); } else if (lhs is BinaryToken) { // If the RHS of the binary token is token which supports hosting we can join to and replace it BinaryToken binaryLhs = (BinaryToken)lhs; TokenImpl lhsRhs = binaryLhs.Rhs; if (lhsRhs is HostSupport) { // We can join it function = new FunctionToken(symbolPos, lhsRhs); binaryLhs.Rhs = function; compiler.Parent.AddChild(binaryLhs); } } else if (lhs is UnaryToken) { // If the RHS of the unary token is token which supports hosting we can join to and replace it UnaryToken unaryLhs = (UnaryToken)lhs; TokenImpl lhsRhs = unaryLhs.Rhs; if (lhsRhs is HostSupport) { // We can join it function = new FunctionToken(symbolPos, lhsRhs); unaryLhs.Rhs = function; compiler.Parent.AddChild(unaryLhs); } } if (function == null) { // Restore the lhs and position compiler.Parent.AddChild(lhs); compiler.Pos = symbolPos; // Couldn't handle the lhs, just return false to continue to parse as a group return(false); } // The function becomes the new parent token compiler.ParentTokens.Push(function); // Keep parsing until we are closed while (!function.IsClosed) { if (!compiler.ParseNextToken()) { throw new ParserException(function, "Unclosed function"); } } return(true); }
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); }