diff --git a/pkg/min_syndicate.nim b/pkg/min_syndicate.nim new file mode 100644 index 0000000..b65406a --- /dev/null +++ b/pkg/min_syndicate.nim @@ -0,0 +1,110 @@ +# SPDX-FileCopyrightText: ☭ Emery Hemingway +# SPDX-License-Identifier: Unlicense + +import + min, + preserves, + syndicate, + ./min_preserves + +const + facetType* = "syndicate-facet" + dictFacetType = "dict:" & facetType + capType* = "syndicate-cap" + dictCapType = "dict:" & capType + +proc discardTurn(turn: var Turn) = discard + +proc newFacetDict(i: In): MinValue = + result = i.scope.newDict + result.objType = facetType + +proc getFacet(q: MinValue): Facet = + assert q.objType == facetType + cast[Facet](q.obj) + +proc newCapDict(i: In): MinValue = + result = i.scope.newDict + result.objType = capType + +proc getCap(q: MinValue): Cap = + assert q.objType == capType + cast[Cap](q.obj) + +proc setCap(q: MinValue; cap: Cap) = + q.obj = addr cap[] + +proc runForObj(q: MinValue) = + while q.obj.isNil: + syndicate.runOnce() + +proc syndicate_module*(i: In) = + let def = i.define() + + def.symbol("actor") do (i: In): + let + vals = i.expect "str" + name = vals[0].getString + dict = i.newFacetDict + bootActor(name) do (turn: var Turn): + dict.obj = addr turn.facet[] + runForObj dict + i.push dict + + def.symbol("stop-actor") do (i: In): + let + vals = i.expect("dict:" & facetType) + facet = vals[0].getFacet + stopActor facet + + def.symbol("dataspace") do (i: In): + let + vals = i.expect(dictFacetType) + facet = vals[0].getFacet + dict = i.newCapDict + facet.queueTurn do (turn: var Turn): + dict.setCap turn.newDataspace + runForObj dict + i.push dict + + def.symbol("assert") do (i: In): + let vals = i.expect(dictCapType, "a") + var + cap = vals[0].getCap + pr = i.toPreserves vals[1] + h = newVal 0 + cap.relay.queueTurn do (turn: var Turn): + h.intVal = publish(turn, cap, pr) + while h.intVal == 0: + syndicate.runOnce() + i.push h + + def.symbol("retract") do (i: In): + let + vals = i.expect(dictCapType, "int") + cap = vals[0].getCap + h = Handle vals[1].intVal + cap.relay.queueTurn do (turn: var Turn): + retract(turn, h) + + def.symbol("message") do (i: In): + let vals = i.expect(dictCapType, "a") + var + cap = vals[0].getCap + pr = i.toPreserves vals[1] + cap.relay.queueTurn do (turn: var Turn): + message(turn, cap, pr) + + def.symbol("sync") do (i: In): + let + vals = i.expect(dictCapType) + cap = vals[0].getCap + var pending = true + cap.relay.queueTurn do (turn: var Turn): + sync(turn, cap) do (turn: var Turn): + pending = false + while pending: + if not syndicate.runOnce(): + raiseInvalid("failed to make sync progress") + + def.finalize("syndicate")