public EnumerationFieldNode(ParseNodeList attributes, AtomicNameNode name, ParseNode value) : base(ParseNodeType.EnumerationFieldDeclaration, name.token) { _attributes = GetParentedNodeList(AttributeNode.GetAttributeList(attributes)); _name = (AtomicNameNode)GetParentedNode(name); if (value is LiteralNode) { LiteralNode literalNode = (LiteralNode)value; _value = ((LiteralToken)literalNode.Token).LiteralValue; } else { // TODO: Clearly we need something more general... // C# allows expressions. Likely expressions to be used // include negative values, binary OR'd values, // expressions involving other enum members (esp. hard to deal with) // For now, just adding support for negative numbers, as // everything else can be worked around in source code. UnaryExpressionNode expressionNode = value as UnaryExpressionNode; if ((expressionNode != null) && (expressionNode.Operator == TokenType.Minus) && (expressionNode.Child is LiteralNode)) { try { LiteralToken literalToken = (LiteralToken)((LiteralNode)expressionNode.Child).Token; int numericValue = (int)Convert.ChangeType(literalToken.LiteralValue, typeof(int)); _value = -numericValue; } catch { } } } }
private Expression ProcessUnaryExpressionNode(UnaryExpressionNode node) { Operator operatorType = Operator.Invalid; switch (node.Operator) { case TokenType.PlusPlus: operatorType = Operator.PostIncrement; break; case TokenType.MinusMinus: operatorType = Operator.PostDecrement; break; case TokenType.Tilde: case TokenType.Bang: operatorType = OperatorConverter.OperatorFromToken(node.Operator); break; case TokenType.Minus: operatorType = Operator.Negative; break; case TokenType.Plus: operatorType = Operator.Plus; break; default: Debug.Fail("Unhandled unary expression with operator " + node.Operator); break; } if (operatorType != Operator.Invalid) { Expression childExpression = BuildExpression(node.Child); if (childExpression is MemberExpression) { childExpression = TransformMemberExpression((MemberExpression)childExpression); } if (operatorType == Operator.Plus) { return childExpression; } return new UnaryExpression(operatorType, childExpression); } return null; }
private ParseNode ParsePrimaryExpression() { ParseNode expr; switch (PeekType()) { case TokenType.Null: case TokenType.True: case TokenType.False: case TokenType.Literal: expr = new LiteralNode(NextToken()); break; case TokenType.OpenParen: Eat(TokenType.OpenParen); expr = ParseExpression(); if (expr is ExpressionNode) { ((ExpressionNode)expr).AddParenthesisHint(); } Eat(TokenType.CloseParen); break; case TokenType.New: expr = ParseNew(); break; case TokenType.Typeof: { Token token = NextToken(); Eat(TokenType.OpenParen); expr = new TypeofNode(token, ParseReturnType()); Eat(TokenType.CloseParen); break; } case TokenType.Sizeof: { Token token = NextToken(); Eat(TokenType.OpenParen); expr = new SizeofNode(token, ParseType()); Eat(TokenType.CloseParen); break; } case TokenType.Checked: case TokenType.Unchecked: { Token token = NextToken(); Eat(TokenType.OpenParen); expr = new UnaryExpressionNode(token, ParseExpression()); Eat(TokenType.CloseParen); break; } case TokenType.This: expr = new ThisNode(NextToken()); break; case TokenType.Base: expr = new BaseNode(NextToken()); if (PeekType() != TokenType.Dot && PeekType() != TokenType.OpenSquare) { this.ReportError(ParseError.BadBaseExpression); } break; case TokenType.Identifier: expr = ParseAliasQualifiedName(true); break; case TokenType.Delegate: expr = ParseAnonymousMethod(); break; default: if (Token.IsPredefinedType(PeekType()) && PeekType() != TokenType.Void) { expr = ParsePredefinedType(); CheckType(TokenType.Dot); } else { ReportError(ParseError.ExpressionExpected); expr = ParseIdentifier(); } break; } // postfix operators bool foundPostfix = true; do { Token token = PeekToken(); switch (PeekType()) { case TokenType.Dot: if (PeekType(1) == TokenType.Default) { expr = new DefaultValueNode(expr); Eat(TokenType.Dot); Eat(TokenType.Default); } else expr = new BinaryExpressionNode(expr, NextToken().Type, ParseSimpleName(true)); break; case TokenType.OpenParen: expr = new BinaryExpressionNode(expr, token.Type, ParseParenArgumentList()); break; case TokenType.PlusPlus: case TokenType.MinusMinus: expr = new BinaryExpressionNode(expr, NextToken().Type, null); break; case TokenType.OpenSquare: expr = new BinaryExpressionNode(expr, NextToken().Type, ParseExpressionList(TokenType.CloseSquare)); Eat(TokenType.CloseSquare); break; case TokenType.Arrow: expr = new BinaryExpressionNode(expr, NextToken().Type, ParseIdentifier()); break; default: foundPostfix = false; break; } } while (foundPostfix); return expr; }