pub enum BinOpKind {
Plus,
Minus,
Times,
Eq,
CellSet,
Cons,
IsCode,
Log,
App,
}Expand description
Binary primitive operators that share the same shape:
- eval e1 → v1
- eval e2 → v2
- dispatch on (v1, v2)
The dispatch differs per op (arithmetic vs equality vs cons-build), but the operand sequencing is identical.
Not in this enum: LiftRef. Although LiftRef takes two Exps,
its dispatch on v1 happens before e2 is evaluated — if v1 is
Code, e2 must be evaluated inside a reify scope, not normally.
LiftRef has its own dedicated continuations (Cont::LiftRefDispatch,
Cont::LiftRefForceCode).
Variants§
Plus
+ — Cst+Cst → Cst, Code+Code → reflect Plus, else TypeError
Minus
- — Cst−Cst → Cst, Code−Code → reflect Minus, else TypeError
Times
* — Cst×Cst → Cst, Code×Code → reflect Times, else TypeError
Eq
eq? — any pair → Cst(0|1), Code+Code → reflect Eq
CellSet
cell-set! — Cell×any → write (returns written value),
Code×Code → reflect CellSet, else TypeError
Cons
cons — any → Tup, never staged (pairs always run-time data).
Cons lives in BinOpKind to reuse the BinOpRight/BinOpFinish
operand-sequencing machinery — it’s the only variant here that
has no Code-dispatch branch and is not stage-polymorphic at all.
The dispatcher just unconditionally builds a Val::Tup; stage
reflection for cons happens one level up, when a Val::Tup of
two Val::Code is fed to lift (see eval/mod.rs::lift’s Tup
arm). Resist the urge to add a fake Code arm to dispatch_binop
for symmetry — the paper’s λ↑↓ does not stage cons directly.
IsCode
code? — Cst(0|1) on second arg’s variant; if first is Code,
reflect IsCode (second must then be Code or TypeError)
Log
log — first=Code → stage the log; else IO-print second.
Both operands are evaluated regardless of the dispatch (unlike
LiftRef), so the standard binop sequencing fits.
App
Function application (f x) — Clo+_ → tail-jump body; Code+Code →
reflect App; else TypeError. This is the only binop where one
outcome is Mode::Eval (tail jump) rather than a pure Val
producer; App is therefore special-cased in step_apply and
not dispatched through dispatch_binop.