Fixed macro expansion
This commit is contained in:
@@ -212,11 +212,6 @@ begin
|
|||||||
FNextIsTail := FIsTailStack.Peek;
|
FNextIsTail := FIsTailStack.Peek;
|
||||||
N.ExpandedBody := Accept(N.ExpandedBody);
|
N.ExpandedBody := Accept(N.ExpandedBody);
|
||||||
|
|
||||||
// Also visit the original call nodes, though they are not in tail pos
|
|
||||||
FNextIsTail := False;
|
|
||||||
N.Callee := Accept(N.Callee);
|
|
||||||
N.Arguments := AcceptNodes(N.Arguments);
|
|
||||||
|
|
||||||
Result := N;
|
Result := N;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ type
|
|||||||
function VisitKeyword(const Node: IKeywordNode): IAstNode; override;
|
function VisitKeyword(const Node: IKeywordNode): IAstNode; override;
|
||||||
|
|
||||||
// Compile-time nodes (should not be present)
|
// Compile-time nodes (should not be present)
|
||||||
function VisitMacroExpansionNode(const Node: IMacroExpansionNode): IAstNode; override;
|
|
||||||
function VisitMacroDefinition(const Node: IMacroDefinitionNode): IAstNode; override;
|
function VisitMacroDefinition(const Node: IMacroDefinitionNode): IAstNode; override;
|
||||||
public
|
public
|
||||||
constructor Create(const ADescriptor: IScopeDescriptor);
|
constructor Create(const ADescriptor: IScopeDescriptor);
|
||||||
@@ -148,12 +147,6 @@ begin
|
|||||||
raise Exception.Create('TTypeChecker: MacroDefinition node encountered.');
|
raise Exception.Create('TTypeChecker: MacroDefinition node encountered.');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TTypeChecker.VisitMacroExpansionNode(const Node: IMacroExpansionNode): IAstNode;
|
|
||||||
begin
|
|
||||||
// TypeChecker runs *after* expansion, so we just visit the body.
|
|
||||||
Result := Accept(Node.ExpandedBody);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TTypeChecker.VisitVariableDeclaration(const Node: IVariableDeclarationNode): IAstNode;
|
function TTypeChecker.VisitVariableDeclaration(const Node: IVariableDeclarationNode): IAstNode;
|
||||||
var
|
var
|
||||||
initType: IStaticType;
|
initType: IStaticType;
|
||||||
|
|||||||
@@ -503,12 +503,14 @@ var
|
|||||||
N: TMacroExpansionNode;
|
N: TMacroExpansionNode;
|
||||||
begin
|
begin
|
||||||
N := (Node as TMacroExpansionNode);
|
N := (Node as TMacroExpansionNode);
|
||||||
// Visit original call parts
|
|
||||||
N.Callee := Accept(N.Callee);
|
// ONLY visit the expanded body, as this is the "real" AST node.
|
||||||
N.Arguments := AcceptNodes(N.Arguments);
|
|
||||||
// Visit expanded body
|
|
||||||
N.ExpandedBody := Accept(N.ExpandedBody);
|
N.ExpandedBody := Accept(N.ExpandedBody);
|
||||||
Result := Node;
|
|
||||||
|
// Callee and Arguments are metadata for the visualizer and must NOT be visited
|
||||||
|
// by subsequent phases (Binder, TypeChecker, etc.).
|
||||||
|
|
||||||
|
Result := Node; // Return the (mutated) wrapper
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TAstTransformer.VisitBlockExpression(const Node: IBlockExpressionNode): IAstNode;
|
function TAstTransformer.VisitBlockExpression(const Node: IBlockExpressionNode): IAstNode;
|
||||||
|
|||||||
@@ -63,10 +63,6 @@ type
|
|||||||
class operator Implicit(const AValue: String): TDataValue; overload; inline;
|
class operator Implicit(const AValue: String): TDataValue; overload; inline;
|
||||||
class operator Implicit(const AValue: TDataValue.TFunc): TDataValue; overload; inline;
|
class operator Implicit(const AValue: TDataValue.TFunc): TDataValue; overload; inline;
|
||||||
|
|
||||||
// atomic operations
|
|
||||||
function CompareAndSet(const Expected, NewValue: TDataValue): Boolean;
|
|
||||||
function Reset(const NewValue: TDataValue): TDataValue;
|
|
||||||
|
|
||||||
class function FromIntf<T: IInterface>(const AValue: T): TDataValue; static;
|
class function FromIntf<T: IInterface>(const AValue: T): TDataValue; static;
|
||||||
function AsIntf<T: IInterface>: T; inline;
|
function AsIntf<T: IInterface>: T; inline;
|
||||||
|
|
||||||
@@ -229,53 +225,6 @@ begin
|
|||||||
Result := (FInterface as TVal<String>).Value;
|
Result := (FInterface as TVal<String>).Value;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDataValue.CompareAndSet(const Expected, NewValue: TDataValue): Boolean;
|
|
||||||
|
|
||||||
function IntfCompareExchange(var VTarget: IInterface; const AValue, Compare: IInterface): IInterface; inline;
|
|
||||||
begin
|
|
||||||
if AValue <> nil then
|
|
||||||
AValue._AddRef;
|
|
||||||
|
|
||||||
Result := IInterface(TInterlocked.CompareExchange(Pointer(VTarget), Pointer(AValue), Pointer(Compare)));
|
|
||||||
|
|
||||||
if (AValue <> nil) and (Pointer(Result) <> Pointer(Compare)) then
|
|
||||||
AValue._Release;
|
|
||||||
end;
|
|
||||||
|
|
||||||
begin
|
|
||||||
Result := false;
|
|
||||||
if FKind <> Expected.Kind then
|
|
||||||
exit;
|
|
||||||
if FKind <> NewValue.Kind then
|
|
||||||
raise EArgumentException.Create('Value kinds have to match');
|
|
||||||
|
|
||||||
if FKind = vkVoid then
|
|
||||||
raise EArgumentException.Create('Value is void');
|
|
||||||
|
|
||||||
case FKind of
|
|
||||||
vkScalar:
|
|
||||||
case FScalar.Kind of
|
|
||||||
TScalar.TKind.Ordinal, TScalar.TKind.Keyword:
|
|
||||||
Result :=
|
|
||||||
TInterlocked
|
|
||||||
.CompareExchange(FScalar.Value.AsInt64, NewValue.AsScalar.Value.AsInt64, Expected.AsScalar.Value.AsInt64)
|
|
||||||
= Expected.AsScalar.Value.AsInt64;
|
|
||||||
TScalar.TKind.Float:
|
|
||||||
Result :=
|
|
||||||
TInterlocked
|
|
||||||
.CompareExchange(FScalar.Value.AsDouble, NewValue.AsScalar.Value.AsDouble, Expected.AsScalar.Value.AsDouble)
|
|
||||||
= Expected.AsScalar.Value.AsDouble;
|
|
||||||
end;
|
|
||||||
vkPointer:
|
|
||||||
Result :=
|
|
||||||
TInterlocked.CompareExchange(FScalar.Value.AsInt64, NewValue.AsScalar.Value.AsInt64, Expected.AsScalar.Value.AsInt64)
|
|
||||||
= Expected.AsScalar.Value.AsInt64;
|
|
||||||
|
|
||||||
vkText, vkSeries, vkRecordSeries, vkRecord, vkGenericRecord, vkManagedObject, vkMethod, vkInterface, vkGeneric:
|
|
||||||
Result := IntfCompareExchange(FInterface, NewValue.FInterface, Expected.FInterface) = Expected.FInterface;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
class function TDataValue.FromIntf<T>(const AValue: T): TDataValue;
|
class function TDataValue.FromIntf<T>(const AValue: T): TDataValue;
|
||||||
begin
|
begin
|
||||||
Result.FKind := vkInterface;
|
Result.FKind := vkInterface;
|
||||||
@@ -345,43 +294,6 @@ begin
|
|||||||
Result := TMapSeries.Create(SourceSeries, MapperFunc);
|
Result := TMapSeries.Create(SourceSeries, MapperFunc);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDataValue.Reset(const NewValue: TDataValue): TDataValue;
|
|
||||||
|
|
||||||
function IntfExchange(var VTarget: IInterface; const AValue: IInterface): IInterface; inline;
|
|
||||||
begin
|
|
||||||
if AValue <> nil then
|
|
||||||
AValue._AddRef;
|
|
||||||
|
|
||||||
Result := IInterface(TInterlocked.Exchange(Pointer(VTarget), Pointer(AValue)));
|
|
||||||
|
|
||||||
if AValue <> nil then
|
|
||||||
AValue._Release;
|
|
||||||
end;
|
|
||||||
|
|
||||||
begin
|
|
||||||
if FKind <> NewValue.Kind then
|
|
||||||
raise EArgumentException.Create('Value kinds have to match');
|
|
||||||
|
|
||||||
if FKind = vkVoid then
|
|
||||||
raise EArgumentException.Create('Value is void');
|
|
||||||
|
|
||||||
case FKind of
|
|
||||||
vkScalar:
|
|
||||||
case FScalar.Kind of
|
|
||||||
TScalar.TKind.Ordinal, TScalar.TKind.Keyword:
|
|
||||||
Result := TInterlocked.Exchange(FScalar.Value.AsInt64, NewValue.AsScalar.Value.AsInt64);
|
|
||||||
TScalar.TKind.Float: Result := TInterlocked.Exchange(FScalar.Value.AsDouble, NewValue.AsScalar.Value.AsDouble);
|
|
||||||
end;
|
|
||||||
vkPointer: Result := TInterlocked.Exchange(FScalar.Value.AsInt64, NewValue.AsScalar.Value.AsInt64);
|
|
||||||
|
|
||||||
vkText, vkSeries, vkRecordSeries, vkRecord, vkGenericRecord, vkManagedObject, vkMethod, vkInterface, vkGeneric:
|
|
||||||
begin
|
|
||||||
Result.FKind := FKind;
|
|
||||||
Result.FInterface := IntfExchange(FInterface, NewValue.FInterface);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TDataValue.ToString: String;
|
function TDataValue.ToString: String;
|
||||||
var
|
var
|
||||||
sb: TStringBuilder;
|
sb: TStringBuilder;
|
||||||
|
|||||||
Reference in New Issue
Block a user