Add initial Syndicate module

This commit is contained in:
Emery Hemingway 2024-04-24 16:15:13 +02:00
parent e52a6dc5ba
commit e946b3a64e
1 changed files with 110 additions and 0 deletions

110
pkg/min_syndicate.nim Normal file
View File

@ -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")