MParser/Parser/Binding/BoundTreeRewriter.cs

394 lines
16 KiB
C#

using System;
using System.Collections.Immutable;
using static Parser.Binding.BoundNodeFactory;
namespace Parser.Binding
{
public abstract class BoundTreeRewriter
{
public virtual BoundStatement RewriteStatement(BoundStatement node)
{
return node.Kind switch
{
BoundNodeKind.AbstractMethodDeclaration =>
RewriteAbstractMethodDeclaration((BoundAbstractMethodDeclaration)node),
BoundNodeKind.BlockStatement =>
RewriteBlockStatement((BoundBlockStatement)node),
BoundNodeKind.ClassDeclaration =>
RewriteClassDeclaration((BoundClassDeclaration)node),
BoundNodeKind.ConcreteMethodDeclaration =>
RewriteConcreteMethodDeclaration((BoundConcreteMethodDeclaration)node),
BoundNodeKind.ConditionalGotoStatement =>
RewriteConditionalGotoStatement((BoundConditionalGotoStatement)node),
BoundNodeKind.EmptyStatement =>
RewriteEmptyStatement((BoundEmptyStatement)node),
BoundNodeKind.ExpressionStatement =>
RewriteExpressionStatement((BoundExpressionStatement)node),
BoundNodeKind.ForStatement =>
RewriteForStatement((BoundForStatement)node),
BoundNodeKind.FunctionDeclaration =>
RewriteFunctionDeclaration((BoundFunctionDeclaration)node),
BoundNodeKind.GotoStatement =>
RewriteGotoStatement((BoundGotoStatement)node),
BoundNodeKind.IfStatement =>
RewriteIfStatement((BoundIfStatement)node),
BoundNodeKind.LabelStatement =>
RewriteLabelStatement((BoundLabelStatement)node),
BoundNodeKind.SwitchStatement =>
RewriteSwitchStatement((BoundSwitchStatement)node),
BoundNodeKind.TryCatchStatement =>
RewriteTryCatchStatement((BoundTryCatchStatement)node),
BoundNodeKind.WhileStatement =>
RewriteWhileStatement((BoundWhileStatement)node),
_ =>
throw new Exception($"Invalid statement kind {node.Kind}."),
};
}
public virtual BoundStatement RewriteGotoStatement(BoundGotoStatement node)
{
return node;
}
public virtual BoundStatement RewriteConditionalGotoStatement(BoundConditionalGotoStatement node)
{
var condition = RewriteExpression(node.Condition);
if (condition == node.Condition)
{
return node;
}
return ConditionalGoto(node.Syntax, condition, node.Label, node.GotoIfTrue);
}
public virtual BoundStatement RewriteWhileStatement(BoundWhileStatement node)
{
throw new NotImplementedException();
}
public virtual BoundStatement RewriteTryCatchStatement(BoundTryCatchStatement node)
{
throw new NotImplementedException();
}
public virtual BoundStatement RewriteSwitchStatement(BoundSwitchStatement node)
{
throw new NotImplementedException();
}
public virtual BoundStatement RewriteLabelStatement(BoundLabelStatement node)
{
return node;
}
public virtual BoundStatement RewriteIfStatement(BoundIfStatement node)
{
var condition = RewriteExpression(node.Condition);
var body = RewriteStatement(node.Body);
ImmutableArray<BoundElseifClause>.Builder? builder = null;
for (var i = 0; i < node.ElseifClauses.Length; i++)
{
var oldClause = node.ElseifClauses[i];
var newClause = RewriteElseifClause(oldClause);
if (oldClause != newClause && builder is null)
{
builder = ImmutableArray.CreateBuilder<BoundElseifClause>(node.ElseifClauses.Length);
for (var j = 0; j < i; j++)
{
builder.Add(node.ElseifClauses[j]);
}
}
if (builder is not null)
{
builder.Add(newClause);
}
}
var elseIfClauses = builder is null ? node.ElseifClauses : builder.MoveToImmutable();
var elseClause = node.ElseClause is null ? null : RewriteStatement(node.ElseClause);
if (condition == node.Condition &&
body == node.Body &&
elseIfClauses == node.ElseifClauses &&
elseClause == node.ElseClause )
{
return node;
}
return IfStatement(node.Syntax, condition, body, elseIfClauses, elseClause);
}
public virtual BoundElseifClause RewriteElseifClause(BoundElseifClause node)
{
var condition = RewriteExpression(node.Condition);
var body = RewriteStatement(node.Body);
if (condition == node.Condition && body == node.Body)
{
return node;
}
return ElseifClause(node.Syntax, condition, body);
}
public virtual BoundStatement RewriteFunctionDeclaration(BoundFunctionDeclaration node)
{
throw new NotImplementedException();
}
public virtual BoundStatement RewriteForStatement(BoundForStatement node)
{
throw new NotImplementedException();
}
public virtual BoundStatement RewriteExpressionStatement(BoundExpressionStatement node)
{
var expression = RewriteExpression(node.Expression);
if (expression == node.Expression)
{
return node;
}
return ExpressionStatement(node.Syntax, expression, node.DiscardResult);
}
public virtual BoundStatement RewriteEmptyStatement(BoundEmptyStatement node)
{
throw new NotImplementedException();
}
public virtual BoundStatement RewriteConcreteMethodDeclaration(BoundConcreteMethodDeclaration node)
{
throw new NotImplementedException();
}
public virtual BoundStatement RewriteClassDeclaration(BoundClassDeclaration node)
{
throw new NotImplementedException();
}
public virtual BoundStatement RewriteBlockStatement(BoundBlockStatement node)
{
ImmutableArray<BoundStatement>.Builder? builder = null;
for (var i = 0; i < node.Statements.Length; i++)
{
var oldStatement = node.Statements[i];
var newStatement = RewriteStatement(oldStatement);
if (oldStatement != newStatement && builder is null)
{
builder = ImmutableArray.CreateBuilder<BoundStatement>(node.Statements.Length);
for (var j = 0; j < i; j++)
{
builder.Add(node.Statements[j]);
}
}
if (builder is not null)
{
builder.Add(newStatement);
}
}
if (builder is null)
{
return node;
}
return Block(node.Syntax, builder.MoveToImmutable());
}
public virtual BoundStatement RewriteAbstractMethodDeclaration(BoundAbstractMethodDeclaration node)
{
throw new NotImplementedException();
}
public virtual BoundExpression RewriteExpression(BoundExpression node)
{
return node.Kind switch
{
BoundNodeKind.ArrayLiteralExpression =>
RewriteArrayLiteralExpression((BoundArrayLiteralExpression)node),
BoundNodeKind.AssignmentExpression =>
RewriteAssignmentExpression((BoundAssignmentExpression)node),
BoundNodeKind.BinaryOperationExpression =>
RewriteBinaryOperationExpression((BoundBinaryOperationExpression)node),
BoundNodeKind.CellArrayElementAccessExpression =>
RewriteCellArrayElementAccessExpression((BoundCellArrayElementAccessExpression)node),
BoundNodeKind.CellArrayLiteralExpression =>
RewriteCellArrayLiteralExpression((BoundCellArrayLiteralExpression)node),
BoundNodeKind.ClassInvokationExpression =>
RewriteClassInvokationExpression((BoundClassInvokationExpression)node),
BoundNodeKind.CommandExpression =>
RewriteCommandExpression((BoundCommandExpression)node),
BoundNodeKind.CompoundNameExpression =>
RewriteCompoundNameExpression((BoundCompoundNameExpression)node),
BoundNodeKind.DoubleQuotedStringLiteralExpression =>
RewriteDoubleQuotedStringLiteralExpression((BoundDoubleQuotedStringLiteralExpression)node),
BoundNodeKind.EmptyExpression =>
RewriteEmptyExpression((BoundEmptyExpression)node),
BoundNodeKind.FunctionCallExpression =>
RewriteFunctionCallExpression((BoundFunctionCallExpression)node),
BoundNodeKind.IdentifierNameExpression =>
RewriteIdentifierNameExpression((BoundIdentifierNameExpression)node),
BoundNodeKind.IndirectMemberAccessExpression =>
RewriteIndirectMemberAccessExpression((BoundIndirectMemberAccessExpression)node),
BoundNodeKind.LambdaExpression =>
RewriteLambdaExpression((BoundLambdaExpression)node),
BoundNodeKind.MemberAccessExpression =>
RewriteMemberAccessExpression((BoundMemberAccessExpression)node),
BoundNodeKind.NamedFunctionHandleExpression =>
RewriteNamedFunctionHandleExpression((BoundNamedFunctionHandleExpression)node),
BoundNodeKind.NumberLiteralExpression =>
RewriteNumberLiteralExpression((BoundNumberLiteralExpression)node),
BoundNodeKind.StringLiteralExpression =>
RewriteStringLiteralExpression((BoundStringLiteralExpression)node),
BoundNodeKind.UnaryOperationExpression =>
RewriteUnaryOperationExpression((BoundUnaryOperationExpression)node),
BoundNodeKind.UnquotedStringLiteralExpression =>
RewriteUnquotedStringLiteralExpression((BoundUnquotedStringLiteralExpression)node),
_ =>
throw new Exception($"Invalid expression kind {node.Kind}."),
};
}
public virtual BoundExpression RewriteUnquotedStringLiteralExpression(BoundUnquotedStringLiteralExpression node)
{
throw new NotImplementedException();
}
public virtual BoundExpression RewriteUnaryOperationExpression(BoundUnaryOperationExpression node)
{
var operand = RewriteExpression(node.Operand);
return new BoundUnaryOperationExpression(node.Syntax, node.Op, operand);
}
public virtual BoundExpression RewriteStringLiteralExpression(BoundStringLiteralExpression node)
{
return node;
}
public virtual BoundExpression RewriteNumberLiteralExpression(BoundNumberLiteralExpression node)
{
return node;
}
public virtual BoundExpression RewriteNamedFunctionHandleExpression(BoundNamedFunctionHandleExpression node)
{
throw new NotImplementedException();
}
public virtual BoundExpression RewriteMemberAccessExpression(BoundMemberAccessExpression node)
{
throw new NotImplementedException();
}
public virtual BoundExpression RewriteLambdaExpression(BoundLambdaExpression node)
{
throw new NotImplementedException();
}
public virtual BoundExpression RewriteIndirectMemberAccessExpression(BoundIndirectMemberAccessExpression node)
{
throw new NotImplementedException();
}
public virtual BoundExpression RewriteIdentifierNameExpression(BoundIdentifierNameExpression node)
{
return node;
}
public virtual BoundExpression RewriteFunctionCallExpression(BoundFunctionCallExpression node)
{
ImmutableArray<BoundExpression>.Builder? builder = null;
for (var i = 0; i < node.Arguments.Length; i++)
{
var oldArgument = node.Arguments[i];
var newArgument = RewriteExpression(oldArgument);
if (oldArgument != newArgument && builder is null)
{
builder = ImmutableArray.CreateBuilder<BoundExpression>(node.Arguments.Length);
for (var j = 0; j < i; j++)
{
builder.Add(node.Arguments[j]);
}
}
if (builder is not null)
{
builder.Add(newArgument);
}
}
if (builder is null)
{
return node;
}
return FunctionCall(node.Syntax, node.Name, builder.MoveToImmutable());
}
public virtual BoundExpression RewriteEmptyExpression(BoundEmptyExpression node)
{
throw new NotImplementedException();
}
public virtual BoundExpression RewriteDoubleQuotedStringLiteralExpression(BoundDoubleQuotedStringLiteralExpression node)
{
throw new NotImplementedException();
}
public virtual BoundExpression RewriteCommandExpression(BoundCommandExpression node)
{
throw new NotImplementedException();
}
public virtual BoundExpression RewriteCompoundNameExpression(BoundCompoundNameExpression node)
{
throw new NotImplementedException();
}
public virtual BoundExpression RewriteClassInvokationExpression(BoundClassInvokationExpression node)
{
throw new NotImplementedException();
}
public virtual BoundExpression RewriteCellArrayLiteralExpression(BoundCellArrayLiteralExpression node)
{
throw new NotImplementedException();
}
public virtual BoundExpression RewriteCellArrayElementAccessExpression(BoundCellArrayElementAccessExpression node)
{
throw new NotImplementedException();
}
public virtual BoundExpression RewriteBinaryOperationExpression(BoundBinaryOperationExpression node)
{
var left = RewriteExpression(node.Left);
var right = RewriteExpression(node.Right);
if (left == node.Left && right == node.Right)
{
return node;
}
return new BoundBinaryOperationExpression(node.Syntax, left, node.Op, right);
}
public virtual BoundExpression RewriteAssignmentExpression(BoundAssignmentExpression node)
{
var left = RewriteExpression(node.Left);
var right = RewriteExpression(node.Right);
if (left == node.Left && right == node.Right)
{
return node;
}
return Assignment(node.Syntax, left, right);
}
public virtual BoundExpression RewriteArrayLiteralExpression(BoundArrayLiteralExpression node)
{
throw new NotImplementedException();
}
}
}