Ast Schema

This commit is contained in:
Michael Schimmel
2026-01-06 14:48:22 +01:00
parent 7313848538
commit 74a5c30ae0
4 changed files with 116 additions and 110 deletions
+1 -1
View File
@@ -288,7 +288,7 @@ begin
CompilerStageBox.BringToFront; CompilerStageBox.BringToFront;
ClearButtonClick(Self); ClearButtonClick(Self);
Memo1.Lines.Text := TAstSchema.GenerateFullSystemPrompt; Memo1.Lines.Add(TAstSchema.GenerateFullSystemPrompt);
end; end;
procedure TForm1.ShowVizualization; procedure TForm1.ShowVizualization;
+14 -12
View File
@@ -15,7 +15,7 @@ uses
type type
TAstSchema = class TAstSchema = class
public public
// Generates the TypeScript definition by scanning classes via RTTI // Generates the TypeScript definition by scanning INTERFACES via RTTI
class function GenerateTypeScriptDefinition: string; class function GenerateTypeScriptDefinition: string;
// Static rules for the format // Static rules for the format
@@ -29,7 +29,6 @@ implementation
type type
// Helper structure to collect fields per type // Helper structure to collect fields per type
// Moved here to avoid scope issues with generics
TFieldInfo = record TFieldInfo = record
Idx: Integer; Idx: Integer;
Def: string; Def: string;
@@ -42,6 +41,7 @@ var
ctx: TRttiContext; ctx: TRttiContext;
types: TArray<TRttiType>; types: TArray<TRttiType>;
typ: TRttiType; typ: TRttiType;
prop: TRttiProperty;
attr: TCustomAttribute; attr: TCustomAttribute;
fieldAttr: AstFieldAttribute; fieldAttr: AstFieldAttribute;
nodeDefs: TDictionary<string, TList<TFieldInfo>>; nodeDefs: TDictionary<string, TList<TFieldInfo>>;
@@ -50,7 +50,6 @@ var
sb: TStringBuilder; sb: TStringBuilder;
tag: string; tag: string;
fieldInfo: TFieldInfo; fieldInfo: TFieldInfo;
f: TRttiField;
i: Integer; i: Integer;
function GetTsType(Kind: TFieldKind): string; function GetTsType(Kind: TFieldKind): string;
@@ -74,15 +73,16 @@ begin
sb := TStringBuilder.Create; sb := TStringBuilder.Create;
try try
// 1. Scan all types in the application context // 1. Scan all types (looking for INTERFACES now)
types := ctx.GetTypes; types := ctx.GetTypes;
for typ in types do for typ in types do
begin begin
if not typ.IsInstance then // CHANGE: We now look for Interfaces, not Classes
if typ.TypeKind <> tkInterface then
Continue; Continue;
// Check for [AstTag] attribute on the class // Check for [AstTag] attribute on the interface
tag := ''; tag := '';
for attr in typ.GetAttributes do for attr in typ.GetAttributes do
if attr is AstTagAttribute then if attr is AstTagAttribute then
@@ -102,10 +102,10 @@ begin
fieldsList := nodeDefs[tag]; fieldsList := nodeDefs[tag];
// Scan Fields (Variables) of the class // CHANGE: Scan Properties of the interface
for f in typ.AsInstance.GetFields do for prop in typ.GetProperties do
begin begin
for attr in f.GetAttributes do for attr in prop.GetAttributes do
if attr is AstFieldAttribute then if attr is AstFieldAttribute then
begin begin
fieldAttr := AstFieldAttribute(attr); fieldAttr := AstFieldAttribute(attr);
@@ -119,7 +119,7 @@ begin
end; end;
// 2. Build the output // 2. Build the output
sb.AppendLine('// AST Schema Definition (Auto-Generated via RTTI)'); sb.AppendLine('// AST Schema Definition (Auto-Generated via RTTI from Interfaces)');
sb.AppendLine('// Format: Compact JSON Arrays [Tag, Arg1, Arg2, ...]'); sb.AppendLine('// Format: Compact JSON Arrays [Tag, Arg1, Arg2, ...]');
sb.AppendLine; sb.AppendLine;
@@ -136,13 +136,15 @@ begin
sb.AppendLine(';'); sb.AppendLine(';');
sb.AppendLine; sb.AppendLine;
// Special Handling for Tuple (it's recursive array structure)
sb.AppendLine('type Tuple = ["Tuple", AstNode[]];'); sb.AppendLine('type Tuple = ["Tuple", AstNode[]];');
sb.AppendLine; sb.AppendLine;
// Node Definitions // Node Definitions
for tag in unionTypes do for tag in unionTypes do
begin begin
// Tuple is special base type // Skip Tuple in automatic generation as we defined it manually above
// to represent the array structure correctly in TypeScript
if tag = 'Tuple' then if tag = 'Tuple' then
Continue; Continue;
@@ -202,7 +204,7 @@ class function TAstSchema.GenerateFullSystemPrompt: string;
begin begin
// Combine everything // Combine everything
Result := Result :=
'You are a compiler frontend for the "Myc" scripting language.' 'You are a compiler frontend for a scripting language.'
+ sLineBreak + sLineBreak
+ 'Your task is to generate a valid Abstract Syntax Tree (AST) in a specific Compact JSON format.' + 'Your task is to generate a valid Abstract Syntax Tree (AST) in a specific Compact JSON format.'
+ sLineBreak + sLineBreak
+99 -97
View File
@@ -1,6 +1,3 @@
//==================================================================================================
//== FULL UNIT START: Myc.Ast.Nodes (from Myc.Ast.Nodes.pas)
//==================================================================================================
unit Myc.Ast.Nodes; unit Myc.Ast.Nodes;
interface interface
@@ -14,7 +11,7 @@ uses
Myc.Ast.Scope, Myc.Ast.Scope,
Myc.Ast.Types, Myc.Ast.Types,
Myc.Ast.Identities, Myc.Ast.Identities,
Myc.Ast.Attributes; // Hinzugefügt für [AstTag] und [AstField] Myc.Ast.Attributes;
type type
// --- Forward Declarations --- // --- Forward Declarations ---
@@ -81,16 +78,12 @@ type
IAstVisitor = interface; IAstVisitor = interface;
IAstTypedNode = interface; IAstTypedNode = interface;
// Core Nodes // Forward Declarations of specific nodes
IConstantNode = interface; IConstantNode = interface;
IIdentifierNode = interface; IIdentifierNode = interface;
IKeywordNode = interface; IKeywordNode = interface;
// Structure
ITupleNode = interface; ITupleNode = interface;
IRecordFieldNode = interface; IRecordFieldNode = interface;
// Control Flow & Structure
IIfExpressionNode = interface; IIfExpressionNode = interface;
ICondExpressionNode = interface; ICondExpressionNode = interface;
ILambdaExpressionNode = interface; ILambdaExpressionNode = interface;
@@ -111,8 +104,6 @@ type
ISeriesLengthNode = interface; ISeriesLengthNode = interface;
IRecurNode = interface; IRecurNode = interface;
INopNode = interface; INopNode = interface;
// Pipes
IPipeNode = interface; IPipeNode = interface;
// Node Kinds & Helpers // Node Kinds & Helpers
@@ -121,8 +112,8 @@ type
akIdentifier, akIdentifier,
akKeyword, akKeyword,
// Containers // Containers
akTuple, // The universal list (replaces ArgList, ParamList, ExprList, FieldList) akTuple,
akRecordField, // Single key-value pair akRecordField,
// Control Flow // Control Flow
akIfExpression, akIfExpression,
akCondExpression, akCondExpression,
@@ -153,7 +144,6 @@ type
function ToString: string; function ToString: string;
end; end;
// Represents a single branch in a Cond expression (Condition -> Branch)
TCondPair = record TCondPair = record
Condition: IAstNode; Condition: IAstNode;
Branch: IAstNode; Branch: IAstNode;
@@ -215,18 +205,21 @@ type
property StaticType: IStaticType read GetStaticType; property StaticType: IStaticType read GetStaticType;
end; end;
[AstTag('Field')]
IRecordFieldNode = interface(IAstNode) IRecordFieldNode = interface(IAstNode)
{$region 'private'} {$region 'private'}
function GetKey: IKeywordNode; function GetKey: IKeywordNode;
function GetValue: IAstNode; function GetValue: IAstNode;
{$endregion} {$endregion}
[AstField(0, 'key', fkNode)]
property Key: IKeywordNode read GetKey; property Key: IKeywordNode read GetKey;
[AstField(1, 'value', fkNode)]
property Value: IAstNode read GetValue; property Value: IAstNode read GetValue;
end; end;
// --- Node Interfaces (Definitions) --- // --- Node Interfaces (Definitions) ---
// Function Definition (Lambda)
IFunctionDefinition = interface(IAstTypedNode) IFunctionDefinition = interface(IAstTypedNode)
{$region 'private'} {$region 'private'}
function GetBody: IAstNode; function GetBody: IAstNode;
@@ -238,59 +231,80 @@ type
property IsPure: Boolean read GetIsPure; property IsPure: Boolean read GetIsPure;
end; end;
[AstTag('Nop')]
INopNode = interface(IAstTypedNode) INopNode = interface(IAstTypedNode)
end; end;
[AstTag('Const')]
IConstantNode = interface(IAstTypedNode) IConstantNode = interface(IAstTypedNode)
{$region 'private'} {$region 'private'}
function GetValue: TDataValue; function GetValue: TDataValue;
{$endregion} {$endregion}
[AstField(0, 'value', fkValue)]
property Value: TDataValue read GetValue; property Value: TDataValue read GetValue;
end; end;
[AstTag('Id')]
IIdentifierNode = interface(IAstTypedNode) IIdentifierNode = interface(IAstTypedNode)
{$region 'private'} {$region 'private'}
function GetAddress: TResolvedAddress; function GetAddress: TResolvedAddress;
function GetName: string; function GetName: string;
{$endregion} {$endregion}
property Address: TResolvedAddress read GetAddress; property Address: TResolvedAddress read GetAddress;
[AstField(0, 'name', fkString)]
property Name: string read GetName; property Name: string read GetName;
end; end;
[AstTag('Key')]
IKeywordNode = interface(IAstTypedNode) IKeywordNode = interface(IAstTypedNode)
{$region 'private'} {$region 'private'}
function GetValue: IKeyword; function GetValue: IKeyword;
{$endregion} {$endregion}
[AstField(0, 'name', fkString)]
property Value: IKeyword read GetValue; property Value: IKeyword read GetValue;
end; end;
[AstTag('Tuple')]
ITupleNode = interface(IAstTypedNode) ITupleNode = interface(IAstTypedNode)
{$region 'private'} {$region 'private'}
function GetElements: TArray<IAstNode>; function GetElements: TArray<IAstNode>;
{$endregion} {$endregion}
[AstField(0, 'elements', fkNode)]
property Elements: TArray<IAstNode> read GetElements; property Elements: TArray<IAstNode> read GetElements;
end; end;
[AstTag('If')]
IIfExpressionNode = interface(IAstTypedNode) IIfExpressionNode = interface(IAstTypedNode)
{$region 'private'} {$region 'private'}
function GetCondition: IAstNode; function GetCondition: IAstNode;
function GetThenBranch: IAstNode; function GetThenBranch: IAstNode;
function GetElseBranch: IAstNode; function GetElseBranch: IAstNode;
{$endregion} {$endregion}
[AstField(0, 'cond', fkNode)]
property Condition: IAstNode read GetCondition; property Condition: IAstNode read GetCondition;
[AstField(1, 'then', fkNode)]
property ThenBranch: IAstNode read GetThenBranch; property ThenBranch: IAstNode read GetThenBranch;
[AstField(2, 'else', fkNullableNode)]
property ElseBranch: IAstNode read GetElseBranch; property ElseBranch: IAstNode read GetElseBranch;
end; end;
[AstTag('Cond')]
ICondExpressionNode = interface(IAstTypedNode) ICondExpressionNode = interface(IAstTypedNode)
{$region 'private'} {$region 'private'}
function GetPairs: TArray<TCondPair>; function GetPairs: TArray<TCondPair>;
function GetElseBranch: IAstNode; function GetElseBranch: IAstNode;
{$endregion} {$endregion}
[AstField(0, 'pairs', fkArrayOfPairs)]
property Pairs: TArray<TCondPair> read GetPairs; property Pairs: TArray<TCondPair> read GetPairs;
[AstField(1, 'else', fkNullableNode)]
property ElseBranch: IAstNode read GetElseBranch; property ElseBranch: IAstNode read GetElseBranch;
end; end;
[AstTag('Fn')]
ILambdaExpressionNode = interface(IFunctionDefinition) ILambdaExpressionNode = interface(IFunctionDefinition)
{$region 'private'} {$region 'private'}
function GetLayout: IScopeLayout; function GetLayout: IScopeLayout;
@@ -302,8 +316,16 @@ type
property Descriptor: IScopeDescriptor read GetDescriptor; property Descriptor: IScopeDescriptor read GetDescriptor;
property Upvalues: TArray<TResolvedAddress> read GetUpvalues; property Upvalues: TArray<TResolvedAddress> read GetUpvalues;
property HasNestedLambdas: Boolean read GetHasNestedLambdas; property HasNestedLambdas: Boolean read GetHasNestedLambdas;
// Annotated properties from base interface (for schema generation)
[AstField(0, 'params', fkTuple)]
property Parameters: ITupleNode read GetParameters;
[AstField(1, 'body', fkNode)]
property Body: IAstNode read GetBody;
end; end;
[AstTag('Call')]
IFunctionCallNode = interface(IAstTypedNode) IFunctionCallNode = interface(IAstTypedNode)
{$region 'private'} {$region 'private'}
function GetCallee: IAstNode; function GetCallee: IAstNode;
@@ -312,8 +334,12 @@ type
function GetStaticTarget: TDataValue.TFunc; function GetStaticTarget: TDataValue.TFunc;
function GetIsTargetPure: Boolean; function GetIsTargetPure: Boolean;
{$endregion} {$endregion}
[AstField(0, 'callee', fkNode)]
property Callee: IAstNode read GetCallee; property Callee: IAstNode read GetCallee;
[AstField(1, 'args', fkTuple)]
property Arguments: ITupleNode read GetArguments; property Arguments: ITupleNode read GetArguments;
property IsTailCall: Boolean read GetIsTailCall; property IsTailCall: Boolean read GetIsTailCall;
property StaticTarget: TDataValue.TFunc read GetStaticTarget; property StaticTarget: TDataValue.TFunc read GetStaticTarget;
property IsTargetPure: Boolean read GetIsTargetPure; property IsTargetPure: Boolean read GetIsTargetPure;
@@ -328,135 +354,186 @@ type
property ExpandedBody: IAstNode read GetExpandedBody; property ExpandedBody: IAstNode read GetExpandedBody;
end; end;
[AstTag('Recur')]
IRecurNode = interface(IAstTypedNode) IRecurNode = interface(IAstTypedNode)
{$region 'private'} {$region 'private'}
function GetArguments: ITupleNode; function GetArguments: ITupleNode;
{$endregion} {$endregion}
[AstField(0, 'args', fkTuple)]
property Arguments: ITupleNode read GetArguments; property Arguments: ITupleNode read GetArguments;
end; end;
[AstTag('Block')]
IBlockExpressionNode = interface(IAstTypedNode) IBlockExpressionNode = interface(IAstTypedNode)
{$region 'private'} {$region 'private'}
function GetExpressions: ITupleNode; function GetExpressions: ITupleNode;
{$endregion} {$endregion}
[AstField(0, 'expressions', fkTuple)]
property Expressions: ITupleNode read GetExpressions; property Expressions: ITupleNode read GetExpressions;
end; end;
[AstTag('Var')]
IVariableDeclarationNode = interface(IAstTypedNode) IVariableDeclarationNode = interface(IAstTypedNode)
{$region 'private'} {$region 'private'}
function GetTarget: IAstNode; function GetTarget: IAstNode;
function GetInitializer: IAstNode; function GetInitializer: IAstNode;
function GetIsBoxed: Boolean; function GetIsBoxed: Boolean;
{$endregion} {$endregion}
[AstField(0, 'target', fkNode)]
property Target: IAstNode read GetTarget; property Target: IAstNode read GetTarget;
[AstField(1, 'init', fkNullableNode)]
property Initializer: IAstNode read GetInitializer; property Initializer: IAstNode read GetInitializer;
property IsBoxed: Boolean read GetIsBoxed; property IsBoxed: Boolean read GetIsBoxed;
end; end;
[AstTag('Assign')]
IAssignmentNode = interface(IAstTypedNode) IAssignmentNode = interface(IAstTypedNode)
{$region 'private'} {$region 'private'}
function GetTarget: IAstNode; function GetTarget: IAstNode;
function GetValue: IAstNode; function GetValue: IAstNode;
{$endregion} {$endregion}
[AstField(0, 'target', fkNode)]
property Target: IAstNode read GetTarget; property Target: IAstNode read GetTarget;
[AstField(1, 'value', fkNode)]
property Value: IAstNode read GetValue; property Value: IAstNode read GetValue;
end; end;
[AstTag('Macro')]
IMacroDefinitionNode = interface(IAstTypedNode) IMacroDefinitionNode = interface(IAstTypedNode)
{$region 'private'} {$region 'private'}
function GetName: IIdentifierNode; function GetName: IIdentifierNode;
function GetParameters: ITupleNode; function GetParameters: ITupleNode;
function GetBody: IAstNode; function GetBody: IAstNode;
{$endregion} {$endregion}
[AstField(0, 'name', fkNode)]
property Name: IIdentifierNode read GetName; property Name: IIdentifierNode read GetName;
[AstField(1, 'params', fkTuple)]
property Parameters: ITupleNode read GetParameters; property Parameters: ITupleNode read GetParameters;
[AstField(2, 'body', fkNode)]
property Body: IAstNode read GetBody; property Body: IAstNode read GetBody;
end; end;
[AstTag('Quote')]
IQuasiquoteNode = interface(IAstNode) IQuasiquoteNode = interface(IAstNode)
{$region 'private'} {$region 'private'}
function GetExpression: IAstNode; function GetExpression: IAstNode;
{$endregion} {$endregion}
[AstField(0, 'expr', fkNode)]
property Expression: IAstNode read GetExpression; property Expression: IAstNode read GetExpression;
end; end;
[AstTag('Unquote')]
IUnquoteNode = interface(IAstNode) IUnquoteNode = interface(IAstNode)
{$region 'private'} {$region 'private'}
function GetExpression: IAstNode; function GetExpression: IAstNode;
{$endregion} {$endregion}
[AstField(0, 'expr', fkNode)]
property Expression: IAstNode read GetExpression; property Expression: IAstNode read GetExpression;
end; end;
[AstTag('Splice')]
IUnquoteSplicingNode = interface(IAstNode) IUnquoteSplicingNode = interface(IAstNode)
{$region 'private'} {$region 'private'}
function GetExpression: IQuasiquoteNode; function GetExpression: IQuasiquoteNode;
{$endregion} {$endregion}
[AstField(0, 'expr', fkNode)]
property Expression: IQuasiquoteNode read GetExpression; property Expression: IQuasiquoteNode read GetExpression;
end; end;
[AstTag('Index')]
IIndexerNode = interface(IAstTypedNode) IIndexerNode = interface(IAstTypedNode)
{$region 'private'} {$region 'private'}
function GetBase: IAstNode; function GetBase: IAstNode;
function GetIndex: IAstNode; function GetIndex: IAstNode;
{$endregion} {$endregion}
[AstField(0, 'base', fkNode)]
property Base: IAstNode read GetBase; property Base: IAstNode read GetBase;
[AstField(1, 'index', fkNode)]
property Index: IAstNode read GetIndex; property Index: IAstNode read GetIndex;
end; end;
[AstTag('Member')]
IMemberAccessNode = interface(IAstTypedNode) IMemberAccessNode = interface(IAstTypedNode)
{$region 'private'} {$region 'private'}
function GetBase: IAstNode; function GetBase: IAstNode;
function GetMember: IKeywordNode; function GetMember: IKeywordNode;
{$endregion} {$endregion}
[AstField(0, 'base', fkNode)]
property Base: IAstNode read GetBase; property Base: IAstNode read GetBase;
[AstField(1, 'member', fkNode)]
property Member: IKeywordNode read GetMember; property Member: IKeywordNode read GetMember;
end; end;
[AstTag('Record')]
IRecordLiteralNode = interface(IAstTypedNode) IRecordLiteralNode = interface(IAstTypedNode)
{$region 'private'} {$region 'private'}
function GetFields: ITupleNode; function GetFields: ITupleNode;
function GetGenericDefinition: IGenericRecordDefinition; function GetGenericDefinition: IGenericRecordDefinition;
function GetScalarDefinition: IScalarRecordDefinition; function GetScalarDefinition: IScalarRecordDefinition;
{$endregion} {$endregion}
[AstField(0, 'fields', fkTuple)]
property Fields: ITupleNode read GetFields; property Fields: ITupleNode read GetFields;
property GenericDefinition: IGenericRecordDefinition read GetGenericDefinition; property GenericDefinition: IGenericRecordDefinition read GetGenericDefinition;
property ScalarDefinition: IScalarRecordDefinition read GetScalarDefinition; property ScalarDefinition: IScalarRecordDefinition read GetScalarDefinition;
end; end;
[AstTag('Series')]
ICreateSeriesNode = interface(IAstTypedNode) ICreateSeriesNode = interface(IAstTypedNode)
{$region 'private'} {$region 'private'}
function GetDefinitionNode: IAstNode; function GetDefinitionNode: IAstNode;
function GetRecordDefinition: IScalarRecordDefinition; function GetRecordDefinition: IScalarRecordDefinition;
{$endregion} {$endregion}
[AstField(0, 'definition', fkNode)]
property DefinitionNode: IAstNode read GetDefinitionNode; property DefinitionNode: IAstNode read GetDefinitionNode;
property RecordDefinition: IScalarRecordDefinition read GetRecordDefinition; property RecordDefinition: IScalarRecordDefinition read GetRecordDefinition;
end; end;
[AstTag('Add')]
IAddSeriesItemNode = interface(IAstTypedNode) IAddSeriesItemNode = interface(IAstTypedNode)
{$region 'private'} {$region 'private'}
function GetSeries: IIdentifierNode; function GetSeries: IIdentifierNode;
function GetValue: IAstNode; function GetValue: IAstNode;
function GetLookback: IAstNode; function GetLookback: IAstNode;
{$endregion} {$endregion}
[AstField(0, 'series', fkNode)]
property Series: IIdentifierNode read GetSeries; property Series: IIdentifierNode read GetSeries;
[AstField(1, 'value', fkNode)]
property Value: IAstNode read GetValue; property Value: IAstNode read GetValue;
[AstField(2, 'lookback', fkNullableNode)]
property Lookback: IAstNode read GetLookback; property Lookback: IAstNode read GetLookback;
end; end;
[AstTag('Count')]
ISeriesLengthNode = interface(IAstTypedNode) ISeriesLengthNode = interface(IAstTypedNode)
{$region 'private'} {$region 'private'}
function GetSeries: IIdentifierNode; function GetSeries: IIdentifierNode;
{$endregion} {$endregion}
[AstField(0, 'series', fkNode)]
property Series: IIdentifierNode read GetSeries; property Series: IIdentifierNode read GetSeries;
end; end;
// The main pipe definition: (pipe [[source [:sel]]...] (fn ...)) // The main pipe definition: (pipe [[source [:sel]]...] (fn ...))
[AstTag('Pipe')]
IPipeNode = interface(IAstTypedNode) IPipeNode = interface(IAstTypedNode)
{$region 'private'} {$region 'private'}
function GetInputs: ITupleNode; function GetInputs: ITupleNode;
function GetTransformation: ILambdaExpressionNode; function GetTransformation: ILambdaExpressionNode;
{$endregion} {$endregion}
[AstField(0, 'inputs', fkTuple)]
property Inputs: ITupleNode read GetInputs; property Inputs: ITupleNode read GetInputs;
[AstField(1, 'transform', fkNode)]
property Transformation: ILambdaExpressionNode read GetTransformation; property Transformation: ILambdaExpressionNode read GetTransformation;
end; end;
@@ -531,12 +608,9 @@ type
property StaticType: IStaticType read GetStaticType; property StaticType: IStaticType read GetStaticType;
end; end;
[AstTag('Field')]
TRecordFieldNode = class(TAstNode, IRecordFieldNode) TRecordFieldNode = class(TAstNode, IRecordFieldNode)
private private
[AstField(0, 'key', fkNode)]
FKey: IKeywordNode; FKey: IKeywordNode;
[AstField(1, 'value', fkNode)]
FValue: IAstNode; FValue: IAstNode;
function GetKey: IKeywordNode; function GetKey: IKeywordNode;
function GetValue: IAstNode; function GetValue: IAstNode;
@@ -549,10 +623,8 @@ type
// --- Core Nodes Implementations --- // --- Core Nodes Implementations ---
[AstTag('Const')]
TConstantNode = class(TAstTypedNode, IConstantNode) TConstantNode = class(TAstTypedNode, IConstantNode)
private private
[AstField(0, 'value', fkValue)]
FConstIdentity: IConstantIdentity; // Typed reference for fast access FConstIdentity: IConstantIdentity; // Typed reference for fast access
function GetValue: TDataValue; function GetValue: TDataValue;
protected protected
@@ -562,10 +634,8 @@ type
function AsConstant: IConstantNode; override; function AsConstant: IConstantNode; override;
end; end;
[AstTag('Id')]
TIdentifierNode = class(TAstTypedNode, IIdentifierNode) TIdentifierNode = class(TAstTypedNode, IIdentifierNode)
private private
[AstField(0, 'name', fkString)]
FNamedIdentity: INamedIdentity; // Typed reference for fast access FNamedIdentity: INamedIdentity; // Typed reference for fast access
FAddress: TResolvedAddress; FAddress: TResolvedAddress;
function GetAddress: TResolvedAddress; function GetAddress: TResolvedAddress;
@@ -577,10 +647,8 @@ type
function AsIdentifier: IIdentifierNode; override; function AsIdentifier: IIdentifierNode; override;
end; end;
[AstTag('Key')]
TKeywordNode = class(TAstTypedNode, IKeywordNode) TKeywordNode = class(TAstTypedNode, IKeywordNode)
private private
[AstField(0, 'name', fkString)]
FKeywordIdentity: IKeywordIdentity; FKeywordIdentity: IKeywordIdentity;
function GetValue: IKeyword; function GetValue: IKeyword;
protected protected
@@ -590,10 +658,8 @@ type
function AsKeyword: IKeywordNode; override; function AsKeyword: IKeywordNode; override;
end; end;
[AstTag('Tuple')]
TTupleNode = class(TAstTypedNode, ITupleNode) TTupleNode = class(TAstTypedNode, ITupleNode)
private private
[AstField(0, 'elements', fkNode)] // Represents array
FElements: TArray<IAstNode>; FElements: TArray<IAstNode>;
function GetElements: TArray<IAstNode>; function GetElements: TArray<IAstNode>;
protected protected
@@ -603,10 +669,8 @@ type
function AsTuple: ITupleNode; override; function AsTuple: ITupleNode; override;
end; end;
[AstTag('Series')]
TCreateSeriesNode = class(TAstTypedNode, ICreateSeriesNode) TCreateSeriesNode = class(TAstTypedNode, ICreateSeriesNode)
private private
[AstField(0, 'definition', fkNode)]
FDefinitionNode: IAstNode; FDefinitionNode: IAstNode;
FRecordDefinition: IScalarRecordDefinition; FRecordDefinition: IScalarRecordDefinition;
function GetDefinitionNode: IAstNode; function GetDefinitionNode: IAstNode;
@@ -623,17 +687,9 @@ type
function AsCreateSeries: ICreateSeriesNode; override; function AsCreateSeries: ICreateSeriesNode; override;
end; end;
// --- Structural Nodes (Identity only for location) ---
[AstTag('If')]
TIfExpressionNode = class(TAstTypedNode, IIfExpressionNode) TIfExpressionNode = class(TAstTypedNode, IIfExpressionNode)
private private
[AstField(0, 'cond', fkNode)] FCondition, FThenBranch, FElseBranch: IAstNode;
FCondition: IAstNode;
[AstField(1, 'then', fkNode)]
FThenBranch: IAstNode;
[AstField(2, 'else', fkNullableNode)]
FElseBranch: IAstNode;
function GetCondition: IAstNode; function GetCondition: IAstNode;
function GetThenBranch: IAstNode; function GetThenBranch: IAstNode;
function GetElseBranch: IAstNode; function GetElseBranch: IAstNode;
@@ -648,12 +704,9 @@ type
function AsIfExpression: IIfExpressionNode; override; function AsIfExpression: IIfExpressionNode; override;
end; end;
[AstTag('Cond')]
TCondExpressionNode = class(TAstTypedNode, ICondExpressionNode) TCondExpressionNode = class(TAstTypedNode, ICondExpressionNode)
private private
[AstField(0, 'pairs', fkArrayOfPairs)]
FPairs: TArray<TCondPair>; FPairs: TArray<TCondPair>;
[AstField(1, 'else', fkNullableNode)]
FElseBranch: IAstNode; FElseBranch: IAstNode;
function GetPairs: TArray<TCondPair>; function GetPairs: TArray<TCondPair>;
function GetElseBranch: IAstNode; function GetElseBranch: IAstNode;
@@ -669,12 +722,9 @@ type
function AsCondExpression: ICondExpressionNode; override; function AsCondExpression: ICondExpressionNode; override;
end; end;
[AstTag('Fn')]
TLambdaExpressionNode = class(TAstTypedNode, ILambdaExpressionNode, IFunctionDefinition) TLambdaExpressionNode = class(TAstTypedNode, ILambdaExpressionNode, IFunctionDefinition)
private private
[AstField(0, 'params', fkTuple)]
FParameters: ITupleNode; FParameters: ITupleNode;
[AstField(1, 'body', fkNode)]
FBody: IAstNode; FBody: IAstNode;
FLayout: IScopeLayout; FLayout: IScopeLayout;
FDescriptor: IScopeDescriptor; FDescriptor: IScopeDescriptor;
@@ -703,12 +753,9 @@ type
function AsLambdaExpression: ILambdaExpressionNode; override; function AsLambdaExpression: ILambdaExpressionNode; override;
end; end;
[AstTag('Call')]
TFunctionCallNode = class(TAstTypedNode, IFunctionCallNode) TFunctionCallNode = class(TAstTypedNode, IFunctionCallNode)
private private
[AstField(0, 'callee', fkNode)]
FCallee: IAstNode; FCallee: IAstNode;
[AstField(1, 'args', fkTuple)]
FArguments: ITupleNode; FArguments: ITupleNode;
FIsTailCall: Boolean; FIsTailCall: Boolean;
FStaticTarget: TDataValue.TFunc; FStaticTarget: TDataValue.TFunc;
@@ -733,14 +780,10 @@ type
function AsFunctionCall: IFunctionCallNode; override; function AsFunctionCall: IFunctionCallNode; override;
end; end;
[AstTag('Macro')]
TMacroDefinitionNode = class(TAstTypedNode, IMacroDefinitionNode) TMacroDefinitionNode = class(TAstTypedNode, IMacroDefinitionNode)
private private
[AstField(0, 'name', fkNode)]
FName: IIdentifierNode; FName: IIdentifierNode;
[AstField(1, 'params', fkTuple)]
FParameters: ITupleNode; FParameters: ITupleNode;
[AstField(2, 'body', fkNode)]
FBody: IAstNode; FBody: IAstNode;
function GetName: IIdentifierNode; function GetName: IIdentifierNode;
function GetParameters: ITupleNode; function GetParameters: ITupleNode;
@@ -770,10 +813,8 @@ type
function AsMacroExpansion: IMacroExpansionNode; override; function AsMacroExpansion: IMacroExpansionNode; override;
end; end;
[AstTag('Quote')]
TQuasiquoteNode = class(TAstNode, IQuasiquoteNode) TQuasiquoteNode = class(TAstNode, IQuasiquoteNode)
private private
[AstField(0, 'expr', fkNode)]
FExpression: IAstNode; FExpression: IAstNode;
function GetExpression: IAstNode; function GetExpression: IAstNode;
protected protected
@@ -783,10 +824,8 @@ type
function AsQuasiquote: IQuasiquoteNode; override; function AsQuasiquote: IQuasiquoteNode; override;
end; end;
[AstTag('Unquote')]
TUnquoteNode = class(TAstNode, IUnquoteNode) TUnquoteNode = class(TAstNode, IUnquoteNode)
private private
[AstField(0, 'expr', fkNode)]
FExpression: IAstNode; FExpression: IAstNode;
function GetExpression: IAstNode; function GetExpression: IAstNode;
protected protected
@@ -796,10 +835,8 @@ type
function AsUnquote: IUnquoteNode; override; function AsUnquote: IUnquoteNode; override;
end; end;
[AstTag('Splice')]
TUnquoteSplicingNode = class(TAstNode, IUnquoteSplicingNode) TUnquoteSplicingNode = class(TAstNode, IUnquoteSplicingNode)
private private
[AstField(0, 'expr', fkNode)]
FExpression: IQuasiquoteNode; FExpression: IQuasiquoteNode;
function GetExpression: IQuasiquoteNode; function GetExpression: IQuasiquoteNode;
protected protected
@@ -809,10 +846,8 @@ type
function AsUnquoteSplicing: IUnquoteSplicingNode; override; function AsUnquoteSplicing: IUnquoteSplicingNode; override;
end; end;
[AstTag('Recur')]
TRecurNode = class(TAstTypedNode, IRecurNode) TRecurNode = class(TAstTypedNode, IRecurNode)
private private
[AstField(0, 'args', fkTuple)]
FArguments: ITupleNode; FArguments: ITupleNode;
function GetArguments: ITupleNode; function GetArguments: ITupleNode;
protected protected
@@ -822,10 +857,8 @@ type
function AsRecur: IRecurNode; override; function AsRecur: IRecurNode; override;
end; end;
[AstTag('Block')]
TBlockExpressionNode = class(TAstTypedNode, IBlockExpressionNode) TBlockExpressionNode = class(TAstTypedNode, IBlockExpressionNode)
private private
[AstField(0, 'expressions', fkTuple)]
FExpressions: ITupleNode; FExpressions: ITupleNode;
function GetExpressions: ITupleNode; function GetExpressions: ITupleNode;
protected protected
@@ -835,13 +868,9 @@ type
function AsBlockExpression: IBlockExpressionNode; override; function AsBlockExpression: IBlockExpressionNode; override;
end; end;
[AstTag('Var')]
TVariableDeclarationNode = class(TAstTypedNode, IVariableDeclarationNode) TVariableDeclarationNode = class(TAstTypedNode, IVariableDeclarationNode)
private private
[AstField(0, 'target', fkNode)] FTarget, FInitializer: IAstNode;
FTarget: IAstNode;
[AstField(1, 'init', fkNullableNode)]
FInitializer: IAstNode;
FIsBoxed: Boolean; FIsBoxed: Boolean;
function GetTarget: IAstNode; function GetTarget: IAstNode;
function GetInitializer: IAstNode; function GetInitializer: IAstNode;
@@ -859,13 +888,9 @@ type
function AsVariableDeclaration: IVariableDeclarationNode; override; function AsVariableDeclaration: IVariableDeclarationNode; override;
end; end;
[AstTag('Assign')]
TAssignmentNode = class(TAstTypedNode, IAssignmentNode) TAssignmentNode = class(TAstTypedNode, IAssignmentNode)
private private
[AstField(0, 'target', fkNode)] FTarget, FValue: IAstNode;
FTarget: IAstNode;
[AstField(1, 'value', fkNode)]
FValue: IAstNode;
function GetTarget: IAstNode; function GetTarget: IAstNode;
function GetValue: IAstNode; function GetValue: IAstNode;
protected protected
@@ -875,13 +900,9 @@ type
function AsAssignment: IAssignmentNode; override; function AsAssignment: IAssignmentNode; override;
end; end;
[AstTag('Index')]
TIndexerNode = class(TAstTypedNode, IIndexerNode) TIndexerNode = class(TAstTypedNode, IIndexerNode)
private private
[AstField(0, 'base', fkNode)] FBase, FIndex: IAstNode;
FBase: IAstNode;
[AstField(1, 'index', fkNode)]
FIndex: IAstNode;
function GetBase: IAstNode; function GetBase: IAstNode;
function GetIndex: IAstNode; function GetIndex: IAstNode;
protected protected
@@ -891,12 +912,9 @@ type
function AsIndexer: IIndexerNode; override; function AsIndexer: IIndexerNode; override;
end; end;
[AstTag('Member')]
TMemberAccessNode = class(TAstTypedNode, IMemberAccessNode) TMemberAccessNode = class(TAstTypedNode, IMemberAccessNode)
private private
[AstField(0, 'base', fkNode)]
FBase: IAstNode; FBase: IAstNode;
[AstField(1, 'member', fkNode)]
FMember: IKeywordNode; FMember: IKeywordNode;
function GetBase: IAstNode; function GetBase: IAstNode;
function GetMember: IKeywordNode; function GetMember: IKeywordNode;
@@ -912,10 +930,8 @@ type
function AsMemberAccess: IMemberAccessNode; override; function AsMemberAccess: IMemberAccessNode; override;
end; end;
[AstTag('Record')]
TRecordLiteralNode = class(TAstTypedNode, IRecordLiteralNode) TRecordLiteralNode = class(TAstTypedNode, IRecordLiteralNode)
private private
[AstField(0, 'fields', fkTuple)]
FFields: ITupleNode; FFields: ITupleNode;
FScalarDef: IScalarRecordDefinition; FScalarDef: IScalarRecordDefinition;
FGenericDef: IGenericRecordDefinition; FGenericDef: IGenericRecordDefinition;
@@ -935,15 +951,10 @@ type
function AsRecordLiteral: IRecordLiteralNode; override; function AsRecordLiteral: IRecordLiteralNode; override;
end; end;
[AstTag('Add')]
TAddSeriesItemNode = class(TAstTypedNode, IAddSeriesItemNode) TAddSeriesItemNode = class(TAstTypedNode, IAddSeriesItemNode)
private private
[AstField(0, 'series', fkNode)]
FSeries: IIdentifierNode; FSeries: IIdentifierNode;
[AstField(1, 'value', fkNode)] FValue, FLookback: IAstNode;
FValue: IAstNode;
[AstField(2, 'lookback', fkNullableNode)]
FLookback: IAstNode;
function GetSeries: IIdentifierNode; function GetSeries: IIdentifierNode;
function GetValue: IAstNode; function GetValue: IAstNode;
function GetLookback: IAstNode; function GetLookback: IAstNode;
@@ -959,10 +970,8 @@ type
function AsAddSeriesItem: IAddSeriesItemNode; override; function AsAddSeriesItem: IAddSeriesItemNode; override;
end; end;
[AstTag('Count')]
TSeriesLengthNode = class(TAstTypedNode, ISeriesLengthNode) TSeriesLengthNode = class(TAstTypedNode, ISeriesLengthNode)
private private
[AstField(0, 'series', fkNode)]
FSeries: IIdentifierNode; FSeries: IIdentifierNode;
function GetSeries: IIdentifierNode; function GetSeries: IIdentifierNode;
protected protected
@@ -972,7 +981,6 @@ type
function AsSeriesLength: ISeriesLengthNode; override; function AsSeriesLength: ISeriesLengthNode; override;
end; end;
[AstTag('Nop')]
TNopNode = class(TAstTypedNode, INopNode) TNopNode = class(TAstTypedNode, INopNode)
protected protected
function GetKind: TAstNodeKind; override; function GetKind: TAstNodeKind; override;
@@ -981,12 +989,9 @@ type
function AsNop: INopNode; override; function AsNop: INopNode; override;
end; end;
[AstTag('Pipe')]
TPipeNode = class(TAstTypedNode, IPipeNode) TPipeNode = class(TAstTypedNode, IPipeNode)
private private
[AstField(0, 'inputs', fkTuple)]
FInputs: ITupleNode; FInputs: ITupleNode;
[AstField(1, 'transform', fkNode)]
FTransformation: ILambdaExpressionNode; FTransformation: ILambdaExpressionNode;
function GetInputs: ITupleNode; function GetInputs: ITupleNode;
function GetTransformation: ILambdaExpressionNode; function GetTransformation: ILambdaExpressionNode;
@@ -1006,9 +1011,9 @@ implementation
uses uses
System.Classes, System.Classes,
System.TypInfo,
System.Rtti, System.Rtti,
System.StrUtils; System.StrUtils,
System.TypInfo; // Added for GetEnumName
{ TCompiledFunction } { TCompiledFunction }
@@ -2129,6 +2134,3 @@ begin
end; end;
end. end.
//==================================================================================================
//== FULL UNIT END: Myc.Ast.Nodes
//==================================================================================================
+2
View File
@@ -193,6 +193,8 @@ begin
FWorkspace.SetFocus; FWorkspace.SetFocus;
var WorldP := FWorkspace.ScreenToWorld(FWorkspace.LocalToScreen(TPointF.Create(X, Y))); var WorldP := FWorkspace.ScreenToWorld(FWorkspace.LocalToScreen(TPointF.Create(X, Y)));
if not Assigned(FWorkspace.RootNode) then
exit;
var Hit := FWorkspace.RootNode.HitTest(WorldP); var Hit := FWorkspace.RootNode.HitTest(WorldP);
if (Button = TMouseButton.mbLeft) and (Hit is TAstViewNode) then if (Button = TMouseButton.mbLeft) and (Hit is TAstViewNode) then