Skip to content

refactor: Replace direct expression building with analysis framework and AST-based compilation#16

Merged
scoizzle merged 39 commits into
masterfrom
experiment/huge-interpretation-refactor-v2
Feb 11, 2026
Merged

refactor: Replace direct expression building with analysis framework and AST-based compilation#16
scoizzle merged 39 commits into
masterfrom
experiment/huge-interpretation-refactor-v2

Conversation

@scoizzle
Copy link
Copy Markdown
Owner

…eware

  • Added VariableScope class to manage named variables and support lexical scoping with shadowing.
  • Introduced Interpreter and InterpreterBuilder classes for orchestrating middleware and AST transformations.
  • Created ReferenceEqualityComparer for reference-based equality checks.
  • Developed SemanticAnalysisMiddleware to enrich AST nodes with semantic information.
  • Added SemanticExtensions for managing semantic analysis data in InterpretationContext.
  • Implemented custom transformer registry for handling specific node patterns.
  • Defined transformation pipeline interfaces and delegates for middleware processing.
  • Created LinqExpressionTransformer to convert AST nodes into LINQ expression trees.
  • Added TerminalTransformMiddleware to delegate transformations to the final transformer.
  • Established a transformation result cache to optimize repeated computations.

…eware

- Added VariableScope class to manage named variables and support lexical scoping with shadowing.
- Introduced Interpreter and InterpreterBuilder classes for orchestrating middleware and AST transformations.
- Created ReferenceEqualityComparer for reference-based equality checks.
- Developed SemanticAnalysisMiddleware to enrich AST nodes with semantic information.
- Added SemanticExtensions for managing semantic analysis data in InterpretationContext.
- Implemented custom transformer registry for handling specific node patterns.
- Defined transformation pipeline interfaces and delegates for middleware processing.
- Created LinqExpressionTransformer to convert AST nodes into LINQ expression trees.
- Added TerminalTransformMiddleware to delegate transformations to the final transformer.
- Established a transformation result cache to optimize repeated computations.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements a major architectural refactoring that introduces a middleware-based interpreter with semantic analysis capabilities, replacing the direct Value.BuildExpression() pattern with a composable transformation pipeline.

Changes:

  • Introduces abstract syntax tree (AST) nodes as immutable records replacing the Value class hierarchy
  • Implements middleware transformation pipeline with ITransformationMiddleware<TResult>, ITransformer<TResult>, and LinqExpressionTransformer
  • Adds semantic analysis middleware that enriches nodes with type and member information stored in InterpretationContext
  • Creates variable scope management with VariableScope supporting lexical scoping and shadowing
  • Establishes transformation result caching and custom transformer registry for domain-specific patterns

Reviewed changes

Copilot reviewed 144 out of 144 changed files in this pull request and generated 15 comments.

