private ExpressionSyntax Simplify(ExpressionSyntax node) { var expression = VisitExpression(node); try { var stringExpression = GetAsString(expression); var value = CSharpScript.EvaluateAsync(stringExpression).Result; switch (value) { case bool bool_value: return(expression); case byte byte_value: return(SF.LiteralExpression(SK.NumericLiteralExpression, SF.Literal(byte_value))); case short short_value: return(SF.LiteralExpression(SK.NumericLiteralExpression, SF.Literal(short_value))); case int int_value: return(SF.LiteralExpression(SK.NumericLiteralExpression, SF.Literal(int_value))); case long long_value: return(SF.LiteralExpression(SK.NumericLiteralExpression, SF.Literal(long_value))); default: throw new NotImplementedException($"Unsupported type: {value.GetType().Name}."); } } catch (Exception) { return(expression); } }
public static void NotNull(object expression) { ExpressionSyntax expr = GetExpression(); CallBinder.StatementSyntax = MakeThrowSyntax( expr.GetLocation(), F.BinaryExpression(K.EqualsExpression, expr, F.LiteralExpression(K.NullLiteralExpression)), "Expected expression to be non-null.", expr.ToString() ); }
private static StatementSyntax MakeThrowSyntax(Location location, ExpressionSyntax condition, string msg, string expr) { // message, expression, file, position, width string file = location.SourceTree.FilePath; ArgumentSyntax[] argsSyntax = { F.Argument(F.LiteralExpression(K.StringLiteralExpression, F.Literal(msg))), F.Argument(F.LiteralExpression(K.StringLiteralExpression, F.Literal(expr))), F.Argument(file == null ? F.LiteralExpression(K.NullLiteralExpression) : F.LiteralExpression(K.StringLiteralExpression, F.Literal(file))), F.Argument(F.LiteralExpression(K.NumericLiteralExpression, F.Literal(location.SourceSpan.Start))), F.Argument(F.LiteralExpression(K.NumericLiteralExpression, F.Literal(location.SourceSpan.Length))) }; return(F.IfStatement( condition, F.ParseStatement($"throw new {typeof(AssertionException).FullName}({string.Join<ArgumentSyntax>(", ", argsSyntax)});") )); }
private ExpressionSyntax VisitExpression(ExpressionSyntax node) { if (node is BinaryExpressionSyntax binaryExpresson) { var left = Simplify(binaryExpresson.Left); var right = Simplify(binaryExpresson.Right); return(SF.BinaryExpression(node.Kind(), left, right)); } if (node is IdentifierNameSyntax identifierName) { var value = Variables[identifierName.Identifier.Text]; return(value); } if (node is LiteralExpressionSyntax) { return(node); } // Consider: // https://stackoverflow.com/a/3346729/2869093 // https://stackoverflow.com/a/7812241/2869093 if (node is PrefixUnaryExpressionSyntax prefixUnaryExpression) { if (prefixUnaryExpression.Operand is IdentifierNameSyntax operantIdentifierName) { operantIdentifierName = (IdentifierNameSyntax)prefixUnaryExpression.Operand; var value = Variables[operantIdentifierName.Identifier.Text]; switch (node.Kind()) { case SK.PreDecrementExpression: return(SF.BinaryExpression(SK.SubtractExpression, value, SF.LiteralExpression(SK.NumericLiteralExpression, SF.Literal(1)))); case SK.PreIncrementExpression: return(SF.BinaryExpression(SK.AddExpression, value, SF.LiteralExpression(SK.NumericLiteralExpression, SF.Literal(1)))); case SK.UnaryMinusExpression: case SK.UnaryPlusExpression: return(node); default: throw new NotImplementedException($"Unsupported expression type: {prefixUnaryExpression.Operand.GetType().Name} ({operantIdentifierName.Kind().ToString()})"); } } if (prefixUnaryExpression.Operand is LiteralExpressionSyntax) { return(node); } if (prefixUnaryExpression.Operand is ParenthesizedExpressionSyntax operandParenthesizedExpression) { return(SF.PrefixUnaryExpression(prefixUnaryExpression.Kind(), Simplify(operandParenthesizedExpression))); } throw new NotImplementedException($"Unsupported expression type: {prefixUnaryExpression.Operand.GetType().Name}"); } if (node is PostfixUnaryExpressionSyntax postfixUnaryExpression) { if (postfixUnaryExpression.Operand is IdentifierNameSyntax operandIdentifierName) { var value = Variables[operandIdentifierName.Identifier.Text]; switch (node.Kind()) { case SK.PostDecrementExpression: return(SF.BinaryExpression(SK.SubtractExpression, value, SF.LiteralExpression(SK.NumericLiteralExpression, SF.Literal(1)))); case SK.PostIncrementExpression: return(SF.BinaryExpression(SK.AddExpression, value, SF.LiteralExpression(SK.NumericLiteralExpression, SF.Literal(1)))); default: throw new NotImplementedException($"Unsupported expression type: {postfixUnaryExpression.Operand.GetType().Name} ({operandIdentifierName.Kind().ToString()})"); } } if (postfixUnaryExpression.Operand is LiteralExpressionSyntax) { return(node); } if (postfixUnaryExpression.Operand is ParenthesizedExpressionSyntax operandParenthesizedExpression) { return(SF.PostfixUnaryExpression(postfixUnaryExpression.Kind(), Simplify(operandParenthesizedExpression))); } throw new NotImplementedException($"Unsupported expression type: {postfixUnaryExpression.Operand.GetType().Name}"); } if (node is ParenthesizedExpressionSyntax parenthesizedExpression) { return(SF.ParenthesizedExpression(Simplify(parenthesizedExpression.Expression))); } throw new NotImplementedException($"Unsupported expression type: {node.GetType().Name}"); }