1st full macro expander

This commit is contained in:
Michael Schimmel
2025-10-03 19:46:30 +02:00
parent bb0ecda6be
commit d9219474e0
16 changed files with 700 additions and 323 deletions
+70 -1
View File
@@ -35,6 +35,9 @@ type
function JsonToTernaryExprNode(const AObj: TJSONObject): ITernaryExpressionNode;
function JsonToLambdaExprNode(const AObj: TJSONObject): ILambdaExpressionNode;
function JsonToMacroDefNode(const AObj: TJSONObject): IMacroDefinitionNode;
function JsonToQuasiquoteNode(const AObj: TJSONObject): IQuasiquoteNode;
function JsonToUnquoteNode(const AObj: TJSONObject): IUnquoteNode;
function JsonToUnquoteSplicingNode(const AObj: TJSONObject): IUnquoteSplicingNode;
function JsonToFunctionCallNode(const AObj: TJSONObject): IFunctionCallNode;
function JsonToRecurNode(const AObj: TJSONObject): IRecurNode;
function JsonToBlockNode(const AObj: TJSONObject): IBlockExpressionNode;
@@ -55,6 +58,9 @@ type
function VisitTernaryExpression(const Node: ITernaryExpressionNode): TDataValue; override;
function VisitLambdaExpression(const Node: ILambdaExpressionNode): TDataValue; override;
function VisitMacroDefinition(const Node: IMacroDefinitionNode): TDataValue; override;
function VisitQuasiquote(const Node: IQuasiquoteNode): TDataValue; override;
function VisitUnquote(const Node: IUnquoteNode): TDataValue; override;
function VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TDataValue; override;
function VisitFunctionCall(const Node: IFunctionCallNode): TDataValue; override;
function VisitRecurNode(const Node: IRecurNode): TDataValue; override;
function VisitBlockExpression(const Node: IBlockExpressionNode): TDataValue; override;
@@ -295,6 +301,21 @@ begin
Result := TDataValue.Void;
end;
function TJsonAstConverter.JsonToQuasiquoteNode(const AObj: TJSONObject): IQuasiquoteNode;
begin
Result := TAst.Quasiquote(JsonToNode(AObj.GetValue('Expression')));
end;
function TJsonAstConverter.JsonToUnquoteNode(const AObj: TJSONObject): IUnquoteNode;
begin
Result := TAst.Unquote(JsonToNode(AObj.GetValue('Expression')));
end;
function TJsonAstConverter.JsonToUnquoteSplicingNode(const AObj: TJSONObject): IUnquoteSplicingNode;
begin
Result := TAst.UnquoteSplicing(JsonToNode(AObj.GetValue('Expression')));
end;
function TJsonAstConverter.VisitFunctionCall(const Node: IFunctionCallNode): TDataValue;
var
obj, calleeObj: TJSONObject;
@@ -362,7 +383,7 @@ begin
for expr in Node.Expressions do
expr.Accept(Self);
SetLength(tempExprs, Node.Expressions.Count);
SetLength(tempExprs, Length(Node.Expressions));
for i := High(tempExprs) downto 0 do
tempExprs[i] := FJsonObjectStack.Pop;
@@ -646,6 +667,48 @@ begin
Result := TAst.MacroDef(name, params, body);
end;
function TJsonAstConverter.VisitQuasiquote(const Node: IQuasiquoteNode): TDataValue;
var
obj, exprObj: TJSONObject;
begin
Node.Expression.Accept(Self);
exprObj := FJsonObjectStack.Pop;
obj := TJSONObject.Create;
obj.AddPair('NodeType', TJSONString.Create('Quasiquote'));
obj.AddPair('Expression', exprObj);
FJsonObjectStack.Push(obj);
Result := TDataValue.Void;
end;
function TJsonAstConverter.VisitUnquote(const Node: IUnquoteNode): TDataValue;
var
obj, exprObj: TJSONObject;
begin
Node.Expression.Accept(Self);
exprObj := FJsonObjectStack.Pop;
obj := TJSONObject.Create;
obj.AddPair('NodeType', TJSONString.Create('Unquote'));
obj.AddPair('Expression', exprObj);
FJsonObjectStack.Push(obj);
Result := TDataValue.Void;
end;
function TJsonAstConverter.VisitUnquoteSplicing(const Node: IUnquoteSplicingNode): TDataValue;
var
obj, exprObj: TJSONObject;
begin
Node.Expression.Accept(Self);
exprObj := FJsonObjectStack.Pop;
obj := TJSONObject.Create;
obj.AddPair('NodeType', TJSONString.Create('UnquoteSplicing'));
obj.AddPair('Expression', exprObj);
FJsonObjectStack.Push(obj);
Result := TDataValue.Void;
end;
function TJsonAstConverter.JsonToFunctionCallNode(const AObj: TJSONObject): IFunctionCallNode;
var
callee: IAstNode;
@@ -774,6 +837,12 @@ begin
Result := JsonToLambdaExprNode(obj)
else if nodeType = 'MacroDef' then
Result := JsonToMacroDefNode(obj)
else if nodeType = 'Quasiquote' then
Result := JsonToQuasiquoteNode(obj)
else if nodeType = 'Unquote' then
Result := JsonToUnquoteNode(obj)
else if nodeType = 'UnquoteSplicing' then
Result := JsonToUnquoteSplicingNode(obj)
else if nodeType = 'FunctionCall' then
Result := JsonToFunctionCallNode(obj)
else if nodeType = 'Recur' then