Idiomatic pattern constructor

This commit is contained in:
Emery Hemingway 2021-10-29 14:06:00 +02:00
parent 5fe1b7a70d
commit 272b6dfcb7
2 changed files with 40 additions and 29 deletions

View File

@ -1,38 +1,49 @@
# SPDX-FileCopyrightText: ☭ 2021 Emery Hemingway # SPDX-FileCopyrightText: ☭ 2021 Emery Hemingway
# SPDX-License-Identifier: Unlicense # SPDX-License-Identifier: Unlicense
import std/tables import std/[macros, tables]
from std/macros import hasCustomPragma, getCustomPragmaVal
import preserves import preserves
import ../syndicate/protocols/[dataspacePatterns] import ../syndicate/protocols/[dataspacePatterns, simpleChatProtocol]
from ./actors import Ref from ./actors import Ref
export dataspacePatterns.`$`
type 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] Pattern* = dataspacePatterns.Pattern[Ref]
proc bindDiscard(): Pattern = proc `?`*(): Pattern =
Pattern( Pattern(orKind: PatternKind.DDiscard)
orKind: PatternKind.DBind,
dbind: DBind[Ref](
pattern: Pattern(
orKind: PatternKind.DDiscard)))
proc toPattern*(T: typedesc): Pattern = proc `?`*(d: DBind): Pattern =
when T.hasCustomPragma(preservesRecord): Pattern(orKind: PatternKind.DBind, dbind: d)
let label = tosymbol(T.getCustomPragmaVal(preservesRecord), Ref)
var proc `?`*(d: DLit): Pattern =
arity: BiggestInt Pattern(orKind: PatternKind.DLit, dlit: d)
members: Table[BiggestInt, Pattern]
t: ptr T # a hack to iterate the fields of a non-existent instance proc `?`*(d: DCompound): Pattern =
for _ in fields(t[]): Pattern(orKind: PatternKind.DCompound, dcompound: d)
members[arity] = bindDiscard()
inc arity proc arity(T: typedesc): int =
result = Pattern( var t: ptr T # a hack to iterate the fields of a non-existent instance
orKind: PatternKind.DCompound, for _ in fields(t[]): inc result
dcompound: DCompound[Ref](
orKind: DCompoundKind.rec, proc `?`*(T: typedesc; bindings: openArray[(int, Pattern)]): Pattern =
rec: DCompoundRec[Ref]( ## Pattern constructor operator.
ctor: CRec[Ref](label: label, arity: arity), when T.hasCustomPragma(preservesRecord):
members: members))) 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))

View File

@ -1,7 +1,7 @@
# SPDX-FileCopyrightText: ☭ 2021 Emery Hemingway # SPDX-FileCopyrightText: ☭ 2021 Emery Hemingway
# SPDX-License-Identifier: Unlicense # SPDX-License-Identifier: Unlicense
import std/[asyncdispatch, asyncfile, random, strutils] import std/[asyncdispatch, asyncfile, strutils]
import preserves, preserves/parse import preserves, preserves/parse
import syndicate/protocols/[simpleChatProtocol] import syndicate/protocols/[simpleChatProtocol]
import syndicate/[actors, capabilities, dataspaces, patterns, relay] import syndicate/[actors, capabilities, dataspaces, patterns, relay]
@ -49,9 +49,9 @@ waitFor runActor("chat") do (turn: var Turn):
echo a.username, " left" echo a.username, " left"
onRetract 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) = message = proc (e: Entity; turn: var Turn; v: Assertion) =
var msg: tuple[who: string, what: string] var msg: tuple[who: string, what: string]
assert fromPreserve(msg, v), $v assert fromPreserve(msg, v), $v