Global data value refactoring + 1st scripting version

This commit is contained in:
Michael Schimmel
2025-09-20 18:30:32 +02:00
parent 09bd25b318
commit 00f5861148
17 changed files with 1430 additions and 2742 deletions
+53 -37
View File
@@ -21,7 +21,7 @@ uses
System.Generics.Collections,
Myc.Ast,
Myc.Data.Scalar,
Myc.Data.Value; // Added for TDataValue
Myc.Data.Value;
type
// TJsonAstConverter implements the visitor pattern for serialization
@@ -29,10 +29,10 @@ type
TJsonAstConverter = class(TInterfacedObject, IAstVisitor)
private
FJsonObjectStack: TStack<TJSONObject>;
procedure ScalarToJson(const AScalar: TScalar; const AParent: TJSONObject; const AName: string);
procedure DataValueToJson(const AValue: TDataValue; const AParent: TJSONObject; const AName: string);
function JsonToNode(const AJson: TJSONValue): IAstNode;
function JsonToScalar(const AObj: TJSONObject; const AName: string): TScalar;
// Updated signatures to return specific node interface types
function JsonToDataValue(const AObj: TJSONObject; const AName: string): TDataValue;
function JsonToConstantNode(const AObj: TJSONObject): IConstantNode;
function JsonToIdentifierNode(const AObj: TJSONObject): IIdentifierNode;
function JsonToBinaryExprNode(const AObj: TJSONObject): IBinaryExpressionNode;
@@ -137,23 +137,31 @@ end;
{ TJsonAstConverter - IAstVisitor for Serialization }
procedure TJsonAstConverter.ScalarToJson(const AScalar: TScalar; const AParent: TJSONObject; const AName: string);
procedure TJsonAstConverter.DataValueToJson(const AValue: TDataValue; const AParent: TJSONObject; const AName: string);
var
scalarObj: TJSONObject;
valObj, scalarObj: TJSONObject;
begin
scalarObj := TJSONObject.Create;
scalarObj.AddPair('Kind', TJSONString.Create(AScalar.Kind.ToString));
valObj := TJSONObject.Create;
valObj.AddPair('Kind', TJSONString.Create(AValue.Kind.ToString));
case AScalar.Kind of
skInt64: scalarObj.AddPair('Value', TJSONNumber.Create(AScalar.Value.AsInt64));
skDouble: scalarObj.AddPair('Value', TJSONNumber.Create(AScalar.Value.AsDouble));
skBoolean: scalarObj.AddPair('Value', TJSONBool.Create(AScalar.Value.AsBoolean));
skString: scalarObj.AddPair('Value', TJSONString.Create(AScalar.Value.AsString));
case AValue.Kind of
vkScalar:
begin
scalarObj := TJSONObject.Create;
scalarObj.AddPair('Kind', TJSONString.Create(AValue.AsScalar.Kind.ToString));
case AValue.AsScalar.Kind of
TScalar.TKind.Ordinal: scalarObj.AddPair('Value', TJSONNumber.Create(AValue.AsScalar.Value.AsInt64));
TScalar.TKind.Float: scalarObj.AddPair('Value', TJSONNumber.Create(AValue.AsScalar.Value.AsDouble));
end;
valObj.AddPair('Value', scalarObj);
end;
vkText: valObj.AddPair('Value', TJSONString.Create(AValue.AsText));
vkVoid:; // No value to add
else
raise ENotSupportedException.CreateFmt('Scalar kind %s not supported for JSON serialization.', [AScalar.Kind.ToString]);
raise ENotSupportedException.Create('Unsupported TDataValue kind for constant serialization.');
end;
AParent.AddPair(AName, scalarObj);
AParent.AddPair(AName, valObj);
end;
function TJsonAstConverter.VisitConstant(const Node: IConstantNode): TDataValue;
@@ -162,7 +170,7 @@ var
begin
obj := TJSONObject.Create;
obj.AddPair('NodeType', TJSONString.Create('Constant'));
ScalarToJson(Node.Value, obj, 'Value');
DataValueToJson(Node.Value, obj, 'Value');
FJsonObjectStack.Push(obj);
Result := TDataValue.Void;
end;
@@ -509,32 +517,40 @@ end;
{ TJsonAstConverter - Deserialization }
function TJsonAstConverter.JsonToScalar(const AObj: TJSONObject; const AName: string): TScalar;
function TJsonAstConverter.JsonToDataValue(const AObj: TJSONObject; const AName: string): TDataValue;
var
scalarObj: TJSONObject;
valObj, scalarObj: TJSONObject;
kindStr: string;
scalarKind: TScalarKind;
jsonValue: TJSONValue;
scalarKind: TScalar.TKind;
begin
scalarObj := AObj.GetValue<TJSONObject>(AName);
kindStr := scalarObj.GetValue<string>('Kind');
scalarKind := TScalar.StringToKind(kindStr);
valObj := AObj.GetValue<TJSONObject>(AName);
kindStr := valObj.GetValue<string>('Kind');
jsonValue := scalarObj.GetValue('Value');
case scalarKind of
skInt64: Result := TScalar.FromInt64((jsonValue as TJSONNumber).AsInt64);
skDouble: Result := TScalar.FromDouble((jsonValue as TJSONNumber).AsDouble);
skBoolean: Result := TScalar.FromBoolean((jsonValue as TJSONBool).AsBoolean);
skString: Result := TScalar.FromString((jsonValue as TJSONString).Value);
if SameText(kindStr, 'Scalar') then
begin
scalarObj := valObj.GetValue<TJSONObject>('Value');
kindStr := scalarObj.GetValue<string>('Kind');
scalarKind := TScalar.StringToKind(kindStr);
case scalarKind of
TScalar.TKind.Ordinal: Result := TScalar.FromInt64(scalarObj.GetValue<TJSONNumber>('Value').AsInt64);
TScalar.TKind.Float: Result := TScalar.FromDouble(scalarObj.GetValue<TJSONNumber>('Value').AsDouble);
end;
end
else if SameText(kindStr, 'Text') then
begin
Result := valObj.GetValue<string>('Value');
end
else if SameText(kindStr, 'Void') then
begin
Result := TDataValue.Void;
end
else
raise ENotSupportedException.CreateFmt('Scalar kind %s not supported for JSON deserialization.', [kindStr]);
end;
raise ENotSupportedException.Create('Unsupported TDataValue kind for constant deserialization.');
end;
function TJsonAstConverter.JsonToConstantNode(const AObj: TJSONObject): IConstantNode;
begin
Result := TAst.Constant(JsonToScalar(AObj, 'Value'));
Result := TAst.Constant(JsonToDataValue(AObj, 'Value'));
end;
function TJsonAstConverter.JsonToIdentifierNode(const AObj: TJSONObject): IIdentifierNode;
@@ -545,11 +561,11 @@ end;
function TJsonAstConverter.JsonToBinaryExprNode(const AObj: TJSONObject): IBinaryExpressionNode;
var
opStr: string;
op: TBinaryOperator;
op: TScalar.TBinaryOp;
leftNode, rightNode: IAstNode;
begin
opStr := AObj.GetValue<string>('Operator');
for op := Low(TBinaryOperator) to High(TBinaryOperator) do
for op := Low(TScalar.TBinaryOp) to High(TScalar.TBinaryOp) do
if SameText(op.ToString, opStr) then
begin
leftNode := JsonToNode(AObj.GetValue('Left'));
@@ -563,11 +579,11 @@ end;
function TJsonAstConverter.JsonToUnaryExprNode(const AObj: TJSONObject): IUnaryExpressionNode;
var
opStr: string;
op: TUnaryOperator;
op: TScalar.TUnaryOp;
rightNode: IAstNode;
begin
opStr := AObj.GetValue<string>('Operator');
for op := Low(TUnaryOperator) to High(TUnaryOperator) do
for op := Low(TScalar.TUnaryOp) to High(TScalar.TUnaryOp) do
if SameText(op.ToString, opStr) then
begin
rightNode := JsonToNode(AObj.GetValue('Right'));