Move `?` operator to DSL module

This commit is contained in:
Emery Hemingway 2022-04-23 20:01:30 -05:00
parent fd47039ca3
commit 9648884997
2 changed files with 93 additions and 70 deletions

View File

@ -24,15 +24,98 @@ runnableExamples:
poll()
import std/macros
import preserves, preserves/jsonhooks
import std/[macros, tables, typetraits]
import preserves
import ./syndicate/[actors, dataspaces, durings, patterns]
from ./syndicate/relays import connectStdio, connectUnix
export Assertion, Facet, Handle, Ref, Symbol, Turn, TurnAction, bootDataspace,
`?`, `$`, connectStdio, connectUnix, facet, drop, grab, message, publish,
retract, replace, run, stop, unembed
`$`, connectStdio, connectUnix, drop, facet, grab, message, publish,
retract, replace, run, stop, unembed
proc `?`*(T: static typedesc): Pattern =
## Construct a `Pattern` from type `T`.
runnableExamples:
import preserves
type Point = tuple[x: int; y: int]
assert $(?Point) == "<arr [<bind <_>> <bind <_>>]>"
type Rect {.preservesRecord: "rect".} = tuple[a: Point; B: Point]
assert $(?Rect) == "<rec rect [<arr [<bind <_>> <bind <_>>]> <arr [<bind <_>> <bind <_>>]>]>"
type ColoredRect {.preservesDictionary.} = tuple[color: string; rect: Rect]
assert $(?ColoredRect) == "<dict {color: <bind <_>>, rect: <rec rect [<arr [<bind <_>> <bind <_>>]> <arr [<bind <_>> <bind <_>>]>]>}>"
## Derive a `Pattern` from type `T`.
## This works for `tuple` and `object` types but in the
## general case will return a wildcard binding.
when T is ref:
?pointerBase(T)
elif T is Preserve: grab()
elif T.hasPreservesRecordPragma:
var
label = T.recordLabel.tosymbol(Ref)
fields = newSeq[Pattern]()
for key, val in fieldPairs(default T):
fields.add ?(typeOf val)
result = ?DCompound(
orKind: DCompoundKind.rec,
rec: DCompoundRec(
label: label, fields: fields))
elif T.hasPreservesDictionaryPragma:
var dict = DCompoundDict()
for key, val in fieldPairs(default T):
dict.entries[key.toSymbol(Ref)] = ?(typeOf val)
?DCompound(
orKind: DCompoundKind.dict,
dict: dict)
elif T.hasPreservesTuplePragma or T is tuple:
var arr = DCompoundArr()
for key, val in fieldPairs(default T):
arr.items.add ?(typeOf val)
?DCompound(
orKind: DCompoundKind.arr,
arr: arr)
else:
grab() # otherwise an abritrary capture
proc `?`*(T: typedesc; bindings: sink openArray[(int, Pattern)]): Pattern =
## Construct a `Pattern` from type `T` that selectively captures fields.
runnableExamples:
import preserves
type Point = tuple[x: int; y: int; z: int]
assert $(Point ? {2: grab()}) == "<arr [<_> <_> <bind <_>>]>"
when T is ref:
`?`(pointerBase(T), bindings)
elif T.hasPreservesRecordPragma:
var
label = T.recordLabel.tosymbol(Ref)
fields = newSeq[Pattern]()
for (i, pat) in bindings:
if i > fields.high: fields.setLen(succ i)
fields[i] = pat
for pat in bindings.mitems:
if pat.isNil: pat = drop()
result = ?DCompound(
orKind: DCompoundKind.rec,
rec: DCompoundRec(
label: label, fields: fields))
elif T is tuple:
var arr = DCompoundArr()
for (i, pat) in bindings:
if i > arr.items.high: arr.items.setLen(succ i)
arr.items[i] = pat
for pat in arr.items.mitems:
if pat.isNil: pat = drop()
result = ?DCompound(
orKind: DCompoundKind.arr,
arr: arr)
else:
{.error: "no preserves pragma on " & $T.}
type
PublishProc = proc (turn: var Turn; v: Assertion; h: Handle) {.closure.}

View File

@ -11,12 +11,12 @@ export dataspacePatterns.`$`, PatternKind, DCompoundKind
type
AnyAtom* = dataspacePatterns.AnyAtom[Ref]
DBind = dataspacePatterns.DBind[Ref]
DCompound = dataspacePatterns.DCompound[Ref]
DCompoundArr = dataspacePatterns.DCompoundArr[Ref]
DCompoundDict = dataspacePatterns.DCompoundDict[Ref]
DCompoundRec = dataspacePatterns.DCompoundRec[Ref]
DLit = dataspacePatterns.DLit[Ref]
DBind* = dataspacePatterns.DBind[Ref]
DCompound* = dataspacePatterns.DCompound[Ref]
DCompoundArr* = dataspacePatterns.DCompoundArr[Ref]
DCompoundDict* = dataspacePatterns.DCompoundDict[Ref]
DCompoundRec* = dataspacePatterns.DCompoundRec[Ref]
DLit* = dataspacePatterns.DLit[Ref]
Pattern* = dataspacePatterns.Pattern[Ref]
proc `?`*(d: DBind): Pattern =
@ -55,66 +55,6 @@ proc grab*(): Pattern = ?DBind(pattern: drop())
proc `?_`*(): Pattern = drop()
proc `?*`*(): Pattern = grab()
proc `?`*(T: typedesc; bindings: sink openArray[(int, Pattern)]): Pattern =
## Pattern constructor operator.
# TODO: get a pattern for T and then replace the inner patterns with bindings.
when T.hasPreservesRecordPragma:
var
label = T.recordLabel.tosymbol(Ref)
fields = newSeq[Pattern]()
for (i, pat) in bindings:
if i > fields.high: fields.setLen(succ i)
fields[i] = pat
result = ?DCompound(
orKind: DCompoundKind.rec,
rec: DCompoundRec(
label: label, fields: fields))
elif T is ref:
`?`(pointerBase(T), bindings)
else:
{.error: "no preserves pragma on " & $T.}
proc `?`*(T: static typedesc): Pattern =
## Derive a `Pattern` from type `T`.
## This works for `tuple` and `object` types but in the
## general case will return a wildcard binding.
when T is ref:
?pointerBase(T)
elif T is Preserve: grab()
elif T.hasPreservesRecordPragma:
var
label = T.recordLabel.tosymbol(Ref)
fields = newSeq[Pattern]()
for key, val in fieldPairs(default T):
fields.add ?(typeOf val)
result = ?DCompound(
orKind: DCompoundKind.rec,
rec: DCompoundRec(
label: label, fields: fields))
elif T.hasPreservesTuplePragma:
var arr = DCompoundArr()
for key, val in fieldPairs(default T):
arr.items.add grab()
?DCompound(
orKind: DCompoundKind.arr,
arr: arr)
elif T.hasPreservesDictionaryPragma:
var dict = DCompoundDict()
for key, val in fieldPairs(default T):
dict.entries[key.toSymbol(Ref)] = ?(typeOf val)
?DCompound(
orKind: DCompoundKind.dict,
dict: dict)
elif T is tuple:
var arr = DCompoundArr()
for key, val in fieldPairs(default T):
arr.items.add ?(typeOf val)
result = ?DCompound(
orKind: DCompoundKind.arr,
arr: arr)
else:
grab() # capture any value
type
Value = Preserve[Ref]
Path = seq[Value]