Binder refactoring
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -21,7 +21,8 @@ uses
|
|||||||
Myc.Utils in '..\Src\Myc.Utils.pas',
|
Myc.Utils in '..\Src\Myc.Utils.pas',
|
||||||
Myc.Ast.Script in '..\Src\AST\Myc.Ast.Script.pas',
|
Myc.Ast.Script in '..\Src\AST\Myc.Ast.Script.pas',
|
||||||
Myc.Ast.Types in '..\Src\AST\Myc.Ast.Types.pas',
|
Myc.Ast.Types in '..\Src\AST\Myc.Ast.Types.pas',
|
||||||
Myc.Data.Keyword in '..\Src\Data\Myc.Data.Keyword.pas';
|
Myc.Data.Keyword in '..\Src\Data\Myc.Data.Keyword.pas',
|
||||||
|
Myc.Ast.Binding.Nodes in '..\Src\AST\Myc.Ast.Binding.Nodes.pas';
|
||||||
|
|
||||||
{$R *.res}
|
{$R *.res}
|
||||||
|
|
||||||
|
|||||||
@@ -152,6 +152,7 @@
|
|||||||
<DCCReference Include="..\Src\AST\Myc.Ast.Script.pas"/>
|
<DCCReference Include="..\Src\AST\Myc.Ast.Script.pas"/>
|
||||||
<DCCReference Include="..\Src\AST\Myc.Ast.Types.pas"/>
|
<DCCReference Include="..\Src\AST\Myc.Ast.Types.pas"/>
|
||||||
<DCCReference Include="..\Src\Data\Myc.Data.Keyword.pas"/>
|
<DCCReference Include="..\Src\Data\Myc.Data.Keyword.pas"/>
|
||||||
|
<DCCReference Include="..\Src\AST\Myc.Ast.Binding.Nodes.pas"/>
|
||||||
<BuildConfiguration Include="Base">
|
<BuildConfiguration Include="Base">
|
||||||
<Key>Base</Key>
|
<Key>Base</Key>
|
||||||
</BuildConfiguration>
|
</BuildConfiguration>
|
||||||
|
|||||||
@@ -0,0 +1,144 @@
|
|||||||
|
unit Myc.Ast.Binding.Nodes;
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
System.SysUtils,
|
||||||
|
System.Classes,
|
||||||
|
System.Generics.Collections,
|
||||||
|
Myc.Data.Scalar,
|
||||||
|
Myc.Data.Value,
|
||||||
|
Myc.Ast.Nodes,
|
||||||
|
Myc.Ast.Visitor,
|
||||||
|
Myc.Ast.Scope,
|
||||||
|
Myc.Ast.Types,
|
||||||
|
Myc.Ast;
|
||||||
|
|
||||||
|
type
|
||||||
|
TBoundIdentifierNode = class(TIdentifierNode)
|
||||||
|
private
|
||||||
|
FAddress: TResolvedAddress;
|
||||||
|
public
|
||||||
|
constructor Create(const AUnboundNode: IIdentifierNode; const AAddress: TResolvedAddress);
|
||||||
|
property Address: TResolvedAddress read FAddress;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TBoundVariableDeclarationNode = class(TVariableDeclarationNode)
|
||||||
|
private
|
||||||
|
FIsBoxed: Boolean;
|
||||||
|
public
|
||||||
|
constructor Create(const AIdentifier: IIdentifierNode; AInitializer: IAstNode; AIsBoxed: Boolean);
|
||||||
|
property IsBoxed: Boolean read FIsBoxed;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TBoundLambdaExpressionNode = class(TLambdaExpressionNode)
|
||||||
|
private
|
||||||
|
FScopeDescriptor: IScopeDescriptor;
|
||||||
|
FUpvalues: TArray<TResolvedAddress>;
|
||||||
|
FHasNestedLambdas: Boolean;
|
||||||
|
public
|
||||||
|
constructor Create(
|
||||||
|
const AUnboundNode: ILambdaExpressionNode;
|
||||||
|
const ABody: IAstNode;
|
||||||
|
const AParameters: TArray<IIdentifierNode>;
|
||||||
|
const AScopeDescriptor: IScopeDescriptor;
|
||||||
|
const AUpvalues: TArray<TResolvedAddress>;
|
||||||
|
AHasNestedLambdas: Boolean
|
||||||
|
);
|
||||||
|
property ScopeDescriptor: IScopeDescriptor read FScopeDescriptor;
|
||||||
|
property Upvalues: TArray<TResolvedAddress> read FUpvalues;
|
||||||
|
property HasNestedLambdas: Boolean read FHasNestedLambdas;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TBoundFunctionCallNode = class(TFunctionCallNode)
|
||||||
|
private
|
||||||
|
FIsTailCall: Boolean;
|
||||||
|
public
|
||||||
|
constructor Create(
|
||||||
|
const AUnboundNode: IFunctionCallNode;
|
||||||
|
const ACallee: IAstNode;
|
||||||
|
const AArguments: TArray<IAstNode>;
|
||||||
|
AIsTailCall: Boolean
|
||||||
|
);
|
||||||
|
property IsTailCall: Boolean read FIsTailCall;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TBoundRecordLiteralNode = class(TRecordLiteralNode)
|
||||||
|
private
|
||||||
|
FDefinition: IScalarRecordDefinition;
|
||||||
|
public
|
||||||
|
constructor Create(const AFields: TArray<TRecordFieldLiteral>; const ADef: IScalarRecordDefinition);
|
||||||
|
property Definition: IScalarRecordDefinition read FDefinition;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Represents a bound record literal that maps to a generic (non-scalar) record
|
||||||
|
TBoundGenericRecordLiteralNode = class(TRecordLiteralNode)
|
||||||
|
private
|
||||||
|
FDefinition: IGenericRecordDefinition;
|
||||||
|
public
|
||||||
|
constructor Create(const AFields: TArray<TRecordFieldLiteral>; const ADef: IGenericRecordDefinition);
|
||||||
|
property Definition: IGenericRecordDefinition read FDefinition;
|
||||||
|
end;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
uses
|
||||||
|
Myc.Data.Keyword;
|
||||||
|
|
||||||
|
{ TBoundIdentifierNode }
|
||||||
|
constructor TBoundIdentifierNode.Create(const AUnboundNode: IIdentifierNode; const AAddress: TResolvedAddress);
|
||||||
|
begin
|
||||||
|
inherited Create(AUnboundNode.Name);
|
||||||
|
FAddress := AAddress;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TBoundVariableDeclarationNode }
|
||||||
|
constructor TBoundVariableDeclarationNode.Create(const AIdentifier: IIdentifierNode; AInitializer: IAstNode; AIsBoxed: Boolean);
|
||||||
|
begin
|
||||||
|
inherited Create(AIdentifier, AInitializer);
|
||||||
|
FIsBoxed := AIsBoxed;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TBoundLambdaExpressionNode }
|
||||||
|
constructor TBoundLambdaExpressionNode.Create(
|
||||||
|
const AUnboundNode: ILambdaExpressionNode;
|
||||||
|
const ABody: IAstNode;
|
||||||
|
const AParameters: TArray<IIdentifierNode>;
|
||||||
|
const AScopeDescriptor: IScopeDescriptor;
|
||||||
|
const AUpvalues: TArray<TResolvedAddress>;
|
||||||
|
AHasNestedLambdas: Boolean
|
||||||
|
);
|
||||||
|
begin
|
||||||
|
inherited Create(AParameters, ABody);
|
||||||
|
FScopeDescriptor := AScopeDescriptor;
|
||||||
|
FUpvalues := AUpvalues;
|
||||||
|
FHasNestedLambdas := AHasNestedLambdas;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TBoundFunctionCallNode }
|
||||||
|
constructor TBoundFunctionCallNode.Create(
|
||||||
|
const AUnboundNode: IFunctionCallNode;
|
||||||
|
const ACallee: IAstNode;
|
||||||
|
const AArguments: TArray<IAstNode>;
|
||||||
|
AIsTailCall: Boolean
|
||||||
|
);
|
||||||
|
begin
|
||||||
|
inherited Create(ACallee, AArguments);
|
||||||
|
FIsTailCall := AIsTailCall;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TBoundGenericRecordLiteralNode }
|
||||||
|
constructor TBoundGenericRecordLiteralNode.Create(const AFields: TArray<TRecordFieldLiteral>; const ADef: IGenericRecordDefinition);
|
||||||
|
begin
|
||||||
|
inherited Create(AFields);
|
||||||
|
FDefinition := ADef;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TBoundRecordLiteralNode }
|
||||||
|
constructor TBoundRecordLiteralNode.Create(const AFields: TArray<TRecordFieldLiteral>; const ADef: IScalarRecordDefinition);
|
||||||
|
begin
|
||||||
|
inherited Create(AFields);
|
||||||
|
FDefinition := ADef;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
+12
-131
@@ -105,77 +105,13 @@ type
|
|||||||
): IAstNode; static;
|
): IAstNode; static;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TBoundIdentifierNode = class(TIdentifierNode)
|
|
||||||
private
|
|
||||||
FAddress: TResolvedAddress;
|
|
||||||
public
|
|
||||||
constructor Create(const AUnboundNode: IIdentifierNode; const AAddress: TResolvedAddress);
|
|
||||||
property Address: TResolvedAddress read FAddress;
|
|
||||||
end;
|
|
||||||
|
|
||||||
TBoundVariableDeclarationNode = class(TVariableDeclarationNode)
|
|
||||||
private
|
|
||||||
FIsBoxed: Boolean;
|
|
||||||
public
|
|
||||||
constructor Create(const AIdentifier: IIdentifierNode; AInitializer: IAstNode; AIsBoxed: Boolean);
|
|
||||||
property IsBoxed: Boolean read FIsBoxed;
|
|
||||||
end;
|
|
||||||
|
|
||||||
TBoundLambdaExpressionNode = class(TLambdaExpressionNode)
|
|
||||||
private
|
|
||||||
FScopeDescriptor: IScopeDescriptor;
|
|
||||||
FUpvalues: TArray<TResolvedAddress>;
|
|
||||||
FHasNestedLambdas: Boolean;
|
|
||||||
public
|
|
||||||
constructor Create(
|
|
||||||
const AUnboundNode: ILambdaExpressionNode;
|
|
||||||
const ABody: IAstNode;
|
|
||||||
const AParameters: TArray<IIdentifierNode>;
|
|
||||||
const AScopeDescriptor: IScopeDescriptor;
|
|
||||||
const AUpvalues: TArray<TResolvedAddress>;
|
|
||||||
AHasNestedLambdas: Boolean
|
|
||||||
);
|
|
||||||
property ScopeDescriptor: IScopeDescriptor read FScopeDescriptor;
|
|
||||||
property Upvalues: TArray<TResolvedAddress> read FUpvalues;
|
|
||||||
property HasNestedLambdas: Boolean read FHasNestedLambdas;
|
|
||||||
end;
|
|
||||||
|
|
||||||
TBoundFunctionCallNode = class(TFunctionCallNode)
|
|
||||||
private
|
|
||||||
FIsTailCall: Boolean;
|
|
||||||
public
|
|
||||||
constructor Create(
|
|
||||||
const AUnboundNode: IFunctionCallNode;
|
|
||||||
const ACallee: IAstNode;
|
|
||||||
const AArguments: TArray<IAstNode>;
|
|
||||||
AIsTailCall: Boolean
|
|
||||||
);
|
|
||||||
property IsTailCall: Boolean read FIsTailCall;
|
|
||||||
end;
|
|
||||||
|
|
||||||
TBoundRecordLiteralNode = class(TRecordLiteralNode)
|
|
||||||
private
|
|
||||||
FDefinition: IScalarRecordDefinition;
|
|
||||||
public
|
|
||||||
constructor Create(const AFields: TArray<TRecordFieldLiteral>; const ADef: IScalarRecordDefinition);
|
|
||||||
property Definition: IScalarRecordDefinition read FDefinition;
|
|
||||||
end;
|
|
||||||
|
|
||||||
// Represents a bound record literal that maps to a generic (non-scalar) record
|
|
||||||
TBoundGenericRecordLiteralNode = class(TRecordLiteralNode)
|
|
||||||
private
|
|
||||||
FDefinition: IGenericRecordDefinition;
|
|
||||||
public
|
|
||||||
constructor Create(const AFields: TArray<TRecordFieldLiteral>; const ADef: IGenericRecordDefinition);
|
|
||||||
property Definition: IGenericRecordDefinition read FDefinition;
|
|
||||||
end;
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
System.Generics.Defaults,
|
System.Generics.Defaults,
|
||||||
System.Character,
|
System.Character,
|
||||||
Myc.Data.Keyword;
|
Myc.Data.Keyword,
|
||||||
|
Myc.Ast.Binding.Nodes;
|
||||||
|
|
||||||
type
|
type
|
||||||
TResolvedAddressComparer = class(TEqualityComparer<TResolvedAddress>)
|
TResolvedAddressComparer = class(TEqualityComparer<TResolvedAddress>)
|
||||||
@@ -307,62 +243,6 @@ begin
|
|||||||
Result := inherited VisitRecordLiteral(Node);
|
Result := inherited VisitRecordLiteral(Node);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TBoundIdentifierNode }
|
|
||||||
constructor TBoundIdentifierNode.Create(const AUnboundNode: IIdentifierNode; const AAddress: TResolvedAddress);
|
|
||||||
begin
|
|
||||||
inherited Create(AUnboundNode.Name);
|
|
||||||
FAddress := AAddress;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TBoundVariableDeclarationNode }
|
|
||||||
constructor TBoundVariableDeclarationNode.Create(const AIdentifier: IIdentifierNode; AInitializer: IAstNode; AIsBoxed: Boolean);
|
|
||||||
begin
|
|
||||||
inherited Create(AIdentifier, AInitializer);
|
|
||||||
FIsBoxed := AIsBoxed;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TBoundLambdaExpressionNode }
|
|
||||||
constructor TBoundLambdaExpressionNode.Create(
|
|
||||||
const AUnboundNode: ILambdaExpressionNode;
|
|
||||||
const ABody: IAstNode;
|
|
||||||
const AParameters: TArray<IIdentifierNode>;
|
|
||||||
const AScopeDescriptor: IScopeDescriptor;
|
|
||||||
const AUpvalues: TArray<TResolvedAddress>;
|
|
||||||
AHasNestedLambdas: Boolean
|
|
||||||
);
|
|
||||||
begin
|
|
||||||
inherited Create(AParameters, ABody);
|
|
||||||
FScopeDescriptor := AScopeDescriptor;
|
|
||||||
FUpvalues := AUpvalues;
|
|
||||||
FHasNestedLambdas := AHasNestedLambdas;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TBoundFunctionCallNode }
|
|
||||||
constructor TBoundFunctionCallNode.Create(
|
|
||||||
const AUnboundNode: IFunctionCallNode;
|
|
||||||
const ACallee: IAstNode;
|
|
||||||
const AArguments: TArray<IAstNode>;
|
|
||||||
AIsTailCall: Boolean
|
|
||||||
);
|
|
||||||
begin
|
|
||||||
inherited Create(ACallee, AArguments);
|
|
||||||
FIsTailCall := AIsTailCall;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TBoundGenericRecordLiteralNode }
|
|
||||||
constructor TBoundGenericRecordLiteralNode.Create(const AFields: TArray<TRecordFieldLiteral>; const ADef: IGenericRecordDefinition);
|
|
||||||
begin
|
|
||||||
inherited Create(AFields);
|
|
||||||
FDefinition := ADef;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TBoundRecordLiteralNode }
|
|
||||||
constructor TBoundRecordLiteralNode.Create(const AFields: TArray<TRecordFieldLiteral>; const ADef: IScalarRecordDefinition);
|
|
||||||
begin
|
|
||||||
inherited Create(AFields);
|
|
||||||
FDefinition := ADef;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TResolvedAddressComparer }
|
{ TResolvedAddressComparer }
|
||||||
function TResolvedAddressComparer.Equals(const Left, Right: TResolvedAddress): Boolean;
|
function TResolvedAddressComparer.Equals(const Left, Right: TResolvedAddress): Boolean;
|
||||||
begin
|
begin
|
||||||
@@ -656,16 +536,17 @@ begin
|
|||||||
if Length(args) <> Length(signature.ParamTypes) then
|
if Length(args) <> Length(signature.ParamTypes) then
|
||||||
raise ETypeException.CreateFmt('Function expects %d arguments, but got %d', [Length(signature.ParamTypes), Length(args)]);
|
raise ETypeException.CreateFmt('Function expects %d arguments, but got %d', [Length(signature.ParamTypes), Length(args)]);
|
||||||
retType := signature.ReturnType;
|
retType := signature.ReturnType;
|
||||||
end;
|
|
||||||
|
|
||||||
// Check argument types (param types are not yet inferred, so skip check for now)
|
// Check argument types
|
||||||
// for i := 0 to High(args) do
|
for i := 0 to High(args) do
|
||||||
// begin
|
begin
|
||||||
// var argType := (args[i] as TAstNode).StaticType;
|
var argType := (args[i] as TAstNode).StaticType;
|
||||||
// var paramType := signature.ParamTypes[i];
|
var paramType := signature.ParamTypes[i];
|
||||||
// if not TTypeRules.CanAssign(paramType, argType) then
|
if not TTypeRules.CanAssign(paramType, argType) then
|
||||||
// raise ETypeException.CreateFmt('Cannot assign argument %d (type %s) to parameter (type %s)', [i, argType.ToString, paramType.ToString]);
|
raise ETypeException
|
||||||
// end;
|
.CreateFmt('Cannot assign argument %d (type %s) to parameter (type %s)', [i, argType.ToString, paramType.ToString]);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
boundCall := TBoundFunctionCallNode.Create(Node, callee, args, isTailCall);
|
boundCall := TBoundFunctionCallNode.Create(Node, callee, args, isTailCall);
|
||||||
Result := SetType(TDataValue.FromIntf<IFunctionCallNode>(boundCall), retType);
|
Result := SetType(TDataValue.FromIntf<IFunctionCallNode>(boundCall), retType);
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ implementation
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Myc.Data.Keyword,
|
Myc.Data.Keyword,
|
||||||
Myc.Ast.Binding; // For TBound...Node classes
|
Myc.Ast.Binding.Nodes;
|
||||||
|
|
||||||
{ TAstDumper }
|
{ TAstDumper }
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,8 @@ uses
|
|||||||
Myc.Data.Keyword,
|
Myc.Data.Keyword,
|
||||||
Myc.Data.Decimal,
|
Myc.Data.Decimal,
|
||||||
Myc.Data.Series,
|
Myc.Data.Series,
|
||||||
Myc.Data.Scalar.JSON;
|
Myc.Data.Scalar.JSON,
|
||||||
|
Myc.Ast.Binding.Nodes;
|
||||||
|
|
||||||
// Helper type for TCO via trampolining.
|
// Helper type for TCO via trampolining.
|
||||||
type
|
type
|
||||||
|
|||||||
Reference in New Issue
Block a user