From 8914d5960703a2a4d265f3245c8e32970db2cab7 Mon Sep 17 00:00:00 2001 From: Michael Schimmel Date: Sun, 4 Jan 2026 15:29:26 +0100 Subject: [PATCH] Refactoring Keyword mapping, introducing tuples --- Src/AST/Myc.Ast.Evaluator.pas | 20 ++++---- Src/AST/Myc.Ast.RTL.Core.pas | 5 +- Src/AST/Myc.Ast.RTL.TypeRegistry.pas | 2 +- Src/Data/Myc.Data.Value.pas | 75 ++++++++++++++-------------- Test/AST/Test.Myc.Ast.Pipes.pas | 8 +-- Test/Demo.Finance.pas | 2 +- 6 files changed, 56 insertions(+), 56 deletions(-) diff --git a/Src/AST/Myc.Ast.Evaluator.pas b/Src/AST/Myc.Ast.Evaluator.pas index 020fdc5..549b037 100644 --- a/Src/AST/Myc.Ast.Evaluator.pas +++ b/Src/AST/Myc.Ast.Evaluator.pas @@ -344,7 +344,7 @@ begin var i64 := idx.AsScalar.Value.AsInt64; for var k := 0 to rs.Def.Count - 1 do vals[k] := rs.Fields[rs.Def.Keywords[k]].Items[Integer(i64)].Value; - Result := TDataValue.FromScalarRecord(TScalarRecord.Create(rs.Def, vals)); + Result := TScalarRecord.Create(rs.Def, vals); end else raise EEvaluatorException.Create('Indexer error'); @@ -358,10 +358,10 @@ begin if base.IsVoid then exit(TDataValue.Void); case base.Kind of - vkRecordSeries: Result := TDataValue.FromSeries(base.AsRecordSeries.Fields[N.Member.Value]); - vkScalarRecord: Result := TDataValue(base.AsScalarRecord.Fields[N.Member.Value]); - vkRecord: Result := TDataValue(base.AsRecord.Fields[N.Member.Value]); - vkStream: Result := TDataValue.FromSeries(base.AsStream.Series.Fields[N.Member.Value]); + vkRecordSeries: Result := base.AsRecordSeries.Fields[N.Member.Value]; + vkScalarRecord: Result := base.AsScalarRecord.Fields[N.Member.Value]; + vkRecord: Result := base.AsRecord.Fields[N.Member.Value]; + vkStream: Result := base.AsStream.Series.Fields[N.Member.Value]; else raise EEvaluatorException.Create('Member error'); end; @@ -377,7 +377,7 @@ begin SetLength(vals, N.Fields.Count); for i := 0 to N.Fields.Count - 1 do vals[i] := Visit(N.Fields[i].Value).AsScalar.Value; - Result := TDataValue.FromScalarRecord(TScalarRecord.Create(N.ScalarDefinition, vals)); + Result := TScalarRecord.Create(N.ScalarDefinition, vals); end else begin @@ -385,16 +385,16 @@ begin SetLength(fields, N.Fields.Count); for i := 0 to N.Fields.Count - 1 do fields[i] := TPair.Create(N.Fields[i].Key.Value, Visit(N.Fields[i].Value)); - Result := TDataValue.FromGenericRecord(TGenericRecord.Create(fields)); + Result := TGenericRecord.Create(fields); end; end; function TEvaluatorVisitor.VisitCreateSeries(const N: ICreateSeriesNode): TDataValue; begin if N.Definition.Trim.StartsWith('[') then - Result := TDataValue.FromRecordSeries(TScalarRecordSeries.Create(TRttiAstHelper.JsonToRecordDefinition(N.Definition))) + Result := TScalarRecordSeries.Create(TRttiAstHelper.JsonToRecordDefinition(N.Definition)) else - Result := TDataValue.FromSeries(TScalarSeries.Create(TScalar.StringToKind(N.Definition))); + Result := TScalarSeries.Create(TScalar.StringToKind(N.Definition)); end; function TEvaluatorVisitor.VisitAddSeriesItem(const N: IAddSeriesItemNode): TDataValue; @@ -465,7 +465,7 @@ begin R[k] := rec.Items[k].Value; Result := True; end; - Result := TDataValue.FromStream(TPipeStream.Create(config, outputDef, sources, pipeAdapter)); + Result := TPipeStream.Create(config, outputDef, sources, pipeAdapter); end; end. diff --git a/Src/AST/Myc.Ast.RTL.Core.pas b/Src/AST/Myc.Ast.RTL.Core.pas index 752fa98..8bdfb77 100644 --- a/Src/AST/Myc.Ast.RTL.Core.pas +++ b/Src/AST/Myc.Ast.RTL.Core.pas @@ -540,7 +540,7 @@ begin if Args[1].Kind <> vkMethod then raise EArgumentException.Create('The second argument to Map must be a function.'); - Result := TDataValue.FromSeries(TDataValue.Map(sourceArg.AsSeries, Args[1].AsMethod())); + Result := TDataValue.Map(sourceArg.AsSeries, Args[1].AsMethod()); end; class function TRtlFunctions.Reduce(const Args: TArray): TDataValue; @@ -629,8 +629,7 @@ begin Result := TDataValue(sourceSeries.Items[idx]); end; - finalSeries := TDataValue.Map(indexSeries, mapperFunc); - Result := TDataValue.FromSeries(finalSeries); + Result := TDataValue.Map(indexSeries, mapperFunc); end; class function TRtlFunctions.Any(const Args: TArray): TDataValue; diff --git a/Src/AST/Myc.Ast.RTL.TypeRegistry.pas b/Src/AST/Myc.Ast.RTL.TypeRegistry.pas index 7f07da4..6dc3cce 100644 --- a/Src/AST/Myc.Ast.RTL.TypeRegistry.pas +++ b/Src/AST/Myc.Ast.RTL.TypeRegistry.pas @@ -482,7 +482,7 @@ begin end; end; - Result := TDataValue.FromGenericRecord(TGenericRecord.Create(recFields.ToArray)); + Result := TGenericRecord.Create(recFields.ToArray); finally recFields.Free; end; diff --git a/Src/Data/Myc.Data.Value.pas b/Src/Data/Myc.Data.Value.pas index 29f5447..dcae958 100644 --- a/Src/Data/Myc.Data.Value.pas +++ b/Src/Data/Myc.Data.Value.pas @@ -10,6 +10,7 @@ uses Myc.Data.Scalar, Myc.Data.Series, Myc.Data.Stream, + Myc.Data.Tuple, Myc.Data.Keyword; type @@ -38,7 +39,6 @@ type TDataValue = record type - TTuple = TArray; TFunc = reference to function(const ArgNodes: TArray): TDataValue; private @@ -76,6 +76,13 @@ type class operator Implicit(const AValue: String): TDataValue; overload; inline; class operator Implicit(const AValue: TDataValue.TFunc): TDataValue; overload; inline; + class operator Implicit(const AValue: IKeywordMapping): TDataValue; overload; inline; + class operator Implicit(const AValue: IKeywordMapping): TDataValue; overload; inline; + + class operator Implicit(const AValue: IWriteableScalarRecordSeries): TDataValue; overload; inline; + class operator Implicit(const AValue: ISeries): TDataValue; overload; inline; + class operator Implicit(const AValue: IStream): TDataValue; overload; inline; + // --- Existing Factories --- class function FromIntf(const AValue: T): TDataValue; static; function AsIntf: T; inline; @@ -91,12 +98,6 @@ type class function Map(const SourceSeries: ISeries; const MapperFunc: TFunc): ISeries; static; - class function FromRecordSeries(const AValue: IWriteableScalarRecordSeries): TDataValue; static; inline; - class function FromScalarRecord(const AValue: IKeywordMapping): TDataValue; static; inline; - class function FromGenericRecord(const AValue: IKeywordMapping): TDataValue; static; inline; - class function FromSeries(const AValue: ISeries): TDataValue; static; inline; - class function FromStream(const AStream: IStream): TDataValue; static; inline; - // --- Existing Accessors --- function AsScalar: TScalar; inline; function AsMethod: TFunc; inline; @@ -264,36 +265,6 @@ begin FInterface := TObjVal.Create(AValue); end; -class function TDataValue.FromSeries(const AValue: ISeries): TDataValue; -begin - Result.FKind := vkSeries; - Result.FInterface := AValue; -end; - -class function TDataValue.FromRecordSeries(const AValue: IWriteableScalarRecordSeries): TDataValue; -begin - Result.FKind := vkRecordSeries; - Result.FInterface := AValue; -end; - -class function TDataValue.FromScalarRecord(const AValue: IKeywordMapping): TDataValue; -begin - Result.FKind := vkScalarRecord; - Result.FInterface := AValue; -end; - -class function TDataValue.FromGenericRecord(const AValue: IKeywordMapping): TDataValue; -begin - Result.FKind := vkRecord; - Result.FInterface := AValue; -end; - -class function TDataValue.FromStream(const AStream: IStream): TDataValue; -begin - Result.FKind := vkStream; - Result.FInterface := AStream; -end; - class function TDataValue.Map(const SourceSeries: ISeries; const MapperFunc: TFunc): ISeries; begin Result := TMapSeries.Create(SourceSeries, MapperFunc); @@ -478,6 +449,36 @@ begin end; end; +class operator TDataValue.Implicit(const AValue: IKeywordMapping): TDataValue; +begin + Result.FKind := vkScalarRecord; + Result.FInterface := AValue; +end; + +class operator TDataValue.Implicit(const AValue: IKeywordMapping): TDataValue; +begin + Result.FKind := vkRecord; + Result.FInterface := AValue; +end; + +class operator TDataValue.Implicit(const AValue: IWriteableScalarRecordSeries): TDataValue; +begin + Result.FKind := vkRecordSeries; + Result.FInterface := AValue; +end; + +class operator TDataValue.Implicit(const AValue: ISeries): TDataValue; +begin + Result.FKind := vkSeries; + Result.FInterface := AValue; +end; + +class operator TDataValue.Implicit(const AValue: IStream): TDataValue; +begin + Result.FKind := vkStream; + Result.FInterface := AValue; +end; + { TMapSeries } constructor TMapSeries.Create(const ASourceSeries: ISeries; const AMapperFunc: TDataValue.TFunc); diff --git a/Test/AST/Test.Myc.Ast.Pipes.pas b/Test/AST/Test.Myc.Ast.Pipes.pas index 256f1c1..267373d 100644 --- a/Test/AST/Test.Myc.Ast.Pipes.pas +++ b/Test/AST/Test.Myc.Ast.Pipes.pas @@ -192,7 +192,7 @@ begin source := CreateSourceSeries('val', TScalar.TKind.Ordinal, [10, 20, 30]); mockStream := TTestStream.Create(source); - FEnv.RootScope.Define('src', TDataValue.FromStream(mockStream), TTypes.CreateRecordSeries(source.Def)); + FEnv.RootScope.Define('src', mockStream, TTypes.CreateRecordSeries(source.Def)); // Act script := '(pipe [src [:val]] (fn [x] {:res (* x 2)}))'; @@ -225,7 +225,7 @@ begin source := CreateSourceSeries('val', TScalar.TKind.Ordinal, [1]); mockStream := TTestStream.Create(source); - FEnv.RootScope.Define('src', TDataValue.FromStream(mockStream), TTypes.CreateRecordSeries(source.Def)); + FEnv.RootScope.Define('src', mockStream, TTypes.CreateRecordSeries(source.Def)); script := '(pipe [src [:non_existent]] (fn [x] {:res x}))'; @@ -249,8 +249,8 @@ begin m1 := TTestStream.Create(s1); m2 := TTestStream.Create(s2); - FEnv.RootScope.Define('in1', TDataValue.FromStream(m1), TTypes.CreateRecordSeries(s1.Def)); - FEnv.RootScope.Define('in2', TDataValue.FromStream(m2), TTypes.CreateRecordSeries(s2.Def)); + FEnv.RootScope.Define('in1', m1, TTypes.CreateRecordSeries(s1.Def)); + FEnv.RootScope.Define('in2', m2, TTypes.CreateRecordSeries(s2.Def)); // Act script := '(pipe [in1 [:a] in2 [:b]] (fn [valA valB] {:sum (+ valA valB)}))'; diff --git a/Test/Demo.Finance.pas b/Test/Demo.Finance.pas index e050a4f..9560383 100644 --- a/Test/Demo.Finance.pas +++ b/Test/Demo.Finance.pas @@ -85,7 +85,7 @@ begin // Für den Compiler ist es eine RecordSeries (Typ), zur Laufzeit ein Stream (Wert) StaticType := TTypes.CreateRecordSeries(Def); - Scope.Define(VarName, TDataValue.FromStream(Stream), StaticType); + Scope.Define(VarName, Stream, StaticType); end; procedure TFinanceSimulator.AddRandomCandle(const Scope: IExecutionScope; const VarName: string);