diff --git a/SyntaxTree/tree/TreeHelper.cs b/SyntaxTree/tree/TreeHelper.cs index 9fa47d58f..1a0fdea48 100644 --- a/SyntaxTree/tree/TreeHelper.cs +++ b/SyntaxTree/tree/TreeHelper.cs @@ -1774,11 +1774,30 @@ namespace PascalABCCompiler.SyntaxTree return result; } + + public override string ToString() => $"var {string.Join(", ", definitions)}"; + } + + public partial class is_pattern_expr + { + public override string ToString() => $"{left} is {right}"; } public partial class deconstructor_pattern { public bool IsRecursive => parameters.Any(x => x is recursive_deconstructor_parameter); + + public override string ToString() => $"{type}({string.Join(", ", parameters.Select(x => x.ToString()))})"; + } + + public partial class var_deconstructor_parameter + { + public override string ToString() => identifier.ToString() + (type == null ? "" : $": {type}"); + } + + public partial class recursive_deconstructor_parameter + { + public override string ToString() => pattern.ToString(); } } diff --git a/SyntaxVisitors/SugarVisitors/PatternsDesugaringVisitor.cs b/SyntaxVisitors/SugarVisitors/PatternsDesugaringVisitor.cs index 03bb95cb1..92bf40b83 100644 --- a/SyntaxVisitors/SugarVisitors/PatternsDesugaringVisitor.cs +++ b/SyntaxVisitors/SugarVisitors/PatternsDesugaringVisitor.cs @@ -46,8 +46,7 @@ namespace SyntaxVisitors.SugarVisitors { var result = new List(); result.Add(CastVariableDefinition); - result.AddRange(DeconstructionVariables - .Select(x => new desugared_deconstruction(DeconstructionVariables, CastVariable, patternContext))); + result.Add(new desugared_deconstruction(DeconstructionVariables, CastVariable, patternContext)); result.Add(SuccessVariableDefinition); return result; @@ -108,7 +107,7 @@ namespace SyntaxVisitors.SugarVisitors { Debug.Assert(GetLocation(isPatternExpr) != PatternLocation.Unknown, "Is-pattern expression is in an unknown context"); Debug.Assert(GetAscendant(isPatternExpr) != null, "Couldn't find statement list in upper nodes"); - + DesugarIsExpression(isPatternExpr); } @@ -207,6 +206,15 @@ namespace SyntaxVisitors.SugarVisitors Debug.Assert(isPatternExpr.right is deconstructor_pattern); var patternLocation = GetLocation(isPatternExpr); + + var pattern = isPatternExpr.right as deconstructor_pattern; + if (pattern.IsRecursive) + { + var desugaredRecursiveIs = DesugarRecursiveDeconstructor(isPatternExpr.left, pattern); + ReplaceUsingParent(isPatternExpr, desugaredRecursiveIs); + desugaredRecursiveIs.visit(this); + return; + } switch (patternLocation) { @@ -215,6 +223,26 @@ namespace SyntaxVisitors.SugarVisitors } } + private expression DesugarRecursiveDeconstructor(expression expression, deconstructor_pattern pattern) + { + List parameters = pattern.parameters; + expression conjunction = new is_pattern_expr(expression, pattern); + for (int i = 0; i < parameters.Count; i++) + { + if (parameters[i] is recursive_deconstructor_parameter parameter) + { + var parameterType = (parameter.pattern as deconstructor_pattern).type; + var newName = NewGeneralName(); + var varParameter = new var_deconstructor_parameter(newName, parameterType); + parameters[i] = varParameter; + varParameter.Parent = parameters[i]; + conjunction = bin_expr.LogicalAnd(conjunction, DesugarRecursiveDeconstructor(newName, parameter.pattern as deconstructor_pattern)); + } + } + + return conjunction; + } + private void DesugarIsExpressionInAssignment(is_pattern_expr isExpression) { var pattern = isExpression.right as deconstructor_pattern;