Refactoring

This commit is contained in:
Michael Schimmel
2025-09-19 09:03:02 +02:00
parent 565742275c
commit ef16003971
4 changed files with 83 additions and 34 deletions
+16 -14
View File
@@ -126,8 +126,6 @@ var
i: Integer; i: Integer;
sourceAddresses: TArray<TResolvedAddress>; sourceAddresses: TArray<TResolvedAddress>;
closureScope: IExecutionScope; closureScope: IExecutionScope;
[weak]
closure: TDataValue.TFunc;
visitorFactory: TVisitorFactory; visitorFactory: TVisitorFactory;
begin begin
sourceAddresses := Node.Upvalues; sourceAddresses := Node.Upvalues;
@@ -146,7 +144,9 @@ begin
var scopeDescriptor := Node.ScopeDescriptor; var scopeDescriptor := Node.ScopeDescriptor;
var params := Node.Parameters; var params := Node.Parameters;
// weak reference to break cyclic referencing // declare closure as weak to break cyclic referencing when it is captured by itself
var [weak] closure: TDataValue.TFunc;
closure := closure :=
TDataValue.TFunc( TDataValue.TFunc(
function(const ArgValues: TArray<TDataValue>): TDataValue function(const ArgValues: TArray<TDataValue>): TDataValue
@@ -182,35 +182,37 @@ begin
end end
); );
Result := TDataValue(closure); Result := closure;
end; end;
function TEvaluatorVisitor.VisitFunctionCall(const Node: IFunctionCallNode): TDataValue; function TEvaluatorVisitor.VisitFunctionCall(const Node: IFunctionCallNode): TDataValue;
var var
calleeValue: TDataValue; calleeValue: TDataValue;
[weak]
callee: TDataValue.TFunc;
begin begin
calleeValue := Node.Callee.Accept(Self); calleeValue := Node.Callee.Accept(Self);
if calleeValue.Kind <> vkMethod then case calleeValue.Kind of
vkMethod: callee := calleeValue.AsMethod();
else
raise EArgumentException.Create('Expression is not invokable in this context.'); raise EArgumentException.Create('Expression is not invokable in this context.');
end;
var argNodes := Node.Arguments; var argNodes := Node.Arguments;
case Length(argNodes) of case Length(argNodes) of
0: Result := (calleeValue.AsMethod)([]); 0: Result := callee([]);
1: Result := (calleeValue.AsMethod)([argNodes[0].Accept(Self)]); 1: Result := callee([argNodes[0].Accept(Self)]);
2: Result := (calleeValue.AsMethod)([argNodes[0].Accept(Self), argNodes[1].Accept(Self)]); 2: Result := callee([argNodes[0].Accept(Self), argNodes[1].Accept(Self)]);
3: Result := (calleeValue.AsMethod)([argNodes[0].Accept(Self), argNodes[1].Accept(Self), argNodes[2].Accept(Self)]); 3: Result := callee([argNodes[0].Accept(Self), argNodes[1].Accept(Self), argNodes[2].Accept(Self)]);
4: 4: Result := callee([argNodes[0].Accept(Self), argNodes[1].Accept(Self), argNodes[2].Accept(Self), argNodes[3].Accept(Self)]);
Result :=
(calleeValue.AsMethod)
([argNodes[0].Accept(Self), argNodes[1].Accept(Self), argNodes[2].Accept(Self), argNodes[3].Accept(Self)]);
else else
var argValues: TArray<TDataValue>; var argValues: TArray<TDataValue>;
SetLength(argValues, Length(argNodes)); SetLength(argValues, Length(argNodes));
for var i := 0 to High(argNodes) do for var i := 0 to High(argNodes) do
argValues[i] := argNodes[i].Accept(Self); argValues[i] := argNodes[i].Accept(Self);
Result := (calleeValue.AsMethod)(argValues); Result := callee(argValues);
end; end;
end; end;
+66 -1
View File
@@ -78,7 +78,7 @@ type
// Creates a new scalar from a kind and a value. // Creates a new scalar from a kind and a value.
constructor Create(AKind: TScalarKind; const AValue: TScalarValue); constructor Create(AKind: TScalarKind; const AValue: TScalarValue);
// Factory methods for specific scalar types. // Factory methods for specific scalar types (do not use anymore, these may become deprecated in the future)
class function FromInteger(AValue: Integer): TScalar; static; inline; class function FromInteger(AValue: Integer): TScalar; static; inline;
class function FromInt64(AValue: Int64): TScalar; static; inline; class function FromInt64(AValue: Int64): TScalar; static; inline;
class function FromUInt64(AValue: UInt64): TScalar; static; inline; class function FromUInt64(AValue: UInt64): TScalar; static; inline;
@@ -93,6 +93,17 @@ type
class function FromBytes(const AValue: TScalarBytes): TScalar; static; inline; class function FromBytes(const AValue: TScalarBytes): TScalar; static; inline;
class function FromDecimal(const AValue: TDecimal): TScalar; static; inline; class function FromDecimal(const AValue: TDecimal): TScalar; static; inline;
// Implicit casts from primitive types to TScalar.
class operator Implicit(AValue: Integer): TScalar; overload; inline;
class operator Implicit(AValue: Int64): TScalar; overload; inline;
class operator Implicit(AValue: UInt64): TScalar; overload; inline;
class operator Implicit(AValue: Single): TScalar; overload; inline;
class operator Implicit(AValue: Double): TScalar; overload; inline;
class operator Implicit(AValue: TDateTime): TScalar; overload; inline;
class operator Implicit(AValue: Boolean): TScalar; overload; inline;
class operator Implicit(AValue: Char): TScalar; overload; inline;
class operator Implicit(const AValue: TDecimal): TScalar; overload; inline;
class function StringToKind(const AName: string): TScalarKind; static; class function StringToKind(const AName: string): TScalarKind; static;
function ToString: String; function ToString: String;
@@ -405,6 +416,60 @@ begin
Result.Value := TScalarValue.FromDouble(AValue); Result.Value := TScalarValue.FromDouble(AValue);
end; end;
class operator TScalar.Implicit(AValue: Boolean): TScalar;
begin
Result.Kind := skBoolean;
Result.Value := TScalarValue.FromBoolean(AValue);
end;
class operator TScalar.Implicit(AValue: Char): TScalar;
begin
Result.Kind := skChar;
Result.Value := TScalarValue.FromChar(AValue);
end;
class operator TScalar.Implicit(AValue: TDateTime): TScalar;
begin
Result.Kind := skDateTime;
Result.Value := TScalarValue.FromDateTime(AValue);
end;
class operator TScalar.Implicit(const AValue: TDecimal): TScalar;
begin
Result.Kind := skDecimal;
Result.Value := TScalarValue.FromDecimal(AValue);
end;
class operator TScalar.Implicit(AValue: Double): TScalar;
begin
Result.Kind := skDouble;
Result.Value := TScalarValue.FromDouble(AValue);
end;
class operator TScalar.Implicit(AValue: Int64): TScalar;
begin
Result.Kind := skInt64;
Result.Value := TScalarValue.FromInt64(AValue);
end;
class operator TScalar.Implicit(AValue: Integer): TScalar;
begin
Result.Kind := skInteger;
Result.Value := TScalarValue.FromInteger(AValue);
end;
class operator TScalar.Implicit(AValue: Single): TScalar;
begin
Result.Kind := skSingle;
Result.Value := TScalarValue.FromSingle(AValue);
end;
class operator TScalar.Implicit(AValue: UInt64): TScalar;
begin
Result.Kind := skUInt64;
Result.Value := TScalarValue.FromUInt64(AValue);
end;
class function TScalar.FromInt64(AValue: Int64): TScalar; class function TScalar.FromInt64(AValue: Int64): TScalar;
begin begin
Result.Kind := skInt64; Result.Kind := skInt64;
+1 -10
View File
@@ -15,7 +15,7 @@ uses
{$ENDIF } {$ENDIF }
DUnitX.TestFramework, DUnitX.TestFramework,
TestNotifier in 'TestNotifier.pas', TestNotifier in 'TestNotifier.pas',
TestNotifier_Threading in 'TestNotifier_Threading.pas' {/TestNotifier_ChaosStress in 'TestNotifier_ChaosStress.pas',}, TestNotifier_Threading in 'TestNotifier_Threading.pas',
TestNotifier_ChaosStress in 'TestNotifier_ChaosStress.pas', TestNotifier_ChaosStress in 'TestNotifier_ChaosStress.pas',
TestTasks in 'TestTasks.pas', TestTasks in 'TestTasks.pas',
TestCoreFutures in 'TestCoreFutures.pas', TestCoreFutures in 'TestCoreFutures.pas',
@@ -25,17 +25,8 @@ uses
Myc.Test.Signals.Dirty in '..\Src\Myc.Test.Signals.Dirty.pas', Myc.Test.Signals.Dirty in '..\Src\Myc.Test.Signals.Dirty.pas',
Test.Core.Mutable in 'Test.Core.Mutable.pas', Test.Core.Mutable in 'Test.Core.Mutable.pas',
TestDataArray in 'TestDataArray.pas', TestDataArray in 'TestDataArray.pas',
Myc.Data.Types in '..\Src\Myc.Data.Types.pas',
Myc.Data.Types.Ordinal in 'Myc.Data.Types.Ordinal.pas',
Myc.Data.Types.Records in 'Myc.Data.Types.Records.pas',
Myc.Data.Types.Float in 'Myc.Data.Types.Float.pas',
Myc.Data.Types.Arrays in 'Myc.Data.Types.Arrays.pas',
TestDataTypes in '..\Src\Data\TestDataTypes.pas', TestDataTypes in '..\Src\Data\TestDataTypes.pas',
Myc.Data.Types.Method in '..\Src\Data\Myc.Data.Types.Method.pas',
Myc.Data.Types.Void in '..\Src\Data\Myc.Data.Types.Void.pas',
Myc.Data.Types.Decimal in '..\Src\Data\Myc.Data.Types.Decimal.pas',
Myc.Ast in '..\Src\AST\Myc.Ast.pas', Myc.Ast in '..\Src\AST\Myc.Ast.pas',
Myc.Data.Types.JSON in '..\Src\Data\Myc.Data.Types.JSON.pas',
TestDataTypes.JSON in '..\Src\Data\TestDataTypes.JSON.pas', TestDataTypes.JSON in '..\Src\Data\TestDataTypes.JSON.pas',
Myc.Data.POD in '..\Src\Data\Myc.Data.Scalar.pas', Myc.Data.POD in '..\Src\Data\Myc.Data.Scalar.pas',
Myc.Data.Decimal in '..\Src\Data\Myc.Data.Decimal.pas', Myc.Data.Decimal in '..\Src\Data\Myc.Data.Decimal.pas',
-9
View File
@@ -126,17 +126,8 @@ $(PreBuildEvent)]]></PreBuildEvent>
<DCCReference Include="..\Src\Myc.Test.Signals.Dirty.pas"/> <DCCReference Include="..\Src\Myc.Test.Signals.Dirty.pas"/>
<DCCReference Include="Test.Core.Mutable.pas"/> <DCCReference Include="Test.Core.Mutable.pas"/>
<DCCReference Include="TestDataArray.pas"/> <DCCReference Include="TestDataArray.pas"/>
<DCCReference Include="..\Src\Myc.Data.Types.pas"/>
<DCCReference Include="Myc.Data.Types.Ordinal.pas"/>
<DCCReference Include="Myc.Data.Types.Records.pas"/>
<DCCReference Include="Myc.Data.Types.Float.pas"/>
<DCCReference Include="Myc.Data.Types.Arrays.pas"/>
<DCCReference Include="..\Src\Data\TestDataTypes.pas"/> <DCCReference Include="..\Src\Data\TestDataTypes.pas"/>
<DCCReference Include="..\Src\Data\Myc.Data.Types.Method.pas"/>
<DCCReference Include="..\Src\Data\Myc.Data.Types.Void.pas"/>
<DCCReference Include="..\Src\Data\Myc.Data.Types.Decimal.pas"/>
<DCCReference Include="..\Src\AST\Myc.Ast.pas"/> <DCCReference Include="..\Src\AST\Myc.Ast.pas"/>
<DCCReference Include="..\Src\Data\Myc.Data.Types.JSON.pas"/>
<DCCReference Include="..\Src\Data\TestDataTypes.JSON.pas"/> <DCCReference Include="..\Src\Data\TestDataTypes.JSON.pas"/>
<DCCReference Include="..\Src\Data\Myc.Data.Scalar.pas"> <DCCReference Include="..\Src\Data\Myc.Data.Scalar.pas">
<ModuleName>Myc.Data.POD</ModuleName> <ModuleName>Myc.Data.POD</ModuleName>