Working recursive patterns

This commit is contained in:
Alexander Zakharenko 2018-05-17 00:01:52 +03:00
parent 97078b0bc3
commit b8e8b237b8
2 changed files with 50 additions and 3 deletions

View file

@ -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();
}
}

View file

@ -46,8 +46,7 @@ namespace SyntaxVisitors.SugarVisitors
{
var result = new List<statement>();
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<statement_list>(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<pattern_deconstructor_parameter> 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;