Ast series indexer
This commit is contained in:
@@ -9,7 +9,8 @@ uses
|
||||
Myc.Ast.Nodes in '..\Src\AST\Myc.Ast.Nodes.pas',
|
||||
Myc.Ast.Scope in '..\Src\AST\Myc.Ast.Scope.pas',
|
||||
DraggablePanel in 'DraggablePanel.pas',
|
||||
Myc.Ast.Visualizer in 'Myc.Ast.Visualizer.pas';
|
||||
Myc.Ast.Visualizer in 'Myc.Ast.Visualizer.pas',
|
||||
Myc.Ast.RttiUtils in 'Myc.Ast.RttiUtils.pas';
|
||||
|
||||
{$R *.res}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<ProjectVersion>20.3</ProjectVersion>
|
||||
<FrameworkType>FMX</FrameworkType>
|
||||
<Base>True</Base>
|
||||
<Config Condition="'$(Config)'==''">Debug</Config>
|
||||
<Config Condition="'$(Config)'==''">Release</Config>
|
||||
<Platform Condition="'$(Platform)'==''">Win64</Platform>
|
||||
<ProjectName Condition="'$(ProjectName)'==''">ASTPlayground</ProjectName>
|
||||
<TargetedPlatforms>2</TargetedPlatforms>
|
||||
@@ -141,6 +141,7 @@
|
||||
<DCCReference Include="..\Src\AST\Myc.Ast.Scope.pas"/>
|
||||
<DCCReference Include="DraggablePanel.pas"/>
|
||||
<DCCReference Include="Myc.Ast.Visualizer.pas"/>
|
||||
<DCCReference Include="Myc.Ast.RttiUtils.pas"/>
|
||||
<BuildConfiguration Include="Base">
|
||||
<Key>Base</Key>
|
||||
</BuildConfiguration>
|
||||
@@ -190,6 +191,12 @@
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployFile LocalName="Win64\Release\ASTPlayground.exe" Configuration="Release" Class="ProjectOutput">
|
||||
<Platform Name="Win64">
|
||||
<RemoteName>ASTPlayground.exe</RemoteName>
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployClass Name="AdditionalDebugSymbols">
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
|
||||
@@ -113,6 +113,17 @@ object Form1: TForm1
|
||||
Text = 'Flow only'
|
||||
OnChange = ClearButtonClick
|
||||
end
|
||||
object SeriesTestButton: TButton
|
||||
Position.X = 24.000000000000000000
|
||||
Position.Y = 152.000000000000000000
|
||||
Size.Width = 80.000000000000000000
|
||||
Size.Height = 22.000000000000000000
|
||||
Size.PlatformDefault = False
|
||||
TabOrder = 14
|
||||
Text = 'Series'
|
||||
TextSettings.Trimming = None
|
||||
OnClick = SeriesTestButtonClick
|
||||
end
|
||||
end
|
||||
object Panel2: TPanel
|
||||
Align = Client
|
||||
|
||||
+138
-13
@@ -5,6 +5,7 @@ interface
|
||||
uses
|
||||
System.SysUtils,
|
||||
System.Types,
|
||||
System.TypInfo,
|
||||
System.UITypes,
|
||||
System.Classes,
|
||||
System.Variants,
|
||||
@@ -46,6 +47,7 @@ type
|
||||
Panel2: TPanel;
|
||||
ClearButton: TButton;
|
||||
FlowOnlyBox: TCheckBox;
|
||||
SeriesTestButton: TButton;
|
||||
procedure ClearButtonClick(Sender: TObject);
|
||||
procedure FormCreate(Sender: TObject);
|
||||
procedure CrerateTriggerExampleButtonClick(Sender: TObject);
|
||||
@@ -55,6 +57,7 @@ type
|
||||
procedure FibonacciButtonClick(Sender: TObject);
|
||||
procedure PrettyPrintButtonClick(Sender: TObject);
|
||||
procedure RecursionButtonClick(Sender: TObject);
|
||||
procedure SeriesTestButtonClick(Sender: TObject);
|
||||
procedure Test1ButtonClick(Sender: TObject);
|
||||
procedure Test2ButtonClick(Sender: TObject);
|
||||
private
|
||||
@@ -74,6 +77,8 @@ implementation
|
||||
|
||||
uses
|
||||
Myc.Ast.Scope,
|
||||
Myc.Ast.RttiUtils,
|
||||
Myc.Data.Decimal,
|
||||
System.Diagnostics; // For TStopwatch
|
||||
|
||||
{$R *.fmx}
|
||||
@@ -185,6 +190,7 @@ begin
|
||||
Application.ProcessMessages; // Update UI before blocking
|
||||
|
||||
sw.Start;
|
||||
{
|
||||
root :=
|
||||
TAst.Block(
|
||||
[
|
||||
@@ -215,7 +221,7 @@ begin
|
||||
TAst.FunctionCall(TAst.Identifier('fib'), [TAst.Constant(TScalar.FromInt64(30))])
|
||||
]
|
||||
);
|
||||
|
||||
}
|
||||
root :=
|
||||
TAst.Block(
|
||||
[
|
||||
@@ -344,18 +350,15 @@ begin
|
||||
[TAst.Identifier('n')],
|
||||
TAst.Block(
|
||||
[
|
||||
TAst.Assign(
|
||||
TAst.Identifier('Result'),
|
||||
TAst.TernaryExpr(
|
||||
TAst.BinaryExpr(TAst.Identifier('n'), boLess, TAst.Constant(TScalar.FromInt64(2))),
|
||||
TAst.Constant(TScalar.FromInt64(1)),
|
||||
TAst.BinaryExpr(
|
||||
TAst.Identifier('n'),
|
||||
boMultiply,
|
||||
TAst.FunctionCall(
|
||||
TAst.Identifier('factorial'),
|
||||
[TAst.BinaryExpr(TAst.Identifier('n'), boSubtract, TAst.Constant(TScalar.FromInt64(1)))]
|
||||
)
|
||||
TAst.TernaryExpr(
|
||||
TAst.BinaryExpr(TAst.Identifier('n'), boLess, TAst.Constant(TScalar.FromInt64(2))),
|
||||
TAst.Constant(TScalar.FromInt64(1)),
|
||||
TAst.BinaryExpr(
|
||||
TAst.Identifier('n'),
|
||||
boMultiply,
|
||||
TAst.FunctionCall(
|
||||
TAst.Identifier('factorial'),
|
||||
[TAst.BinaryExpr(TAst.Identifier('n'), boSubtract, TAst.Constant(TScalar.FromInt64(1)))]
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -379,6 +382,128 @@ begin
|
||||
Memo1.Lines.Add('(AST structure stored. Click "Pretty Print" or "Debug" to view.)');
|
||||
end;
|
||||
|
||||
procedure TForm1.SeriesTestButtonClick(Sender: TObject);
|
||||
type
|
||||
// A test record to generate a definition from.
|
||||
TOHLCV = record
|
||||
Timestamp: TDateTime;
|
||||
Open: Double;
|
||||
High: Double;
|
||||
Low: Double;
|
||||
Close: Double;
|
||||
Volume: Int64;
|
||||
end;
|
||||
var
|
||||
jsonDef: string;
|
||||
recordDef: TScalarRecordDefinition;
|
||||
series: TScalarRecordSeries;
|
||||
recordValue: TScalarRecord;
|
||||
visitor: IAstVisitor;
|
||||
ast: IAstNode;
|
||||
resultValue: TAstValue;
|
||||
resultRecord: TScalarRecord;
|
||||
i: Integer;
|
||||
begin
|
||||
Memo1.Lines.Clear;
|
||||
Memo1.Lines.Add('--- Series Test ---');
|
||||
|
||||
// --- 1. Arrange (in Delphi) ---
|
||||
Memo1.Lines.Add('1. Arranging test data in Delphi...');
|
||||
|
||||
// Clear and prepare the global scope for the script.
|
||||
FGScope.Clear;
|
||||
RegisterNativeFunctions(FGScope);
|
||||
|
||||
// Generate JSON definition from our test record type.
|
||||
jsonDef := TRttiAstHelper.RecordDefinitionToJson(TypeInfo(TOHLCV));
|
||||
FGScope.SetValue('ohlcvDef', TAstValue.FromText(jsonDef));
|
||||
Memo1.Lines.Add(' - Generated and injected JSON definition for TOHLCV.');
|
||||
|
||||
// Create a TScalarRecordSeries and populate it with some data.
|
||||
recordDef := TRttiAstHelper.JsonToRecordDefinition(jsonDef);
|
||||
series := TScalarRecordSeries.Create(recordDef);
|
||||
for i := 0 to 4 do
|
||||
begin
|
||||
recordValue :=
|
||||
TScalarRecord.Create(
|
||||
recordDef,
|
||||
[
|
||||
TScalarValue.FromDateTime(Now + i),
|
||||
TScalarValue.FromDouble(100.0 + i),
|
||||
TScalarValue.FromDouble(105.0 + i),
|
||||
TScalarValue.FromDouble(98.0 + i),
|
||||
TScalarValue.FromDouble(102.0 + i),
|
||||
TScalarValue.FromInt64(10000 * (i + 1))
|
||||
]
|
||||
);
|
||||
series.Add(recordValue);
|
||||
end;
|
||||
|
||||
// Inject the pre-populated series into the script's scope.
|
||||
FGScope.SetValue('ohlcvSeries', TAstValue.FromRecordSeries(series));
|
||||
Memo1.Lines.Add(Format(' - Created and injected a series with %d records.', [series.TotalCount]));
|
||||
Memo1.Lines.Add('');
|
||||
|
||||
// --- 2. Act (in Script) ---
|
||||
Memo1.Lines.Add('2. Executing script...');
|
||||
|
||||
// Create an AST that:
|
||||
// a) Creates a new, empty series to test the native function.
|
||||
// b) Accesses the 3rd element (index 2) of the pre-populated series.
|
||||
// c) Returns the accessed record as the final result.
|
||||
ast :=
|
||||
TAst.Block(
|
||||
[
|
||||
TAst.VarDecl(
|
||||
TAst.Identifier('newSeries'),
|
||||
TAst.FunctionCall(TAst.Identifier('CreateRecordSeries'), [TAst.Identifier('ohlcvDef')])
|
||||
),
|
||||
TAst.Indexer(TAst.Identifier('ohlcvSeries'), TAst.Constant(TScalar.FromInt64(2)))
|
||||
]
|
||||
);
|
||||
FLastAst := ast;
|
||||
|
||||
visitor := TEvaluatorVisitor.Create(FGScope);
|
||||
resultValue := ast.Accept(visitor);
|
||||
Memo1.Lines.Add(' - Script finished.');
|
||||
Memo1.Lines.Add(Format(' - Script returned value of type: %s', [GetEnumName(TypeInfo(TAstValueKind), Ord(resultValue.Kind))]));
|
||||
Memo1.Lines.Add('');
|
||||
|
||||
// --- 3. Assert (in Delphi) ---
|
||||
Memo1.Lines.Add('3. Asserting results in Delphi...');
|
||||
|
||||
if (resultValue.Kind <> avkRecord) then
|
||||
begin
|
||||
Memo1.Lines.Add('TEST FAILED: Script did not return a record.');
|
||||
exit;
|
||||
end;
|
||||
|
||||
resultRecord := resultValue.AsRecord;
|
||||
Memo1.Lines.Add(' - Result is a record, as expected.');
|
||||
|
||||
// Verify the 'Close' price of the 3rd record (index 2)
|
||||
var closeValue := resultRecord.Items['Close'].Value.AsDouble;
|
||||
var expectedClose := 102.0 + 2; // from the data generation loop for i=2
|
||||
if (abs(closeValue - expectedClose) > 0.001) then
|
||||
begin
|
||||
Memo1.Lines.Add(Format('TEST FAILED: Expected Close price %f, but got %f.', [expectedClose, closeValue]));
|
||||
exit;
|
||||
end;
|
||||
Memo1.Lines.Add(Format(' - Verified Close price: %f.', [closeValue]));
|
||||
|
||||
// Verify the 'Volume' of the 3rd record (index 2)
|
||||
var volumeValue := resultRecord.Items['Volume'].Value.AsInt64;
|
||||
var expectedVolume := 10000 * (2 + 1); // for i=2
|
||||
if (volumeValue <> expectedVolume) then
|
||||
begin
|
||||
Memo1.Lines.Add(Format('TEST FAILED: Expected Volume %d, but got %d.', [expectedVolume, volumeValue]));
|
||||
exit;
|
||||
end;
|
||||
Memo1.Lines.Add(Format(' - Verified Volume: %d.', [volumeValue]));
|
||||
Memo1.Lines.Add('');
|
||||
Memo1.Lines.Add('--- TEST PASSED ---');
|
||||
end;
|
||||
|
||||
procedure TForm1.Test1ButtonClick(Sender: TObject);
|
||||
var
|
||||
scope: IExecutionScope;
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
unit Myc.Ast.RttiUtils;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
System.SysUtils,
|
||||
System.Rtti,
|
||||
System.TypInfo,
|
||||
Myc.Data.POD;
|
||||
|
||||
type
|
||||
TRttiAstHelper = class
|
||||
private
|
||||
// Maps a Delphi RTTI type to its TScalarKind.
|
||||
class function TypeToScalarKind(AType: TRttiType): TScalarKind; static;
|
||||
public
|
||||
// Creates a JSON definition string from a record type info.
|
||||
class function RecordDefinitionToJson(ATypeInfo: PTypeInfo): string; static;
|
||||
// Creates a record definition from a JSON string.
|
||||
class function JsonToRecordDefinition(const AJson: string): TScalarRecordDefinition; static;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
Myc.Data.Decimal,
|
||||
System.JSON;
|
||||
|
||||
{ TRttiAstHelper }
|
||||
|
||||
class function TRttiAstHelper.JsonToRecordDefinition(const AJson: string): TScalarRecordDefinition;
|
||||
var
|
||||
jsonValue: TJSONValue;
|
||||
rootObj: TJSONObject;
|
||||
fieldsArray: TJSONArray;
|
||||
i: Integer;
|
||||
fieldObj: TJSONObject;
|
||||
kindStr: string;
|
||||
fields: TArray<TScalarRecordField>;
|
||||
begin
|
||||
jsonValue := TJSONObject.ParseJSONValue(AJson);
|
||||
if not Assigned(jsonValue) then
|
||||
exit;
|
||||
|
||||
try
|
||||
if not (jsonValue is TJSONObject) then
|
||||
exit;
|
||||
|
||||
rootObj := jsonValue as TJSONObject;
|
||||
if not rootObj.TryGetValue<TJSONArray>('fields', fieldsArray) then
|
||||
exit;
|
||||
|
||||
SetLength(fields, fieldsArray.Count);
|
||||
for i := 0 to fieldsArray.Count - 1 do
|
||||
begin
|
||||
fieldObj := fieldsArray.Items[i] as TJSONObject;
|
||||
if not Assigned(fieldObj) then
|
||||
continue; // or raise error
|
||||
|
||||
fields[i].Name := fieldObj.GetValue<string>('name');
|
||||
|
||||
kindStr := fieldObj.GetValue<string>('kind');
|
||||
fields[i].Kind := TScalarKind(GetEnumValue(TypeInfo(TScalarKind), kindStr));
|
||||
end;
|
||||
Result := TScalarRecordDefinition.Create(fields);
|
||||
finally
|
||||
jsonValue.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
class function TRttiAstHelper.RecordDefinitionToJson(ATypeInfo: PTypeInfo): string;
|
||||
var
|
||||
ctx: TRttiContext;
|
||||
rttiType: TRttiType;
|
||||
rttiRecordType: TRttiRecordType;
|
||||
field: TRttiField;
|
||||
rootObj: TJSONObject;
|
||||
fieldsArray: TJSONArray;
|
||||
fieldObj: TJSONObject;
|
||||
begin
|
||||
// 1. Create TRttiContext and get TRttiRecordType.
|
||||
ctx := TRttiContext.Create;
|
||||
rttiType := ctx.GetType(ATypeInfo);
|
||||
|
||||
if not (rttiType is TRttiRecordType) then
|
||||
raise EArgumentException.Create('PTypeInfo provided is not a record type.');
|
||||
|
||||
rttiRecordType := rttiType as TRttiRecordType;
|
||||
|
||||
// 2. Create root TJSONObject and a TJSONArray for 'fields'.
|
||||
rootObj := TJSONObject.Create;
|
||||
try
|
||||
fieldsArray := TJSONArray.Create;
|
||||
rootObj.AddPair('fields', fieldsArray);
|
||||
|
||||
// 3. Loop through all fields of the record type.
|
||||
for field in rttiRecordType.GetFields do
|
||||
begin
|
||||
// 4a. Create a TJSONObject for the field definition.
|
||||
fieldObj := TJSONObject.Create;
|
||||
|
||||
// 4b. Add field name.
|
||||
fieldObj.AddPair('name', TJSONString.Create(field.Name));
|
||||
|
||||
// 4c. Call TypeToScalarKind to get the type and add it.
|
||||
fieldObj.AddPair('kind', TJSONString.Create(GetEnumName(TypeInfo(TScalarKind), Ord(TypeToScalarKind(field.FieldType)))));
|
||||
|
||||
// 4d. Add the field object to the 'fields' array.
|
||||
fieldsArray.Add(fieldObj);
|
||||
end;
|
||||
|
||||
// 5. Convert the root JSON object to a string and set it as Result.
|
||||
Result := rootObj.ToJSON;
|
||||
finally
|
||||
rootObj.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
class function TRttiAstHelper.TypeToScalarKind(AType: TRttiType): TScalarKind;
|
||||
var
|
||||
typeHandle: PTypeInfo;
|
||||
begin
|
||||
// 1. Use a case statement or if-checks on AType.Handle.
|
||||
typeHandle := AType.Handle;
|
||||
|
||||
// 2. Compare with TypeInfo(Integer), TypeInfo(Double), TypeInfo(TDecimal) etc.
|
||||
if typeHandle = TypeInfo(Integer) then
|
||||
Result := skInteger
|
||||
else if typeHandle = TypeInfo(Int64) then
|
||||
Result := skInt64
|
||||
else if typeHandle = TypeInfo(UInt64) then
|
||||
Result := skUInt64
|
||||
else if typeHandle = TypeInfo(Single) then
|
||||
Result := skSingle
|
||||
else if typeHandle = TypeInfo(Double) then
|
||||
Result := skDouble
|
||||
else if typeHandle = TypeInfo(TDateTime) then
|
||||
Result := skDateTime
|
||||
else if typeHandle = TypeInfo(Boolean) then
|
||||
Result := skBoolean
|
||||
else if typeHandle = TypeInfo(Char) then
|
||||
Result := skChar
|
||||
else if typeHandle = TypeInfo(TDecimal) then
|
||||
Result := skDecimal
|
||||
else if typeHandle = TypeInfo(TTimestamp) then
|
||||
Result := skTimestamp
|
||||
else
|
||||
// 4. Raise an exception for unsupported types.
|
||||
raise EArgumentException.CreateFmt('Unsupported record field type: %s', [AType.Name]);
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -127,6 +127,7 @@ type
|
||||
function VisitBlockExpression(const Node: IBlockExpressionNode): TAstValue;
|
||||
function VisitVariableDeclaration(const Node: IVariableDeclarationNode): TAstValue;
|
||||
function VisitAssignment(const Node: IAssignmentNode): TAstValue;
|
||||
function VisitIndexer(const Node: IIndexerNode): TAstValue;
|
||||
end;
|
||||
|
||||
TAuraWorkspace = class(TStyledControl)
|
||||
@@ -198,6 +199,7 @@ type
|
||||
function VisitBlockExpression(const Node: IBlockExpressionNode): TAstValue;
|
||||
function VisitVariableDeclaration(const Node: IVariableDeclarationNode): TAstValue;
|
||||
function VisitAssignment(const Node: IAssignmentNode): TAstValue;
|
||||
function VisitIndexer(const Node: IIndexerNode): TAstValue;
|
||||
end;
|
||||
|
||||
constructor TAstToTextVisitor.Create;
|
||||
@@ -264,6 +266,15 @@ begin
|
||||
Result := TAstValue.FromText(Node.Condition.Accept(Self).AsText);
|
||||
end;
|
||||
|
||||
function TAstToTextVisitor.VisitIndexer(const Node: IIndexerNode): TAstValue;
|
||||
var
|
||||
baseStr, indexStr: string;
|
||||
begin
|
||||
baseStr := Node.Base.Accept(Self).AsText;
|
||||
indexStr := Node.Index.Accept(Self).AsText;
|
||||
Result := TAstValue.FromText(Format('%s[%s]', [baseStr, indexStr]));
|
||||
end;
|
||||
|
||||
function TAstToTextVisitor.VisitLambdaExpression(const Node: ILambdaExpressionNode): TAstValue;
|
||||
var
|
||||
i: Integer;
|
||||
@@ -942,6 +953,46 @@ begin
|
||||
Result := TAstValue.Void;
|
||||
end;
|
||||
|
||||
function TAstToAuraNodeVisitor.VisitIndexer(const Node: IIndexerNode): TAstValue;
|
||||
var
|
||||
details: String;
|
||||
begin
|
||||
if (FMode = vmControlFlow) and TryGetDescr(Node, details) then
|
||||
begin
|
||||
var indexerNode := CreateNodeControl('Expression', details);
|
||||
FLastResult.OutputPin := CreateOutput(indexerNode);
|
||||
FinalizeNodeLayout(indexerNode);
|
||||
end
|
||||
else
|
||||
begin
|
||||
VisitOperatorNode(
|
||||
[Node.Base, Node.Index],
|
||||
function(const InputResults: TAuraNodeResultList): TAuraNodeResult
|
||||
var
|
||||
indexerNode: TAuraNode;
|
||||
basePin, indexPin, outPin: TControl;
|
||||
begin
|
||||
indexerNode := BuildNodeControl('[]', '');
|
||||
indexerNode.TitleFont.Size := 20;
|
||||
|
||||
basePin := CreateInput(indexerNode, 'Base');
|
||||
indexPin := CreateInput(indexerNode, 'Index');
|
||||
outPin := CreateOutput(indexerNode);
|
||||
|
||||
if Assigned(InputResults[0].OutputPin) then
|
||||
FConnections.Add(TPinConnection.Create(InputResults[0].OutputPin, basePin));
|
||||
if Assigned(InputResults[1].OutputPin) then
|
||||
FConnections.Add(TPinConnection.Create(InputResults[1].OutputPin, indexPin));
|
||||
|
||||
FinalizeNodeLayout(indexerNode);
|
||||
Result.LayoutNode := indexerNode;
|
||||
Result.OutputPin := outPin;
|
||||
end
|
||||
);
|
||||
end;
|
||||
Result := TAstValue.Void;
|
||||
end;
|
||||
|
||||
function TAstToAuraNodeVisitor.VisitLambdaExpression(const Node: ILambdaExpressionNode): TAstValue;
|
||||
var
|
||||
paramStr: String;
|
||||
@@ -1122,13 +1173,12 @@ end;
|
||||
|
||||
function TAstToAuraNodeVisitor.VisitVariableDeclaration(const Node: IVariableDeclarationNode): TAstValue;
|
||||
var
|
||||
varDeclNode: TAuraNode;
|
||||
outPin: TControl;
|
||||
begin
|
||||
var details: String;
|
||||
if (FMode = vmControlFlow) and TryGetDescr(Node, details) then
|
||||
begin
|
||||
varDeclNode := CreateNodeControl('VarDecl', details);
|
||||
var varDeclNode := CreateNodeControl('VarDecl', details);
|
||||
CreateEntry(varDeclNode);
|
||||
CreateExit(varDeclNode, '');
|
||||
FinalizeNodeLayout(varDeclNode);
|
||||
@@ -1137,40 +1187,39 @@ begin
|
||||
begin
|
||||
if Assigned(Node.Initializer) then
|
||||
begin
|
||||
varDeclNode :=
|
||||
VisitOperatorNode(
|
||||
[Node.Initializer],
|
||||
function(const InputResults: TAuraNodeResultList): TAuraNodeResult
|
||||
var
|
||||
varDeclNode: TAuraNode;
|
||||
inputPin: TControl;
|
||||
initializerResult: TAuraNodeResult;
|
||||
outPin: TControl; // variable for the output pin
|
||||
begin
|
||||
initializerResult := InputResults[0];
|
||||
varDeclNode := BuildNodeControl('VarDecl', Node.Identifier.Name);
|
||||
VisitOperatorNode(
|
||||
[Node.Initializer],
|
||||
function(const InputResults: TAuraNodeResultList): TAuraNodeResult
|
||||
var
|
||||
varDeclNode: TAuraNode;
|
||||
inputPin: TControl;
|
||||
initializerResult: TAuraNodeResult;
|
||||
outPin: TControl; // variable for the output pin
|
||||
begin
|
||||
initializerResult := InputResults[0];
|
||||
varDeclNode := BuildNodeControl('VarDecl', Node.Identifier.Name);
|
||||
|
||||
CreateEntry(varDeclNode);
|
||||
inputPin := CreateInput(varDeclNode, 'Value');
|
||||
CreateExit(varDeclNode, '');
|
||||
CreateEntry(varDeclNode);
|
||||
inputPin := CreateInput(varDeclNode, 'Value');
|
||||
CreateExit(varDeclNode, '');
|
||||
|
||||
// Create the output pin before finalizing the layout.
|
||||
outPin := CreateOutput(varDeclNode);
|
||||
// Create the output pin before finalizing the layout.
|
||||
outPin := CreateOutput(varDeclNode);
|
||||
|
||||
if Assigned(initializerResult.OutputPin) then
|
||||
FConnections.Add(TPinConnection.Create(initializerResult.OutputPin, inputPin));
|
||||
if Assigned(initializerResult.OutputPin) then
|
||||
FConnections.Add(TPinConnection.Create(initializerResult.OutputPin, inputPin));
|
||||
|
||||
// Now finalize, all pins are present.
|
||||
FinalizeNodeLayout(varDeclNode);
|
||||
Result.LayoutNode := varDeclNode;
|
||||
Result.OutputPin := outPin;
|
||||
end
|
||||
);
|
||||
// Now finalize, all pins are present.
|
||||
FinalizeNodeLayout(varDeclNode);
|
||||
Result.LayoutNode := varDeclNode;
|
||||
Result.OutputPin := outPin;
|
||||
end
|
||||
);
|
||||
end
|
||||
else
|
||||
begin
|
||||
// Case without initializer is a simple sequential node.
|
||||
varDeclNode := CreateNodeControl('VarDecl', Node.Identifier.Name);
|
||||
var varDeclNode := CreateNodeControl('VarDecl', Node.Identifier.Name);
|
||||
CreateEntry(varDeclNode);
|
||||
CreateExit(varDeclNode, '');
|
||||
// Create the output pin before finalizing the layout.
|
||||
|
||||
Reference in New Issue
Block a user