Skip to content

Commit

Permalink
Implemented specialization
Browse files Browse the repository at this point in the history
  • Loading branch information
LPeter1997 committed Oct 5, 2023
1 parent b3df53d commit 429410e
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 6 deletions.
1 change: 1 addition & 0 deletions src/Draco.Compiler/Internal/BoundTree/BoundNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -207,5 +207,6 @@ internal partial class BoundPattern

internal partial class BoundDiscardPattern
{
public static BoundDiscardPattern Default { get; } = new(null);
public override TypeSymbol Type => IntrinsicSymbols.Never;
}
60 changes: 54 additions & 6 deletions src/Draco.Compiler/Internal/FlowAnalysis/DecisionTree.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
Expand Down Expand Up @@ -80,6 +81,14 @@ public abstract class Node
public abstract ImmutableArray<KeyValuePair<BoundPattern, Node>> Children { get; }
}

/// <summary>
/// A method that builds the accessor expression for a given expression and its member.
/// </summary>
/// <param name="value">The expression to build the accessor for.</param>
/// <param name="member">The accessed member.</param>
/// <returns>An expression that accesses the given member of the given value.</returns>
public delegate BoundExpression BuildAccessorDelegate(BoundExpression value, object? member);

private sealed class MutableNode : Node
{
// Observers
Expand Down Expand Up @@ -176,7 +185,11 @@ public static DecisionTree<TAction> Build(
.Select(a => a.Action)
.ToList());
// Wrap in the tree
var tree = new DecisionTree<TAction>(intrinsicSymbols, root);
var tree = new DecisionTree<TAction>(
intrinsicSymbols,
// TODO
(expr, mem) => throw new NotImplementedException(),
root);
// Build it
tree.Build(root);
return tree;
Expand Down Expand Up @@ -217,11 +230,13 @@ public static DecisionTree<TAction> Build(
public BoundPattern? UncoveredExample => throw new NotImplementedException();

private readonly IntrinsicSymbols intrinsicSymbols;
private readonly BuildAccessorDelegate buildAccessor;

private DecisionTree(IntrinsicSymbols intrinsicSymbols, MutableNode root)
private DecisionTree(IntrinsicSymbols intrinsicSymbols, BuildAccessorDelegate buildAccessor, MutableNode root)
{
this.intrinsicSymbols = intrinsicSymbols;
this.mutableRoot = root;
this.buildAccessor = buildAccessor;
}

private void Build(MutableNode node)
Expand Down Expand Up @@ -258,20 +273,53 @@ private void Build(MutableNode node)
foreach (var pat in coveredPatterns)
{
// Specialize to the pattern
this.Specialize(node, pat);
var child = this.Specialize(node, pat);
// We covered the value, subtract
uncoveredDomain.SubtractPattern(pat);
// Add as child
node.Children.Add(new(pat, child));
}

// If not complete, do defaulting
if (!uncoveredDomain.IsEmpty) this.Default(node);
if (!uncoveredDomain.IsEmpty)
{
var @default = this.Default(node);
// Add as child
node.Children.Add(new(BoundDiscardPattern.Default, @default));
}

// Recurse to children
foreach (var (_, child) in node.MutableChildren) this.Build(child);
}

private MutableNode Specialize(MutableNode node, BoundPattern specializer) =>
throw new NotImplementedException();
private MutableNode Specialize(MutableNode node, BoundPattern specializer)
{
var remainingRows = new List<List<BoundPattern>>();
var remainingActions = new List<TAction>();
foreach (var (row, action) in node.PatternMatrix.Zip(node.Actions))
{
var exploded = TryExplode(specializer, row[0]);
if (exploded is null) continue;

var newRow = exploded.Concat(row.Skip(1)).ToList();
if (newRow.Count == 0) newRow.Add(BoundDiscardPattern.Default);

remainingRows.Add(newRow);
remainingActions.Add(action);
}

var newArguments = Enumerable
.Range(0, remainingRows[0].Count - node.PatternMatrix[0].Count + 1)
.Select(i => this.buildAccessor(node.Arguments[0], i))
.Concat(node.Arguments.Skip(1))
.ToList();

return new MutableNode(
parent: node,
arguments: newArguments,
patternMatrix: remainingRows,
actions: remainingActions);
}

private MutableNode Default(MutableNode node) =>
throw new NotImplementedException();
Expand Down

0 comments on commit 429410e

Please sign in to comment.