Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update tree/pass model #5

Merged
merged 14 commits into from
Aug 20, 2022
Merged

Update tree/pass model #5

merged 14 commits into from
Aug 20, 2022

Conversation

thinker227
Copy link
Owner

Update the model used for representing type node trees and passes in accordance with the language overhaul proposal (see #2). The exact implementation is still being actively discussed and this PR currently serves as more of a test to see what would work.

@thinker227 thinker227 added enhancement New feature or request functionality Core functionality and features labels Aug 1, 2022
@thinker227 thinker227 added this to the Language overhaul milestone Aug 1, 2022
@thinker227 thinker227 requested a review from LPeter1997 August 1, 2022 21:33
Copy link
Collaborator

@LPeter1997 LPeter1997 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some nitpicks and a possible design consideration about the relation of transformations and patterns.

/// <summary>
/// The pattern the transformation is triggered by.
/// </summary>
ITransformationPattern? Pattern { get; }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should decouple the pattern and the transformation. It could reduce code-duplication, as the transformation would not need to implement querying for relevant nodes each time. In exchange, Apply would change to something like Apply(Tree, Node).

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So a transformation would only handle the transformation of individual types as opposed to entire tree? How would the transformation know what to transform if not supplied with a pattern to work off of?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it would handle the individual node. I'd say the situation depends on the transformation. A transformation might not need a pattern because it works with the entire tree (in which case the node would be null). If a pattern is not provided for a transformation that works on some node, you could come up with a sane default (like all nodes are transformed or something).

You could also keep the current design, I just feel like the node matching logic should be externalized to minimize code repetition.

Copy link
Owner Author

@thinker227 thinker227 Aug 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just feel like the node matching logic should be externalized to minimize code repetition.

I agree with this, although I'm still wondering about the transformation stuff. If a transformation should transform a member of a node, how would it know which member to transform without having a pattern to find the member(s) by? Or are members also "nodes" and can therefore also be sent to Apply?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ooooh fair point, I forgot about members honestly. That's a tough one, I have no immediate answer to that.

Copy link
Owner Author

@thinker227 thinker227 Aug 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could personally see three possible solutions for this:

  1. ITransformation has two overloads for Apply, Apply(Tree, TypeNode) and Apply(Tree, TypeNode, MemberNode). For transformations which only transform one of them, the other can simply return the input tree.

  2. Alternatively it could be Apply(Tree, TypeNode, MemberNode?) where the member could be null if only the type should be transformed.

  3. There are two sub-interfaces of ITransformation, ITypeTransformation which deals with transformations of types, and IMemberTransformation which deals with transformations of members. A simple switch expression would be enough to call the appropriate method.

(
string Name,
string? Documentation,
Pass Previous,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this was mutable, both the prev. and the next pass could be referenced.

/// </summary>
/// <param name="Root">The root node.</param>
/// <param name="Nodes">The nodes of the tree.</param>
public sealed record class TypeNodeTree
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a fan of this name, it doesn't immediately yell that this is the node hierarchy.

/// <param name="Nodes">The nodes of the tree.</param>
public sealed record class TypeNodeTree
(
TypeNode Root,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a possibility for multiple root nodes? Or is this a non-concern for now?

Copy link
Owner Author

@thinker227 thinker227 Aug 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Depends on what kind of hierarchy we're trying to model, I suppose. In languages like C# and Java, nested types exist which would naturally lead to tree-like structure, but in other langs, the types would just have to be laid out flat and the tree structure implied by the referenced types in each type.

In these other langs, would each node be a root node?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say that you are still modeling a hierarchy, what this compiles to is a detail.

/// <param name="Children">The children of the node (typically nested types).</param>
/// <param name="Members">The members of the type.</param>
/// <param name="Attributes">The language-specific attributes of the type.</param>
public sealed record class TypeNode
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, the name is a bit cryptic. Why TypeNode? Why not AstNode?

/// May be <see langword="null"/> in dynamically typed languages
/// or languages without explicitly typed members.</param>
/// <param name="Attributes">The language-specific attributes of the member.</param>
public sealed record class Member
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, I'd consider the naming here. Maybe AstNodeMember? Or even ClassMember? NodeProperty?

/// <param name="Documentation">The pass' corresponding documentation.</param>
/// <param name="Transformations">The transformations the pass applies to its nodes.</param>
/// <param name="Tree">The original node tree of the pass.</param>
public sealed record class Pass
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe CompilerPass?

@thinker227 thinker227 merged commit 020b487 into main Aug 20, 2022
@thinker227 thinker227 deleted the updated-tree-model branch August 20, 2022 17:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request functionality Core functionality and features
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants