Macro expander integrated in binder
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -24,7 +24,7 @@ type
|
|||||||
private
|
private
|
||||||
FJsonObjectStack: TStack<TJSONObject>;
|
FJsonObjectStack: TStack<TJSONObject>;
|
||||||
procedure DataValueToJson(const AValue: TDataValue; const AParent: TJSONObject; const AName: string);
|
procedure DataValueToJson(const AValue: TDataValue; const AParent: TJSONObject; const AName: string);
|
||||||
function JsonToNode(const AJson: TJSONValue): IAstNode;
|
function JsonToNode(const AJson: TJSONValue; const ExpectedType: String = ''): IAstNode;
|
||||||
function JsonToDataValue(const AObj: TJSONObject; const AName: string): TDataValue;
|
function JsonToDataValue(const AObj: TJSONObject; const AName: string): TDataValue;
|
||||||
|
|
||||||
function JsonToConstantNode(const AObj: TJSONObject): IConstantNode;
|
function JsonToConstantNode(const AObj: TJSONObject): IConstantNode;
|
||||||
@@ -276,7 +276,6 @@ var
|
|||||||
param: IIdentifierNode;
|
param: IIdentifierNode;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
// Added serialization for macro definitions.
|
|
||||||
Node.Name.Accept(Self);
|
Node.Name.Accept(Self);
|
||||||
for param in Node.Parameters do
|
for param in Node.Parameters do
|
||||||
param.Accept(Self);
|
param.Accept(Self);
|
||||||
@@ -719,7 +718,7 @@ function TJsonAstConverter.JsonToMacroDefNode(const AObj: TJSONObject): IMacroDe
|
|||||||
var
|
var
|
||||||
name: IIdentifierNode;
|
name: IIdentifierNode;
|
||||||
params: TArray<IIdentifierNode>;
|
params: TArray<IIdentifierNode>;
|
||||||
body: IAstNode;
|
body: IQuasiquoteNode;
|
||||||
paramArray: TJSONArray;
|
paramArray: TJSONArray;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
@@ -731,7 +730,7 @@ begin
|
|||||||
for i := 0 to paramArray.Count - 1 do
|
for i := 0 to paramArray.Count - 1 do
|
||||||
params[i] := JsonToIdentifierNode(paramArray.Items[i] as TJSONObject);
|
params[i] := JsonToIdentifierNode(paramArray.Items[i] as TJSONObject);
|
||||||
|
|
||||||
body := JsonToNode(AObj.GetValue('Body'));
|
body := IQuasiquoteNode(JsonToNode(AObj.GetValue('Body'), 'Quasiquote'));
|
||||||
Result := TAst.MacroDef(name, params, body);
|
Result := TAst.MacroDef(name, params, body);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@@ -874,7 +873,7 @@ begin
|
|||||||
Result := TAst.SeriesLength(JsonToIdentifierNode(AObj.GetValue('Series') as TJSONObject));
|
Result := TAst.SeriesLength(JsonToIdentifierNode(AObj.GetValue('Series') as TJSONObject));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TJsonAstConverter.JsonToNode(const AJson: TJSONValue): IAstNode;
|
function TJsonAstConverter.JsonToNode(const AJson: TJSONValue; const ExpectedType: String = ''): IAstNode;
|
||||||
var
|
var
|
||||||
obj: TJSONObject;
|
obj: TJSONObject;
|
||||||
nodeType: string;
|
nodeType: string;
|
||||||
@@ -885,6 +884,9 @@ begin
|
|||||||
obj := AJson as TJSONObject;
|
obj := AJson as TJSONObject;
|
||||||
nodeType := obj.GetValue<string>('NodeType');
|
nodeType := obj.GetValue<string>('NodeType');
|
||||||
|
|
||||||
|
if (ExpectedType <> '') and (nodeType <> ExpectedType) then
|
||||||
|
raise EInvalidCast.CreateFmt('Expected a JSON object of type %s for deserialization, but got a %s.', [ExpectedType, nodeType]);
|
||||||
|
|
||||||
if nodeType = 'Constant' then
|
if nodeType = 'Constant' then
|
||||||
Result := JsonToConstantNode(obj)
|
Result := JsonToConstantNode(obj)
|
||||||
else if nodeType = 'Identifier' then
|
else if nodeType = 'Identifier' then
|
||||||
|
|||||||
@@ -200,11 +200,11 @@ type
|
|||||||
{$region 'private'}
|
{$region 'private'}
|
||||||
function GetName: IIdentifierNode;
|
function GetName: IIdentifierNode;
|
||||||
function GetParameters: TArray<IIdentifierNode>;
|
function GetParameters: TArray<IIdentifierNode>;
|
||||||
function GetBody: IAstNode;
|
function GetBody: IQuasiquoteNode;
|
||||||
{$endregion}
|
{$endregion}
|
||||||
property Name: IIdentifierNode read GetName;
|
property Name: IIdentifierNode read GetName;
|
||||||
property Parameters: TArray<IIdentifierNode> read GetParameters;
|
property Parameters: TArray<IIdentifierNode> read GetParameters;
|
||||||
property Body: IAstNode read GetBody;
|
property Body: IQuasiquoteNode read GetBody;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Represents a quasiquoted expression, e.g., `(a b)
|
// Represents a quasiquoted expression, e.g., `(a b)
|
||||||
|
|||||||
@@ -403,7 +403,11 @@ begin
|
|||||||
|
|
||||||
var macroName := IIdentifierNode(tailNodes[0]);
|
var macroName := IIdentifierNode(tailNodes[0]);
|
||||||
var macroParams := elements[2].Params;
|
var macroParams := elements[2].Params;
|
||||||
var macroBody := tailNodes[2];
|
|
||||||
|
if tailTokens[2].Kind <> tkQuote then
|
||||||
|
raise Exception.Create('Syntax Error: Expected a quasiquote as macro body.');
|
||||||
|
|
||||||
|
var macroBody := IQuasiQuoteNode(tailNodes[2]);
|
||||||
|
|
||||||
Result := TAst.MacroDef(macroName, macroParams, macroBody);
|
Result := TAst.MacroDef(macroName, macroParams, macroBody);
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ function TAstTransformer.VisitMacroDefinition(const Node: IMacroDefinitionNode):
|
|||||||
begin
|
begin
|
||||||
var name := Accept(Node.Name).AsIntf<IIdentifierNode>;
|
var name := Accept(Node.Name).AsIntf<IIdentifierNode>;
|
||||||
var parameters := TransformNodes<IIdentifierNode>(Node.Parameters);
|
var parameters := TransformNodes<IIdentifierNode>(Node.Parameters);
|
||||||
var body := Accept(Node.Body).AsIntf<IAstNode>;
|
var body := Accept(Node.Body).AsIntf<IQuasiquoteNode>;
|
||||||
if (name = Node.Name) and (parameters = Node.Parameters) and (body = Node.Body) then
|
if (name = Node.Name) and (parameters = Node.Parameters) and (body = Node.Body) then
|
||||||
Result := TDataValue.FromIntf<IMacroDefinitionNode>(Node)
|
Result := TDataValue.FromIntf<IMacroDefinitionNode>(Node)
|
||||||
else
|
else
|
||||||
|
|||||||
+11
-7
@@ -39,7 +39,7 @@ type
|
|||||||
class function MacroDef(
|
class function MacroDef(
|
||||||
const AName: IIdentifierNode;
|
const AName: IIdentifierNode;
|
||||||
const AParameters: TArray<IIdentifierNode>;
|
const AParameters: TArray<IIdentifierNode>;
|
||||||
const ABody: IAstNode
|
const ABody: IQuasiquoteNode
|
||||||
): IMacroDefinitionNode; static;
|
): IMacroDefinitionNode; static;
|
||||||
class function Quasiquote(const AExpression: IAstNode): IQuasiquoteNode; static;
|
class function Quasiquote(const AExpression: IAstNode): IQuasiquoteNode; static;
|
||||||
class function Unquote(const AExpression: IAstNode): IUnquoteNode; static;
|
class function Unquote(const AExpression: IAstNode): IUnquoteNode; static;
|
||||||
@@ -158,12 +158,12 @@ type
|
|||||||
private
|
private
|
||||||
FName: IIdentifierNode;
|
FName: IIdentifierNode;
|
||||||
FParameters: TArray<IIdentifierNode>;
|
FParameters: TArray<IIdentifierNode>;
|
||||||
FBody: IAstNode;
|
FBody: IQuasiquoteNode;
|
||||||
function GetName: IIdentifierNode;
|
function GetName: IIdentifierNode;
|
||||||
function GetParameters: TArray<IIdentifierNode>;
|
function GetParameters: TArray<IIdentifierNode>;
|
||||||
function GetBody: IAstNode;
|
function GetBody: IQuasiquoteNode;
|
||||||
public
|
public
|
||||||
constructor Create(const AName: IIdentifierNode; const AParameters: TArray<IIdentifierNode>; const ABody: IAstNode);
|
constructor Create(const AName: IIdentifierNode; const AParameters: TArray<IIdentifierNode>; const ABody: IQuasiquoteNode);
|
||||||
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
function Accept(const Visitor: IAstVisitor): TDataValue; override;
|
||||||
property Name: IIdentifierNode read GetName;
|
property Name: IIdentifierNode read GetName;
|
||||||
end;
|
end;
|
||||||
@@ -494,7 +494,11 @@ end;
|
|||||||
|
|
||||||
{ TMacroDefinitionNode }
|
{ TMacroDefinitionNode }
|
||||||
|
|
||||||
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: IQuasiquoteNode
|
||||||
|
);
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
FName := AName;
|
FName := AName;
|
||||||
@@ -507,7 +511,7 @@ begin
|
|||||||
Result := Visitor.VisitMacroDefinition(Self);
|
Result := Visitor.VisitMacroDefinition(Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TMacroDefinitionNode.GetBody: IAstNode;
|
function TMacroDefinitionNode.GetBody: IQuasiquoteNode;
|
||||||
begin
|
begin
|
||||||
Result := FBody;
|
Result := FBody;
|
||||||
end;
|
end;
|
||||||
@@ -927,7 +931,7 @@ end;
|
|||||||
class function TAst.MacroDef(
|
class function TAst.MacroDef(
|
||||||
const AName: IIdentifierNode;
|
const AName: IIdentifierNode;
|
||||||
const AParameters: TArray<IIdentifierNode>;
|
const AParameters: TArray<IIdentifierNode>;
|
||||||
const ABody: IAstNode
|
const ABody: IQuasiquoteNode
|
||||||
): IMacroDefinitionNode;
|
): IMacroDefinitionNode;
|
||||||
begin
|
begin
|
||||||
Result := TMacroDefinitionNode.Create(AName, AParameters, ABody);
|
Result := TMacroDefinitionNode.Create(AName, AParameters, ABody);
|
||||||
|
|||||||
Reference in New Issue
Block a user