From 272b6dfcb7112bb5997dc86df753a2a668687e1d Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Fri, 29 Oct 2021 14:06:00 +0200 Subject: [PATCH] Idiomatic pattern constructor --- src/syndicate/patterns.nim | 63 ++++++++++++++++++++++---------------- tests/chat.nim | 6 ++-- 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/src/syndicate/patterns.nim b/src/syndicate/patterns.nim index 3cb8d4d..78aa26b 100644 --- a/src/syndicate/patterns.nim +++ b/src/syndicate/patterns.nim @@ -1,38 +1,49 @@ # SPDX-FileCopyrightText: ☭ 2021 Emery Hemingway # SPDX-License-Identifier: Unlicense -import std/tables -from std/macros import hasCustomPragma, getCustomPragmaVal +import std/[macros, tables] import preserves -import ../syndicate/protocols/[dataspacePatterns] +import ../syndicate/protocols/[dataspacePatterns, simpleChatProtocol] from ./actors import Ref +export dataspacePatterns.`$` + type + CRec = dataspacePatterns.CRec[Ref] + DCompoundRec = dataspacePatterns.DCompoundRec[Ref] + DBind* = dataspacePatterns.DBind[Ref] + DLit* = dataspacePatterns.DLit[Ref] + DCompound* = dataspacePatterns.DCompound[Ref] Pattern* = dataspacePatterns.Pattern[Ref] -proc bindDiscard(): Pattern = - Pattern( - orKind: PatternKind.DBind, - dbind: DBind[Ref]( - pattern: Pattern( - orKind: PatternKind.DDiscard))) +proc `?`*(): Pattern = + Pattern(orKind: PatternKind.DDiscard) -proc toPattern*(T: typedesc): Pattern = - when T.hasCustomPragma(preservesRecord): - let label = tosymbol(T.getCustomPragmaVal(preservesRecord), Ref) - var - arity: BiggestInt - members: Table[BiggestInt, Pattern] - t: ptr T # a hack to iterate the fields of a non-existent instance - for _ in fields(t[]): - members[arity] = bindDiscard() - inc arity - result = Pattern( - orKind: PatternKind.DCompound, - dcompound: DCompound[Ref]( - orKind: DCompoundKind.rec, - rec: DCompoundRec[Ref]( - ctor: CRec[Ref](label: label, arity: arity), - members: members))) +proc `?`*(d: DBind): Pattern = + Pattern(orKind: PatternKind.DBind, dbind: d) + +proc `?`*(d: DLit): Pattern = + Pattern(orKind: PatternKind.DLit, dlit: d) + +proc `?`*(d: DCompound): Pattern = + Pattern(orKind: PatternKind.DCompound, dcompound: d) + +proc arity(T: typedesc): int = + var t: ptr T # a hack to iterate the fields of a non-existent instance + for _ in fields(t[]): inc result + +proc `?`*(T: typedesc; bindings: openArray[(int, Pattern)]): Pattern = + ## Pattern constructor operator. + when T.hasCustomPragma(preservesRecord): + var + label = tosymbol(T.getCustomPragmaVal(preservesRecord), Ref) + members: Table[BiggestInt, Pattern] + for (i, p) in bindings: + members[BiggestInt i] = ?DBind(pattern: p) + result = ?DCompound( + orKind: DCompoundKind.rec, + rec: DCompoundRec( + ctor: CRec(label: label, arity: T.arity), + members: members)) diff --git a/tests/chat.nim b/tests/chat.nim index 93180b0..c2d343e 100644 --- a/tests/chat.nim +++ b/tests/chat.nim @@ -1,7 +1,7 @@ # SPDX-FileCopyrightText: ☭ 2021 Emery Hemingway # SPDX-License-Identifier: Unlicense -import std/[asyncdispatch, asyncfile, random, strutils] +import std/[asyncdispatch, asyncfile, strutils] import preserves, preserves/parse import syndicate/protocols/[simpleChatProtocol] import syndicate/[actors, capabilities, dataspaces, patterns, relay] @@ -49,9 +49,9 @@ waitFor runActor("chat") do (turn: var Turn): echo a.username, " left" onRetract - discard observe(turn, ds, toPattern(Present), during(duringPresent)) + discard observe(turn, ds, Present ? {0: `?`()}, during(duringPresent)) - discard observe(turn, ds, toPattern(Says), newEntity( + discard observe(turn, ds, Says ? {0: `?`(), 1: `?`()}, newEntity( message = proc (e: Entity; turn: var Turn; v: Assertion) = var msg: tuple[who: string, what: string] assert fromPreserve(msg, v), $v