Added user library
This commit is contained in:
+44
-99
@@ -4,29 +4,23 @@ interface
|
||||
|
||||
uses
|
||||
System.SysUtils,
|
||||
System.Generics.Collections,
|
||||
System.JSON,
|
||||
Myc.Data.Scalar,
|
||||
Myc.Data.Value,
|
||||
Myc.Ast,
|
||||
Myc.Ast.Visitor,
|
||||
Myc.Ast.Nodes;
|
||||
|
||||
type
|
||||
// TAstJson provides static methods for serializing and deserializing an AST to/from JSON.
|
||||
TAstJson = record
|
||||
public
|
||||
class function Serialize(const ANode: IAstNode): string; static;
|
||||
class function Deserialize(const AJson: string): IAstNode; static;
|
||||
IJsonAstConverter = interface
|
||||
function Serialize(const RootNode: IAstNode): TJSONObject;
|
||||
function Deserialize(const AJson: TJSONObject): IAstNode;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
System.JSON,
|
||||
System.Generics.Collections,
|
||||
Myc.Ast,
|
||||
Myc.Data.Scalar,
|
||||
Myc.Data.Value;
|
||||
|
||||
type
|
||||
// TJsonAstConverter implements the visitor pattern for serialization
|
||||
// and uses factory functions for deserialization.
|
||||
TJsonAstConverter = class(TInterfacedObject, IAstVisitor)
|
||||
TJsonAstConverter = class(TAstVisitor, IJsonAstConverter)
|
||||
private
|
||||
FJsonObjectStack: TStack<TJSONObject>;
|
||||
procedure DataValueToJson(const AValue: TDataValue; const AParent: TJSONObject; const AName: string);
|
||||
@@ -52,31 +46,33 @@ type
|
||||
function JsonToSeriesLengthNode(const AObj: TJSONObject): ISeriesLengthNode;
|
||||
protected
|
||||
// IAstVisitor implementation for serialization
|
||||
function VisitConstant(const Node: IConstantNode): TDataValue;
|
||||
function VisitIdentifier(const Node: IIdentifierNode): TDataValue;
|
||||
function VisitBinaryExpression(const Node: IBinaryExpressionNode): TDataValue;
|
||||
function VisitUnaryExpression(const Node: IUnaryExpressionNode): TDataValue;
|
||||
function VisitIfExpression(const Node: IIfExpressionNode): TDataValue;
|
||||
function VisitTernaryExpression(const Node: ITernaryExpressionNode): TDataValue;
|
||||
function VisitLambdaExpression(const Node: ILambdaExpressionNode): TDataValue;
|
||||
function VisitFunctionCall(const Node: IFunctionCallNode): TDataValue;
|
||||
function VisitRecurNode(const Node: IRecurNode): TDataValue;
|
||||
function VisitBlockExpression(const Node: IBlockExpressionNode): TDataValue;
|
||||
function VisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue;
|
||||
function VisitAssignment(const Node: IAssignmentNode): TDataValue;
|
||||
function VisitIndexer(const Node: IIndexerNode): TDataValue;
|
||||
function VisitMemberAccess(const Node: IMemberAccessNode): TDataValue;
|
||||
function VisitCreateSeries(const Node: ICreateSeriesNode): TDataValue;
|
||||
function VisitAddSeriesItem(const Node: IAddSeriesItemNode): TDataValue;
|
||||
function VisitSeriesLength(const Node: ISeriesLengthNode): TDataValue;
|
||||
function VisitConstant(const Node: IConstantNode): TDataValue; override;
|
||||
function VisitIdentifier(const Node: IIdentifierNode): TDataValue; override;
|
||||
function VisitBinaryExpression(const Node: IBinaryExpressionNode): TDataValue; override;
|
||||
function VisitUnaryExpression(const Node: IUnaryExpressionNode): TDataValue; override;
|
||||
function VisitIfExpression(const Node: IIfExpressionNode): TDataValue; override;
|
||||
function VisitTernaryExpression(const Node: ITernaryExpressionNode): TDataValue; override;
|
||||
function VisitLambdaExpression(const Node: ILambdaExpressionNode): TDataValue; override;
|
||||
function VisitFunctionCall(const Node: IFunctionCallNode): TDataValue; override;
|
||||
function VisitRecurNode(const Node: IRecurNode): TDataValue; override;
|
||||
function VisitBlockExpression(const Node: IBlockExpressionNode): TDataValue; override;
|
||||
function VisitVariableDeclaration(const Node: IVariableDeclarationNode): TDataValue; override;
|
||||
function VisitAssignment(const Node: IAssignmentNode): TDataValue; override;
|
||||
function VisitIndexer(const Node: IIndexerNode): TDataValue; override;
|
||||
function VisitMemberAccess(const Node: IMemberAccessNode): TDataValue; override;
|
||||
function VisitCreateSeries(const Node: ICreateSeriesNode): TDataValue; override;
|
||||
function VisitAddSeriesItem(const Node: IAddSeriesItemNode): TDataValue; override;
|
||||
function VisitSeriesLength(const Node: ISeriesLengthNode): TDataValue; override;
|
||||
|
||||
function Serialize(const RootNode: IAstNode): TJSONObject;
|
||||
function Deserialize(const AJson: TJSONObject): IAstNode;
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
function Execute(const RootNode: IAstNode): TDataValue;
|
||||
function Serialize(const ANode: IAstNode): string;
|
||||
function Deserialize(const AJson: string): IAstNode;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TJsonAstConverter }
|
||||
|
||||
constructor TJsonAstConverter.Create;
|
||||
@@ -91,48 +87,9 @@ begin
|
||||
inherited;
|
||||
end;
|
||||
|
||||
function TJsonAstConverter.Serialize(const ANode: IAstNode): string;
|
||||
var
|
||||
rootObj: TJSONObject;
|
||||
function TJsonAstConverter.Deserialize(const AJson: TJSONObject): IAstNode;
|
||||
begin
|
||||
if not Assigned(ANode) then
|
||||
exit('');
|
||||
|
||||
FJsonObjectStack.Clear;
|
||||
ANode.Accept(Self);
|
||||
|
||||
if FJsonObjectStack.Count <> 1 then
|
||||
raise EInvalidOpException.Create('JSON serialization stack is corrupt.');
|
||||
|
||||
rootObj := FJsonObjectStack.Pop;
|
||||
try
|
||||
Result := rootObj.Format(4);
|
||||
finally
|
||||
rootObj.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TJsonAstConverter.Deserialize(const AJson: string): IAstNode;
|
||||
var
|
||||
jsonValue: TJSONValue;
|
||||
begin
|
||||
if AJson.IsEmpty then
|
||||
exit(nil);
|
||||
|
||||
jsonValue := TJSONObject.ParseJSONValue(AJson);
|
||||
if jsonValue = nil then
|
||||
raise EJSONParseException.Create('Invalid JSON format.');
|
||||
|
||||
try
|
||||
Result := JsonToNode(jsonValue);
|
||||
finally
|
||||
jsonValue.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TJsonAstConverter.Execute(const RootNode: IAstNode): TDataValue;
|
||||
begin
|
||||
Result := RootNode.Accept(Self);
|
||||
Result := JsonToNode(AJson);
|
||||
end;
|
||||
|
||||
{ TJsonAstConverter - IAstVisitor for Serialization }
|
||||
@@ -782,30 +739,18 @@ begin
|
||||
raise ENotSupportedException.CreateFmt('Unsupported NodeType "%s" for JSON deserialization.', [nodeType]);
|
||||
end;
|
||||
|
||||
{ TAstJson }
|
||||
|
||||
class function TAstJson.Deserialize(const AJson: string): IAstNode;
|
||||
var
|
||||
converter: TJsonAstConverter;
|
||||
function TJsonAstConverter.Serialize(const RootNode: IAstNode): TJSONObject;
|
||||
begin
|
||||
converter := TJsonAstConverter.Create;
|
||||
try
|
||||
Result := converter.Deserialize(AJson);
|
||||
finally
|
||||
converter.Free;
|
||||
end;
|
||||
end;
|
||||
FJsonObjectStack.Clear;
|
||||
if not Assigned(RootNode) then
|
||||
exit(nil);
|
||||
|
||||
class function TAstJson.Serialize(const ANode: IAstNode): string;
|
||||
var
|
||||
converter: TJsonAstConverter;
|
||||
begin
|
||||
converter := TJsonAstConverter.Create;
|
||||
try
|
||||
Result := converter.Serialize(ANode);
|
||||
finally
|
||||
converter.Free;
|
||||
end;
|
||||
RootNode.Accept(Self);
|
||||
|
||||
if FJsonObjectStack.Count <> 1 then
|
||||
raise EInvalidOpException.Create('JSON serialization stack is corrupt.');
|
||||
|
||||
Result := FJsonObjectStack.Pop;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
Reference in New Issue
Block a user