Snippets

Patrick Logan CPS Evaluation Via Trampoline

Created by Patrick Logan last modified
type Combination []Expression

type CombinationK struct {
  Es []Expression    // Execute each expression of a combination via successive CombinationK continuations
  Ds []Datum         // Collect the data, giving the final expression an Applicationk continuation
  NextK Continuation
}

type Application []Datum    // Apply the first datum, a procedure, to the remaining data, the actual arguments

type ApplicationK struct {
  Ds []Datum    // Collect the data from evaluating each element of a combination then apply via Application
  NextK Continuation
}

func (k CombinationK) Invoke(result Datum, rte *RuntimeFrame, interp *Interpreter) (b Bouncer, d Datum, err error) {
  switch len(k.Es) {
  case 0:
    err = ImplementationError("A combination continuation must have at least one expression to execute")
    return
  case 1:
    k1 := ApplicationK{Ds: append(k.Ds, result), NextK: k.NextK}
    b = Bouncer{E: k.Es[0], F: rte, K: k1}
    return
  default:
    k1 := CombinationK{Es: k.Es[1:], Ds: append(k.Ds, result), NextK: k.NextK}
    b = Bouncer{E: k.Es[0], F: rte, K: k1}
    return
  }
}

func (c Combination) Execute(rte *RuntimeFrame, rtk Continuation, interp *Interpreter) (b Bouncer, d Datum, err error) {
  switch len(c) {
  case 0:
    err = EmptyListError{}
    return
  case 1:
    k := ApplicationK{NextK: rtk}
    b = Bouncer{E: c[0], F: rte, K: k}
    return
  default:
    k := CombinationK{Es: c[1:], NextK: rtk}
    b = Bouncer{E: c[0], F: rte, K: k}
    return
  }
}

func (interp *Interpreter) Eval(d Datum) (result Datum, err error) {
  var e Expression
  e, err = d.Compile(nil, interp)
  if err != nil {
    return
  }
  result, err = interp.Execute(e)
  return
}

func (interp *Interpreter) Execute(e Expression) (result Datum, err error) {
  var b Bouncer
  b, result, err = e.Execute(nil, IdentityK{}, interp)
  for b.E != nil && result == nil && err == nil {
    b, result, err = b.E.Execute(b.F, b.K, interp)
  }
  if result == nil && err == nil {
    err = ImplementationError("Execution completed with neither a result nor an error")
    return
  }
  return result, err
}

Comments (0)

HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.