Show a summary per file
File Description
Poly/Interpretation/AbstractSyntaxTree/* New immutable AST node records (Node, Constant, Parameter, Variable, operators)
Poly/Interpretation/TransformationPipeline/* Middleware infrastructure (ITransformer, ITransformationMiddleware, LinqExpressionTransformer, TerminalTransformMiddleware)
Poly/Interpretation/SemanticAnalysis/* Semantic analysis middleware and extensions for type/member resolution
Poly/Interpretation/ReferenceEqualityComparer.cs Reference-based equality comparer for caching
Poly/Interpretation/TransformationResultCache.cs Pipeline-level cache for transformation results
Poly/Interpretation/Interpreter*.cs Interpreter and InterpreterBuilder for middleware orchestration
Poly/Validation/* Updated to use Node instead of Value in rules and constraints
Poly/Introspection/CommonLanguageRuntime/* Updated member accessors to use Node and Transform pattern
Poly/GlobalUsings.cs Alias System.Linq.Expressions to avoid naming conflicts
Poly.Tests/* Test updates with NodeTestHelpers and proper middleware usage

Comment on lines +272 to +279
foreach (var param in _parameters)
{
var expr = param.BuildNode(this);
if (expr is Exprs.ParameterExpression paramExpr)
{
yield return paramExpr;
}
}
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

This foreach loop immediately maps its iteration variable to another variable - consider mapping the sequence explicitly using '.Select(...)'.

Copilot uses AI. Check for mistakes.
Comment on lines 363 to 364
var valueLiteral = Wrap(value);
var accessor = addMethod!.GetMemberAccessor(listLiteral, [valueLiteral]);
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

This foreach loop immediately maps its iteration variable to another variable - consider mapping the sequence explicitly using '.Select(...)'.

Suggested change
var valueLiteral = Wrap(value);
var accessor = addMethod!.GetMemberAccessor(listLiteral, [valueLiteral]);
var accessor = addMethod!.GetMemberAccessor(listLiteral, [Wrap(value)]);

Copilot uses AI. Check for mistakes.
Comment thread Poly.Benchmarks/FluentApiExample.cs Outdated
var paramExpr = param.BuildExpression(context);
var lambda = Expression.Lambda<Func<T, TResult>>(expression, paramExpr);
var expression = expr.BuildNode(context);
var paramExpr = param.ToParameterExpression();
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

Call to obsolete method ToParameterExpression.

Copilot uses AI. Check for mistakes.
Comment thread Poly.Benchmarks/FluentApiExample.cs Outdated
var paramExpr2 = param2.BuildExpression(context);
var lambda = Expression.Lambda<Func<T1, T2, TResult>>(expression, paramExpr1, paramExpr2);
var expression = expr.BuildNode(context);
var paramExpr1 = param1.ToParameterExpression();
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

Call to obsolete method ToParameterExpression.

Copilot uses AI. Check for mistakes.
Comment thread Poly.Benchmarks/FluentApiExample.cs Outdated
var lambda = Expression.Lambda<Func<T1, T2, TResult>>(expression, paramExpr1, paramExpr2);
var expression = expr.BuildNode(context);
var paramExpr1 = param1.ToParameterExpression();
var paramExpr2 = param2.ToParameterExpression();
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

Call to obsolete method ToParameterExpression.

Copilot uses AI. Check for mistakes.
[Obsolete("Use the middleware interpreter instead.")]
public IEnumerable<Exprs.ParameterExpression> GetParameterNodes()
{
var transformer = new LinqExpressionTransformer();
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

This assignment to transformer is useless, since its value is never read.

Copilot uses AI. Check for mistakes.
Comment thread Poly.Benchmarks/FluentApiExample.cs Outdated
var expression = expr.BuildExpression(context);
var paramExpr = param.BuildExpression(context);
var lambda = Expression.Lambda<Func<T, TResult>>(expression, paramExpr);
var expression = expr.BuildNode(context);
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

This assignment to expression is useless, since its value is never read.

Copilot uses AI. Check for mistakes.
Comment thread Poly.Benchmarks/FluentApiExample.cs Outdated
var paramExpr1 = param1.BuildExpression(context);
var paramExpr2 = param2.BuildExpression(context);
var lambda = Expression.Lambda<Func<T1, T2, TResult>>(expression, paramExpr1, paramExpr2);
var expression = expr.BuildNode(context);
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

This assignment to expression is useless, since its value is never read.

Copilot uses AI. Check for mistakes.
// Push scope and declare 'y' within a block's scope
context.PushScope();
var y = context.DeclareVariable("y", Value.Wrap(10));
var y = context.DeclareVariable("y", Wrap(10));
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

This assignment to y is useless, since its value is never read.

Suggested change
var y = context.DeclareVariable("y", Wrap(10));
context.DeclareVariable("y", Wrap(10));

Copilot uses AI. Check for mistakes.
Comment on lines +272 to +279
if (leftType != null && rightType != null)
{
if (leftType.ReflectedType != rightType.ReflectedType)
{
throw new InvalidOperationException(
$"Type mismatch in {node.GetType().Name}: " +
$"{leftType.Name} and {rightType.Name} are incompatible");
}
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

These 'if' statements can be combined.

Suggested change
if (leftType != null && rightType != null)
{
if (leftType.ReflectedType != rightType.ReflectedType)
{
throw new InvalidOperationException(
$"Type mismatch in {node.GetType().Name}: " +
$"{leftType.Name} and {rightType.Name} are incompatible");
}
if (leftType != null &&
rightType != null &&
leftType.ReflectedType != rightType.ReflectedType)
{
throw new InvalidOperationException(
$"Type mismatch in {node.GetType().Name}: " +
$"{leftType.Name} and {rightType.Name} are incompatible");

Copilot uses AI. Check for mistakes.
…ation rules

- Deleted ClrTypeFieldInterpretationAccessor, ClrTypeIndexInterpretationAccessor, and ClrTypePropertyInterpretationAccessor as they are no longer needed.
- Updated ITypeMember interface by removing the GetMemberAccessor method.
- Refactored TypeDefinitionProviderCollection to implement ICollection<ITypeDefinitionProvider> for better collection management.
- Cleaned up validation builders by removing unnecessary references to Poly.Interpretation.AbstractSyntaxTree.
- Introduced new interfaces and classes for transformation middleware and semantic analysis, enhancing the interpretation pipeline.
- Added LinqExpressionMiddleware for compiling AST nodes into LINQ expressions.
- Implemented semantic analysis extensions for managing type and member resolution during interpretation.
…eference for type handling

- Introduced unit tests for arithmetic operations (Add, Subtract, Multiply, Divide, Modulo) in ArithmeticNodeTests.
- Added ConditionalNodeTests for testing conditional expressions and coalescing behavior.
- Created ConstantNodeTests to validate constant expressions of various types.
- Implemented ParameterNodeTests to ensure parameter expressions compile and execute correctly.
- Developed InterpreterIntegrationTests for complex multi-node expressions and integration scenarios.
- Added TypeReference class to facilitate type handling in expressions.
- Commented out unused code in RuleBuildingContext for clarity.
- Updated various test files to replace manual expression building and compilation with the new CompileLambda method for cleaner and more maintainable code.
- Modified ConditionalTests, InterpreterIntegrationTests, ModuloTests, NumericTypePromotionTests, ParameterNodeTests, TypeCastTests, and UnaryMinusTests to streamline the compilation process.
- Enhanced Block and Coalesce node implementations to support new constructor patterns.
- Improved semantic analysis middleware to handle variable types and block expressions more effectively.
- Adjusted RuleBuildingContext and RuleSet to simplify the interpretation tree building process.
…onPass for improved analysis and type resolution
…, DoWhile, For, Goto, If, Label, Return, Switch, Throw, TryCatchFinally, Using, and While constructs
…es and introduce LinqExpressionGenerator for AST to LINQ expression compilation
…le, DoWhile, For, Break, Continue, Return, TryCatchFinally, and Using statements in LinqExpressionGenerator
…ion system

- Deleted `InterpreterBuilder` class, which was responsible for building interpreters with middleware.
- Removed `LinqExpressionMiddleware`, which compiled AST nodes to LINQ expressions.
- Eliminated `LinqExpressionMiddlewareExtensions` for adding LINQ expression compilation middleware.
- Removed `ISemanticInfoProvider` interface and its implementation, which provided semantic information about AST nodes.
- Deleted `SemanticAnalysisExtensions` for accessing and storing semantic analysis information.
- Removed `SemanticAnalysisMiddleware`, which enriched AST nodes with semantic information.
- Deleted `TransformationDelegate` delegate type used in the middleware pipeline.
- Removed `DelegateTransformationMiddleware`, which wrapped transformation functions for middleware.
…d AST visualization

- Implemented `ArithmeticParserEvaluatorTests` to cover various arithmetic operations, operator precedence, and error handling.
- Created `MermaidAstVisualizationTests` to validate the generation of Mermaid diagrams from AST nodes, including simple and complex expressions.
- Developed `MermaidAstGenerator` to produce Mermaid markdown for visualizing AST structures, supporting various node types and shapes.
- Added examples and usage notes in `README.md` for the Mermaid AST generator.
- Updated `MiddlewareInterpreterIntegrationTests` to improve type mismatch detection during code generation.
- Implemented Control Flow Analysis with a new ControlFlowAnalysisPass that builds a control flow graph (CFG) from the AST and performs reachability analysis.
- Introduced BasicBlock and ControlFlowGraph classes to represent and manage the structure of the CFG.
- Added support for various control flow constructs including if statements, loops, and switch statements.
- Implemented dead code detection and reporting for unreachable statements in the CFG.
- Created ConstantFoldingPass to evaluate constant expressions at analysis time, optimizing the AST by folding constant operations.
- Added unit tests for control flow analysis to ensure correctness of CFG generation and dead code detection.
…rences

- Added `OptionalTypeReference` to represent nullable types in the AST.
- Introduced `PrimitiveTypeReference` for referencing primitive types by ID, including nullable support.
- Created `PropertyDefinitionNode` for defining properties in types, with support for default values and constraints.
- Implemented `TypeDefinitionNode` to represent type definitions, including properties, methods, fields, and base types.
- Developed `TypeDefinitionNodeAnalyzer` to extract and store type definitions from the AST.
- Enhanced type resolution with support for new type references in `TypeResolver`.
- Added `PrimitiveTypeId` and `TypeCategory` enums for better type classification.
- Updated constraints to include applicability checks based on type categories.
- Introduced `ConstraintApplicabilityException` for handling constraint application errors.
- Enhanced LINQ expression generation with support for custom node compilers.
- Added DataPropertyPath for managing property paths.
- Created DataType to define data types with properties, rules, and mutations.
- Implemented DataTypeBuilder for constructing DataType instances fluently.
- Developed DataTypeValidator to validate instances against defined rules.
- Introduced DataModelMemberAccessAnalyzer for transforming member accesses in data models.
- Added DataModelPropertyAccessor for accessing properties in dynamic objects.
- Implemented DataTypeDefinition to represent data types in the introspection system.
- Created mutation-related classes including Mutation, MutationParameter, and various effects.
- Added validation classes for rule evaluation and error handling.
- Introduced type expressions for modeling various data types including collections, enums, and maps.
- Updated README to reflect changes in the data modeling structure.
@scoizzle
Copy link
Copy Markdown
Owner Author

@copilot Re-review this PR and suggest a better Title.

Copy link
Copy Markdown

Copilot AI commented Feb 11, 2026

@scoizzle I've opened a new pull request, #17, to work on those changes. Once the pull request is ready, I'll request review from you.

@scoizzle scoizzle changed the title feat: Implement variable scope management and semantic analysis middl… refactor: Replace direct expression building with analysis framework and AST-based compilation Feb 11, 2026
@scoizzle scoizzle marked this pull request as ready for review February 11, 2026 14:22
@scoizzle scoizzle merged commit 5ff5d2b into master Feb 11, 2026
@scoizzle scoizzle deleted the experiment/huge-interpretation-refactor-v2 branch February 11, 2026 14:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants