diff --git a/src/Draco.Compiler/Draco.Compiler.csproj b/src/Draco.Compiler/Draco.Compiler.csproj
index 47af57f3e..9297f2e3e 100644
--- a/src/Draco.Compiler/Draco.Compiler.csproj
+++ b/src/Draco.Compiler/Draco.Compiler.csproj
@@ -10,7 +10,6 @@
-
diff --git a/src/Draco.Compiler/Internal/Binding/Binder_BoundExpression.cs b/src/Draco.Compiler/Internal/Binding/Binder_BoundExpression.cs
deleted file mode 100644
index 9a4b5de89..000000000
--- a/src/Draco.Compiler/Internal/Binding/Binder_BoundExpression.cs
+++ /dev/null
@@ -1,425 +0,0 @@
-using System;
-using System.Collections.Immutable;
-using System.Linq;
-using Draco.Compiler.Api.Diagnostics;
-using Draco.Compiler.Api.Syntax;
-using Draco.Compiler.Internal.BoundTree;
-using Draco.Compiler.Internal.Diagnostics;
-using Draco.Compiler.Internal.Solver;
-using Draco.Compiler.Internal.Symbols;
-using Draco.Compiler.Internal.Symbols.Synthetized;
-using Draco.Compiler.Internal.UntypedTree;
-
-namespace Draco.Compiler.Internal.Binding;
-
-internal partial class Binder
-{
- ///
- /// Binds the given untyped expression to a bound expression.
- ///
- /// The untyped expression to bind.
- /// The constraints that has been collected during the binding process.
- /// The diagnostics produced during the process.
- /// The bound expression for .
- internal virtual BoundExpression TypeExpression(UntypedExpression expression, ConstraintSolver constraints, DiagnosticBag diagnostics) => expression switch
- {
- UntypedUnexpectedExpression unexpected => new BoundUnexpectedExpression(unexpected.Syntax),
- UntypedModuleExpression module => this.TypeModuleExpression(module, constraints, diagnostics),
- UntypedTypeExpression type => this.TypeTypeExpression(type, constraints, diagnostics),
- UntypedUnitExpression unit => this.TypeUnitExpression(unit, constraints, diagnostics),
- UntypedLiteralExpression literal => this.TypeLiteralExpression(literal, constraints, diagnostics),
- UntypedStringExpression str => this.TypeStringExpression(str, constraints, diagnostics),
- UntypedParameterExpression @param => this.TypeParameterExpression(param, constraints, diagnostics),
- UntypedLocalExpression local => this.TypeLocalExpression(local, constraints, diagnostics),
- UntypedGlobalExpression global => this.TypeGlobalExpression(global, constraints, diagnostics),
- UntypedFieldExpression field => this.TypeFieldExpression(field, constraints, diagnostics),
- UntypedPropertyGetExpression prop => this.TypePropertyGetExpression(prop, constraints, diagnostics),
- UntypedIndexGetExpression index => this.TypeIndexGetExpression(index, constraints, diagnostics),
- UntypedFunctionGroupExpression group => this.TypeFunctionGroupExpression(group, constraints, diagnostics),
- UntypedReferenceErrorExpression err => this.TypeReferenceErrorExpression(err, constraints, diagnostics),
- UntypedReturnExpression @return => this.TypeReturnExpression(@return, constraints, diagnostics),
- UntypedBlockExpression block => this.TypeBlockExpression(block, constraints, diagnostics),
- UntypedGotoExpression @goto => this.TypeGotoExpression(@goto, constraints, diagnostics),
- UntypedIfExpression @if => this.TypeIfExpression(@if, constraints, diagnostics),
- UntypedWhileExpression @while => this.TypeWhileExpression(@while, constraints, diagnostics),
- UntypedForExpression @for => this.TypeForExpression(@for, constraints, diagnostics),
- UntypedCallExpression call => this.TypeCallExpression(call, constraints, diagnostics),
- UntypedIndirectCallExpression call => this.TypeIndirectCallExpression(call, constraints, diagnostics),
- UntypedAssignmentExpression assignment => this.TypeAssignmentExpression(assignment, constraints, diagnostics),
- UntypedUnaryExpression ury => this.TypeUnaryExpression(ury, constraints, diagnostics),
- UntypedBinaryExpression bin => this.TypeBinaryExpression(bin, constraints, diagnostics),
- UntypedRelationalExpression rel => this.TypeRelationalExpression(rel, constraints, diagnostics),
- UntypedAndExpression and => this.TypeAndExpression(and, constraints, diagnostics),
- UntypedOrExpression or => this.TypeOrExpression(or, constraints, diagnostics),
- UntypedMemberExpression mem => this.TypeMemberExpression(mem, constraints, diagnostics),
- UntypedDelayedExpression delay => this.TypeDelayedExpression(delay, constraints, diagnostics),
- _ => throw new ArgumentOutOfRangeException(nameof(expression)),
- };
-
- private BoundUnexpectedExpression TypeModuleExpression(UntypedModuleExpression module, ConstraintSolver constraints, DiagnosticBag diagnostics)
- {
- // A module expression is illegal by itself, report it
- diagnostics.Add(Diagnostic.Create(
- template: SymbolResolutionErrors.IllegalModuleExpression,
- location: module.Syntax?.Location,
- formatArgs: module.Module.Name));
- return new BoundUnexpectedExpression(module.Syntax);
- }
-
- private BoundUnexpectedExpression TypeTypeExpression(UntypedTypeExpression type, ConstraintSolver constraints, DiagnosticBag diagnostics)
- {
- // A type expression is illegal by itself, report it
- diagnostics.Add(Diagnostic.Create(
- template: SymbolResolutionErrors.IllegalTypeExpression,
- location: type.Syntax?.Location,
- formatArgs: type.Type.Name));
- return new BoundUnexpectedExpression(type.Syntax);
- }
-
- private BoundExpression TypeUnitExpression(UntypedUnitExpression unit, ConstraintSolver constraints, DiagnosticBag diagnostics) =>
- unit.Syntax is null ? BoundUnitExpression.Default : new BoundUnitExpression(unit.Syntax);
-
- private BoundExpression TypeLiteralExpression(UntypedLiteralExpression literal, ConstraintSolver constraints, DiagnosticBag diagnostics) =>
- new BoundLiteralExpression(literal.Syntax, literal.Value, literal.TypeRequired);
-
- private BoundExpression TypeStringExpression(UntypedStringExpression str, ConstraintSolver constraints, DiagnosticBag diagnostics) =>
- new BoundStringExpression(
- str.Syntax,
- str.Parts.Select(p => this.TypeStringPart(p, constraints, diagnostics)).ToImmutableArray(),
- this.IntrinsicSymbols.String);
-
- private BoundStringPart TypeStringPart(UntypedStringPart part, ConstraintSolver constraints, DiagnosticBag diagnostics) => part switch
- {
- UntypedUnexpectedStringPart unexpected => new BoundUnexpectedStringPart(unexpected.Syntax),
- UntypedStringText text => new BoundStringText(text.Syntax, text.Text),
- UntypedStringInterpolation interpolation => new BoundStringInterpolation(
- interpolation.Syntax,
- this.TypeExpression(interpolation.Value, constraints, diagnostics)),
- _ => throw new ArgumentOutOfRangeException(nameof(part)),
- };
-
- private BoundExpression TypeParameterExpression(UntypedParameterExpression param, ConstraintSolver constraints, DiagnosticBag diagnostics) =>
- new BoundParameterExpression(param.Syntax, param.Parameter);
-
- private BoundExpression TypeLocalExpression(UntypedLocalExpression local, ConstraintSolver constraints, DiagnosticBag diagnostics) =>
- new BoundLocalExpression(local.Syntax, constraints.GetTypedLocal(local.Local, diagnostics));
-
- private BoundExpression TypeGlobalExpression(UntypedGlobalExpression global, ConstraintSolver constraints, DiagnosticBag diagnostics) =>
- new BoundGlobalExpression(global.Syntax, global.Global);
-
- private BoundExpression TypeFieldExpression(UntypedFieldExpression field, ConstraintSolver constraints, DiagnosticBag diagnostics)
- {
- var receiver = this.TypeExpression(field.Reciever, constraints, diagnostics);
- return new BoundFieldExpression(field.Syntax, receiver, field.Field);
- }
-
- private BoundExpression TypePropertyGetExpression(UntypedPropertyGetExpression prop, ConstraintSolver constraints, DiagnosticBag diagnostics)
- {
- var receiver = prop.Receiver is null ? null : this.TypeExpression(prop.Receiver, constraints, diagnostics);
- return new BoundPropertyGetExpression(prop.Syntax, receiver, prop.Getter);
- }
-
- private BoundExpression TypeIndexGetExpression(UntypedIndexGetExpression index, ConstraintSolver constraints, DiagnosticBag diagnostics)
- {
- var receiver = this.TypeExpression(index.Receiver, constraints, diagnostics);
- var indices = index.Indices.Select(x => this.TypeExpression(x, constraints, diagnostics)).ToImmutableArray();
- var getter = index.Getter.Result;
- var arrayIndexProperty = (getter.GenericDefinition as IPropertyAccessorSymbol)?.Property as ArrayIndexPropertySymbol;
- if (arrayIndexProperty is not null)
- {
- // Array getter
- return new BoundArrayAccessExpression(index.Syntax, receiver, indices);
- }
- return new BoundIndexGetExpression(index.Syntax, receiver, index.Getter.Result, indices);
- }
-
- private BoundExpression TypeFunctionGroupExpression(UntypedFunctionGroupExpression group, ConstraintSolver constraints, DiagnosticBag diagnostics)
- {
- // A function group expression is illegal by itself, report it
- diagnostics.Add(Diagnostic.Create(
- template: SymbolResolutionErrors.IllegalFounctionGroupExpression,
- location: group.Syntax?.Location,
- formatArgs: group.Functions.First().Name));
- return new BoundUnexpectedExpression(group.Syntax);
- }
-
- private BoundExpression TypeReferenceErrorExpression(UntypedReferenceErrorExpression err, ConstraintSolver constraints, DiagnosticBag diagnostics) =>
- new BoundReferenceErrorExpression(err.Syntax, err.Symbol);
-
- private BoundExpression TypeReturnExpression(UntypedReturnExpression @return, ConstraintSolver constraints, DiagnosticBag diagnostics)
- {
- var typedValue = this.TypeExpression(@return.Value, constraints, diagnostics);
- return new BoundReturnExpression(@return.Syntax, typedValue);
- }
-
- private BoundExpression TypeBlockExpression(UntypedBlockExpression block, ConstraintSolver constraints, DiagnosticBag diagnostics)
- {
- var locals = block.Locals
- .Select(l => constraints.GetTypedLocal(l, diagnostics))
- .ToImmutableArray();
- var typedStatements = block.Statements
- .Select(s => this.TypeStatement(s, constraints, diagnostics))
- .ToImmutableArray();
- var typedValue = this.TypeExpression(block.Value, constraints, diagnostics);
- return new BoundBlockExpression(block.Syntax, locals, typedStatements, typedValue);
- }
-
- private BoundExpression TypeGotoExpression(UntypedGotoExpression @goto, ConstraintSolver constraints, DiagnosticBag diagnostics) =>
- new BoundGotoExpression(@goto.Syntax, @goto.Target);
-
- private BoundExpression TypeIfExpression(UntypedIfExpression @if, ConstraintSolver constraints, DiagnosticBag diagnostics)
- {
- var typedCondition = this.TypeExpression(@if.Condition, constraints, diagnostics);
- var typedThen = this.TypeExpression(@if.Then, constraints, diagnostics);
- var typedElse = this.TypeExpression(@if.Else, constraints, diagnostics);
- var resultType = @if.TypeRequired.Substitution;
- return new BoundIfExpression(@if.Syntax, typedCondition, typedThen, typedElse, resultType);
- }
-
- private BoundExpression TypeWhileExpression(UntypedWhileExpression @while, ConstraintSolver constraints, DiagnosticBag diagnostics)
- {
- var typedCondition = this.TypeExpression(@while.Condition, constraints, diagnostics);
- var typedThen = this.TypeExpression(@while.Then, constraints, diagnostics);
- return new BoundWhileExpression(@while.Syntax, typedCondition, typedThen, @while.ContinueLabel, @while.BreakLabel);
- }
-
- private BoundExpression TypeForExpression(UntypedForExpression @for, ConstraintSolver constraints, DiagnosticBag diagnostics)
- {
- var iterator = constraints.GetTypedLocal(@for.Iterator, diagnostics);
-
- // NOTE: Hack, see the note above this method definition
- var iteratorSyntax = (@for.Syntax as ForExpressionSyntax)?.Iterator;
- if (iteratorSyntax is not null) this.BindSyntaxToSymbol(iteratorSyntax, iterator);
-
- var sequence = this.TypeExpression(@for.Sequence, constraints, diagnostics);
- var then = this.TypeExpression(@for.Then, constraints, diagnostics);
-
- return new BoundForExpression(
- @for.Syntax,
- iterator,
- sequence,
- then,
- @for.ContinueLabel,
- @for.BreakLabel,
- @for.GetEnumeratorMethod.Result,
- @for.MoveNextMethod.Result,
- @for.CurrentProperty.Result);
- }
-
- private BoundExpression TypeCallExpression(UntypedCallExpression call, ConstraintSolver constraints, DiagnosticBag diagnostics)
- {
- var receiver = call.Receiver is null ? null : this.TypeExpression(call.Receiver, constraints, diagnostics);
- var function = call.Method.Result;
- var typedArgs = call.Arguments
- .Select(arg => this.TypeExpression(arg, constraints, diagnostics))
- .ToImmutableArray();
-
- return new BoundCallExpression(call.Syntax, receiver, function, typedArgs);
- }
-
- private BoundExpression TypeIndirectCallExpression(UntypedIndirectCallExpression call, ConstraintSolver constraints, DiagnosticBag diagnostics)
- {
- var function = this.TypeExpression(call.Method, constraints, diagnostics);
- var typedArgs = call.Arguments
- .Select(arg => this.TypeExpression(arg, constraints, diagnostics))
- .ToImmutableArray();
- var resultType = call.TypeRequired.Substitution;
- return new BoundIndirectCallExpression(call.Syntax, function, typedArgs, resultType);
- }
-
- private BoundExpression TypeAssignmentExpression(UntypedAssignmentExpression assignment, ConstraintSolver constraints, DiagnosticBag diagnostics)
- {
- var typedRight = this.TypeExpression(assignment.Right, constraints, diagnostics);
- var compoundOperator = assignment.CompoundOperator?.Result;
-
- // NOTE: This is how we deal with properties and indexers
- if (assignment.Left is UntypedPropertySetLvalue prop)
- {
- if (prop.Setter.IsError)
- {
- return new BoundReferenceErrorExpression(prop.Syntax, prop.Setter);
- }
- var receiver = prop.Receiver is null ? null : this.TypeExpression(prop.Receiver, constraints, diagnostics);
- return new BoundPropertySetExpression(
- assignment.Syntax,
- receiver,
- prop.Setter,
- compoundOperator is not null
- ? this.CompoundPropertyExpression(
- assignment.Syntax,
- receiver,
- typedRight,
- ((IPropertyAccessorSymbol)prop.Setter).Property,
- compoundOperator,
- ImmutableArray.Empty,
- diagnostics)
- : typedRight);
- }
-
- if (assignment.Left is UntypedIndexSetLvalue index)
- {
- if (index.Setter.Result.IsError)
- {
- return new BoundReferenceErrorExpression(index.Syntax, index.Setter.Result);
- }
- var receiver = this.TypeExpression(index.Receiver, constraints, diagnostics);
- var indices = index.Indices
- .Select(x => this.TypeExpression(x, constraints, diagnostics))
- .ToImmutableArray();
-
- var setter = index.Setter.Result;
- var arrayIndexProperty = (setter.GenericDefinition as IPropertyAccessorSymbol)?.Property as ArrayIndexPropertySymbol;
- if (arrayIndexProperty is not null)
- {
- // Array setter
- var arrayLvalue = new BoundArrayAccessLvalue(
- assignment.Left.Syntax,
- receiver,
- indices);
- return new BoundAssignmentExpression(
- assignment.Syntax,
- compoundOperator,
- arrayLvalue,
- typedRight);
- }
-
- return new BoundIndexSetExpression(
- assignment.Syntax,
- receiver,
- index.Setter.Result,
- compoundOperator is not null
- ? this.CompoundPropertyExpression(
- assignment.Syntax,
- receiver,
- typedRight,
- ((IPropertyAccessorSymbol)index.Setter.Result).Property,
- compoundOperator,
- indices,
- diagnostics)
- : typedRight,
- indices);
- }
- else if (assignment.Left is UntypedMemberLvalue mem && mem.Member.Result is PropertySymbol pr)
- {
- var receiver = this.TypeExpression(mem.Accessed, constraints, diagnostics);
- var setter = GetSetterSymbol(assignment.Syntax, pr, diagnostics);
- return new BoundPropertySetExpression(
- assignment.Syntax,
- receiver,
- setter,
- compoundOperator is not null
- ? this.CompoundPropertyExpression(
- assignment.Syntax,
- receiver,
- typedRight,
- pr,
- compoundOperator,
- ImmutableArray.Empty,
- diagnostics)
- : typedRight);
- }
- var typedLeft = this.TypeLvalue(assignment.Left, constraints, diagnostics);
- return new BoundAssignmentExpression(assignment.Syntax, compoundOperator, typedLeft, typedRight);
- }
-
- private BoundExpression TypeUnaryExpression(UntypedUnaryExpression ury, ConstraintSolver constraints, DiagnosticBag diagnostics)
- {
- var typedOperand = this.TypeExpression(ury.Operand, constraints, diagnostics);
- var unaryOperator = ury.Operator.Result;
- var resultType = ury.TypeRequired.Substitution;
- return new BoundUnaryExpression(ury.Syntax, unaryOperator, typedOperand, resultType);
- }
-
- private BoundExpression TypeBinaryExpression(UntypedBinaryExpression bin, ConstraintSolver constraints, DiagnosticBag diagnostics)
- {
- var typedLeft = this.TypeExpression(bin.Left, constraints, diagnostics);
- var typedRight = this.TypeExpression(bin.Right, constraints, diagnostics);
- var binaryOperator = bin.Operator.Result;
- var resultType = bin.TypeRequired.Substitution;
- return new BoundBinaryExpression(bin.Syntax, binaryOperator, typedLeft, typedRight, resultType);
- }
-
- private BoundExpression TypeRelationalExpression(UntypedRelationalExpression rel, ConstraintSolver constraints, DiagnosticBag diagnostics)
- {
- var first = this.TypeExpression(rel.First, constraints, diagnostics);
- var comparisons = rel.Comparisons
- .Select(cmp => this.TypeComparison(cmp, constraints, diagnostics))
- .ToImmutableArray();
- return new BoundRelationalExpression(rel.Syntax, first, comparisons, this.IntrinsicSymbols.Bool);
- }
-
- private BoundComparison TypeComparison(UntypedComparison cmp, ConstraintSolver constraints, DiagnosticBag diagnostics)
- {
- var next = this.TypeExpression(cmp.Next, constraints, diagnostics);
- var comparisonOperator = cmp.Operator.Result;
- return new BoundComparison(cmp.Syntax, comparisonOperator, next);
- }
-
- private BoundExpression TypeAndExpression(UntypedAndExpression and, ConstraintSolver constraints, DiagnosticBag diagnostics)
- {
- var left = this.TypeExpression(and.Left, constraints, diagnostics);
- var right = this.TypeExpression(and.Right, constraints, diagnostics);
- return new BoundAndExpression(and.Syntax, left, right);
- }
-
- private BoundExpression TypeOrExpression(UntypedOrExpression or, ConstraintSolver constraints, DiagnosticBag diagnostics)
- {
- var left = this.TypeExpression(or.Left, constraints, diagnostics);
- var right = this.TypeExpression(or.Right, constraints, diagnostics);
- return new BoundOrExpression(or.Syntax, left, right);
- }
-
- private BoundExpression TypeMemberExpression(UntypedMemberExpression mem, ConstraintSolver constraints, DiagnosticBag diagnostics)
- {
- var left = this.TypeExpression(mem.Accessed, constraints, diagnostics);
- var members = mem.Member.Result;
- if (members is ITypedSymbol member)
- {
- if (member is FieldSymbol field) return new BoundFieldExpression(mem.Syntax, left, field);
- if (member is PropertySymbol prop)
- {
- // It could be array length
- if (prop.GenericDefinition is ArrayLengthPropertySymbol)
- {
- return new BoundArrayLengthExpression(mem.Syntax, left);
- }
- else
- {
- var getter = GetGetterSymbol(mem.Syntax, prop, diagnostics);
- return new BoundPropertyGetExpression(mem.Syntax, left, getter);
- }
- }
- return new BoundMemberExpression(mem.Syntax, left, (Symbol)member, member.Type);
- }
- else
- {
- // NOTE: This can happen in case of function with more overloads, but without () after the function name. For example builder.Append
- diagnostics.Add(Diagnostic.Create(
- template: SymbolResolutionErrors.IllegalFounctionGroupExpression,
- location: mem.Syntax?.Location,
- formatArgs: members.Name));
- return new BoundUnexpectedExpression(mem.Syntax);
- }
- }
-
- private BoundExpression TypeDelayedExpression(UntypedDelayedExpression delay, ConstraintSolver constraints, DiagnosticBag diagnostics)
- {
- // Just take result and type that
- var result = delay.Promise.Result;
- return this.TypeExpression(result, constraints, diagnostics);
- }
-
- private BoundExpression CompoundPropertyExpression(
- SyntaxNode? syntax,
- BoundExpression? receiver,
- BoundExpression right,
- PropertySymbol prop,
- FunctionSymbol compoundOperator,
- ImmutableArray args,
- DiagnosticBag diagnostics)
- {
- var getter = GetGetterSymbol(syntax, prop, diagnostics);
- var getterCall = new BoundCallExpression(null, receiver, getter, args);
- return new BoundBinaryExpression(syntax, compoundOperator, getterCall, right, right.TypeRequired);
- }
-}
diff --git a/src/Draco.Compiler/Internal/Binding/Binder_BoundLvalue.cs b/src/Draco.Compiler/Internal/Binding/Binder_BoundLvalue.cs
deleted file mode 100644
index cac23fab5..000000000
--- a/src/Draco.Compiler/Internal/Binding/Binder_BoundLvalue.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-using System;
-using Draco.Compiler.Api.Diagnostics;
-using Draco.Compiler.Internal.BoundTree;
-using Draco.Compiler.Internal.Diagnostics;
-using Draco.Compiler.Internal.Solver;
-using Draco.Compiler.Internal.Symbols;
-using Draco.Compiler.Internal.UntypedTree;
-
-namespace Draco.Compiler.Internal.Binding;
-
-internal partial class Binder
-{
- ///
- /// Binds the given untyped lvalue to a bound lvalue.
- ///
- /// The untyped lvalue to bind.
- /// The constraints that has been collected during the binding process.
- /// The diagnostics produced during the process.
- /// The bound lvalue for .
- internal virtual BoundLvalue TypeLvalue(UntypedLvalue lvalue, ConstraintSolver constraints, DiagnosticBag diagnostics) => lvalue switch
- {
- UntypedUnexpectedLvalue unexpected => new BoundUnexpectedLvalue(unexpected.Syntax),
- UntypedIllegalLvalue illegal => new BoundIllegalLvalue(illegal.Syntax),
- UntypedLocalLvalue local => this.TypeLocalLvalue(local, constraints, diagnostics),
- UntypedGlobalLvalue global => this.TypeGlobalLvalue(global, constraints, diagnostics),
- UntypedFieldLvalue field => this.TypeFieldLvalue(field, constraints, diagnostics),
- UntypedMemberLvalue member => this.TypeMemberLvalue(member, constraints, diagnostics),
- _ => throw new ArgumentOutOfRangeException(nameof(lvalue)),
- };
-
- private BoundLvalue TypeLocalLvalue(UntypedLocalLvalue local, ConstraintSolver constraints, DiagnosticBag diagnostics) =>
- new BoundLocalLvalue(local.Syntax, constraints.GetTypedLocal(local.Local, diagnostics));
-
- private BoundLvalue TypeGlobalLvalue(UntypedGlobalLvalue global, ConstraintSolver constraints, DiagnosticBag diagnostics) =>
- new BoundGlobalLvalue(global.Syntax, global.Global);
-
- private BoundLvalue TypeFieldLvalue(UntypedFieldLvalue field, ConstraintSolver constraints, DiagnosticBag diagnostics)
- {
- var receiver = this.TypeExpression(field.Reciever, constraints, diagnostics);
- return new BoundFieldLvalue(field.Syntax, receiver, field.Field);
- }
-
- private BoundLvalue TypeMemberLvalue(UntypedMemberLvalue mem, ConstraintSolver constraints, DiagnosticBag diagnostics)
- {
- var left = this.TypeExpression(mem.Accessed, constraints, diagnostics);
- var members = mem.Member.Result;
- if (members is ITypedSymbol member)
- {
- // Error, don't cascade
- if (members.IsError)
- {
- return new BoundIllegalLvalue(mem.Syntax);
- }
- if (member is FieldSymbol field)
- {
- return new BoundFieldLvalue(mem.Syntax, left, field);
- }
- diagnostics.Add(Diagnostic.Create(
- template: SymbolResolutionErrors.IllegalLvalue,
- location: mem.Syntax?.Location));
- return new BoundIllegalLvalue(mem.Syntax);
- }
- else
- {
- // NOTE: This can happen in case of function with more overloads, but without () after the function name. For example builder.Append
- diagnostics.Add(Diagnostic.Create(
- template: SymbolResolutionErrors.IllegalFounctionGroupExpression,
- location: mem.Syntax?.Location,
- formatArgs: members.Name));
- return new BoundUnexpectedLvalue(mem.Syntax);
- }
- }
-}
diff --git a/src/Draco.Compiler/Internal/Binding/Binder_BoundStatement.cs b/src/Draco.Compiler/Internal/Binding/Binder_BoundStatement.cs
deleted file mode 100644
index fee1f86a7..000000000
--- a/src/Draco.Compiler/Internal/Binding/Binder_BoundStatement.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-using System;
-using Draco.Compiler.Internal.BoundTree;
-using Draco.Compiler.Internal.Diagnostics;
-using Draco.Compiler.Internal.Solver;
-using Draco.Compiler.Internal.UntypedTree;
-
-namespace Draco.Compiler.Internal.Binding;
-
-internal partial class Binder
-{
- ///
- /// Binds the given untyped statement to a bound statement.
- ///
- /// The untyped statement to bind.
- /// The constraints that has been collected during the binding process.
- /// The diagnostics produced during the process.
- /// The bound statement for .
- internal virtual BoundStatement TypeStatement(UntypedStatement statement, ConstraintSolver constraints, DiagnosticBag diagnostics) => statement switch
- {
- UntypedUnexpectedStatement unexpected => new BoundUnexpectedStatement(unexpected.Syntax),
- UntypedNoOpStatement noOp => this.TypeNoOpStatement(noOp, constraints, diagnostics),
- UntypedLocalFunction func => this.TypeLocalFunction(func, constraints, diagnostics),
- UntypedLabelStatement label => this.TypeLabelStatement(label, constraints, diagnostics),
- UntypedLocalDeclaration local => this.TypeLocalDeclaration(local, constraints, diagnostics),
- UntypedExpressionStatement expr => this.TypeExpressionStatement(expr, constraints, diagnostics),
- _ => throw new ArgumentOutOfRangeException(nameof(statement)),
- };
-
- private BoundStatement TypeNoOpStatement(UntypedNoOpStatement noOp, ConstraintSolver constraints, DiagnosticBag diagnostics)
- {
- if (noOp.Syntax is null) return BoundNoOpStatement.Default;
- return new BoundNoOpStatement(noOp.Syntax);
- }
-
- private BoundStatement TypeLocalFunction(UntypedLocalFunction func, ConstraintSolver constraints, DiagnosticBag diagnostics) =>
- new BoundLocalFunction(func.Syntax, func.Symbol);
-
- private BoundStatement TypeLabelStatement(UntypedLabelStatement label, ConstraintSolver constraints, DiagnosticBag diagnostics) =>
- new BoundLabelStatement(label.Syntax, label.Label);
-
- private BoundStatement TypeLocalDeclaration(UntypedLocalDeclaration local, ConstraintSolver constraints, DiagnosticBag diagnostics)
- {
- var typedValue = local.Value is null ? null : this.TypeExpression(local.Value, constraints, diagnostics);
- var typedLocal = constraints.GetTypedLocal(local.Local, diagnostics);
- return new BoundLocalDeclaration(local.Syntax, typedLocal, typedValue);
- }
-
- private BoundStatement TypeExpressionStatement(UntypedExpressionStatement expr, ConstraintSolver constraints, DiagnosticBag diagnostics)
- {
- var typedExpr = this.TypeExpression(expr.Expression, constraints, diagnostics);
- return new BoundExpressionStatement(expr.Syntax, typedExpr);
- }
-}
diff --git a/src/Draco.Compiler/Internal/Binding/Binder_UntypedCommon.cs b/src/Draco.Compiler/Internal/Binding/Binder_Common.cs
similarity index 90%
rename from src/Draco.Compiler/Internal/Binding/Binder_UntypedCommon.cs
rename to src/Draco.Compiler/Internal/Binding/Binder_Common.cs
index 2d7eb294f..af6852c03 100644
--- a/src/Draco.Compiler/Internal/Binding/Binder_UntypedCommon.cs
+++ b/src/Draco.Compiler/Internal/Binding/Binder_Common.cs
@@ -1,15 +1,15 @@
using System.Diagnostics;
using Draco.Compiler.Api.Syntax;
+using Draco.Compiler.Internal.BoundTree;
using Draco.Compiler.Internal.Solver;
using Draco.Compiler.Internal.Symbols;
using Draco.Compiler.Internal.Symbols.Source;
-using Draco.Compiler.Internal.UntypedTree;
namespace Draco.Compiler.Internal.Binding;
internal partial class Binder
{
- protected void ConstraintReturnType(SyntaxNode returnSyntax, UntypedExpression returnValue, ConstraintSolver constraints)
+ protected void ConstraintReturnType(SyntaxNode returnSyntax, BoundExpression returnValue, ConstraintSolver constraints)
{
var containingFunction = (FunctionSymbol?)this.ContainingSymbol;
Debug.Assert(containingFunction is not null);
diff --git a/src/Draco.Compiler/Internal/Binding/Binder_UntypedExpression.cs b/src/Draco.Compiler/Internal/Binding/Binder_Expression.cs
similarity index 81%
rename from src/Draco.Compiler/Internal/Binding/Binder_UntypedExpression.cs
rename to src/Draco.Compiler/Internal/Binding/Binder_Expression.cs
index 9c3f6a703..f8660f5e7 100644
--- a/src/Draco.Compiler/Internal/Binding/Binder_UntypedExpression.cs
+++ b/src/Draco.Compiler/Internal/Binding/Binder_Expression.cs
@@ -3,13 +3,13 @@
using System.Linq;
using Draco.Compiler.Api.Diagnostics;
using Draco.Compiler.Api.Syntax;
+using Draco.Compiler.Internal.BoundTree;
using Draco.Compiler.Internal.Diagnostics;
using Draco.Compiler.Internal.Solver;
using Draco.Compiler.Internal.Symbols;
using Draco.Compiler.Internal.Symbols.Error;
using Draco.Compiler.Internal.Symbols.Source;
using Draco.Compiler.Internal.Symbols.Synthetized;
-using Draco.Compiler.Internal.UntypedTree;
using Draco.Compiler.Internal.Utilities;
namespace Draco.Compiler.Internal.Binding;
@@ -23,10 +23,10 @@ internal partial class Binder
/// The constraints that has been collected during the binding process.
/// The diagnostics produced during the process.
/// The untyped expression for .
- protected virtual UntypedExpression BindExpression(SyntaxNode syntax, ConstraintSolver constraints, DiagnosticBag diagnostics) => syntax switch
+ protected virtual BoundExpression BindExpression(SyntaxNode syntax, ConstraintSolver constraints, DiagnosticBag diagnostics) => syntax switch
{
// NOTE: The syntax error is already reported
- UnexpectedExpressionSyntax => new UntypedUnexpectedExpression(syntax),
+ UnexpectedExpressionSyntax => new BoundUnexpectedExpression(syntax),
GroupingExpressionSyntax grp => this.BindExpression(grp.Expression, constraints, diagnostics),
StatementExpressionSyntax stmt => this.BindStatementExpression(stmt, constraints, diagnostics),
LiteralExpressionSyntax lit => this.BindLiteralExpression(lit, constraints, diagnostics),
@@ -48,27 +48,27 @@ internal partial class Binder
_ => throw new ArgumentOutOfRangeException(nameof(syntax)),
};
- private UntypedExpression BindStatementExpression(StatementExpressionSyntax syntax, ConstraintSolver constraints, DiagnosticBag diagnostics)
+ private BoundExpression BindStatementExpression(StatementExpressionSyntax syntax, ConstraintSolver constraints, DiagnosticBag diagnostics)
{
// We just desugar stmt; into { stmt; }
var stmt = this.BindStatement(syntax.Statement, constraints, diagnostics);
- return new UntypedBlockExpression(
+ return new BoundBlockExpression(
syntax: syntax,
locals: ImmutableArray.Empty,
statements: ImmutableArray.Create(stmt),
- value: UntypedUnitExpression.Default);
+ value: BoundUnitExpression.Default);
}
- private UntypedExpression BindLiteralExpression(LiteralExpressionSyntax syntax, ConstraintSolver constraints, DiagnosticBag diagnostics)
+ private BoundExpression BindLiteralExpression(LiteralExpressionSyntax syntax, ConstraintSolver constraints, DiagnosticBag diagnostics)
{
if (!BinderFacts.TryGetLiteralType(syntax.Literal.Value, this.IntrinsicSymbols, out var literalType))
{
throw new InvalidOperationException("can not determine literal type");
}
- return new UntypedLiteralExpression(syntax, syntax.Literal.Value, literalType);
+ return new BoundLiteralExpression(syntax, syntax.Literal.Value, literalType);
}
- private UntypedExpression BindStringExpression(StringExpressionSyntax syntax, ConstraintSolver constraints, DiagnosticBag diagnostics)
+ private BoundExpression BindStringExpression(StringExpressionSyntax syntax, ConstraintSolver constraints, DiagnosticBag diagnostics)
{
var lastNewline = true;
var cutoff = SyntaxFacts.ComputeCutoff(syntax);
@@ -104,10 +104,10 @@ private UntypedExpression BindStringExpression(StringExpressionSyntax syntax, Co
throw new ArgumentOutOfRangeException();
}
}
- return new UntypedStringExpression(syntax, parts.ToImmutable(), this.IntrinsicSymbols.String);
+ return new BoundStringExpression(syntax, parts.ToImmutable(), this.IntrinsicSymbols.String);
}
- private UntypedExpression BindNameExpression(NameExpressionSyntax syntax, ConstraintSolver constraints, DiagnosticBag diagnostics)
+ private BoundExpression BindNameExpression(NameExpressionSyntax syntax, ConstraintSolver constraints, DiagnosticBag diagnostics)
{
var symbol = BinderFacts.SyntaxMustNotReferenceTypes(syntax)
? this.LookupNonTypeValueSymbol(syntax.Name.Text, syntax, diagnostics)
@@ -115,7 +115,7 @@ private UntypedExpression BindNameExpression(NameExpressionSyntax syntax, Constr
return this.SymbolToExpression(syntax, symbol, constraints, diagnostics);
}
- private UntypedExpression BindBlockExpression(BlockExpressionSyntax syntax, ConstraintSolver constraints, DiagnosticBag diagnostics)
+ private BoundExpression BindBlockExpression(BlockExpressionSyntax syntax, ConstraintSolver constraints, DiagnosticBag diagnostics)
{
var binder = this.GetBinder(syntax);
var locals = binder.DeclaredSymbols
@@ -125,29 +125,29 @@ private UntypedExpression BindBlockExpression(BlockExpressionSyntax syntax, Cons
.Select(s => binder.BindStatement(s, constraints, diagnostics))
.ToImmutableArray();
var value = syntax.Value is null
- ? UntypedUnitExpression.Default
+ ? BoundUnitExpression.Default
: binder.BindExpression(syntax.Value, constraints, diagnostics);
- return new UntypedBlockExpression(syntax, locals, statements, value);
+ return new BoundBlockExpression(syntax, locals, statements, value);
}
- private UntypedExpression BindGotoExpression(GotoExpressionSyntax syntax, ConstraintSolver constraints, DiagnosticBag diagnostics)
+ private BoundExpression BindGotoExpression(GotoExpressionSyntax syntax, ConstraintSolver constraints, DiagnosticBag diagnostics)
{
var target = (LabelSymbol)this.BindLabel(syntax.Target, constraints, diagnostics);
- return new UntypedGotoExpression(syntax, target);
+ return new BoundGotoExpression(syntax, target);
}
- private UntypedExpression BindReturnExpression(ReturnExpressionSyntax syntax, ConstraintSolver constraints, DiagnosticBag diagnostics)
+ private BoundExpression BindReturnExpression(ReturnExpressionSyntax syntax, ConstraintSolver constraints, DiagnosticBag diagnostics)
{
var value = syntax.Value is null
- ? UntypedUnitExpression.Default
+ ? BoundUnitExpression.Default
: this.BindExpression(syntax.Value, constraints, diagnostics);
this.ConstraintReturnType(syntax, value, constraints);
- return new UntypedReturnExpression(syntax, value);
+ return new BoundReturnExpression(syntax, value);
}
- private UntypedExpression BindIfExpression(IfExpressionSyntax syntax, ConstraintSolver constraints, DiagnosticBag diagnostics)
+ private BoundExpression BindIfExpression(IfExpressionSyntax syntax, ConstraintSolver constraints, DiagnosticBag diagnostics)
{
var condition = this.BindExpression(syntax.Condition, constraints, diagnostics);
// Condition must be bool
@@ -155,7 +155,7 @@ private UntypedExpression BindIfExpression(IfExpressionSyntax syntax, Constraint
var then = this.BindExpression(syntax.Then, constraints, diagnostics);
var @else = syntax.Else is null
- ? UntypedUnitExpression.Default
+ ? BoundUnitExpression.Default
: this.BindExpression(syntax.Else.Expression, constraints, diagnostics);
// Then and else must be compatible types
@@ -175,10 +175,10 @@ private UntypedExpression BindIfExpression(IfExpressionSyntax syntax, Constraint
// If there is an else clause, we annotate the then clause as related info
location: ExtractValueSyntax(syntax.Then).Location));
- return new UntypedIfExpression(syntax, condition, then, @else, resultType);
+ return new BoundIfExpression(syntax, condition, then, @else, resultType);
}
- private UntypedExpression BindWhileExpression(WhileExpressionSyntax syntax, ConstraintSolver constraints, DiagnosticBag diagnostics)
+ private BoundExpression BindWhileExpression(WhileExpressionSyntax syntax, ConstraintSolver constraints, DiagnosticBag diagnostics)
{
var binder = this.GetBinder(syntax);
@@ -198,10 +198,10 @@ private UntypedExpression BindWhileExpression(WhileExpressionSyntax syntax, Cons
.OfType()
.First(sym => sym.Name == "break");
- return new UntypedWhileExpression(syntax, condition, then, continueLabel, breakLabel);
+ return new BoundWhileExpression(syntax, condition, then, continueLabel, breakLabel);
}
- private UntypedExpression BindForExpression(ForExpressionSyntax syntax, ConstraintSolver constraints, DiagnosticBag diagnostics)
+ private BoundExpression BindForExpression(ForExpressionSyntax syntax, ConstraintSolver constraints, DiagnosticBag diagnostics)
{
var binder = this.GetBinder(syntax);
@@ -230,13 +230,13 @@ private UntypedExpression BindForExpression(ForExpressionSyntax syntax, Constrai
// GetEnumerator
var getEnumeratorMethodsPromise = constraints.Member(sequence.TypeRequired, "GetEnumerator", out _, syntax.Sequence);
- var exprPromise = constraints.Await(getEnumeratorMethodsPromise, UntypedExpression () =>
+ var exprPromise = constraints.Await(getEnumeratorMethodsPromise, BoundExpression () =>
{
var getEnumeratorResult = getEnumeratorMethodsPromise.Result;
if (getEnumeratorResult.IsError)
{
constraints.UnifyAsserted(elementType, IntrinsicSymbols.ErrorType);
- return new UntypedForExpression(
+ return new BoundForExpression(
syntax,
iterator,
sequence,
@@ -318,7 +318,7 @@ private UntypedExpression BindForExpression(ForExpressionSyntax syntax, Constrai
return default;
});
- return new UntypedForExpression(
+ return new BoundForExpression(
syntax,
iterator,
sequence,
@@ -329,10 +329,10 @@ private UntypedExpression BindForExpression(ForExpressionSyntax syntax, Constrai
moveNextPromise,
currentPromise);
});
- return new UntypedDelayedExpression(syntax, exprPromise, IntrinsicSymbols.Unit);
+ return new BoundDelayedExpression(syntax, exprPromise, IntrinsicSymbols.Unit);
}
- private UntypedExpression BindCallExpression(CallExpressionSyntax syntax, ConstraintSolver constraints, DiagnosticBag diagnostics)
+ private BoundExpression BindCallExpression(CallExpressionSyntax syntax, ConstraintSolver constraints, DiagnosticBag diagnostics)
{
var method = this.BindExpression(syntax.Function, constraints, diagnostics);
var args = syntax.ArgumentList.Values
@@ -342,14 +342,14 @@ private UntypedExpression BindCallExpression(CallExpressionSyntax syntax, Constr
return this.BindCallExpression(syntax, method, args, constraints, diagnostics);
}
- private UntypedExpression BindCallExpression(
+ private BoundExpression BindCallExpression(
CallExpressionSyntax syntax,
- UntypedExpression method,
- ImmutableArray args,
+ BoundExpression method,
+ ImmutableArray args,
ConstraintSolver constraints,
DiagnosticBag diagnostics)
{
- if (method is UntypedDelayedExpression delayed)
+ if (method is BoundDelayedExpression delayed)
{
// The binding is delayed, we have to delay this as well
var promisedType = constraints.AllocateTypeVariable();
@@ -360,9 +360,9 @@ private UntypedExpression BindCallExpression(
constraints.UnifyAsserted(promisedType, call.TypeRequired);
return call;
});
- return new UntypedDelayedExpression(syntax, promise, promisedType);
+ return new BoundDelayedExpression(syntax, promise, promisedType);
}
- else if (method is UntypedFunctionGroupExpression group)
+ else if (method is BoundFunctionGroupExpression group)
{
// Simple overload
// Resolve symbol overload
@@ -373,9 +373,9 @@ private UntypedExpression BindCallExpression(
out var resultType,
syntax.Function);
- return new UntypedCallExpression(syntax, null, symbolPromise, args, resultType);
+ return new BoundCallExpression(syntax, null, symbolPromise, args, resultType);
}
- else if (method is UntypedMemberExpression mem)
+ else if (method is BoundMemberExpression mem)
{
// We are in a bit of a pickle here, the member expression might not be resolved yet,
// and based on it this can be a direct, or indirect call
@@ -383,7 +383,7 @@ private UntypedExpression BindCallExpression(
// otherwise this becomes an indirect call
var promisedType = constraints.AllocateTypeVariable();
- var promise = constraints.Await(mem.Member, UntypedExpression () =>
+ var promise = constraints.Await(mem.Member, BoundExpression () =>
{
var members = mem.Member.Result;
if (members is FunctionSymbol or OverloadSymbol)
@@ -398,7 +398,7 @@ private UntypedExpression BindCallExpression(
syntax.Function);
constraints.UnifyAsserted(resultType, promisedType);
- return new UntypedCallExpression(syntax, mem.Accessed, symbolPromise, args, resultType);
+ return new BoundCallExpression(syntax, mem.Accessed, symbolPromise, args, resultType);
}
else
{
@@ -409,10 +409,10 @@ private UntypedExpression BindCallExpression(
syntax);
constraints.UnifyAsserted(resultType, promisedType);
- return new UntypedIndirectCallExpression(syntax, mem, args, resultType);
+ return new BoundIndirectCallExpression(syntax, mem, args, resultType);
}
});
- return new UntypedDelayedExpression(syntax, promise, promisedType);
+ return new BoundDelayedExpression(syntax, promise, promisedType);
}
else
{
@@ -421,11 +421,11 @@ private UntypedExpression BindCallExpression(
args.Cast