added macro quoting nodes
This commit is contained in:
@@ -24,6 +24,9 @@ type
|
|||||||
IVariableDeclarationNode = interface;
|
IVariableDeclarationNode = interface;
|
||||||
IAssignmentNode = interface;
|
IAssignmentNode = interface;
|
||||||
IMacroDefinitionNode = interface;
|
IMacroDefinitionNode = interface;
|
||||||
|
IQuasiquoteNode = interface;
|
||||||
|
IUnquoteNode = interface;
|
||||||
|
IUnquoteSplicingNode = interface;
|
||||||
IIndexerNode = interface;
|
IIndexerNode = interface;
|
||||||
IMemberAccessNode = interface;
|
IMemberAccessNode = interface;
|
||||||
ICreateSeriesNode = interface;
|
ICreateSeriesNode = interface;
|
||||||
@@ -59,6 +62,9 @@ type
|
|||||||
function VisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue;
|
function VisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue;
|
||||||
function VisitAssignment(const Node: IAssignmentNode): TDataValue;
|
function VisitAssignment(const Node: IAssignmentNode): TDataValue;
|
||||||
function VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue;
|
function VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue;
|
||||||
|
function VisitQuasiquote(const Node: IQuasiquoteNode): TDataValue;
|
||||||
|
function VisitUnquote(const Node: IUnquoteNode): TDataValue;
|
||||||
|
function VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TDataValue;
|
||||||
function VisitIndexer(const Node: IIndexerNode): TDataValue;
|
function VisitIndexer(const Node: IIndexerNode): TDataValue;
|
||||||
function VisitMemberAccess(const Node: IMemberAccessNode): TDataValue;
|
function VisitMemberAccess(const Node: IMemberAccessNode): TDataValue;
|
||||||
function VisitCreateSeries(const Node: ICreateSeriesNode): TDataValue;
|
function VisitCreateSeries(const Node: ICreateSeriesNode): TDataValue;
|
||||||
@@ -190,6 +196,30 @@ type
|
|||||||
property Body: IAstNode read GetBody;
|
property Body: IAstNode read GetBody;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// Represents a quasiquoted expression, e.g., `(a b)
|
||||||
|
IQuasiquoteNode = interface(IAstNode)
|
||||||
|
{$region 'private'}
|
||||||
|
function GetExpression: IAstNode;
|
||||||
|
{$endregion}
|
||||||
|
property Expression: IAstNode read GetExpression;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Represents an unquoted expression, e.g., ~x
|
||||||
|
IUnquoteNode = interface(IAstNode)
|
||||||
|
{$region 'private'}
|
||||||
|
function GetExpression: IAstNode;
|
||||||
|
{$endregion}
|
||||||
|
property Expression: IAstNode read GetExpression;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Represents an unquote-splicing expression, e.g., ~@y
|
||||||
|
IUnquoteSplicingNode = interface(IAstNode)
|
||||||
|
{$region 'private'}
|
||||||
|
function GetExpression: IAstNode;
|
||||||
|
{$endregion}
|
||||||
|
property Expression: IAstNode read GetExpression;
|
||||||
|
end;
|
||||||
|
|
||||||
IIndexerNode = interface(IAstNode)
|
IIndexerNode = interface(IAstNode)
|
||||||
{$region 'private'}
|
{$region 'private'}
|
||||||
function GetBase: IAstNode;
|
function GetBase: IAstNode;
|
||||||
|
|||||||
+93
-16
@@ -34,6 +34,9 @@ type
|
|||||||
tkRightParen, // )
|
tkRightParen, // )
|
||||||
tkLeftBracket, // [
|
tkLeftBracket, // [
|
||||||
tkRightBracket, // ]
|
tkRightBracket, // ]
|
||||||
|
tkQuote, // '
|
||||||
|
tkBacktick, // `
|
||||||
|
tkTilde, // ~
|
||||||
tkIdentifier,
|
tkIdentifier,
|
||||||
tkNumber,
|
tkNumber,
|
||||||
tkString,
|
tkString,
|
||||||
@@ -109,6 +112,9 @@ type
|
|||||||
function VisitTernaryExpression(const Node: ITernaryExpressionNode): TDataValue;
|
function VisitTernaryExpression(const Node: ITernaryExpressionNode): TDataValue;
|
||||||
function VisitLambdaExpression(const Node: ILambdaExpressionNode): TDataValue;
|
function VisitLambdaExpression(const Node: ILambdaExpressionNode): TDataValue;
|
||||||
function VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue;
|
function VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue;
|
||||||
|
function VisitQuasiquote(const Node: IQuasiquoteNode): TDataValue;
|
||||||
|
function VisitUnquote(const Node: IUnquoteNode): TDataValue;
|
||||||
|
function VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TDataValue;
|
||||||
function VisitFunctionCall(const Node: IFunctionCallNode): TDataValue;
|
function VisitFunctionCall(const Node: IFunctionCallNode): TDataValue;
|
||||||
function VisitBlockExpression(const Node: IBlockExpressionNode): TDataValue;
|
function VisitBlockExpression(const Node: IBlockExpressionNode): TDataValue;
|
||||||
function VisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue;
|
function VisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue;
|
||||||
@@ -148,8 +154,8 @@ var
|
|||||||
startPos: Integer;
|
startPos: Integer;
|
||||||
begin
|
begin
|
||||||
startPos := FCurrentPos;
|
startPos := FCurrentPos;
|
||||||
// Corrected W1050: Use CharInSet for robust unicode support.
|
// Reader macro characters are now also delimiters for identifiers.
|
||||||
while (Peek <> #0) and (not (Peek.IsWhiteSpace or CharInSet(Peek, ['(', ')', '[', ']']))) do
|
while (Peek <> #0) and (not (Peek.IsWhiteSpace or CharInSet(Peek, ['(', ')', '[', ']', '''', '`', '~']))) do
|
||||||
Advance;
|
Advance;
|
||||||
Result := Copy(FSource, startPos, FCurrentPos - startPos);
|
Result := Copy(FSource, startPos, FCurrentPos - startPos);
|
||||||
end;
|
end;
|
||||||
@@ -228,6 +234,21 @@ begin
|
|||||||
Result.Kind := tkRightBracket;
|
Result.Kind := tkRightBracket;
|
||||||
Advance;
|
Advance;
|
||||||
end;
|
end;
|
||||||
|
'''':
|
||||||
|
begin
|
||||||
|
Result.Kind := tkQuote;
|
||||||
|
Advance;
|
||||||
|
end;
|
||||||
|
'`':
|
||||||
|
begin
|
||||||
|
Result.Kind := tkBacktick;
|
||||||
|
Advance;
|
||||||
|
end;
|
||||||
|
'~':
|
||||||
|
begin
|
||||||
|
Result.Kind := tkTilde;
|
||||||
|
Advance;
|
||||||
|
end;
|
||||||
'"':
|
'"':
|
||||||
begin
|
begin
|
||||||
Result.Kind := tkString;
|
Result.Kind := tkString;
|
||||||
@@ -382,7 +403,6 @@ begin
|
|||||||
end
|
end
|
||||||
else if SameText(head.Token.Text, 'fn') then
|
else if SameText(head.Token.Text, 'fn') then
|
||||||
begin
|
begin
|
||||||
// Corrected handling for lambda expressions
|
|
||||||
if Length(tailNodes) <> 2 then
|
if Length(tailNodes) <> 2 then
|
||||||
raise Exception.Create('Syntax Error: ''fn'' requires a parameter list and a body.');
|
raise Exception.Create('Syntax Error: ''fn'' requires a parameter list and a body.');
|
||||||
if elements[1].Node <> nil then
|
if elements[1].Node <> nil then
|
||||||
@@ -438,19 +458,43 @@ function TParser.ParseExpression: TExpr;
|
|||||||
var
|
var
|
||||||
i64: Int64;
|
i64: Int64;
|
||||||
dbl: Double;
|
dbl: Double;
|
||||||
|
expr: TExpr;
|
||||||
begin
|
begin
|
||||||
// TODO: Implement reader macros for quasiquoting here.
|
// Handle reader macros.
|
||||||
// The current lexer will tokenize `, ~, and ~@ as identifiers.
|
case FCurrentToken.Kind of
|
||||||
// Check for them here and wrap the subsequent expression accordingly.
|
tkBacktick:
|
||||||
// Example:
|
begin
|
||||||
// if FCurrentToken.Text = '`' then
|
NextToken;
|
||||||
// begin
|
expr := ParseExpression;
|
||||||
// NextToken;
|
Result.Node := TAst.Quasiquote(expr.Node);
|
||||||
// var exprToQuote := ParseExpression;
|
exit;
|
||||||
// Result.Node := TAst.Quasiquote(exprToQuote.Node);
|
end;
|
||||||
// exit;
|
tkTilde:
|
||||||
// end;
|
begin
|
||||||
// (This requires IQuasiquoteNode and TAst.Quasiquote to be defined first).
|
NextToken;
|
||||||
|
// Check for unquote-splicing ('~@')
|
||||||
|
if (FCurrentToken.Kind = tkIdentifier) and (FCurrentToken.Text = '@') then
|
||||||
|
begin
|
||||||
|
NextToken;
|
||||||
|
expr := ParseExpression;
|
||||||
|
Result.Node := TAst.UnquoteSplicing(expr.Node);
|
||||||
|
end
|
||||||
|
else // It's a regular unquote ('~')
|
||||||
|
begin
|
||||||
|
expr := ParseExpression;
|
||||||
|
Result.Node := TAst.Unquote(expr.Node);
|
||||||
|
end;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
tkQuote:
|
||||||
|
begin
|
||||||
|
NextToken;
|
||||||
|
expr := ParseExpression;
|
||||||
|
// A regular quote '(...) can be desugared into (quote (...))
|
||||||
|
Result.Node := TAst.FunctionCall(TAst.Identifier('quote'), [expr.Node]);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
Result.Token := FCurrentToken;
|
Result.Token := FCurrentToken;
|
||||||
case FCurrentToken.Kind of
|
case FCurrentToken.Kind of
|
||||||
@@ -639,7 +683,6 @@ var
|
|||||||
param: IIdentifierNode;
|
param: IIdentifierNode;
|
||||||
sb: TStringBuilder;
|
sb: TStringBuilder;
|
||||||
begin
|
begin
|
||||||
// Added visitor for pretty printing macro definitions.
|
|
||||||
sb := TStringBuilder.Create;
|
sb := TStringBuilder.Create;
|
||||||
try
|
try
|
||||||
for param in Node.Parameters do
|
for param in Node.Parameters do
|
||||||
@@ -661,10 +704,41 @@ begin
|
|||||||
Result := TDataValue.Void;
|
Result := TDataValue.Void;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TPrettyPrintVisitor.VisitQuasiquote(const Node: IQuasiquoteNode): TDataValue;
|
||||||
|
begin
|
||||||
|
Append('`');
|
||||||
|
Node.Expression.Accept(Self);
|
||||||
|
Result := TDataValue.Void;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TPrettyPrintVisitor.VisitUnquote(const Node: IUnquoteNode): TDataValue;
|
||||||
|
begin
|
||||||
|
Append('~');
|
||||||
|
Node.Expression.Accept(Self);
|
||||||
|
Result := TDataValue.Void;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TPrettyPrintVisitor.VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TDataValue;
|
||||||
|
begin
|
||||||
|
// To handle '~@', we need to check if the expression is an identifier '@'.
|
||||||
|
// However, the parser logic now handles this, so we just print '~@'.
|
||||||
|
Append('~@');
|
||||||
|
Node.Expression.Accept(Self);
|
||||||
|
Result := TDataValue.Void;
|
||||||
|
end;
|
||||||
|
|
||||||
function TPrettyPrintVisitor.VisitFunctionCall(const Node: IFunctionCallNode): TDataValue;
|
function TPrettyPrintVisitor.VisitFunctionCall(const Node: IFunctionCallNode): TDataValue;
|
||||||
var
|
var
|
||||||
arg: IAstNode;
|
arg: IAstNode;
|
||||||
begin
|
begin
|
||||||
|
// Special case for (quote ...) to print it as '...
|
||||||
|
if (Node.Callee is TIdentifierNode) and (TIdentifierNode(Node.Callee).Name = 'quote') and (Length(Node.Arguments) = 1) then
|
||||||
|
begin
|
||||||
|
Append('''');
|
||||||
|
Node.Arguments[0].Accept(Self);
|
||||||
|
exit(TDataValue.Void);
|
||||||
|
end;
|
||||||
|
|
||||||
Append('(');
|
Append('(');
|
||||||
Node.Callee.Accept(Self);
|
Node.Callee.Accept(Self);
|
||||||
|
|
||||||
@@ -828,6 +902,9 @@ begin
|
|||||||
tkRightParen: Result := ')';
|
tkRightParen: Result := ')';
|
||||||
tkLeftBracket: Result := '[';
|
tkLeftBracket: Result := '[';
|
||||||
tkRightBracket: Result := ']';
|
tkRightBracket: Result := ']';
|
||||||
|
tkQuote: Result := '''';
|
||||||
|
tkBacktick: Result := '`';
|
||||||
|
tkTilde: Result := '~';
|
||||||
tkIdentifier: Result := '<identifier>';
|
tkIdentifier: Result := '<identifier>';
|
||||||
tkNumber: Result := '<number>';
|
tkNumber: Result := '<number>';
|
||||||
tkString: Result := '<string>';
|
tkString: Result := '<string>';
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ type
|
|||||||
function VisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue; virtual; abstract;
|
function VisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue; virtual; abstract;
|
||||||
function VisitAssignment(const Node: IAssignmentNode): TDataValue; virtual; abstract;
|
function VisitAssignment(const Node: IAssignmentNode): TDataValue; virtual; abstract;
|
||||||
function VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue; virtual; abstract;
|
function VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue; virtual; abstract;
|
||||||
|
function VisitQuasiquote(const Node: IQuasiquoteNode): TDataValue; virtual; abstract;
|
||||||
|
function VisitUnquote(const Node: IUnquoteNode): TDataValue; virtual; abstract;
|
||||||
|
function VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TDataValue; virtual; abstract;
|
||||||
function VisitIndexer(const Node: IIndexerNode): TDataValue; virtual; abstract;
|
function VisitIndexer(const Node: IIndexerNode): TDataValue; virtual; abstract;
|
||||||
function VisitMemberAccess(const Node: IMemberAccessNode): TDataValue; virtual; abstract;
|
function VisitMemberAccess(const Node: IMemberAccessNode): TDataValue; virtual; abstract;
|
||||||
function VisitCreateSeries(const Node: ICreateSeriesNode): TDataValue; virtual; abstract;
|
function VisitCreateSeries(const Node: ICreateSeriesNode): TDataValue; virtual; abstract;
|
||||||
@@ -59,6 +62,9 @@ type
|
|||||||
function VisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue; override; final;
|
function VisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue; override; final;
|
||||||
function VisitAssignment(const Node: IAssignmentNode): TDataValue; override; final;
|
function VisitAssignment(const Node: IAssignmentNode): TDataValue; override; final;
|
||||||
function VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue; override; final;
|
function VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue; override; final;
|
||||||
|
function VisitQuasiquote(const Node: IQuasiquoteNode): TDataValue; override; final;
|
||||||
|
function VisitUnquote(const Node: IUnquoteNode): TDataValue; override; final;
|
||||||
|
function VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TDataValue; override; final;
|
||||||
function VisitIndexer(const Node: IIndexerNode): TDataValue; override; final;
|
function VisitIndexer(const Node: IIndexerNode): TDataValue; override; final;
|
||||||
function VisitMemberAccess(const Node: IMemberAccessNode): TDataValue; override; final;
|
function VisitMemberAccess(const Node: IMemberAccessNode): TDataValue; override; final;
|
||||||
function VisitCreateSeries(const Node: ICreateSeriesNode): TDataValue; override; final;
|
function VisitCreateSeries(const Node: ICreateSeriesNode): TDataValue; override; final;
|
||||||
@@ -79,6 +85,9 @@ type
|
|||||||
function TransformVariableDeclaration(const Node: IVariableDeclarationNode): IVariableDeclarationNode; virtual;
|
function TransformVariableDeclaration(const Node: IVariableDeclarationNode): IVariableDeclarationNode; virtual;
|
||||||
function TransformAssignment(const Node: IAssignmentNode): IAssignmentNode; virtual;
|
function TransformAssignment(const Node: IAssignmentNode): IAssignmentNode; virtual;
|
||||||
function TransformMacroDefinition(const Node: IMacroDefinitionNode): IMacroDefinitionNode; virtual;
|
function TransformMacroDefinition(const Node: IMacroDefinitionNode): IMacroDefinitionNode; virtual;
|
||||||
|
function TransformQuasiquote(const Node: IQuasiquoteNode): IQuasiquoteNode; virtual;
|
||||||
|
function TransformUnquote(const Node: IUnquoteNode): IUnquoteNode; virtual;
|
||||||
|
function TransformUnquoteSplicing(const Node: IUnquoteSplicingNode): IUnquoteSplicingNode; virtual;
|
||||||
function TransformIndexer(const Node: IIndexerNode): IIndexerNode; virtual;
|
function TransformIndexer(const Node: IIndexerNode): IIndexerNode; virtual;
|
||||||
function TransformMemberAccess(const Node: IMemberAccessNode): IMemberAccessNode; virtual;
|
function TransformMemberAccess(const Node: IMemberAccessNode): IMemberAccessNode; virtual;
|
||||||
function TransformCreateSeries(const Node: ICreateSeriesNode): ICreateSeriesNode; virtual;
|
function TransformCreateSeries(const Node: ICreateSeriesNode): ICreateSeriesNode; virtual;
|
||||||
@@ -249,6 +258,33 @@ begin
|
|||||||
Result := TAst.MacroDef(name, parameters, body);
|
Result := TAst.MacroDef(name, parameters, body);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TAstTransformer.TransformQuasiquote(const Node: IQuasiquoteNode): IQuasiquoteNode;
|
||||||
|
begin
|
||||||
|
var expr := Accept(Node.Expression).AsIntf<IAstNode>;
|
||||||
|
if expr = Node.Expression then
|
||||||
|
Result := Node
|
||||||
|
else
|
||||||
|
Result := TAst.Quasiquote(expr);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TAstTransformer.TransformUnquote(const Node: IUnquoteNode): IUnquoteNode;
|
||||||
|
begin
|
||||||
|
var expr := Accept(Node.Expression).AsIntf<IAstNode>;
|
||||||
|
if expr = Node.Expression then
|
||||||
|
Result := Node
|
||||||
|
else
|
||||||
|
Result := TAst.Unquote(expr);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TAstTransformer.TransformUnquoteSplicing(const Node: IUnquoteSplicingNode): IUnquoteSplicingNode;
|
||||||
|
begin
|
||||||
|
var expr := Accept(Node.Expression).AsIntf<IAstNode>;
|
||||||
|
if expr = Node.Expression then
|
||||||
|
Result := Node
|
||||||
|
else
|
||||||
|
Result := TAst.UnquoteSplicing(expr);
|
||||||
|
end;
|
||||||
|
|
||||||
function TAstTransformer.TransformIndexer(const Node: IIndexerNode): IIndexerNode;
|
function TAstTransformer.TransformIndexer(const Node: IIndexerNode): IIndexerNode;
|
||||||
begin
|
begin
|
||||||
var base := Accept(Node.Base).AsIntf<IAstNode>;
|
var base := Accept(Node.Base).AsIntf<IAstNode>;
|
||||||
@@ -377,10 +413,24 @@ end;
|
|||||||
|
|
||||||
function TAstTransformer.VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue;
|
function TAstTransformer.VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue;
|
||||||
begin
|
begin
|
||||||
// Added visit method for macro definitions.
|
|
||||||
Result := TDataValue.FromIntf<IMacroDefinitionNode>(TransformMacroDefinition(Node));
|
Result := TDataValue.FromIntf<IMacroDefinitionNode>(TransformMacroDefinition(Node));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TAstTransformer.VisitQuasiquote(const Node: IQuasiquoteNode): TDataValue;
|
||||||
|
begin
|
||||||
|
Result := TDataValue.FromIntf<IQuasiquoteNode>(TransformQuasiquote(Node));
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TAstTransformer.VisitUnquote(const Node: IUnquoteNode): TDataValue;
|
||||||
|
begin
|
||||||
|
Result := TDataValue.FromIntf<IUnquoteNode>(TransformUnquote(Node));
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TAstTransformer.VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TDataValue;
|
||||||
|
begin
|
||||||
|
Result := TDataValue.FromIntf<IUnquoteSplicingNode>(TransformUnquoteSplicing(Node));
|
||||||
|
end;
|
||||||
|
|
||||||
function TAstTransformer.VisitIndexer(const Node: IIndexerNode): TDataValue;
|
function TAstTransformer.VisitIndexer(const Node: IIndexerNode): TDataValue;
|
||||||
begin
|
begin
|
||||||
Result := TDataValue.FromIntf<IIndexerNode>(TransformIndexer(Node));
|
Result := TDataValue.FromIntf<IIndexerNode>(TransformIndexer(Node));
|
||||||
|
|||||||
+99
-2
@@ -41,6 +41,9 @@ type
|
|||||||
const AParameters: TArray<IIdentifierNode>;
|
const AParameters: TArray<IIdentifierNode>;
|
||||||
const ABody: IAstNode
|
const ABody: IAstNode
|
||||||
): IMacroDefinitionNode; static;
|
): IMacroDefinitionNode; static;
|
||||||
|
class function Quasiquote(const AExpression: IAstNode): IQuasiquoteNode; static;
|
||||||
|
class function Unquote(const AExpression: IAstNode): IUnquoteNode; static;
|
||||||
|
class function UnquoteSplicing(const AExpression: IAstNode): IUnquoteSplicingNode; static;
|
||||||
class function FunctionCall(const ACallee: IAstNode; const AArguments: TArray<IAstNode>): IFunctionCallNode; static;
|
class function FunctionCall(const ACallee: IAstNode; const AArguments: TArray<IAstNode>): IFunctionCallNode; static;
|
||||||
class function Recur(const AArguments: array of IAstNode): IRecurNode; static;
|
class function Recur(const AArguments: array of IAstNode): IRecurNode; static;
|
||||||
class function Block(const AExpressions: array of IAstNode): IBlockExpressionNode; static;
|
class function Block(const AExpressions: array of IAstNode): IBlockExpressionNode; static;
|
||||||
@@ -159,6 +162,33 @@ type
|
|||||||
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
TQuasiquoteNode = class(TAstNode, IQuasiquoteNode)
|
||||||
|
private
|
||||||
|
FExpression: IAstNode;
|
||||||
|
function GetExpression: IAstNode;
|
||||||
|
public
|
||||||
|
constructor Create(const AExpression: IAstNode);
|
||||||
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TUnquoteNode = class(TAstNode, IUnquoteNode)
|
||||||
|
private
|
||||||
|
FExpression: IAstNode;
|
||||||
|
function GetExpression: IAstNode;
|
||||||
|
public
|
||||||
|
constructor Create(const AExpression: IAstNode);
|
||||||
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TUnquoteSplicingNode = class(TAstNode, IUnquoteSplicingNode)
|
||||||
|
private
|
||||||
|
FExpression: IAstNode;
|
||||||
|
function GetExpression: IAstNode;
|
||||||
|
public
|
||||||
|
constructor Create(const AExpression: IAstNode);
|
||||||
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
||||||
|
end;
|
||||||
|
|
||||||
TFunctionCallNode = class(TAstNode, IFunctionCallNode)
|
TFunctionCallNode = class(TAstNode, IFunctionCallNode)
|
||||||
private
|
private
|
||||||
FCallee: IAstNode;
|
FCallee: IAstNode;
|
||||||
@@ -450,7 +480,6 @@ end;
|
|||||||
|
|
||||||
constructor TMacroDefinitionNode.Create(const AName: IIdentifierNode; const AParameters: TArray<IIdentifierNode>; const ABody: IAstNode);
|
constructor TMacroDefinitionNode.Create(const AName: IIdentifierNode; const AParameters: TArray<IIdentifierNode>; const ABody: IAstNode);
|
||||||
begin
|
begin
|
||||||
// Added concrete class for macro definitions.
|
|
||||||
inherited Create;
|
inherited Create;
|
||||||
FName := AName;
|
FName := AName;
|
||||||
FParameters := AParameters;
|
FParameters := AParameters;
|
||||||
@@ -477,6 +506,60 @@ begin
|
|||||||
Result := FParameters;
|
Result := FParameters;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TQuasiquoteNode }
|
||||||
|
|
||||||
|
constructor TQuasiquoteNode.Create(const AExpression: IAstNode);
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
FExpression := AExpression;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TQuasiquoteNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
||||||
|
begin
|
||||||
|
Result := Visitor.VisitQuasiquote(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TQuasiquoteNode.GetExpression: IAstNode;
|
||||||
|
begin
|
||||||
|
Result := FExpression;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TUnquoteNode }
|
||||||
|
|
||||||
|
constructor TUnquoteNode.Create(const AExpression: IAstNode);
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
FExpression := AExpression;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TUnquoteNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
||||||
|
begin
|
||||||
|
Result := Visitor.VisitUnquote(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TUnquoteNode.GetExpression: IAstNode;
|
||||||
|
begin
|
||||||
|
Result := FExpression;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TUnquoteSplicingNode }
|
||||||
|
|
||||||
|
constructor TUnquoteSplicingNode.Create(const AExpression: IAstNode);
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
FExpression := AExpression;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TUnquoteSplicingNode.Accept(const Visitor: IAstVisitor): TDataValue;
|
||||||
|
begin
|
||||||
|
Result := Visitor.VisitUnquoteSplicing(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TUnquoteSplicingNode.GetExpression: IAstNode;
|
||||||
|
begin
|
||||||
|
Result := FExpression;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TFunctionCallNode }
|
{ TFunctionCallNode }
|
||||||
|
|
||||||
constructor TFunctionCallNode.Create(const ACallee: IAstNode; const AArguments: TArray<IAstNode>);
|
constructor TFunctionCallNode.Create(const ACallee: IAstNode; const AArguments: TArray<IAstNode>);
|
||||||
@@ -811,7 +894,6 @@ class function TAst.MacroDef(
|
|||||||
const ABody: IAstNode
|
const ABody: IAstNode
|
||||||
): IMacroDefinitionNode;
|
): IMacroDefinitionNode;
|
||||||
begin
|
begin
|
||||||
// Added factory for macro definitions.
|
|
||||||
Result := TMacroDefinitionNode.Create(AName, AParameters, ABody);
|
Result := TMacroDefinitionNode.Create(AName, AParameters, ABody);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@@ -820,6 +902,11 @@ begin
|
|||||||
Result := TMemberAccessNode.Create(ABase, AMember);
|
Result := TMemberAccessNode.Create(ABase, AMember);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
class function TAst.Quasiquote(const AExpression: IAstNode): IQuasiquoteNode;
|
||||||
|
begin
|
||||||
|
Result := TQuasiquoteNode.Create(AExpression);
|
||||||
|
end;
|
||||||
|
|
||||||
class function TAst.Recur(const AArguments: array of IAstNode): IRecurNode;
|
class function TAst.Recur(const AArguments: array of IAstNode): IRecurNode;
|
||||||
var
|
var
|
||||||
args: TArray<IAstNode>;
|
args: TArray<IAstNode>;
|
||||||
@@ -841,6 +928,16 @@ begin
|
|||||||
Result := TTernaryExpressionNode.Create(ACondition, AThenBranch, AElseBranch);
|
Result := TTernaryExpressionNode.Create(ACondition, AThenBranch, AElseBranch);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
class function TAst.Unquote(const AExpression: IAstNode): IUnquoteNode;
|
||||||
|
begin
|
||||||
|
Result := TUnquoteNode.Create(AExpression);
|
||||||
|
end;
|
||||||
|
|
||||||
|
class function TAst.UnquoteSplicing(const AExpression: IAstNode): IUnquoteSplicingNode;
|
||||||
|
begin
|
||||||
|
Result := TUnquoteSplicingNode.Create(AExpression);
|
||||||
|
end;
|
||||||
|
|
||||||
class function TAst.UnaryExpr(const AOperator: TScalar.TUnaryOp; const ARight: IAstNode): IUnaryExpressionNode;
|
class function TAst.UnaryExpr(const AOperator: TScalar.TUnaryOp; const ARight: IAstNode): IUnaryExpressionNode;
|
||||||
begin
|
begin
|
||||||
Result := TUnaryExpressionNode.Create(AOperator, ARight);
|
Result := TUnaryExpressionNode.Create(AOperator, ARight);
|
||||||
|
|||||||
Reference in New Issue
Block a user