From 57e4bb6badb39dfc197c709f1bd833d96d8a1d5a Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Wed, 15 Jun 2022 22:27:25 -0500 Subject: [PATCH] Generate literal patterns by preserving values --- src/syndicate.nim | 13 ++---- src/syndicate/actors.nim | 2 + src/syndicate/membranes.nim | 3 +- src/syndicate/patterns.nim | 89 ++++++++++++++++++++++++++++++------- 4 files changed, 80 insertions(+), 27 deletions(-) diff --git a/src/syndicate.nim b/src/syndicate.nim index 95809ec..ae96d6c 100644 --- a/src/syndicate.nim +++ b/src/syndicate.nim @@ -30,9 +30,9 @@ import ./syndicate/[actors, dataspaces, durings, patterns] from ./syndicate/relays import connectStdio, connectUnix -export Assertion, Facet, Handle, Ref, Symbol, Turn, TurnAction, `$`, `?`, - bootDataspace, connectStdio, connectUnix, drop, facet, grab, message, - newDataspace, publish, retract, replace, run, stop, unembed +export Actor, Assertion, Facet, Handle, Ref, Symbol, Turn, TurnAction, + `$`, `?`, `??`, bootDataspace, connectStdio, connectUnix, drop, facet, + future, grab, message, newDataspace, publish, retract, replace, run, stop, unembed proc `?`*[T](val: T): Pattern = ## Construct a `Pattern` from value of type `T`. @@ -42,9 +42,6 @@ proc `?`*[T](val: T): Pattern = value: AnyAtom( orKind: AnyAtomKind.embedded, embedded: embed(val)))) - # elif T is Preserve[Ref]: - # result = grab() - # TODO elif T is ptr | ref: if system.`==`(val, nil): result = ?(Symbol "null") else: result = ?(val[]) @@ -94,8 +91,7 @@ proc `?`*[T](val: T): Pattern = rec: DCompoundRec( label: label, fields: fields)) else: - {.error: "cannot derive literal pattern from " & $T.} - + ?(toPreserve(val, Ref)) proc `?`*(T: static typedesc): Pattern = ## Construct a `Pattern` from type `T`. @@ -116,7 +112,6 @@ proc `?`*(T: static typedesc): Pattern = ## 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) diff --git a/src/syndicate/actors.nim b/src/syndicate/actors.nim index 8fcfb48..ec42ec2 100644 --- a/src/syndicate/actors.nim +++ b/src/syndicate/actors.nim @@ -475,3 +475,5 @@ proc sync*(turn, refer: Ref, cb: proc(t: Turn) {.gcsafe.}) = proc runActor*(name: string; bootProc: TurnAction): Future[void] = bootActor(name, bootProc).future + +proc future*(actor): Future[void] = actor.future diff --git a/src/syndicate/membranes.nim b/src/syndicate/membranes.nim index 2972c18..75d24ef 100644 --- a/src/syndicate/membranes.nim +++ b/src/syndicate/membranes.nim @@ -34,8 +34,7 @@ proc grab*(mem: Membrane; key: Oid|Ref): WireSymbol = proc drop*(mem: var Membrane; sym: WireSymbol) = ## Drop a `WireSymbol` from a `Membrane`. - when not defined(release): assert sym.mem == mem, - "cannot drop WireSymbol at the wrong Membrane" + assert sym.mem == mem, "cannot drop WireSymbol at the wrong Membrane" assert sym.count > 0 dec sym.count if sym.count < 1: diff --git a/src/syndicate/patterns.nim b/src/syndicate/patterns.nim index 9b2b948..7d8cf66 100644 --- a/src/syndicate/patterns.nim +++ b/src/syndicate/patterns.nim @@ -1,8 +1,7 @@ # SPDX-FileCopyrightText: ☭ 2021 Emery Hemingway # SPDX-License-Identifier: Unlicense -import std/[tables, typetraits] -from std/sequtils import toSeq +import std/[sequtils, tables, typetraits] import preserves import ./protocols/dataspacePatterns @@ -11,6 +10,7 @@ from ./actors import Ref export dataspacePatterns.`$`, PatternKind, DCompoundKind type + Assertion = Preserve[Ref] AnyAtom* = dataspacePatterns.AnyAtom[Ref] DBind* = dataspacePatterns.DBind[Ref] DCompound* = dataspacePatterns.DCompound[Ref] @@ -20,38 +20,95 @@ type DLit* = dataspacePatterns.DLit[Ref] Pattern* = dataspacePatterns.Pattern[Ref] -proc `?`*(d: DBind): Pattern = +proc `?`*(d: sink DBind): Pattern = Pattern(orKind: PatternKind.DBind, dbind: d) -proc `?`*(d: DLit): Pattern = +proc `?`*(d: sink DLit): Pattern = Pattern(orKind: PatternKind.DLit, dlit: d) -proc `?`*(d: DCompound): Pattern = +proc `?`*(aa: sink AnyAtom): Pattern = + ?DLit(value: aa) + +proc `?`*(d: sink DCompound): Pattern = Pattern(orKind: PatternKind.DCompound, dcompound: d) -proc `?`*(d: DCompoundRec): Pattern = +proc `?`*(d: sink DCompoundRec): Pattern = ?DCompound(orKind: DCompoundKind.rec, rec: d) +proc `?`*(d: sink DCompoundArr): Pattern = + ?DCompound(orKind: DCompoundKind.arr, arr: d) + +proc `?`*(d: sink DCompoundDict): Pattern = + ?DCompound(orKind: DCompoundKind.dict, dict: d) + proc `?`*(x: bool): Pattern = - ?DLit(value: AnyAtom(orKind: AnyAtomKind.`bool`, bool: x)) + ?AnyAtom(orKind: AnyAtomKind.`bool`, bool: x) proc `?`*(x: float32): Pattern = - ?DLit(value: AnyAtom(orKind: AnyAtomKind.`float`, float: x)) + ?AnyAtom(orKind: AnyAtomKind.`float`, float: x) proc `?`*(x: float64): Pattern = - ?DLit(value: AnyAtom(orKind: AnyAtomKind.`double`, double: x)) + ?AnyAtom(orKind: AnyAtomKind.`double`, double: x) proc `?`*(x: int): Pattern = - ?DLit(value: AnyAtom(orKind: AnyAtomKind.`int`, int: x)) + ?AnyAtom(orKind: AnyAtomKind.`int`, int: x) -proc `?`*(s: string): Pattern = - ?DLit(value: AnyAtom(orKind: AnyAtomKind.`string`, string: s)) +proc `?`*(s: sink string): Pattern = + ?AnyAtom(orKind: AnyAtomKind.`string`, string: s) -proc `?`*(x: seq[byte]): Pattern = - ?DLit(value: AnyAtom(orKind: AnyAtomKind.`bytes`, bytes: x)) +proc `?`*(x: sink seq[byte]): Pattern = + ?AnyAtom(orKind: AnyAtomKind.`bytes`, bytes: x) -proc `?`*(x: Symbol): Pattern = - ?DLit(value: AnyAtom(orKind: AnyAtomKind.`symbol`, symbol: x)) +proc `?`*(x: sink Symbol): Pattern = + ?AnyAtom(orKind: AnyAtomKind.`symbol`, symbol: x) + +proc `?`*[T](pr: Preserve[T]): Pattern = + assert not pr.embedded + case pr.kind + of pkBoolean: ?pr.bool + of pkFloat: ?pr.float + of pkDouble: ?pr.double + of pkSignedInteger: ?(int pr.int) # TODO: overflow! + of pkString: ?pr.string + of pkByteString: ?pr.bytes + of pkSymbol: ?pr.symbol + of pkRecord: + ?DCompoundRec( + label: pr.label, + fields: map[Preserve[T], Pattern](pr.fields, `?`[T])) + of pkSequence: + ?DCompoundArr(items: map(pr.sequence, `?`[T])) + of pkSet: raise newException( + ValueError, "cannot construct a pattern over a set literal") + of pkDictionary: + var dict = DCompoundDict() + for key, val in pr.pairs: dict.entries[key] = ?val + ?dict + of pkEmbedded: + raiseAssert "cannot construct a pattern over a embedded literal" + +proc `??`*(pat: Pattern): Pattern = + ## Construct a `Pattern` that matches a `Pattern`. + case pat.orKind + of PatternKind.DDiscard, PatternKind.DBind: + result = pat + of PatternKind.DLit: + result = ?(pat.toPreserve(Ref)) + of PatternKind.DCompound: + case pat.dcompound.orKind + of DCompoundKind.rec: + var fields = move pat.dcompound.rec.fields + result = ?(pat.toPreserve(Ref)) + result.dcompound.rec.fields[1].dcompound.arr.items = fields + of DCompoundKind.arr: + var items = move pat.dcompound.arr.items + result = ?(pat.toPreserve(Ref)) + result.dcompound.rec.fields[0].dcompound.arr.items = items + of DCompoundKind.dict: + # var entries = move pat.dcompound.dict.entries + # result = ?(pat.toPreserve(Ref)) + stderr.writeLine "pattern construction from DCompoundKind not implemented" + raiseAssert "not implemented" proc drop*(): Pattern = Pattern(orKind: PatternKind.DDiscard) proc grab*(): Pattern = ?DBind(pattern: drop())