Ast Schema
This commit is contained in:
@@ -42,7 +42,9 @@ uses
|
|||||||
Myc.Data.Stream in '..\Src\Data\Myc.Data.Stream.pas',
|
Myc.Data.Stream in '..\Src\Data\Myc.Data.Stream.pas',
|
||||||
Myc.Fmx.AstEditor.Handlers.Pipes in '..\Src\AST\Myc.Fmx.AstEditor.Handlers.Pipes.pas',
|
Myc.Fmx.AstEditor.Handlers.Pipes in '..\Src\AST\Myc.Fmx.AstEditor.Handlers.Pipes.pas',
|
||||||
Demo.Finance in '..\Test\Demo.Finance.pas',
|
Demo.Finance in '..\Test\Demo.Finance.pas',
|
||||||
Myc.Ast.Script.Print in '..\Src\AST\Myc.Ast.Script.Print.pas';
|
Myc.Ast.Script.Print in '..\Src\AST\Myc.Ast.Script.Print.pas',
|
||||||
|
Myc.Ast.Json.Schema in '..\Src\AST\Myc.Ast.Json.Schema.pas',
|
||||||
|
Myc.Ast.Attributes in 'Myc.Ast.Attributes.pas';
|
||||||
|
|
||||||
{$R *.res}
|
{$R *.res}
|
||||||
|
|
||||||
|
|||||||
@@ -173,6 +173,8 @@
|
|||||||
<DCCReference Include="..\Src\AST\Myc.Fmx.AstEditor.Handlers.Pipes.pas"/>
|
<DCCReference Include="..\Src\AST\Myc.Fmx.AstEditor.Handlers.Pipes.pas"/>
|
||||||
<DCCReference Include="..\Test\Demo.Finance.pas"/>
|
<DCCReference Include="..\Test\Demo.Finance.pas"/>
|
||||||
<DCCReference Include="..\Src\AST\Myc.Ast.Script.Print.pas"/>
|
<DCCReference Include="..\Src\AST\Myc.Ast.Script.Print.pas"/>
|
||||||
|
<DCCReference Include="..\Src\AST\Myc.Ast.Json.Schema.pas"/>
|
||||||
|
<DCCReference Include="Myc.Ast.Attributes.pas"/>
|
||||||
<BuildConfiguration Include="Base">
|
<BuildConfiguration Include="Base">
|
||||||
<Key>Base</Key>
|
<Key>Base</Key>
|
||||||
</BuildConfiguration>
|
</BuildConfiguration>
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ uses
|
|||||||
Myc.Ast.Environment,
|
Myc.Ast.Environment,
|
||||||
Myc.Ast.RTL,
|
Myc.Ast.RTL,
|
||||||
Myc.Ast.Compiler.Macros,
|
Myc.Ast.Compiler.Macros,
|
||||||
|
Myc.Ast.Json.Schema,
|
||||||
// Editor Units
|
// Editor Units
|
||||||
Myc.Fmx.AstEditor,
|
Myc.Fmx.AstEditor,
|
||||||
Demo.Finance,
|
Demo.Finance,
|
||||||
@@ -286,6 +287,8 @@ begin
|
|||||||
|
|
||||||
CompilerStageBox.BringToFront;
|
CompilerStageBox.BringToFront;
|
||||||
ClearButtonClick(Self);
|
ClearButtonClick(Self);
|
||||||
|
|
||||||
|
Memo1.Lines.Text := TAstSchema.GenerateFullSystemPrompt;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TForm1.ShowVizualization;
|
procedure TForm1.ShowVizualization;
|
||||||
@@ -1223,24 +1226,29 @@ end;
|
|||||||
|
|
||||||
procedure TForm1.ToJSONButtonClick(Sender: TObject);
|
procedure TForm1.ToJSONButtonClick(Sender: TObject);
|
||||||
var
|
var
|
||||||
jsonObj: TJSONObject;
|
jsonVal: TJSONValue;
|
||||||
converter: IJsonAstConverter;
|
converter: IJsonAstConverter;
|
||||||
begin
|
begin
|
||||||
Memo1.Lines.Clear;
|
Memo1.Lines.Clear;
|
||||||
|
|
||||||
if not Assigned(FCurrExec.Func) then
|
// Wir prüfen besser direkt, ob der AST da ist, den wir serialisieren wollen
|
||||||
|
if not Assigned(FCurrUnboundAst) then
|
||||||
begin
|
begin
|
||||||
Memo1.Lines.Add('No *compiled* AST has been generated yet. Click a test button first.');
|
Memo1.Lines.Add('No AST has been generated yet. Click a test button first.');
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
try
|
try
|
||||||
converter := TJsonAstConverter.Create;
|
converter := TJsonAstConverter.Create;
|
||||||
jsonObj := converter.Serialize(FCurrUnboundAst);
|
// Serialize liefert jetzt TJSONValue (Compact Array Format)
|
||||||
|
jsonVal := converter.Serialize(FCurrUnboundAst);
|
||||||
try
|
try
|
||||||
Memo1.Lines.Text := jsonObj.Format(4);
|
if Assigned(jsonVal) then
|
||||||
|
Memo1.Lines.Text := jsonVal.Format(4)
|
||||||
|
else
|
||||||
|
Memo1.Lines.Text := 'null';
|
||||||
finally
|
finally
|
||||||
jsonObj.Free;
|
jsonVal.Free;
|
||||||
end;
|
end;
|
||||||
except
|
except
|
||||||
on E: Exception do
|
on E: Exception do
|
||||||
|
|||||||
+453
-638
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,219 @@
|
|||||||
|
unit Myc.Ast.Json.Schema;
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
System.SysUtils,
|
||||||
|
System.Classes,
|
||||||
|
System.Generics.Collections,
|
||||||
|
System.Generics.Defaults,
|
||||||
|
System.Rtti,
|
||||||
|
System.TypInfo,
|
||||||
|
Myc.Ast.Nodes,
|
||||||
|
Myc.Ast.Attributes;
|
||||||
|
|
||||||
|
type
|
||||||
|
TAstSchema = class
|
||||||
|
public
|
||||||
|
// Generates the TypeScript definition by scanning classes via RTTI
|
||||||
|
class function GenerateTypeScriptDefinition: string;
|
||||||
|
|
||||||
|
// Static rules for the format
|
||||||
|
class function GenerateGenerationRules: string;
|
||||||
|
|
||||||
|
// Combined prompt
|
||||||
|
class function GenerateFullSystemPrompt: string;
|
||||||
|
end;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
type
|
||||||
|
// Helper structure to collect fields per type
|
||||||
|
// Moved here to avoid scope issues with generics
|
||||||
|
TFieldInfo = record
|
||||||
|
Idx: Integer;
|
||||||
|
Def: string;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TAstSchema }
|
||||||
|
|
||||||
|
class function TAstSchema.GenerateTypeScriptDefinition: string;
|
||||||
|
var
|
||||||
|
ctx: TRttiContext;
|
||||||
|
types: TArray<TRttiType>;
|
||||||
|
typ: TRttiType;
|
||||||
|
attr: TCustomAttribute;
|
||||||
|
fieldAttr: AstFieldAttribute;
|
||||||
|
nodeDefs: TDictionary<string, TList<TFieldInfo>>;
|
||||||
|
unionTypes: TList<string>;
|
||||||
|
fieldsList: TList<TFieldInfo>;
|
||||||
|
sb: TStringBuilder;
|
||||||
|
tag: string;
|
||||||
|
fieldInfo: TFieldInfo;
|
||||||
|
f: TRttiField;
|
||||||
|
i: Integer;
|
||||||
|
|
||||||
|
function GetTsType(Kind: TFieldKind): string;
|
||||||
|
begin
|
||||||
|
case Kind of
|
||||||
|
fkNode: Result := 'AstNode';
|
||||||
|
fkTuple: Result := 'Tuple';
|
||||||
|
fkString: Result := 'string';
|
||||||
|
fkValue: Result := 'number | string | boolean';
|
||||||
|
fkNullableNode: Result := 'AstNode | null';
|
||||||
|
fkArrayOfPairs: Result := 'Array<[AstNode, AstNode]>';
|
||||||
|
else
|
||||||
|
Result := 'any';
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
ctx := TRttiContext.Create;
|
||||||
|
nodeDefs := TDictionary<string, TList<TFieldInfo>>.Create;
|
||||||
|
unionTypes := TList<string>.Create;
|
||||||
|
sb := TStringBuilder.Create;
|
||||||
|
|
||||||
|
try
|
||||||
|
// 1. Scan all types in the application context
|
||||||
|
types := ctx.GetTypes;
|
||||||
|
|
||||||
|
for typ in types do
|
||||||
|
begin
|
||||||
|
if not typ.IsInstance then
|
||||||
|
Continue;
|
||||||
|
|
||||||
|
// Check for [AstTag] attribute on the class
|
||||||
|
tag := '';
|
||||||
|
for attr in typ.GetAttributes do
|
||||||
|
if attr is AstTagAttribute then
|
||||||
|
begin
|
||||||
|
tag := AstTagAttribute(attr).Tag;
|
||||||
|
Break;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if tag = '' then
|
||||||
|
Continue;
|
||||||
|
|
||||||
|
if not nodeDefs.ContainsKey(tag) then
|
||||||
|
begin
|
||||||
|
nodeDefs.Add(tag, TList<TFieldInfo>.Create);
|
||||||
|
unionTypes.Add(tag);
|
||||||
|
end;
|
||||||
|
|
||||||
|
fieldsList := nodeDefs[tag];
|
||||||
|
|
||||||
|
// Scan Fields (Variables) of the class
|
||||||
|
for f in typ.AsInstance.GetFields do
|
||||||
|
begin
|
||||||
|
for attr in f.GetAttributes do
|
||||||
|
if attr is AstFieldAttribute then
|
||||||
|
begin
|
||||||
|
fieldAttr := AstFieldAttribute(attr);
|
||||||
|
|
||||||
|
fieldInfo.Idx := fieldAttr.Index;
|
||||||
|
fieldInfo.Def := GetTsType(fieldAttr.Kind) + ' /*' + fieldAttr.Name + '*/';
|
||||||
|
|
||||||
|
fieldsList.Add(fieldInfo);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// 2. Build the output
|
||||||
|
sb.AppendLine('// AST Schema Definition (Auto-Generated via RTTI)');
|
||||||
|
sb.AppendLine('// Format: Compact JSON Arrays [Tag, Arg1, Arg2, ...]');
|
||||||
|
sb.AppendLine;
|
||||||
|
|
||||||
|
unionTypes.Sort;
|
||||||
|
|
||||||
|
// Union Type Definition
|
||||||
|
sb.AppendLine('type AstNode = ');
|
||||||
|
for i := 0 to unionTypes.Count - 1 do
|
||||||
|
begin
|
||||||
|
sb.Append(' | ' + unionTypes[i]);
|
||||||
|
if i < unionTypes.Count - 1 then
|
||||||
|
sb.AppendLine;
|
||||||
|
end;
|
||||||
|
sb.AppendLine(';');
|
||||||
|
sb.AppendLine;
|
||||||
|
|
||||||
|
sb.AppendLine('type Tuple = ["Tuple", AstNode[]];');
|
||||||
|
sb.AppendLine;
|
||||||
|
|
||||||
|
// Node Definitions
|
||||||
|
for tag in unionTypes do
|
||||||
|
begin
|
||||||
|
// Tuple is special base type
|
||||||
|
if tag = 'Tuple' then
|
||||||
|
Continue;
|
||||||
|
|
||||||
|
fieldsList := nodeDefs[tag];
|
||||||
|
|
||||||
|
// Sort fields by Index to ensure correct JSON array order
|
||||||
|
fieldsList.Sort(TComparer<TFieldInfo>.Construct(function(const L, R: TFieldInfo): Integer begin Result := L.Idx - R.Idx; end));
|
||||||
|
|
||||||
|
sb.Append('type ' + tag + ' = ["' + tag + '"');
|
||||||
|
|
||||||
|
for fieldInfo in fieldsList do
|
||||||
|
sb.Append(', ' + fieldInfo.Def);
|
||||||
|
|
||||||
|
sb.AppendLine('];');
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result := sb.ToString;
|
||||||
|
|
||||||
|
finally
|
||||||
|
// Clean up lists in dictionary
|
||||||
|
for tag in nodeDefs.Keys do
|
||||||
|
nodeDefs[tag].Free;
|
||||||
|
|
||||||
|
nodeDefs.Free;
|
||||||
|
unionTypes.Free;
|
||||||
|
sb.Free;
|
||||||
|
ctx.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
class function TAstSchema.GenerateGenerationRules: string;
|
||||||
|
var
|
||||||
|
sb: TStringBuilder;
|
||||||
|
begin
|
||||||
|
// These rules describe the PROTOCOL (Compact Arrays), not the content.
|
||||||
|
// They remain static unless you change TJsonAstConverter logic significantly.
|
||||||
|
sb := TStringBuilder.Create;
|
||||||
|
try
|
||||||
|
sb.AppendLine('**⚠️ CRITICAL GENERATION RULES:**');
|
||||||
|
sb.AppendLine;
|
||||||
|
sb.AppendLine('1. **NO JSON OBJECTS:** Do not use `{ "key": "value" }`. Every node MUST be a JSON Array `["Tag", Arg1, Arg2]`.');
|
||||||
|
sb.AppendLine(
|
||||||
|
'2. **EXPLICIT TUPLES:** Whenever a field in the schema is defined as `Tuple`, you MUST wrap the list in a `["Tuple", [...]]` node.'
|
||||||
|
);
|
||||||
|
sb.AppendLine(
|
||||||
|
'3. **EXPLICIT NULLS:** Optional fields (marked as `| null`) MUST be explicit `null` if not present. Do not omit them.'
|
||||||
|
);
|
||||||
|
sb.AppendLine('4. **STRICT ORDER:** The order of elements in the array is fixed defined by the schema. Never swap arguments.');
|
||||||
|
|
||||||
|
Result := sb.ToString;
|
||||||
|
finally
|
||||||
|
sb.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
class function TAstSchema.GenerateFullSystemPrompt: string;
|
||||||
|
begin
|
||||||
|
// Combine everything
|
||||||
|
Result :=
|
||||||
|
'You are a compiler frontend for the "Myc" scripting language.'
|
||||||
|
+ sLineBreak
|
||||||
|
+ 'Your task is to generate a valid Abstract Syntax Tree (AST) in a specific Compact JSON format.'
|
||||||
|
+ sLineBreak
|
||||||
|
+ sLineBreak
|
||||||
|
+ '### 1. AST Schema (TypeScript Definition)'
|
||||||
|
+ sLineBreak
|
||||||
|
+ GenerateTypeScriptDefinition
|
||||||
|
+ sLineBreak
|
||||||
|
+ '### 2. Constraints & Rules'
|
||||||
|
+ sLineBreak
|
||||||
|
+ GenerateGenerationRules;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
//==================================================================================================
|
||||||
|
//== FULL UNIT START: Myc.Ast.Nodes (from Myc.Ast.Nodes.pas)
|
||||||
|
//==================================================================================================
|
||||||
unit Myc.Ast.Nodes;
|
unit Myc.Ast.Nodes;
|
||||||
|
|
||||||
interface
|
interface
|
||||||
@@ -10,7 +13,8 @@ uses
|
|||||||
Myc.Data.Keyword,
|
Myc.Data.Keyword,
|
||||||
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]
|
||||||
|
|
||||||
type
|
type
|
||||||
// --- Forward Declarations ---
|
// --- Forward Declarations ---
|
||||||
@@ -197,7 +201,6 @@ type
|
|||||||
function AsRecur: IRecurNode;
|
function AsRecur: IRecurNode;
|
||||||
function AsNop: INopNode;
|
function AsNop: INopNode;
|
||||||
|
|
||||||
// Pipes
|
|
||||||
function AsPipe: IPipeNode;
|
function AsPipe: IPipeNode;
|
||||||
|
|
||||||
property IsTyped: Boolean read GetIsTyped;
|
property IsTyped: Boolean read GetIsTyped;
|
||||||
@@ -528,9 +531,12 @@ 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;
|
||||||
@@ -543,8 +549,10 @@ 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
|
||||||
@@ -554,8 +562,10 @@ 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;
|
||||||
@@ -567,8 +577,10 @@ 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
|
||||||
@@ -578,8 +590,10 @@ 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
|
||||||
@@ -589,8 +603,10 @@ 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;
|
||||||
@@ -609,9 +625,15 @@ type
|
|||||||
|
|
||||||
// --- Structural Nodes (Identity only for location) ---
|
// --- Structural Nodes (Identity only for location) ---
|
||||||
|
|
||||||
|
[AstTag('If')]
|
||||||
TIfExpressionNode = class(TAstTypedNode, IIfExpressionNode)
|
TIfExpressionNode = class(TAstTypedNode, IIfExpressionNode)
|
||||||
private
|
private
|
||||||
FCondition, FThenBranch, FElseBranch: IAstNode;
|
[AstField(0, 'cond', fkNode)]
|
||||||
|
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;
|
||||||
@@ -626,9 +648,12 @@ 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;
|
||||||
@@ -644,9 +669,12 @@ 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;
|
||||||
@@ -675,9 +703,12 @@ 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;
|
||||||
@@ -702,10 +733,14 @@ 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;
|
||||||
@@ -735,8 +770,10 @@ 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
|
||||||
@@ -746,8 +783,10 @@ 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
|
||||||
@@ -757,8 +796,10 @@ 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
|
||||||
@@ -768,8 +809,10 @@ 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
|
||||||
@@ -779,8 +822,10 @@ 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
|
||||||
@@ -790,9 +835,13 @@ type
|
|||||||
function AsBlockExpression: IBlockExpressionNode; override;
|
function AsBlockExpression: IBlockExpressionNode; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
[AstTag('Var')]
|
||||||
TVariableDeclarationNode = class(TAstTypedNode, IVariableDeclarationNode)
|
TVariableDeclarationNode = class(TAstTypedNode, IVariableDeclarationNode)
|
||||||
private
|
private
|
||||||
FTarget, FInitializer: IAstNode;
|
[AstField(0, 'target', fkNode)]
|
||||||
|
FTarget: IAstNode;
|
||||||
|
[AstField(1, 'init', fkNullableNode)]
|
||||||
|
FInitializer: IAstNode;
|
||||||
FIsBoxed: Boolean;
|
FIsBoxed: Boolean;
|
||||||
function GetTarget: IAstNode;
|
function GetTarget: IAstNode;
|
||||||
function GetInitializer: IAstNode;
|
function GetInitializer: IAstNode;
|
||||||
@@ -810,9 +859,13 @@ type
|
|||||||
function AsVariableDeclaration: IVariableDeclarationNode; override;
|
function AsVariableDeclaration: IVariableDeclarationNode; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
[AstTag('Assign')]
|
||||||
TAssignmentNode = class(TAstTypedNode, IAssignmentNode)
|
TAssignmentNode = class(TAstTypedNode, IAssignmentNode)
|
||||||
private
|
private
|
||||||
FTarget, FValue: IAstNode;
|
[AstField(0, 'target', fkNode)]
|
||||||
|
FTarget: IAstNode;
|
||||||
|
[AstField(1, 'value', fkNode)]
|
||||||
|
FValue: IAstNode;
|
||||||
function GetTarget: IAstNode;
|
function GetTarget: IAstNode;
|
||||||
function GetValue: IAstNode;
|
function GetValue: IAstNode;
|
||||||
protected
|
protected
|
||||||
@@ -822,9 +875,13 @@ type
|
|||||||
function AsAssignment: IAssignmentNode; override;
|
function AsAssignment: IAssignmentNode; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
[AstTag('Index')]
|
||||||
TIndexerNode = class(TAstTypedNode, IIndexerNode)
|
TIndexerNode = class(TAstTypedNode, IIndexerNode)
|
||||||
private
|
private
|
||||||
FBase, FIndex: IAstNode;
|
[AstField(0, 'base', fkNode)]
|
||||||
|
FBase: IAstNode;
|
||||||
|
[AstField(1, 'index', fkNode)]
|
||||||
|
FIndex: IAstNode;
|
||||||
function GetBase: IAstNode;
|
function GetBase: IAstNode;
|
||||||
function GetIndex: IAstNode;
|
function GetIndex: IAstNode;
|
||||||
protected
|
protected
|
||||||
@@ -834,9 +891,12 @@ 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;
|
||||||
@@ -852,8 +912,10 @@ 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;
|
||||||
@@ -873,10 +935,15 @@ 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;
|
||||||
FValue, FLookback: IAstNode;
|
[AstField(1, 'value', fkNode)]
|
||||||
|
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;
|
||||||
@@ -892,8 +959,10 @@ 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
|
||||||
@@ -903,6 +972,7 @@ 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;
|
||||||
@@ -911,9 +981,12 @@ 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;
|
||||||
@@ -933,6 +1006,7 @@ implementation
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
System.Classes,
|
System.Classes,
|
||||||
|
System.TypInfo,
|
||||||
System.Rtti,
|
System.Rtti,
|
||||||
System.StrUtils;
|
System.StrUtils;
|
||||||
|
|
||||||
@@ -949,7 +1023,7 @@ end;
|
|||||||
|
|
||||||
function TAstNodeKindHelper.ToString: string;
|
function TAstNodeKindHelper.ToString: string;
|
||||||
begin
|
begin
|
||||||
Result := TRttiEnumerationType.GetName<TAstNodeKind>(Self);
|
Result := GetEnumName(TypeInfo(TAstNodeKind), Ord(Self));
|
||||||
Assert(StartsText('ak', Result));
|
Assert(StartsText('ak', Result));
|
||||||
Result := Result.Substring(2);
|
Result := Result.Substring(2);
|
||||||
end;
|
end;
|
||||||
@@ -2055,3 +2129,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
//==================================================================================================
|
||||||
|
//== FULL UNIT END: Myc.Ast.Nodes
|
||||||
|
//==================================================================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user