public BinaryOperatorExpression(Expression left, BinaryOperatorLiteral op, Expression right, TextSpan textSpan) : base(textSpan) { Left = left; Operator = op; Right = right; }
public override Ust VisitConditionalAccessExpression(ConditionalAccessExpressionSyntax node) { Ust ustNode = base.Visit(node.Expression); Expression expression = ustNode as Expression; if (expression == null) { expression = new MultichildExpression(((ArgsUst)ustNode).Collection, ustNode.TextSpan); } Expression whenNotNullExpression; if (node.WhenNotNull is ElementBindingExpressionSyntax) { var args = (ArgsUst)VisitElementBindingExpression((ElementBindingExpressionSyntax)node.WhenNotNull); whenNotNullExpression = new IndexerExpression(expression, args, args.TextSpan); } else { whenNotNullExpression = (Expression)base.Visit(node.WhenNotNull); } var nullExpr = new NullLiteral(default(TextSpan)); var binayOpLiteral = new BinaryOperatorLiteral(BinaryOperator.Equal, default(TextSpan)); var condition = new BinaryOperatorExpression(expression, binayOpLiteral, nullExpr, default(TextSpan)); var result = new ConditionalExpression(condition, nullExpr, whenNotNullExpression, node.GetTextSpan()); return(result); }
public UstNode VisitComparisonExpression([NotNull] DslParser.ComparisonExpressionContext context) { var left = (Expression)VisitExpression(context.expression(0)); var right = (Expression)VisitExpression(context.expression(1)); var opLiteral = new BinaryOperatorLiteral(BinaryOperatorLiteral.TextBinaryOperator[context.op.Text], context.op.GetTextSpan(), null); var result = new BinaryOperatorExpression(left, opLiteral, right, context.GetTextSpan(), null); return(result); }
protected Ust CreateBinaryOperatorExpression(BinaryExpressionSyntax node) { var left = (Expression)base.Visit(node.Left); var op = new BinaryOperatorLiteral(node.OperatorToken.ValueText, node.OperatorToken.GetTextSpan()); var right = (Expression)base.Visit(node.Right); var result = new BinaryOperatorExpression(left, op, right, node.GetTextSpan()); return(result); }
public static AssignmentExpression ConvertToAssignmentExpression( Expression left, BinaryOperator op, TextSpan opSpan, Expression right, TextSpan textSpan, FileNode fileNode) { var opLiteral = new BinaryOperatorLiteral(op, opSpan, fileNode); var expression = new BinaryOperatorExpression(left, opLiteral, right, textSpan, fileNode); var result = new AssignmentExpression(left, expression, textSpan, fileNode); return(result); }
public UstNode VisitBinaryOperatorExpression(DslParser.BinaryOperatorExpressionContext context) { var left = (Expression)VisitExpression(context.expression(0)); var literal = new BinaryOperatorLiteral(context.op.Text, context.op.GetTextSpan(), null); var right = (Expression)VisitExpression(context.expression(1)); var textSpan = context.GetTextSpan(); var result = new BinaryOperatorExpression(left, literal, right, textSpan, null); return(result); }
public static AssignmentExpression CreateAssignExpr(Expression left, Expression right, TextSpan textSpan, string assignExprOpText, TextSpan assignOpTextSpan) { BinaryOperatorLiteral binaryOperator = null; if (assignExprOpText != null && assignExprOpText.Length > 1) { var operatorText = assignExprOpText.Remove(assignExprOpText.Length - 1); binaryOperator = new BinaryOperatorLiteral(operatorText, assignOpTextSpan); } return(new AssignmentExpression(left, right, textSpan) { Operator = binaryOperator }); }
public override Ust Visit(BinaryOperatorExpression binaryOperatorExpression) { Expression result = null; Expression leftExpression = (Expression)Visit(binaryOperatorExpression.Left); BinaryOperatorLiteral op = (BinaryOperatorLiteral)Visit(binaryOperatorExpression.Operator); Expression rightExpression = (Expression)Visit(binaryOperatorExpression.Right); if (leftExpression is StringLiteral leftString && rightExpression is StringLiteral rightString) { if (op.BinaryOperator == BinaryOperator.Plus || op.BinaryOperator == BinaryOperator.Concat) { string resultText = leftString.Text + rightString.Text; result = new StringLiteral(resultText); Logger.LogDebug($"Strings {binaryOperatorExpression} has been concatenated to \"{resultText}\" at {binaryOperatorExpression.TextSpan}"); } }
public override UstNode VisitBinaryExpression(BinaryExpressionSyntax node) { if (node.OperatorToken.ValueText == "is") // x is y -> (y)x != null { var type = ConvertType(base.Visit(node.Right)); var expression = (Expression)base.Visit(node.Left); var left = new CastExpression(type, expression, node.GetTextSpan(), FileNode); var operatorSpan = node.OperatorToken.GetTextSpan(); var literal = new BinaryOperatorLiteral(BinaryOperator.NotEqual, operatorSpan, FileNode); var right = new NullLiteral(operatorSpan, FileNode); var result = new BinaryOperatorExpression(left, literal, right, node.GetTextSpan(), FileNode); return(result); } if (node.OperatorToken.ValueText == "as") { var type = ConvertType(base.Visit(node.Right)); var expression = (Expression)base.Visit(node.Left); var result = new CastExpression(type, expression, node.GetTextSpan(), FileNode); return(result); } if (node.OperatorToken.ValueText == "??") { var trueExpression = (Expression)base.Visit(node.Left); var operatorSpan = node.OperatorToken.GetTextSpan(); var condition = new BinaryOperatorExpression( trueExpression, new BinaryOperatorLiteral(BinaryOperator.NotEqual, operatorSpan, FileNode), new NullLiteral(operatorSpan, FileNode), operatorSpan, FileNode); var falseExpression = (Expression)base.Visit(node.Right); var result = new ConditionalExpression(condition, trueExpression, falseExpression, node.GetTextSpan(), FileNode); return(result); } else { var result = CreateBinaryOperatorExpression(node); return(result); } }
public Ust VisitExpression(JavaParser.ExpressionContext context) { var textSpan = context.GetTextSpan(); var child0Terminal = context.GetChild(0) as ITerminalNode; Expression target; Expression result; if (child0Terminal != null) { switch (child0Terminal.Symbol.Type) { case JavaParser.NEW: result = (Expression)Visit(context.creator()); return(result); case JavaParser.LPAREN: // '(' type ')' expression var type = (TypeToken)Visit(context.typeType()); target = (Expression)Visit(context.expression(0)); result = new CastExpression(type, target, textSpan); return(result); default: // unary operator ('+', '-', '++', '--', '~', '!') UnaryOperator op = UnaryOperatorLiteral.PrefixTextUnaryOperator[child0Terminal.GetText()]; var opLiteral = new UnaryOperatorLiteral(op, child0Terminal.GetTextSpan()); target = (Expression)Visit(context.expression(0)); result = new UnaryOperatorExpression(opLiteral, target, textSpan); return(result); } } ArgsUst args; var child1Terminal = context.GetChild(1) as ITerminalNode; if (child1Terminal != null) { switch (child1Terminal.Symbol.Type) { case JavaParser.DOT: // '.' target = (Expression)Visit(context.expression(0)); if (context.methodCall() != null) { var invocation = (InvocationExpression)Visit(context.methodCall()); return(new InvocationExpression( new MemberReferenceExpression(target, invocation.Target, target.TextSpan.Union(invocation.Target.TextSpan)), invocation.Arguments, textSpan)); } // TODO: implement base processing Expression rightPart = null; if (context.IDENTIFIER() != null) { rightPart = (IdToken)Visit(context.IDENTIFIER()); } else if (context.THIS() != null) { rightPart = new ThisReferenceToken(context.THIS().GetTextSpan()); } if (rightPart != null) { return(new MemberReferenceExpression(target, rightPart, textSpan)); } if (context.innerCreator() != null) { return(Visit(context.innerCreator())); } if (context.explicitGenericInvocation() != null) { return(VisitChildren(context.explicitGenericInvocation()).ToExpressionIfRequired()); } break; case JavaParser.LBRACK: // '[' target = (Expression)Visit(context.expression(0)); Expression expr = (Expression)Visit(context.expression(1)); args = new ArgsUst(new Expression[] { expr }, expr.TextSpan); result = new IndexerExpression(target, args, textSpan); return(result); case JavaParser.INSTANCEOF: // x instanceof y -> (y)x != null var expression = (Expression)Visit(context.expression(0)); var type = (TypeToken)Visit(context.typeType()); result = new BinaryOperatorExpression(context.GetTextSpan()) { Left = new CastExpression(type, expression, context.GetTextSpan()), Operator = new BinaryOperatorLiteral(BinaryOperator.NotEqual, default), Right = new NullLiteral(default), Root = root }; return(result); case JavaParser.QUESTION: // '?' var condition = (Expression)Visit(context.expression(0)); var trueExpr = (Expression)Visit(context.expression(1)); var falseExpr = (Expression)Visit(context.expression(2)); result = new ConditionalExpression(condition, trueExpr, falseExpr, textSpan); return(result); case JavaParser.COLONCOLON: return(VisitChildren(context)); default: // binary operator var left = (Expression)Visit(context.expression(0)); JavaParser.ExpressionContext expr1 = context.expression(1); if (expr1 != null) { string opText = string.Concat(context.children.Skip(1).Take(context.children.Count - 2)); var right = (Expression)Visit(expr1); // TODO: fix via grammar refactoring (alternative labels). if (opText == "=" || (opText.EndsWith("=") && BinaryOperatorLiteral.TextBinaryOperator.ContainsKey(opText.Remove(opText.Length - 1)))) { result = UstUtils.CreateAssignExpr(left, right, context.GetTextSpan(), opText, child1Terminal.GetTextSpan()); } else { BinaryOperator op = BinaryOperatorLiteral.TextBinaryOperator[opText]; var opLiteral = new BinaryOperatorLiteral(op, child1Terminal.GetTextSpan()); result = new BinaryOperatorExpression(left, opLiteral, right, textSpan); } } else { // post increment or decrement. UnaryOperator op = UnaryOperatorLiteral.PostfixTextUnaryOperator[context.postfix.Text]; var opLiteral = new UnaryOperatorLiteral(op, child1Terminal.GetTextSpan()); result = new UnaryOperatorExpression(opLiteral, left, textSpan); return(result); } return(result); } } return(VisitChildren(context)); }
public UstNode VisitExpression(JavaParser.ExpressionContext context) { var textSpan = context.GetTextSpan(); var child0Terminal = context.GetChild(0) as ITerminalNode; Expression target; Expression result; if (child0Terminal != null) { switch (child0Terminal.Symbol.Type) { case JavaParser.NEW: result = (Expression)Visit(context.creator()); return(result); case JavaParser.LPAREN: // '(' type ')' expression var type = (TypeToken)Visit(context.typeType()); target = (Expression)Visit(context.expression(0)); result = new CastExpression(type, target, textSpan, FileNode); return(result); default: // unary operator ('+', '-', '++', '--', '~', '!') UnaryOperator op = UnaryOperatorLiteral.PrefixTextUnaryOperator[child0Terminal.GetText()]; var opLiteral = new UnaryOperatorLiteral(op, child0Terminal.GetTextSpan(), FileNode); target = (Expression)Visit(context.expression(0)); result = new UnaryOperatorExpression(opLiteral, target, textSpan, FileNode); return(result); } } ArgsNode args; var child1Terminal = context.GetChild(1) as ITerminalNode; if (child1Terminal != null) { switch (child1Terminal.Symbol.Type) { case JavaParser.DOT: // '.' target = (Expression)Visit(context.expression(0)); var id = context.IDENTIFIER(); if (id != null) { result = new MemberReferenceExpression(target, (IdToken)Visit(id), textSpan, FileNode); return(result); } var explicitGenericInvocation = context.explicitGenericInvocation(); if (explicitGenericInvocation != null) { return(VisitChildren(context).ToExpressionIfRequired()); } var child2Terminal = context.GetChild <ITerminalNode>(1); // TODO: implement switch (child2Terminal.Symbol.Type) { case JavaParser.THIS: break; case JavaParser.NEW: break; case JavaParser.SUPER: break; } break; case JavaParser.LBRACK: // '[' target = (Expression)Visit(context.expression(0)); Expression expr = (Expression)Visit(context.expression(1)); args = new ArgsNode(new Expression[] { expr }, expr.TextSpan, FileNode); result = new IndexerExpression(target, args, textSpan, FileNode); return(result); case JavaParser.LPAREN: // '(' target = (Expression)Visit(context.expression(0)); // TODO: fix with ArgsNode JavaParser.ExpressionListContext expressionList = context.expressionList(); if (expressionList != null) { args = (ArgsNode)Visit(expressionList); } else { args = new ArgsNode(); } result = new InvocationExpression(target, args, textSpan, FileNode); return(result); case JavaParser.INSTANCEOF: // x instanceof y -> (y)x != null var expression = (Expression)Visit(context.expression(0)); var type = (TypeToken)Visit(context.typeType()); result = new BinaryOperatorExpression { Left = new CastExpression(type, expression, context.GetTextSpan(), FileNode), Operator = new BinaryOperatorLiteral(BinaryOperator.NotEqual, default(TextSpan), FileNode), Right = new NullLiteral(default(TextSpan), FileNode), TextSpan = context.GetTextSpan(), FileNode = FileNode }; return(result); case JavaParser.QUESTION: // '?' var condition = (Expression)Visit(context.expression(0)); var trueExpr = (Expression)Visit(context.expression(1)); var falseExpr = (Expression)Visit(context.expression(2)); result = new ConditionalExpression(condition, trueExpr, falseExpr, textSpan, FileNode); return(result); default: // binary operator string text = child1Terminal.GetText(); var left = (Expression)Visit(context.expression(0)); JavaParser.ExpressionContext expr1 = context.expression(1); if (expr1 != null) { var right = (Expression)Visit(expr1); if (text == "=") { result = new AssignmentExpression(left, right, textSpan, FileNode); } else if (BinaryOperatorLiteral.TextBinaryAssignmentOperator.Contains(text)) { BinaryOperator op; if (text == ">>>=") { op = BinaryOperator.ShiftRight; // TODO: fix shift operator. } else { op = BinaryOperatorLiteral.TextBinaryOperator[text.Remove(text.Length - 1)]; } result = ConverterHelper.ConvertToAssignmentExpression(left, op, child1Terminal.GetTextSpan(), right, context.GetTextSpan(), FileNode); } else { BinaryOperator op; if (text == ">>>") { op = BinaryOperator.ShiftRight; // TODO: fix shift operator. } else { op = BinaryOperatorLiteral.TextBinaryOperator[text]; } var opLiteral = new BinaryOperatorLiteral(op, child1Terminal.GetTextSpan(), FileNode); result = new BinaryOperatorExpression(left, opLiteral, right, textSpan, FileNode); } } else { // post increment or decrement. UnaryOperator op = UnaryOperatorLiteral.PostfixTextUnaryOperator[text]; var opLiteral = new UnaryOperatorLiteral(op, child1Terminal.GetTextSpan(), FileNode); result = new UnaryOperatorExpression(opLiteral, left, textSpan, FileNode); return(result); } return(result); } } return(Visit(context.GetChild(0))); }
public override UstNode Visit(BinaryOperatorExpression binaryOperatorExpression) { Expression result = null; Expression leftExpression = Visit((dynamic)binaryOperatorExpression.Left); BinaryOperatorLiteral op = Visit((dynamic)binaryOperatorExpression.Operator); Expression rightExpression = Visit((dynamic)binaryOperatorExpression.Right); if (leftExpression.NodeType == NodeType.StringLiteral && rightExpression.NodeType == NodeType.StringLiteral) { string leftValue = ((StringLiteral)leftExpression).Text; string rightValue = ((StringLiteral)rightExpression).Text; if (op.BinaryOperator == BinaryOperator.Plus) { string resultText = leftValue + rightValue; result = new StringLiteral { Text = resultText, FileNode = binaryOperatorExpression.FileNode, TextSpan = leftExpression.TextSpan.Union(rightExpression.TextSpan) }; Logger.LogDebug($"Strings {binaryOperatorExpression} has been concatenated to \"{resultText}\" at {result.TextSpan}"); } } else if (leftExpression.NodeType == NodeType.IntLiteral && rightExpression.NodeType == NodeType.IntLiteral) { long leftValue = ((IntLiteral)leftExpression).Value; long rightValue = ((IntLiteral)rightExpression).Value; long resultValue = 0; bool folded = true; try { checked { switch (op.BinaryOperator) { case BinaryOperator.Plus: resultValue = leftValue + rightValue; break; case BinaryOperator.Minus: resultValue = leftValue - rightValue; break; case BinaryOperator.Multiply: resultValue = leftValue * rightValue; break; case BinaryOperator.Divide: resultValue = leftValue / rightValue; break; case BinaryOperator.Mod: resultValue = leftValue % rightValue; break; case BinaryOperator.BitwiseAnd: resultValue = leftValue & rightValue; break; case BinaryOperator.BitwiseOr: resultValue = leftValue | rightValue; break; case BinaryOperator.BitwiseXor: resultValue = leftValue ^ rightValue; break; default: folded = false; break; } } } catch (Exception ex) { folded = false; Logger.LogDebug($"Error while constant folding: {ex}"); } if (folded) { result = new IntLiteral { Value = resultValue, FileNode = binaryOperatorExpression.FileNode, TextSpan = leftExpression.TextSpan.Union(rightExpression.TextSpan) }; Logger.LogDebug($"Arithmetic expression {binaryOperatorExpression} has been folded to {resultValue} at {result.TextSpan}"); } } if (result == null) { result = new BinaryOperatorExpression(leftExpression, op, rightExpression, new TextSpan(binaryOperatorExpression.TextSpan), binaryOperatorExpression.FileNode); leftExpression.Parent = result; rightExpression.Parent = result; op.Parent = result; } return(result); }
public virtual T Visit(BinaryOperatorLiteral binaryOperatorLiteral) { return(VisitChildren(binaryOperatorLiteral)); }
public virtual void Exit(BinaryOperatorLiteral binaryOperatorLiteral) { }
private bool TryFoldIntBinaryOperatorExpression(object left, object right, BinaryOperatorLiteral op, out BigInteger result) { bool folded = true; if (!((left is long || left is int || left is BigInteger) && (right is long || right is int || right is BigInteger))) { return(false); } BigInteger leftBigInt = left is int leftInt ? (BigInteger)leftInt : left is long leftLong ? (BigInteger)leftLong : (BigInteger)left; BigInteger rightBigInt = right is int rightInt ? (BigInteger)rightInt : right is long rightLong ? (BigInteger)rightLong : (BigInteger)right; switch (op.BinaryOperator) { case BinaryOperator.Plus: result = leftBigInt + rightBigInt; break; case BinaryOperator.Minus: result = leftBigInt - rightBigInt; break; case BinaryOperator.Multiply: result = leftBigInt * rightBigInt; break; case BinaryOperator.Divide: if (rightBigInt == 0) { folded = false; } else { result = leftBigInt / rightBigInt; } break; case BinaryOperator.Mod: if (rightBigInt == 0) { folded = false; } else { result = leftBigInt % rightBigInt; } break; case BinaryOperator.BitwiseAnd: result = leftBigInt & rightBigInt; break; case BinaryOperator.BitwiseOr: result = leftBigInt | rightBigInt; break; case BinaryOperator.BitwiseXor: result = leftBigInt ^ rightBigInt; break; default: folded = false; break; } return(folded); }
private FoldResult TryFoldBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression) { FoldResult leftFold = TryGetOrFold(binaryOperatorExpression.Left); if (leftFold == null) { NormalizeAndAdd(binaryOperatorExpression.Left, ref leftFold); return(null); } FoldResult rightFold = TryGetOrFold(binaryOperatorExpression.Right); if (rightFold == null) { NormalizeAndAdd(binaryOperatorExpression.Right, ref rightFold); return(null); } object leftValue = leftFold.Value; object rightValue = rightFold.Value; BinaryOperatorLiteral op = binaryOperatorExpression.Operator; if (leftValue is string || leftValue is StringBuilder) { if (op.BinaryOperator == BinaryOperator.Plus || op.BinaryOperator == BinaryOperator.Concat) { // Use StringBuilder instead of immutable strings and concatenation string rightString = rightValue.ToString(); StringBuilder leftStringBuilder; if (leftValue is string leftString) { leftStringBuilder = new StringBuilder((leftString.Length + rightString.Length) * 2); leftStringBuilder.Append(leftString); } else { leftStringBuilder = (StringBuilder)leftValue; } leftStringBuilder.Append(rightString); FoldResult result = ProcessBinaryExpression(binaryOperatorExpression, leftFold, rightFold, leftStringBuilder); if (Logger.IsLogDebugs) { Logger.LogDebug( $"Strings {binaryOperatorExpression} concatenated to \"{leftStringBuilder}\" at {binaryOperatorExpression.TextSpan}"); } return(result); } } else { if (TryFoldIntBinaryOperatorExpression(leftValue, rightValue, op, out BigInteger bigInt)) { FoldResult result = ProcessBinaryExpression(binaryOperatorExpression, leftFold, rightFold, bigInt); if (Logger.IsLogDebugs) { Logger.LogDebug($"Arithmetic expression {binaryOperatorExpression} folded to {bigInt} at {binaryOperatorExpression.TextSpan}"); } return(result); } } return(null); }