Skip to content
Closed
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion sjsonnet/src/sjsonnet/Evaluator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1103,7 +1103,7 @@ class Evaluator(
}

def visitObjComp(e: ObjBody.ObjComp, sup: Val.Obj)(implicit scope: ValScope): Val.Obj = {
val binds = e.preLocals ++ e.postLocals
val binds = e.allLocals
val compScope: ValScope = scope // .clearSuper
val builder = new java.util.LinkedHashMap[String, Val.Obj.Member]
val compScopes = visitComp(e.first :: e.rest, Array(compScope))
Expand Down
2 changes: 2 additions & 0 deletions sjsonnet/src/sjsonnet/Expr.scala
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,8 @@ object Expr {
override def exprErrorString: String = "object comprehension"
override def toString: String =
s"ObjComp($pos, ${arrStr(preLocals)}, $key, $value, ${arrStr(postLocals)}, $first, $rest)"
// Cache concatenation of preLocals and postLocals to avoid repeated array allocation
lazy val allLocals: Array[Bind] = preLocals ++ postLocals
}
}
}
Expand Down
36 changes: 26 additions & 10 deletions sjsonnet/src/sjsonnet/stdlib/ArrayModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -487,26 +487,35 @@ object ArrayModule extends AbstractFunctionModule {
if (idx == -1) {
arr
} else {
Val.Arr(
arr.pos,
arr.asLazyArray.slice(0, idx) ++ arr.asLazyArray.slice(idx + 1, arr.length)
)
val src = arr.asLazyArray
val result = new Array[Eval](src.length - 1)
System.arraycopy(src, 0, result, 0, idx)
System.arraycopy(src, idx + 1, result, idx, src.length - idx - 1)
Val.Arr(arr.pos, result)
}
},
builtin("removeAt", "arr", "idx") { (_, _, arr: Val.Arr, idx: Int) =>
if (!(0 <= idx && idx < arr.length)) {
Error.fail("index out of bounds: 0 <= " + idx + " < " + arr.length)
}
Val.Arr(
arr.pos,
arr.asLazyArray.slice(0, idx) ++ arr.asLazyArray.slice(idx + 1, arr.length)
)
val src = arr.asLazyArray
val result = new Array[Eval](src.length - 1)
System.arraycopy(src, 0, result, 0, idx)
System.arraycopy(src, idx + 1, result, idx, src.length - idx - 1)
Val.Arr(arr.pos, result)
},
builtin("sum", "arr") { (_, _, arr: Val.Arr) =>
if (!arr.forall(_.isInstanceOf[Val.Num])) {
Error.fail("Argument must be an array of numbers")
}
arr.asLazyArray.map(_.value.asDouble).sum
val a = arr.asLazyArray
var sum = 0.0
var i = 0
while (i < a.length) {
sum += a(i).value.asDouble
i += 1
}
sum
},
builtin("avg", "arr") { (_, _, arr: Val.Arr) =>
if (!arr.forall(_.isInstanceOf[Val.Num])) {
Expand All @@ -515,7 +524,14 @@ object ArrayModule extends AbstractFunctionModule {
if (arr.length == 0) {
Error.fail("Cannot calculate average of an empty array")
}
arr.asLazyArray.map(_.value.asDouble).sum / arr.length
val a = arr.asLazyArray
var sum = 0.0
var i = 0
while (i < a.length) {
sum += a(i).value.asDouble
i += 1
}
sum / arr.length
}
)
}