Skip to content

Commit

Permalink
simplify letAll in MatchlessToValue
Browse files Browse the repository at this point in the history
  • Loading branch information
johnynek committed Dec 9, 2023
1 parent dd2ee1a commit e8677fd
Showing 1 changed file with 17 additions and 10 deletions.
27 changes: 17 additions & 10 deletions core/src/main/scala/org/bykn/bosatsu/MatchlessToValue.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.bykn.bosatsu

import cats.{Eval, Foldable, Functor, Applicative}
import cats.{Eval, Functor, Applicative}
import cats.data.NonEmptyList
import cats.evidence.Is
import java.math.BigInteger
Expand Down Expand Up @@ -68,21 +68,28 @@ object MatchlessToValue {
locals: Map[Bindable, Eval[Value]],
anon: LongMap[Value],
muts: MLongMap[Value],
slots: Vector[Eval[Value]]) {
slots: Vector[Value]) {

def let(b: Bindable, v: Eval[Value]): Scope =
copy(locals = locals.updated(b, v))

def letAll[F[_]: Foldable](bs: F[(Bindable, Value)]): Scope =
copy(locals = bs.foldLeft(locals) { case (locals, (b, v)) => locals.updated(b, Eval.now(v)) })
def letAll(bs: NonEmptyList[Bindable], vs: NonEmptyList[Value]): Scope = {
val b = bs.iterator
val v = vs.iterator
var local1 = locals
while (b.hasNext) {
local1 = local1.updated(b.next(), Eval.now(v.next()))
}
copy(locals = local1)
}

def updateMut(mutIdx: Long, v: Value): Unit = {
assert(muts.contains(mutIdx))
muts.put(mutIdx, v)
()
}

def capture(it: Vector[Eval[Value]], name: Option[Bindable]): Scope =
def capture(it: Vector[Value], name: Option[Bindable]): Scope =
Scope(
name match {
case None => Map.empty
Expand Down Expand Up @@ -326,7 +333,7 @@ object MatchlessToValue {
// It may make things go faster
// if the caps are really small
// or if we can GC things sooner.
val scope1 = scope.capture(caps.map { s => Eval.later(s(scope)) }, Some(fnName))
val scope1 = scope.capture(caps.map { s => s(scope) }, Some(fnName))

FnValue { allArgs =>
var registers: NonEmptyList[Value] = allArgs
Expand Down Expand Up @@ -373,7 +380,7 @@ object MatchlessToValue {
// we can allocate once if there is no closure
val scope1 = Scope.empty()
val fn = FnValue { argV =>
val scope2 = scope1.letAll(args.zip(argV))
val scope2 = scope1.letAll(args, argV)
resFn(scope2)
}
Static(fn)
Expand All @@ -382,12 +389,12 @@ object MatchlessToValue {
val capScoped = caps.map(loop).toVector
Dynamic { scope =>
val scope1 = scope
.capture(capScoped.map { scoped => Eval.later(scoped(scope)) }, name)
.capture(capScoped.map { scoped => scoped(scope) }, name)

// hopefully optimization/normalization has lifted anything
// that doesn't depend on argV above this lambda
FnValue { argV =>
val scope2 = scope1.letAll(args.zip(argV))
val scope2 = scope1.letAll(args, argV)
resFn(scope2)
}
}
Expand All @@ -405,7 +412,7 @@ object MatchlessToValue {
case Local(b) => Dynamic(_.locals(b).value)
case LocalAnon(a) => Dynamic(_.anon(a))
case LocalAnonMut(m) => Dynamic(_.muts(m))
case ClosureSlot(idx) => Dynamic(_.slots(idx).value)
case ClosureSlot(idx) => Dynamic(_.slots(idx))
case App(expr, args) =>
// TODO: App(LoopFn(..
// can be optimized into a while
Expand Down

0 comments on commit e8677fd

Please sign in to comment.