Skip to content
This repository was archived by the owner on Jan 12, 2024. It is now read-only.

Commit 8300921

Browse files
author
Bettina Heim
committed
almost done with #2
1 parent b8423bc commit 8300921

File tree

2 files changed

+71
-56
lines changed

2 files changed

+71
-56
lines changed

src/QsCompiler/Core/TransformationDefinition.fs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ and ExpressionTypeTransformation<'T> private (parentTransformation) =
7979
internal new() = ExpressionTypeTransformation<'T>(None)
8080
new (parentTransformation : QsSyntaxTreeTransformation<'T>) = ExpressionTypeTransformation<'T>(Some parentTransformation)
8181

82+
8283
and ExpressionKindTransformation<'T> private (parentTransformation) =
8384
inherit ExpressionKindTransformation()
8485
let mutable _Transformation : QsSyntaxTreeTransformation<'T> option = parentTransformation

src/QsCompiler/Transformations/SearchAndReplace.cs

Lines changed: 70 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ public override QsTypeKind onTypeParameter(QsTypeParameter tp)
191191

192192

193193
private IdentifierLocation(Func<Identifier, bool> trackId, QsLocation defaultOffset) :
194-
base(null, new OnTypedExpression<TypeLocation>(null, _ => new TypeLocation(), recur: true))
194+
base(null, new OnTypedExpression<TypeLocation>(null, _ => new TypeLocation()))
195195
{
196196
this.TrackIdentifier = trackId ?? throw new ArgumentNullException(nameof(trackId));
197197
this.Locations = ImmutableList<IdentifierReferences.Location>.Empty;
@@ -278,82 +278,88 @@ private void OnExpression(TypedExpression ex)
278278

279279
// routines for finding all symbols/identifiers
280280

281+
/// <summary>
282+
/// Generates a look-up for all used local variables and their location in any of the transformed scopes,
283+
/// as well as one for all local variables reassigned in any of the transformed scopes and their locations.
284+
/// Note that the location information is relative to the root node, i.e. the start position of the containing specialization declaration.
285+
/// </summary>
281286
public class __AccumulateIdentifiers__
282287
: QsSyntaxTreeTransformation<__AccumulateIdentifiers__.TransformationState>
283288
{
284-
285289
public class TransformationState
286290
{
291+
internal QsLocation StatementLocation = null;
292+
internal Func<TypedExpression, TypedExpression> UpdatedExpression;
293+
294+
private readonly List<(NonNullable<string>, QsLocation)> UpdatedLocals = new List<(NonNullable<string>, QsLocation)>();
295+
private readonly List<(NonNullable<string>, QsLocation)> UsedLocals = new List<(NonNullable<string>, QsLocation)>();
296+
297+
internal TransformationState() =>
298+
this.UpdatedExpression = new __OnTypedExpression__<TransformationState>(this, this.UpdatedLocal).Transform; // FIXME: ENTIRELY NEW PARENT!
299+
300+
public ILookup<NonNullable<string>, QsLocation> ReassignedVariables =>
301+
this.UpdatedLocals.ToLookup(var => var.Item1, var => var.Item2);
302+
303+
public ILookup<NonNullable<string>, QsLocation> UsedLocalVariables =>
304+
this.UsedLocals.ToLookup(var => var.Item1, var => var.Item2);
287305

306+
307+
private Func<TypedExpression, TypedExpression> Add(List<(NonNullable<string>, QsLocation)> accumulate) => (TypedExpression ex) =>
308+
{
309+
if (ex.Expression is QsExpressionKind.Identifier id &&
310+
id.Item1 is Identifier.LocalVariable var)
311+
{
312+
var range = ex.Range.IsValue ? ex.Range.Item : this.StatementLocation.Range;
313+
accumulate.Add((var.Item, new QsLocation(this.StatementLocation.Offset, range)));
314+
}
315+
};
316+
317+
internal Func<TypedExpression, TypedExpression> UsedLocal => Add(this.UsedLocals);
318+
internal Func<TypedExpression, TypedExpression> UpdatedLocal => Add(this.UpdatedLocals);
288319
}
289320

321+
290322
public __AccumulateIdentifiers__() :
291323
base(new TransformationState())
292324
{ }
293-
}
294325

295-
/// <summary>
296-
/// Generates a look-up for all used local variables and their location in any of the transformed scopes,
297-
/// as well as one for all local variables reassigned in any of the transformed scopes and their locations.
298-
/// Note that the location information is relative to the root node, i.e. the start position of the containing specialization declaration.
299-
/// </summary>
300-
public class AccumulateIdentifiers :
301-
ScopeTransformation<AccumulateIdentifiers.VariableReassignments, OnTypedExpression<Core.ExpressionTypeTransformation>>
302-
{
303-
private QsLocation StatementLocation;
304-
private Func<TypedExpression, TypedExpression> UpdatedExpression;
326+
public override Core.ExpressionTransformation<TransformationState> NewExpressionTransformation() =>
327+
new __OnTypedExpression__<TransformationState>(this, this.InternalState.UsedLocal);
305328

306-
private List<(NonNullable<string>, QsLocation)> UpdatedLocals;
307-
private List<(NonNullable<string>, QsLocation)> UsedLocals;
329+
public override Core.StatementKindTransformation<TransformationState> NewStatementKindTransformation() =>
330+
new VariableReassignments(this);
308331

309-
public ILookup<NonNullable<string>, QsLocation> ReassignedVariables =>
310-
this.UpdatedLocals.ToLookup(var => var.Item1, var => var.Item2);
332+
public override StatementTransformation<TransformationState> NewStatementTransformation() =>
333+
new AccumulateIdentifiers(this);
311334

312-
public ILookup<NonNullable<string>, QsLocation> UsedLocalVariables =>
313-
this.UsedLocals.ToLookup(var => var.Item1, var => var.Item2);
314335

336+
// helper classes
315337

316-
public AccumulateIdentifiers() :
317-
base(
318-
scope => new VariableReassignments(scope as AccumulateIdentifiers),
319-
new OnTypedExpression<Core.ExpressionTypeTransformation>(recur: true))
338+
public class AccumulateIdentifiers :
339+
StatementTransformation<TransformationState>
320340
{
321-
this.UpdatedLocals = new List<(NonNullable<string>, QsLocation)>();
322-
this.UsedLocals = new List<(NonNullable<string>, QsLocation)>();
323-
this._Expression.OnExpression = this.onLocal(this.UsedLocals);
324-
this.UpdatedExpression = new OnTypedExpression<Core.ExpressionTypeTransformation>(this.onLocal(this.UpdatedLocals), recur: true).Transform;
325-
}
341+
public AccumulateIdentifiers(QsSyntaxTreeTransformation<TransformationState> parent)
342+
: base(parent)
343+
{ }
326344

327-
private Action<TypedExpression> onLocal(List<(NonNullable<string>, QsLocation)> accumulate) => (TypedExpression ex) =>
328-
{
329-
if (ex.Expression is QsExpressionKind.Identifier id &&
330-
id.Item1 is Identifier.LocalVariable var)
345+
public override QsStatement onStatement(QsStatement stm)
331346
{
332-
var range = ex.Range.IsValue ? ex.Range.Item : this.StatementLocation.Range;
333-
accumulate.Add((var.Item, new QsLocation(this.StatementLocation.Offset, range)));
347+
this.Transformation.InternalState.StatementLocation = stm.Location.IsNull ? null : stm.Location.Item;
348+
this.StatementKind.Transform(stm.Statement);
349+
return stm;
334350
}
335-
};
336-
337-
public override QsStatement onStatement(QsStatement stm)
338-
{
339-
this.StatementLocation = stm.Location.IsNull ? null : stm.Location.Item;
340-
this.StatementKind.Transform(stm.Statement);
341-
return stm;
342351
}
343352

344-
345-
// helper class
346-
347353
public class VariableReassignments :
348-
StatementKindTransformation<AccumulateIdentifiers>
354+
Core.StatementKindTransformation<TransformationState>
349355
{
350-
public VariableReassignments(AccumulateIdentifiers scope)
351-
: base(scope)
356+
public VariableReassignments(QsSyntaxTreeTransformation<TransformationState> parent)
357+
: base(parent)
352358
{ }
353359

354360
public override QsStatementKind onValueUpdate(QsValueUpdate stm)
355361
{
356-
this._Scope.UpdatedExpression(stm.Lhs);
362+
this.Transformation.InternalState.UpdatedExpression(stm.Lhs);
357363
this.ExpressionTransformation(stm.Rhs);
358364
return QsStatementKind.NewQsValueUpdate(stm);
359365
}
@@ -456,21 +462,29 @@ public class OnTypedExpression<T> :
456462
ExpressionTransformation<ExpressionKindTransformation<OnTypedExpression<T>>, T>
457463
where T : Core.ExpressionTypeTransformation
458464
{
459-
private readonly bool recur;
460-
461-
public OnTypedExpression(Action<TypedExpression> onExpression = null, Func<OnTypedExpression<T>, T> typeTransformation = null, bool recur = false) :
465+
public OnTypedExpression(Action<TypedExpression> onExpression = null, Func<OnTypedExpression<T>, T> typeTransformation = null) :
462466
base(e => new ExpressionKindTransformation<OnTypedExpression<T>>(e as OnTypedExpression<T>),
463-
e => typeTransformation?.Invoke(e as OnTypedExpression<T>))
464-
{
467+
e => typeTransformation?.Invoke(e as OnTypedExpression<T>)) =>
465468
this.OnExpression = onExpression;
466-
this.recur = recur;
467-
}
468469

469470
public Action<TypedExpression> OnExpression;
470471
public override TypedExpression Transform(TypedExpression ex)
471472
{
472473
this.OnExpression?.Invoke(ex);
473-
return this.recur ? base.Transform(ex) : ex;
474+
return base.Transform(ex);
474475
}
475476
}
477+
478+
479+
public class __OnTypedExpression__<T> :
480+
Core.ExpressionTransformation<T>
481+
{
482+
public __OnTypedExpression__(QsSyntaxTreeTransformation<T> parent, Func<TypedExpression, TypedExpression> onExpression)
483+
: base(parent) =>
484+
this.OnExpression = onExpression ?? throw new ArgumentNullException(nameof(onExpression));
485+
486+
public Func<TypedExpression, TypedExpression> OnExpression;
487+
public override TypedExpression Transform(TypedExpression ex) =>
488+
this.OnExpression(ex);
489+
}
476490
}

0 commit comments

Comments
 (0)