Macro expander integrated in binder

This commit is contained in:
Michael Schimmel
2025-10-05 02:45:13 +02:00
parent 54bf350c70
commit 0d73a13051
6 changed files with 373 additions and 218 deletions
+17 -5
View File
@@ -345,17 +345,29 @@ begin
if not (pair.JsonValue is TJSONObject) then
continue;
// First, deserialize the AST node from JSON.
funcAst := converter.Deserialize(pair.JsonValue as TJSONObject);
// Execute the lambda to get a callable function value
var adr := scopeDescr.FindSymbol(pair.JsonString.Value);
if adr.Kind = akUnresolved then
begin
funcValue := ExecuteAst(funcAst, FGScope);
FGScope.Define(pair.JsonString.Value, funcValue);
Memo1.Lines.Add(Format('Defined function "%s"', [pair.JsonString.Value]));
// Distinguish between loading a macro and loading a function.
if funcAst is TMacroDefinitionNode then
begin
// Macros are stored as raw AST nodes in the scope.
FGScope.Define(pair.JsonString.Value, TDataValue.FromIntf<IAstNode>(funcAst));
Memo1.Lines.Add(Format('Defined macro "%s"', [pair.JsonString.Value]));
end
else
begin
// Functions (lambdas) must be executed to create a callable closure.
funcValue := ExecuteAst(funcAst, FGScope);
FGScope.Define(pair.JsonString.Value, funcValue);
Memo1.Lines.Add(Format('Defined function "%s"', [pair.JsonString.Value]));
end;
end
else
Memo1.Lines.Add(Format('Function "%s" already defined', [pair.JsonString.Value]));
Memo1.Lines.Add(Format('Symbol "%s" already defined', [pair.JsonString.Value]));
end;
finally
jsonObj.Free;