[#470] Added `UNPAIR n` instruction
Description
This MR adds the new UNPAIR n
instruction.
UNPAIR n
takes a right-combed pair off the top of the stack, and splits it into n
values.
UNPAIR 3 : [pair a b c] -> [a : b : c]
If the pair contains more than n
elements, then the remaining elements are left "tupled".
UNPAIR 3 : [pair a b c d] -> [a : b : pair c d]
Implementation note:
Usually, while typecheking an instruction, we insert the annotations in right stack elements, and then Helpers.wrapWithNotes
extracts those annotations and wraps them in meta-instructions (like InstrWithNotes
and InstrWithVarAnns
).
Later, when interpreting an instruction, we rely on those meta-instructions to handle annotations.
-- handles annotations
runInstrImpl runner (InstrWithVarAnns vns i) inp = do
runner i inp <&> \case
StkEl v1 _ n1 :& StkEl v2 vn2 n2 :& r -> case vns of
U.OneVarAnn vn -> StkEl v1 vn n1 :& StkEl v2 vn2 n2 :& r
U.TwoVarAnns vn vn' -> StkEl v1 vn n1 :& StkEl v2 vn' n2 :& r
StkEl v _ n :& r -> case vns of
U.OneVarAnn vn -> StkEl v vn n :& r
U.TwoVarAnns _ _ -> error "Input stack is exhausted but there is still a variable annotation."
RNil -> error "Input stack is exhausted but there is still variables annotations."
-- does not need to handle annotations, they've already been handled by the meta-instr
runInstrImpl _ (AnnPAIR{}) ((StkEl a _ _) :& (StkEl b _ _) :& r) =
pure $ starNotesStkEl (VPair (a, b)) :& r
However, this separation of concerns it a lot harder to do for UNPAIR n
.
All other instructions put a fixed number of values at the top of the stack (either 1 or 2 values), whereas UNPAIR n
pushes a variable number of values.
Thus, capturing all polymorphic Notes x
and then later, in the interpreter, lining them up again with the stack elements, is not trivial.
IMO, it's much simpler to not use meta-instructions here, and simply handle the annotations in runInstrImpl _ UNPAIRN
.
Please let me know what you think about this, and if there are other advantages to using meta-instructions that I may have overlooked.
Related issue(s)
Resolves part of #470 (closed)
✅ Checklist for your Merge Request
Related changes (conditional)
-
Tests (see short guidelines)
-
If I added new functionality, I added tests covering it. -
If I fixed a bug, I added a regression test to prevent the bug from silently reappearing again.
-
-
Documentation
Stylistic guide (mandatory)
-
My commits comply with the following policy. -
My code complies with the style guide.