Json Schema for LLMs
This commit is contained in:
File diff suppressed because one or more lines are too long
+184
-101
@@ -3,57 +3,49 @@
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
System.SysUtils,
|
system.sysutils,
|
||||||
System.Classes,
|
system.classes,
|
||||||
System.Generics.Collections,
|
system.generics.collections,
|
||||||
System.Generics.Defaults,
|
system.generics.defaults,
|
||||||
System.Rtti,
|
system.rtti,
|
||||||
System.TypInfo,
|
system.typinfo,
|
||||||
Myc.Ast.Nodes,
|
Myc.Ast.Nodes,
|
||||||
Myc.Ast.Attributes;
|
Myc.Ast.Attributes,
|
||||||
|
Myc.Ast.RTL,
|
||||||
|
Myc.Ast.RTL.Core;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
{ Scans AST and RTL metadata to generate a high-precision LLM system prompt. }
|
||||||
TAstSchema = class
|
TAstSchema = class
|
||||||
|
strict private
|
||||||
|
type
|
||||||
|
TFieldInfo = record
|
||||||
|
Idx: Integer;
|
||||||
|
Name: string;
|
||||||
|
Kind: TFieldKind;
|
||||||
|
end;
|
||||||
|
|
||||||
|
class function GetTsType(Kind: TFieldKind): string; static;
|
||||||
public
|
public
|
||||||
// Generates the TypeScript definition by scanning INTERFACES via RTTI
|
// Generates the TypeScript definition including JSDoc and multiple @example entries
|
||||||
class function GenerateTypeScriptDefinition: string;
|
class function GenerateTypeScriptDefinition: string; static;
|
||||||
|
|
||||||
// Static rules for the format
|
// Generates documented RTL function signatures with all overloads
|
||||||
class function GenerateGenerationRules: string;
|
class function GenerateRtlDocumentation: string; static;
|
||||||
|
|
||||||
// Combined prompt
|
// Detailed generation rules to eliminate ambiguity
|
||||||
class function GenerateFullSystemPrompt: string;
|
class function GenerateGenerationRules: string; static;
|
||||||
|
|
||||||
|
// The final consolidated system prompt
|
||||||
|
class function GenerateFullSystemPrompt: string; static;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
type
|
|
||||||
// Helper structure to collect fields per type
|
|
||||||
TFieldInfo = record
|
|
||||||
Idx: Integer;
|
|
||||||
Def: string;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TAstSchema }
|
{ TAstSchema }
|
||||||
|
|
||||||
class function TAstSchema.GenerateTypeScriptDefinition: string;
|
class function TAstSchema.GetTsType(Kind: TFieldKind): string;
|
||||||
var
|
begin
|
||||||
ctx: TRttiContext;
|
|
||||||
types: TArray<TRttiType>;
|
|
||||||
typ: TRttiType;
|
|
||||||
prop: TRttiProperty;
|
|
||||||
attr: TCustomAttribute;
|
|
||||||
fieldAttr: AstFieldAttribute;
|
|
||||||
nodeDefs: TDictionary<string, TList<TFieldInfo>>;
|
|
||||||
unionTypes: TList<string>;
|
|
||||||
fieldsList: TList<TFieldInfo>;
|
|
||||||
sb: TStringBuilder;
|
|
||||||
tag: string;
|
|
||||||
fieldInfo: TFieldInfo;
|
|
||||||
i: Integer;
|
|
||||||
|
|
||||||
function GetTsType(Kind: TFieldKind): string;
|
|
||||||
begin
|
|
||||||
case Kind of
|
case Kind of
|
||||||
fkNode: Result := 'AstNode';
|
fkNode: Result := 'AstNode';
|
||||||
fkTuple: Result := 'Tuple';
|
fkTuple: Result := 'Tuple';
|
||||||
@@ -64,68 +56,91 @@ var
|
|||||||
else
|
else
|
||||||
Result := 'any';
|
Result := 'any';
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
class function TAstSchema.GenerateTypeScriptDefinition: string;
|
||||||
|
var
|
||||||
|
ctx: TRttiContext;
|
||||||
|
typ: TRttiType;
|
||||||
|
attr: TCustomAttribute;
|
||||||
|
nodeDefs: TDictionary<string, TList<TFieldInfo>>;
|
||||||
|
nodeDocs: TDictionary<string, string>;
|
||||||
|
nodeExamples: TDictionary<string, TList<string>>;
|
||||||
|
unionTypes: TList<string>;
|
||||||
|
sb: TStringBuilder;
|
||||||
|
tag, doc: string;
|
||||||
|
fieldList: TList<TFieldInfo>;
|
||||||
|
exampleList: TList<string>;
|
||||||
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
ctx := TRttiContext.Create;
|
ctx := TRttiContext.Create;
|
||||||
nodeDefs := TDictionary<string, TList<TFieldInfo>>.Create;
|
nodeDefs := TDictionary<string, TList<TFieldInfo>>.Create;
|
||||||
|
nodeDocs := TDictionary<string, string>.Create;
|
||||||
|
nodeExamples := TDictionary<string, TList<string>>.Create;
|
||||||
unionTypes := TList<string>.Create;
|
unionTypes := TList<string>.Create;
|
||||||
sb := TStringBuilder.Create;
|
sb := TStringBuilder.Create;
|
||||||
|
|
||||||
try
|
try
|
||||||
// 1. Scan all types (looking for INTERFACES now)
|
for typ in ctx.GetTypes do
|
||||||
types := ctx.GetTypes;
|
|
||||||
|
|
||||||
for typ in types do
|
|
||||||
begin
|
begin
|
||||||
// CHANGE: We now look for Interfaces, not Classes
|
|
||||||
if typ.TypeKind <> tkInterface then
|
if typ.TypeKind <> tkInterface then
|
||||||
Continue;
|
continue;
|
||||||
|
|
||||||
// Check for [AstTag] attribute on the interface
|
|
||||||
tag := '';
|
tag := '';
|
||||||
|
doc := '';
|
||||||
|
fieldList := nil;
|
||||||
|
exampleList := nil;
|
||||||
|
|
||||||
for attr in typ.GetAttributes do
|
for attr in typ.GetAttributes do
|
||||||
|
begin
|
||||||
if attr is AstTagAttribute then
|
if attr is AstTagAttribute then
|
||||||
begin
|
|
||||||
tag := AstTagAttribute(attr).Tag;
|
tag := AstTagAttribute(attr).Tag;
|
||||||
Break;
|
|
||||||
|
if attr is AstDocAttribute then
|
||||||
|
doc := AstDocAttribute(attr).Description;
|
||||||
|
|
||||||
|
if attr is AstExampleAttribute then
|
||||||
|
begin
|
||||||
|
if exampleList = nil then
|
||||||
|
exampleList := TList<string>.Create;
|
||||||
|
exampleList.Add(AstExampleAttribute(attr).Example);
|
||||||
end;
|
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];
|
|
||||||
|
|
||||||
// CHANGE: Scan Properties of the interface
|
|
||||||
for prop in typ.GetProperties do
|
|
||||||
begin
|
|
||||||
for attr in prop.GetAttributes do
|
|
||||||
if attr is AstFieldAttribute then
|
if attr is AstFieldAttribute then
|
||||||
begin
|
begin
|
||||||
fieldAttr := AstFieldAttribute(attr);
|
if fieldList = nil then
|
||||||
|
fieldList := TList<TFieldInfo>.Create;
|
||||||
fieldInfo.Idx := fieldAttr.Index;
|
var f: TFieldInfo;
|
||||||
fieldInfo.Def := GetTsType(fieldAttr.Kind) + ' /*' + fieldAttr.Name + '*/';
|
f.Idx := AstFieldAttribute(attr).Index;
|
||||||
|
f.Name := AstFieldAttribute(attr).Name;
|
||||||
fieldsList.Add(fieldInfo);
|
f.Kind := AstFieldAttribute(attr).Kind;
|
||||||
end;
|
fieldList.Add(f);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// 2. Build the output
|
if tag <> '' then
|
||||||
sb.AppendLine('// AST Schema Definition (Auto-Generated via RTTI from Interfaces)');
|
begin
|
||||||
|
unionTypes.Add(tag);
|
||||||
|
if doc <> '' then
|
||||||
|
nodeDocs.Add(tag, doc);
|
||||||
|
if exampleList <> nil then
|
||||||
|
nodeExamples.Add(tag, exampleList);
|
||||||
|
if fieldList = nil then
|
||||||
|
fieldList := TList<TFieldInfo>.Create;
|
||||||
|
nodeDefs.Add(tag, fieldList);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
fieldList.Free;
|
||||||
|
exampleList.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
sb.AppendLine('// AST Schema Definition (Auto-Generated)');
|
||||||
sb.AppendLine('// Format: Compact JSON Arrays [Tag, Arg1, Arg2, ...]');
|
sb.AppendLine('// Format: Compact JSON Arrays [Tag, Arg1, Arg2, ...]');
|
||||||
sb.AppendLine;
|
sb.AppendLine;
|
||||||
|
|
||||||
unionTypes.Sort;
|
unionTypes.Sort;
|
||||||
|
|
||||||
// Union Type Definition
|
|
||||||
sb.AppendLine('type AstNode = ');
|
sb.AppendLine('type AstNode = ');
|
||||||
for i := 0 to unionTypes.Count - 1 do
|
for i := 0 to unionTypes.Count - 1 do
|
||||||
begin
|
begin
|
||||||
@@ -136,63 +151,131 @@ begin
|
|||||||
sb.AppendLine(';');
|
sb.AppendLine(';');
|
||||||
sb.AppendLine;
|
sb.AppendLine;
|
||||||
|
|
||||||
// Special Handling for Tuple (it's recursive array structure)
|
sb.AppendLine('/** Explicit list structure */');
|
||||||
sb.AppendLine('type Tuple = ["Tuple", AstNode[]];');
|
sb.AppendLine('type Tuple = ["Tuple", AstNode[]];');
|
||||||
sb.AppendLine;
|
sb.AppendLine;
|
||||||
|
|
||||||
// Node Definitions
|
|
||||||
for tag in unionTypes do
|
for tag in unionTypes do
|
||||||
begin
|
begin
|
||||||
// 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;
|
||||||
|
|
||||||
fieldsList := nodeDefs[tag];
|
sb.Append('/** ');
|
||||||
|
if nodeDocs.TryGetValue(tag, doc) then
|
||||||
|
sb.Append(doc);
|
||||||
|
|
||||||
// Sort fields by Index to ensure correct JSON array order
|
if nodeExamples.TryGetValue(tag, exampleList) then
|
||||||
fieldsList.Sort(TComparer<TFieldInfo>.Construct(function(const L, R: TFieldInfo): Integer begin Result := L.Idx - R.Idx; end));
|
begin
|
||||||
|
for var ex in exampleList do
|
||||||
|
sb.Append(sLineBreak + ' @example ' + ex);
|
||||||
|
end;
|
||||||
|
sb.AppendLine(' */');
|
||||||
|
|
||||||
|
fieldList := nodeDefs[tag];
|
||||||
|
fieldList.Sort(TComparer<TFieldInfo>.Construct(function(const L, R: TFieldInfo): Integer begin Result := L.Idx - R.Idx; end));
|
||||||
|
|
||||||
sb.Append('type ' + tag + ' = ["' + tag + '"');
|
sb.Append('type ' + tag + ' = ["' + tag + '"');
|
||||||
|
for var f in fieldList do
|
||||||
for fieldInfo in fieldsList do
|
sb.Append(Format(', %s /* %s */', [GetTsType(f.Kind), f.Name]));
|
||||||
sb.Append(', ' + fieldInfo.Def);
|
|
||||||
|
|
||||||
sb.AppendLine('];');
|
sb.AppendLine('];');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Result := sb.ToString;
|
Result := sb.ToString;
|
||||||
|
|
||||||
finally
|
finally
|
||||||
// Clean up lists in dictionary
|
for fieldList in nodeDefs.Values do
|
||||||
for tag in nodeDefs.Keys do
|
fieldList.Free;
|
||||||
nodeDefs[tag].Free;
|
for exampleList in nodeExamples.Values do
|
||||||
|
exampleList.Free;
|
||||||
nodeDefs.Free;
|
nodeDefs.Free;
|
||||||
|
nodeDocs.Free;
|
||||||
|
nodeExamples.Free;
|
||||||
unionTypes.Free;
|
unionTypes.Free;
|
||||||
sb.Free;
|
sb.Free;
|
||||||
ctx.Free;
|
ctx.Free;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
class function TAstSchema.GenerateRtlDocumentation: string;
|
||||||
|
var
|
||||||
|
ctx: TRttiContext;
|
||||||
|
typ: TRttiType;
|
||||||
|
meth: TRttiMethod;
|
||||||
|
attr: TCustomAttribute;
|
||||||
|
doc, rtlName: string;
|
||||||
|
sigs: TList<string>;
|
||||||
|
sb: TStringBuilder;
|
||||||
|
processedNames: THashSet<string>;
|
||||||
|
begin
|
||||||
|
ctx := TRttiContext.Create;
|
||||||
|
sb := TStringBuilder.Create;
|
||||||
|
sigs := TList<string>.Create;
|
||||||
|
processedNames := THashSet<string>.Create;
|
||||||
|
try
|
||||||
|
typ := ctx.GetType(TypeInfo(TRtlFunctions));
|
||||||
|
sb.AppendLine('### 3. Runtime Library (Available Functions)');
|
||||||
|
sb.AppendLine;
|
||||||
|
|
||||||
|
for meth in typ.GetMethods do
|
||||||
|
begin
|
||||||
|
doc := '';
|
||||||
|
rtlName := '';
|
||||||
|
sigs.Clear;
|
||||||
|
|
||||||
|
for attr in meth.GetAttributes do
|
||||||
|
begin
|
||||||
|
if attr is AstDocAttribute then
|
||||||
|
doc := AstDocAttribute(attr).Description;
|
||||||
|
if attr is TRtlExportAttribute then
|
||||||
|
rtlName := TRtlExportAttribute(attr).Name;
|
||||||
|
if attr is AstSignatureAttribute then
|
||||||
|
sigs.Add(AstSignatureAttribute(attr).Signature);
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (rtlName <> '') and (not processedNames.Contains(rtlName)) then
|
||||||
|
begin
|
||||||
|
sb.Append(Format('- `%s`', [rtlName]));
|
||||||
|
if sigs.Count > 0 then
|
||||||
|
sb.Append(': ' + string.Join(' | ', sigs.ToArray));
|
||||||
|
if doc <> '' then
|
||||||
|
sb.Append(' — ' + doc);
|
||||||
|
sb.AppendLine;
|
||||||
|
processedNames.Add(rtlName);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Result := sb.ToString;
|
||||||
|
finally
|
||||||
|
processedNames.Free;
|
||||||
|
sigs.Free;
|
||||||
|
sb.Free;
|
||||||
|
ctx.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
class function TAstSchema.GenerateGenerationRules: string;
|
class function TAstSchema.GenerateGenerationRules: string;
|
||||||
var
|
var
|
||||||
sb: TStringBuilder;
|
sb: TStringBuilder;
|
||||||
begin
|
begin
|
||||||
// These rules describe the PROTOCOL (Compact Arrays), not the content.
|
|
||||||
// They remain static unless you change TJsonAstConverter logic significantly.
|
|
||||||
sb := TStringBuilder.Create;
|
sb := TStringBuilder.Create;
|
||||||
try
|
try
|
||||||
sb.AppendLine('**⚠️ CRITICAL GENERATION RULES:**');
|
sb.AppendLine('**⚠️ CRITICAL GENERATION RULES:**');
|
||||||
sb.AppendLine;
|
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('1. **NO JSON OBJECTS:** Do not use `{}`. Every node MUST be a JSON Array `["Tag", Arg1, Arg2]`.');
|
||||||
|
sb.AppendLine('2. **EXPLICIT TUPLES:** Fields defined as `Tuple` MUST be wrapped in `["Tuple", [...]]`.');
|
||||||
|
sb.AppendLine('3. **EXPLICIT NULLS:** Optional fields (`| null`) MUST be explicit `null` if not present.');
|
||||||
|
sb.AppendLine('4. **STRICT ORDER:** Array elements must follow the schema index exactly. Never swap arguments.');
|
||||||
sb.AppendLine(
|
sb.AppendLine(
|
||||||
'2. **EXPLICIT TUPLES:** Whenever a field in the schema is defined as `Tuple`, you MUST wrap the list in a `["Tuple", [...]]` node.'
|
'5. **OPERATORS:** Use `Call` with an `Id` for operators: `["Call", ["Id", "+"], ["Tuple", [["Const", 1], ["Const", 2]]]]`.'
|
||||||
);
|
);
|
||||||
sb.AppendLine(
|
sb.AppendLine(
|
||||||
'3. **EXPLICIT NULLS:** Optional fields (marked as `| null`) MUST be explicit `null` if not present. Do not omit them.'
|
'6. **ID VS KEY:** Use `Key` for record keys (e.g. `["Field", ["Key", "p"], ...]`). Use `Id` for variables, functions, and operators.'
|
||||||
);
|
);
|
||||||
sb.AppendLine('4. **STRICT ORDER:** The order of elements in the array is fixed defined by the schema. Never swap arguments.');
|
sb.AppendLine('7. **BOOLEANS:** The literals `true` and `false` are identifiers: `["Id", "true"]` or `["Id", "false"]`.');
|
||||||
|
sb.AppendLine(
|
||||||
|
'8. **SCALAR TYPES:** Valid types for series definitions are: `:Ordinal`, `:Float`, `:Boolean`, `:Text`, `:DateTime`.'
|
||||||
|
);
|
||||||
|
sb.AppendLine('9. **NESTED ARRAYS:** In "Cond", the pairs are an array of arrays: `[ [cond1, branch1], [cond2, branch2] ]`.');
|
||||||
|
sb.AppendLine('10. **RECURSION:** Use `Recur` for tail-recursive calls to enable optimization.');
|
||||||
|
sb.AppendLine('11. **NO COMMENTS:** Output raw JSON only. No explanations.');
|
||||||
|
|
||||||
Result := sb.ToString;
|
Result := sb.ToString;
|
||||||
finally
|
finally
|
||||||
@@ -202,9 +285,8 @@ end;
|
|||||||
|
|
||||||
class function TAstSchema.GenerateFullSystemPrompt: string;
|
class function TAstSchema.GenerateFullSystemPrompt: string;
|
||||||
begin
|
begin
|
||||||
// Combine everything
|
|
||||||
Result :=
|
Result :=
|
||||||
'You are a compiler frontend for a scripting language.'
|
'You are a compiler frontend for a domain-specific 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
|
||||||
@@ -215,8 +297,9 @@ begin
|
|||||||
+ sLineBreak
|
+ sLineBreak
|
||||||
+ '### 2. Constraints & Rules'
|
+ '### 2. Constraints & Rules'
|
||||||
+ sLineBreak
|
+ sLineBreak
|
||||||
+ GenerateGenerationRules;
|
+ GenerateGenerationRules
|
||||||
//TODO add 3. RTL
|
+ sLineBreak
|
||||||
|
+ GenerateRtlDocumentation;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|||||||
+796
-801
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@ unit Myc.Ast.RTL.Core;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
System.SysUtils,
|
system.sysutils,
|
||||||
Myc.Utils,
|
Myc.Utils,
|
||||||
Myc.Data.Scalar,
|
Myc.Data.Scalar,
|
||||||
Myc.Data.Value,
|
Myc.Data.Value,
|
||||||
@@ -11,140 +11,184 @@ uses
|
|||||||
Myc.Ast.Attributes;
|
Myc.Ast.Attributes;
|
||||||
|
|
||||||
type
|
type
|
||||||
// Contains the "pure" native implementations.
|
{ Contains the native implementations for the Myc standard library. }
|
||||||
TRtlFunctions = record
|
TRtlFunctions = record
|
||||||
public
|
public
|
||||||
// Arithmetic
|
// --- Arithmetic ---
|
||||||
|
|
||||||
[TRtlExport('+', Pure)]
|
[TRtlExport('+', Pure)]
|
||||||
[AstDoc('Adds two numbers or concatenates two strings.')]
|
[AstDoc('Adds two numbers or concatenates two strings.')]
|
||||||
|
[AstSignature('(number, number) -> number')]
|
||||||
|
[AstSignature('(string, string) -> string')]
|
||||||
class function Add(const Args: TArray<TDataValue>): TDataValue; overload; static;
|
class function Add(const Args: TArray<TDataValue>): TDataValue; overload; static;
|
||||||
|
|
||||||
[TRtlExport('-', Pure)]
|
[TRtlExport('-', Pure)]
|
||||||
[AstDoc('Subtracts B from A, or negates A if called with one argument.')]
|
[AstDoc('Subtracts B from A, or negates A if called with one argument.')]
|
||||||
|
[AstSignature('(number, number) -> number')]
|
||||||
|
[AstSignature('(number) -> number')]
|
||||||
class function Subtract(const Args: TArray<TDataValue>): TDataValue; static;
|
class function Subtract(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
[TRtlExport('*', Pure)]
|
[TRtlExport('*', Pure)]
|
||||||
[AstDoc('Multiplies two numbers.')]
|
[AstDoc('Multiplies two numbers.')]
|
||||||
|
[AstSignature('(number, number) -> number')]
|
||||||
class function Multiply(const Args: TArray<TDataValue>): TDataValue; static;
|
class function Multiply(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
[TRtlExport('/', Pure)]
|
[TRtlExport('/', Pure)]
|
||||||
[AstDoc('Divides A by B. Returns a Float.')]
|
[AstDoc('Divides A by B. Always returns a floating point number.')]
|
||||||
|
[AstSignature('(number, number) -> number')]
|
||||||
class function Divide(const Args: TArray<TDataValue>): TDataValue; static;
|
class function Divide(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
[TRtlExport('div', Pure)]
|
[TRtlExport('div', Pure)]
|
||||||
[AstDoc('Integer division.')]
|
[AstDoc('Performs integer division.')]
|
||||||
|
[AstSignature('(number, number) -> number')]
|
||||||
class function IntDivide(const Args: TArray<TDataValue>): TDataValue; static;
|
class function IntDivide(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
[TRtlExport('mod', Pure)]
|
[TRtlExport('mod', Pure)]
|
||||||
[AstDoc('Remainder of integer division.')]
|
[AstDoc('Returns the remainder of integer division.')]
|
||||||
|
[AstSignature('(number, number) -> number')]
|
||||||
class function Modulus(const Args: TArray<TDataValue>): TDataValue; static;
|
class function Modulus(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
// Comparison
|
// --- Comparison ---
|
||||||
|
|
||||||
[TRtlExport('=', Pure)]
|
[TRtlExport('=', Pure)]
|
||||||
[AstDoc('Returns true if A equals B.')]
|
[AstDoc('Checks if A is equal to B.')]
|
||||||
|
[AstSignature('(any, any) -> boolean')]
|
||||||
class function Equal(const Args: TArray<TDataValue>): TDataValue; static;
|
class function Equal(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
[TRtlExport('<>', Pure)]
|
[TRtlExport('<>', Pure)]
|
||||||
[AstDoc('Returns true if A is not equal to B.')]
|
[AstDoc('Checks if A is not equal to B.')]
|
||||||
|
[AstSignature('(any, any) -> boolean')]
|
||||||
class function NotEqual(const Args: TArray<TDataValue>): TDataValue; static;
|
class function NotEqual(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
[TRtlExport('<', Pure)]
|
[TRtlExport('<', Pure)]
|
||||||
[AstDoc('Returns true if A is less than B.')]
|
[AstDoc('Checks if A is less than B.')]
|
||||||
|
[AstSignature('(number, number) -> boolean')]
|
||||||
class function LessThan(const Args: TArray<TDataValue>): TDataValue; static;
|
class function LessThan(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
[TRtlExport('<=', Pure)]
|
[TRtlExport('<=', Pure)]
|
||||||
[AstDoc('Returns true if A is less than or equal to B.')]
|
[AstDoc('Checks if A is less than or equal to B.')]
|
||||||
|
[AstSignature('(number, number) -> boolean')]
|
||||||
class function LessThanOrEqual(const Args: TArray<TDataValue>): TDataValue; static;
|
class function LessThanOrEqual(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
[TRtlExport('>', Pure)]
|
[TRtlExport('>', Pure)]
|
||||||
[AstDoc('Returns true if A is greater than B.')]
|
[AstDoc('Checks if A is greater than B.')]
|
||||||
|
[AstSignature('(number, number) -> boolean')]
|
||||||
class function GreaterThan(const Args: TArray<TDataValue>): TDataValue; static;
|
class function GreaterThan(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
[TRtlExport('>=', Pure)]
|
[TRtlExport('>=', Pure)]
|
||||||
[AstDoc('Returns true if A is greater than or equal to B.')]
|
[AstDoc('Checks if A is greater than or equal to B.')]
|
||||||
|
[AstSignature('(number, number) -> boolean')]
|
||||||
class function GreaterThanOrEqual(const Args: TArray<TDataValue>): TDataValue; static;
|
class function GreaterThanOrEqual(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
// Logic / Bitwise
|
// --- Logic / Bitwise ---
|
||||||
|
|
||||||
[TRtlExport('not', Pure)]
|
[TRtlExport('not', Pure)]
|
||||||
[AstDoc('Logical or bitwise NOT.')]
|
[AstDoc('Logical or bitwise NOT operation.')]
|
||||||
|
[AstSignature('(boolean) -> boolean')]
|
||||||
|
[AstSignature('(number) -> number')]
|
||||||
class function LogicalNot(const Args: TArray<TDataValue>): TDataValue; static;
|
class function LogicalNot(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
[TRtlExport('and', Pure)]
|
[TRtlExport('and', Pure)]
|
||||||
[AstDoc('Logical or bitwise AND.')]
|
[AstDoc('Logical or bitwise AND operation.')]
|
||||||
|
[AstSignature('(boolean, boolean) -> boolean')]
|
||||||
|
[AstSignature('(number, number) -> number')]
|
||||||
class function BitwiseAnd(const Args: TArray<TDataValue>): TDataValue; static;
|
class function BitwiseAnd(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
[TRtlExport('or', Pure)]
|
[TRtlExport('or', Pure)]
|
||||||
[AstDoc('Logical or bitwise OR.')]
|
[AstDoc('Logical or bitwise OR operation.')]
|
||||||
|
[AstSignature('(boolean, boolean) -> boolean')]
|
||||||
|
[AstSignature('(number, number) -> number')]
|
||||||
class function BitwiseOr(const Args: TArray<TDataValue>): TDataValue; static;
|
class function BitwiseOr(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
[TRtlExport('xor', Pure)]
|
[TRtlExport('xor', Pure)]
|
||||||
[AstDoc('Logical or bitwise XOR.')]
|
[AstDoc('Logical or bitwise XOR operation.')]
|
||||||
|
[AstSignature('(boolean, boolean) -> boolean')]
|
||||||
|
[AstSignature('(number, number) -> number')]
|
||||||
class function BitwiseXor(const Args: TArray<TDataValue>): TDataValue; static;
|
class function BitwiseXor(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
[TRtlExport('shl', Pure)]
|
[TRtlExport('shl', Pure)]
|
||||||
[AstDoc('Bitwise shift left.')]
|
[AstDoc('Bitwise shift left.')]
|
||||||
|
[AstSignature('(number, number) -> number')]
|
||||||
class function LeftShift(const Args: TArray<TDataValue>): TDataValue; static;
|
class function LeftShift(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
[TRtlExport('shr', Pure)]
|
[TRtlExport('shr', Pure)]
|
||||||
[AstDoc('Bitwise shift right.')]
|
[AstDoc('Bitwise shift right.')]
|
||||||
|
[AstSignature('(number, number) -> number')]
|
||||||
class function RightShift(const Args: TArray<TDataValue>): TDataValue; static;
|
class function RightShift(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
// Math Functions
|
// --- Math Functions ---
|
||||||
|
|
||||||
[TRtlExport('Abs', Pure)]
|
[TRtlExport('Abs', Pure)]
|
||||||
[AstDoc('Returns the absolute value.')]
|
[AstDoc('Returns the absolute value of a number.')]
|
||||||
|
[AstSignature('(number) -> number')]
|
||||||
class function Abs(const Arg: TScalar): TScalar; static;
|
class function Abs(const Arg: TScalar): TScalar; static;
|
||||||
|
|
||||||
[TRtlExport('Round', Pure)]
|
[TRtlExport('Round', Pure)]
|
||||||
[AstDoc('Rounds a float to the nearest integer.')]
|
[AstDoc('Rounds a float to the nearest integer.')]
|
||||||
|
[AstSignature('(number) -> number')]
|
||||||
class function Round(const Arg: TScalar): TScalar; static;
|
class function Round(const Arg: TScalar): TScalar; static;
|
||||||
|
|
||||||
[TRtlExport('Trunc', Pure)]
|
[TRtlExport('Trunc', Pure)]
|
||||||
[AstDoc('Truncates a float to an integer.')]
|
[AstDoc('Returns the integer part of a float.')]
|
||||||
|
[AstSignature('(number) -> number')]
|
||||||
class function Trunc(const Arg: TScalar): TScalar; static;
|
class function Trunc(const Arg: TScalar): TScalar; static;
|
||||||
|
|
||||||
[TRtlExport('Ceil', Pure)]
|
[TRtlExport('Ceil', Pure)]
|
||||||
[AstDoc('Returns the smallest integer greater than or equal to the argument.')]
|
[AstDoc('Returns the smallest integer >= the argument.')]
|
||||||
|
[AstSignature('(number) -> number')]
|
||||||
class function Ceil(const Arg: TScalar): TScalar; static;
|
class function Ceil(const Arg: TScalar): TScalar; static;
|
||||||
|
|
||||||
[TRtlExport('Floor', Pure)]
|
[TRtlExport('Floor', Pure)]
|
||||||
[AstDoc('Returns the largest integer less than or equal to the argument.')]
|
[AstDoc('Returns the largest integer <= the argument.')]
|
||||||
|
[AstSignature('(number) -> number')]
|
||||||
class function Floor(const Arg: TScalar): TScalar; static;
|
class function Floor(const Arg: TScalar): TScalar; static;
|
||||||
|
|
||||||
[TRtlExport('Sign', Pure)]
|
[TRtlExport('Sign', Pure)]
|
||||||
[AstDoc('Returns -1 for negative numbers, 1 for positive numbers, and 0 for zero.')]
|
[AstDoc('Returns -1 for negative, 1 for positive, 0 for zero.')]
|
||||||
|
[AstSignature('(number) -> number')]
|
||||||
class function Sign(const Arg: TScalar): TScalar; static;
|
class function Sign(const Arg: TScalar): TScalar; static;
|
||||||
|
|
||||||
// DateTime
|
// --- DateTime ---
|
||||||
|
|
||||||
[TRtlExport('Now', Impure)]
|
[TRtlExport('Now', Impure)]
|
||||||
[AstDoc('Returns the current system date and time.')]
|
[AstDoc('Returns the current system timestamp.')]
|
||||||
|
[AstSignature('() -> datetime')]
|
||||||
class function Now(const Args: TArray<TDataValue>): TDataValue; static;
|
class function Now(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
[TRtlExport('Date', Impure)]
|
[TRtlExport('Date', Impure)]
|
||||||
[AstDoc('Returns the current date or constructs a date from (Year, Month, Day).')]
|
[AstDoc('Returns the current date or constructs a date from Y, M, D.')]
|
||||||
|
[AstSignature('() -> datetime')]
|
||||||
|
[AstSignature('(number, number, number) -> datetime')]
|
||||||
class function Date(const Args: TArray<TDataValue>): TDataValue; static;
|
class function Date(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
// High-Order / Series
|
// --- Functional / Series ---
|
||||||
|
|
||||||
[TRtlExport('Memoize', Pure)]
|
[TRtlExport('Memoize', Pure)]
|
||||||
[AstDoc('Returns a memoized version of the provided function.')]
|
[AstDoc('Creates a memoized version of a function for performance.')]
|
||||||
|
[AstSignature('((any) -> any) -> ((any) -> any)')]
|
||||||
class function Memoize(const Args: TArray<TDataValue>): TDataValue; static;
|
class function Memoize(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
[TRtlExport('Map', Pure)]
|
[TRtlExport('Map', Pure)]
|
||||||
[AstDoc('Maps a function over a series.')]
|
[AstDoc('Applies a function to every element of a series.')]
|
||||||
|
[AstSignature('(series, (any) -> any) -> series')]
|
||||||
class function Map(const Args: TArray<TDataValue>): TDataValue; static;
|
class function Map(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
[TRtlExport('Reduce', Pure)]
|
[TRtlExport('Reduce', Pure)]
|
||||||
[AstDoc('Reduces a series using a combining function and an accumulator.')]
|
[AstDoc('Collapses a series into a single value using a reducer function.')]
|
||||||
|
[AstSignature('(series, any, (any, any) -> any) -> any')]
|
||||||
class function Reduce(const Args: TArray<TDataValue>): TDataValue; static;
|
class function Reduce(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
[TRtlExport('Where', Pure)]
|
[TRtlExport('Where', Pure)]
|
||||||
[AstDoc('Filters a series using a predicate function.')]
|
[AstDoc('Filters a series based on a predicate function.')]
|
||||||
|
[AstSignature('(series, (any) -> boolean) -> series')]
|
||||||
class function Where(const Args: TArray<TDataValue>): TDataValue; static;
|
class function Where(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
[TRtlExport('Any', Pure)]
|
[TRtlExport('Any', Pure)]
|
||||||
[AstDoc('Returns true if any element in the series satisfies the predicate.')]
|
[AstDoc('Returns true if at least one element satisfies the predicate.')]
|
||||||
|
[AstSignature('(series, (any) -> boolean) -> boolean')]
|
||||||
class function Any(const Args: TArray<TDataValue>): TDataValue; static;
|
class function Any(const Args: TArray<TDataValue>): TDataValue; static;
|
||||||
|
|
||||||
// --- Static Specializations (Picked up by TRtlRegistry via attributes) ---
|
// --- Static Specializations (Targets for TypeChecker/Specializer) ---
|
||||||
|
|
||||||
[TRtlExport('+', Pure)]
|
[TRtlExport('+', Pure)]
|
||||||
class function Add_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; static;
|
class function Add_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; static;
|
||||||
@@ -155,7 +199,7 @@ type
|
|||||||
[TRtlExport('+', Pure)]
|
[TRtlExport('+', Pure)]
|
||||||
class function Add_Float_Ordinal_Float(A: Double; B: Int64): Double; static;
|
class function Add_Float_Ordinal_Float(A: Double; B: Int64): Double; static;
|
||||||
[TRtlExport('+', Pure)]
|
[TRtlExport('+', Pure)]
|
||||||
class function Add_Text_Text_Text(const A: String; const B: String): String; static;
|
class function Add_Text_Text_Text(const A: string; const B: string): string; static;
|
||||||
|
|
||||||
[TRtlExport('-', Pure)]
|
[TRtlExport('-', Pure)]
|
||||||
class function Subtract_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; static;
|
class function Subtract_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; static;
|
||||||
|
|||||||
Reference in New Issue
Block a user