protected override BoundExpression RewriteFunctionCall(BoundFunctionCall expression) { var newExpressions = ImmutableArray.CreateBuilder <BoundExpression>(); bool isSame = true; for (int index = 0; index < expression.Parameters.Length; index++) { var parameter = expression.Parameters[index]; var newParameter = RewriteExpression(parameter); if (!newParameter.ValueType.Equals(expression.ParameterTypes[index]) && TypeConversionSymbol.TryFind(newParameter.ValueType, expression.ParameterTypes[index], out var symbol)) { newParameter = new BoundInternalTypeConversion(symbol, parameter); } newExpressions.Add(newParameter); if (newParameter != parameter) { isSame = false; } } if (isSame) { return(expression); } return(new BoundFunctionCall(expression.Function, expression.PointerSymbol, newExpressions.ToImmutable())); }
protected override BoundExpression RewriteBinaryExpression(BoundBinaryExpression expression) { var op = expression.Op; BoundExpression newLeft = RewriteExpression(expression.LeftExpression); BoundExpression newRight = RewriteExpression(expression.RightExpression); if (newLeft.ValueType != newRight.ValueType) { if (TypeConversionSymbol.TryFind(newLeft.ValueType, newRight.ValueType, out var leftConversion)) { newLeft = new BoundInternalTypeConversion(leftConversion, newLeft); } else if (TypeConversionSymbol.TryFind(newRight.ValueType, newLeft.ValueType, out var rightConversion)) { newRight = new BoundInternalTypeConversion(rightConversion, newRight); } } if (newLeft == expression.LeftExpression && newRight == expression.RightExpression) { return(expression); } return(new BoundBinaryExpression(newLeft, op, newRight)); }
private void OutputInternalTypeConversion(BoundInternalTypeConversion node, string prefix) { builder.AddFragment(new OutputFragment(prefix, DefaultColour)); builder.AddFragment(new OutputFragment(node.ValueType.Name, TypeColour)); builder.AddFragment(new OutputFragment("(", DefaultColour)); Output(node.Expression, string.Empty); builder.AddFragment(new OutputFragment(")", DefaultColour)); }
protected override BoundExpression RewriteAssignmentExpression(BoundAssignmentExpression assignment) { BoundExpression expression = RewriteExpression(assignment.Expression); if (expression.ValueType != assignment.Identifier.ValueType && TypeConversionSymbol.TryFind(expression.ValueType, assignment.Identifier.ValueType, out var symbol)) { expression = new BoundInternalTypeConversion(symbol, expression); } if (expression == assignment.Expression) { return(assignment); } return(new BoundAssignmentExpression(assignment.Identifier, expression)); }
private object EvaluateInternalTypeConversion(BoundInternalTypeConversion expression) { if (expression.ConversionSymbol.ToType == ValueTypeSymbol.String) { return(EvaluateExpression(expression.Expression).ToString()); } if (expression.ConversionSymbol.ToType == ValueTypeSymbol.Double) { return(Convert.ToDouble(EvaluateExpression(expression.Expression))); } if (expression.ConversionSymbol.ToType == ValueTypeSymbol.Integer) { return(Convert.ToInt32(EvaluateExpression(expression.Expression))); } throw new Exception($"Unhandled type conversion {expression.ConversionSymbol}"); }
protected override BoundStatement RewriteVariableDeclaration(BoundVariableDeclarationStatement statement) { if (statement.Initialiser == null) { return(statement); } BoundExpression initialiser = RewriteExpression(statement.Initialiser); if (initialiser.ValueType != statement.Variable.ValueType && TypeConversionSymbol.TryFind(initialiser.ValueType, statement.Variable.ValueType, out var symbol)) { initialiser = new BoundInternalTypeConversion(symbol, initialiser); } if (initialiser == statement.Initialiser) { return(statement); } return(new BoundVariableDeclarationStatement(statement.Variable, initialiser)); }