Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 48 additions & 19 deletions sjsonnet/src/sjsonnet/ScopedExprTransform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -132,40 +132,64 @@ class ScopedExprTransform extends ExprTransform {
else {
val oldScope = scope
try {
val mappings = a.zipWithIndex.map { case (b, idx) =>
(b.name, ScopedVal(if (b.args == null) b.rhs else b, scope, scope.size + idx))
val baseSize = oldScope.size
val scopedVals = new Array[ScopedVal](a.length)
var mappings = oldScope.mappings
var idx = 0
while (idx < a.length) {
val b = a(idx)
val sv = ScopedVal(if (b.args == null) b.rhs else b, oldScope, baseSize + idx)
scopedVals(idx) = sv
mappings = mappings.updated(b.name, sv)
idx += 1
}
scope = new Scope(oldScope.mappings ++ mappings, oldScope.size + a.length)
var changed = false
val a2 = a.zipWithIndex.map { case (b, idx) =>
val scopeSize = baseSize + a.length
scope = new Scope(mappings, scopeSize)
var a2: Array[Bind] = null
idx = 0
while (idx < a.length) {
val b = a(idx)
val b2 = f(b)
val sv = mappings(idx)._2.copy(v = if (b2.args == null) b2.rhs else b2)
scope = new Scope(scope.mappings.updated(b.name, sv), scope.size)
if (b2 ne b) changed = true
b2
if ((a2 eq null) && (b2 ne b)) a2 = a.clone()
if (a2 ne null) a2(idx) = b2
val sv0 = scopedVals(idx)
val sv =
if (b2 eq b) sv0
else sv0.copy(v = if (b2.args == null) b2.rhs else b2)
mappings = mappings.updated(b.name, sv)
scope = new Scope(mappings, scopeSize)
idx += 1
}
(if (changed) a2 else a, g)
(if (a2 eq null) a else a2, g)
} finally { scope = oldScope }
}
}

protected def nestedBindings[T](a: Array[Bind])(f: => T): T = {
if (a == null || a.length == 0) f
else {
val newm = a.zipWithIndex.map { case (b, idx) =>
// println(s"Binding ${b.name} to ${scope.size + idx}")
(b.name, ScopedVal(if (b.args == null) b.rhs else b, scope, scope.size + idx))
val oldScope = scope
val baseSize = oldScope.size
var newMappings = oldScope.mappings
var idx = 0
while (idx < a.length) {
val b = a(idx)
newMappings = newMappings.updated(
b.name,
ScopedVal(if (b.args == null) b.rhs else b, oldScope, baseSize + idx)
)
idx += 1
}
nestedNew(new Scope(scope.mappings ++ newm, scope.size + a.length))(f)
nestedNew(new Scope(newMappings, baseSize + a.length))(f)
}
}

protected def nestedObject[T](self0: Expr, super0: Expr)(f: => T): T = {
val self = ScopedVal(self0, scope, scope.size)
val sup = ScopedVal(super0, scope, scope.size + 1)
val newm = {
val m1 = scope.mappings + (("self", self)) + (("super", sup))
if (scope.contains("self")) m1 else m1 + (("$", self))
val m1 = scope.mappings.updated("self", self).updated("super", sup)
if (scope.contains("self")) m1 else m1.updated("$", self)
}
nestedNew(new Scope(newm, scope.size + 2))(f)
}
Expand All @@ -176,10 +200,15 @@ class ScopedExprTransform extends ExprTransform {
protected def nestedNames[T](a: Array[String])(f: => T): T = {
if (a == null || a.length == 0) f
else {
val newm = a.zipWithIndex.map { case (n, idx) =>
(n, ScopedVal(dynamicExpr, scope, scope.size + idx))
val oldScope = scope
val baseSize = oldScope.size
var newMappings = oldScope.mappings
var idx = 0
while (idx < a.length) {
newMappings = newMappings.updated(a(idx), ScopedVal(dynamicExpr, oldScope, baseSize + idx))
idx += 1
}
nestedNew(new Scope(scope.mappings ++ newm, scope.size + a.length))(f)
nestedNew(new Scope(newMappings, baseSize + a.length))(f)
}
}
}
Expand Down
Loading