Here’s my proposal for a MAKE_EXTDICT opcode.
[[MAKE_EXTDICT]]
=== MAKE_EXTDICT
*DEST DEST DEST*
if(arg3 is a store variant) {
if(arg1 is a store variant || arg2 is a store variant) fail
arg3 <- make_extdict(arg1, arg2)
} else {
local variable a3 = deref(arg3)
if(a3.tag == reference) {
if(arg1 is a store variant || arg2 is a store variant) fail
unify(a3, make_extdict(arg1, arg2))
} else if(a3.tag == extdict) {
if(heap[a3.value + 0].tag == pair) { // Must be an extended word, not an unrecognized word
fail
}
arg1 <- <reference, a3.value + 0>
arg2 <- <reference, a3.value + 1>
} else {
fail
}
}
def make_extdict(required, optional):
local variable addr = TOP
TOP += 2
if(TOP > min(ENV, CHO)) runtime_error(1)
local variable r = deref(required)
if(r.tag != dict) fail
heap[addr + 0] = r
local variable o = deref(optional)
if(o.tag != pair) fail
heap[addr + 1] = o
return <extdict, addr>
This implementation is similar to <<MAKE_PAIR>>, with a few key changes.
It uses the extdict tag instead of the pair tag, and some of its arguments must
be bound: either arg3 (an existing extdict to unpack) or both arg1 and arg2
(the parts of a new extdict to create). It is not valid to create an extdict
containing unbound references, and any attempt to do so will fail.
Does this seem like it would suit your purposes?