syndicate-nim/src/syndicate/protocols/dataspacePatterns.nim

167 lines
5.6 KiB
Nim

import
std/typetraits, preserves, std/tables, std/tables, std/tables
type
PatternKind* {.pure.} = enum
`Ddiscard`, `Dbind`, `Dlit`, `Dcompound`
Pattern*[E = void] = ref object ## ``/ DDiscard / DBind / DLit / DCompound``
case kind*: PatternKind
of PatternKind.`Ddiscard`:
`ddiscard`*: DDiscard
of PatternKind.`Dbind`:
`dbind`*: DBind[E]
of PatternKind.`Dlit`:
`dlit`*: DLit[E]
of PatternKind.`Dcompound`:
`dcompound`*: DCompound[E]
DDiscard* {.record: "_".} = object ## ``<_>``
discard
DBind*[E = void] {.record: "bind".} = ref object ## ``<bind @pattern Pattern>``
`pattern`*: Pattern[E]
DLit*[E = void] {.record: "lit".} = ref object ## ``<lit @value any>``
`value`*: Preserve[E]
DcompoundKind* {.pure.} = enum
`rec`, `arr`, `dict`
DCompoundrec*[E = void] {.record: "compound".} = ref object
`ctor`*: CRec[E]
`members`*: TableRef[BiggestInt, Pattern[E]]
DCompoundarr*[E = void] {.record: "compound".} = ref object
`ctor`*: CArr
`members`*: TableRef[BiggestInt, Pattern[E]]
DCompounddict*[E = void] {.record: "compound".} = ref object
`ctor`*: CDict
`members`*: TableRef[Preserve[E], Pattern[E]]
DCompound*[E = void] = ref object ## ``/ <compound @ctor CRec @members {int : Pattern ...:...}> / <compound @ctor CArr @members {int : Pattern ...:...}> / <compound @ctor CDict @members {any : Pattern ...:...}>``
case kind*: DcompoundKind
of DcompoundKind.`rec`:
`rec`*: DCompoundrec[E]
of DcompoundKind.`arr`:
`arr`*: DCompoundarr[E]
of DcompoundKind.`dict`:
`dict`*: DCompounddict[E]
CRec*[E = void] {.record: "rec".} = ref object ## ``<rec @label any @arity int>``
`label`*: Preserve[E]
`arity`*: BiggestInt
CArr* {.record: "arr".} = ref object ## ``<arr @arity int>``
`arity`*: BiggestInt
CDict* {.record: "dict".} = object ## ``<dict>``
discard
proc toPreserveHook*(v: Pattern; E: typedesc): Preserve[E] =
case v.kind
of PatternKind.`Ddiscard`:
toPreserve(v.`ddiscard`, E)
of PatternKind.`Dbind`:
toPreserve(v.`dbind`, E)
of PatternKind.`Dlit`:
toPreserve(v.`dlit`, E)
of PatternKind.`Dcompound`:
toPreserve(v.`dcompound`, E)
proc fromPreserveHook*[E](v: var Pattern; pr: Preserve[E]): bool =
if isRecord(pr) and pr.label.isSymbol("DDiscard"):
v = Pattern(kind: PatternKind.`Ddiscard`)
result = fromPreserve(v.`ddiscard`, pr)
elif isRecord(pr) and pr.label.isSymbol("DBind"):
v = Pattern(kind: PatternKind.`Dbind`)
result = fromPreserve(v.`dbind`, pr)
elif isRecord(pr) and pr.label.isSymbol("DLit"):
v = Pattern(kind: PatternKind.`Dlit`)
result = fromPreserve(v.`dlit`, pr)
elif false: ## snkOr - / <compound @ctor CRec @members {int : Pattern ...:...}> / <compound @ctor CArr @members {int : Pattern ...:...}> / <compound @ctor CDict @members {any : Pattern ...:...}>
discard
proc `dDiscard`*[E = void](): Preserve[E] =
## Preserves constructor for ``DDiscard``.
initRecord[E](symbol[E]("_"))
proc toPreserveHook*(`ddiscard`: DDiscard; E: typedesc): Preserve[E] =
initRecord[E](symbol[E]("_"))
proc `dBind`*[E = void](`pattern`: Pattern | Preserve[E]): Preserve[E] =
## Preserves constructor for ``DBind``.
initRecord[E](symbol[E]("bind"), toPreserve(`pattern`, E))
proc toPreserveHook*(`dbind`: DBind; E: typedesc): Preserve[E] =
initRecord[E](symbol[E]("bind"), toPreserve(`dbind`.`pattern`, E))
proc `dLit`*[E = void](`value`: Preserve[E]): Preserve[E] =
## Preserves constructor for ``DLit``.
initRecord[E](symbol[E]("lit"), toPreserve(`value`, E))
proc toPreserveHook*(`dlit`: DLit; E: typedesc): Preserve[E] =
initRecord[E](symbol[E]("lit"), toPreserve(`dlit`.`value`, E))
proc toPreserveHook*(v: DCompound; E: typedesc): Preserve[E] =
case v.kind
of DCompoundKind.`rec`:
toPreserve(v.`rec`, E)
of DCompoundKind.`arr`:
toPreserve(v.`arr`, E)
of DCompoundKind.`dict`:
toPreserve(v.`dict`, E)
proc fromPreserveHook*[E](v: var DCompound; pr: Preserve[E]): bool =
if isRecord(pr) and pr.label.isSymbol("rec"):
v = DCompound(kind: DCompoundKind.`rec`)
result = fromPreserve(v.`rec`, pr)
elif isRecord(pr) and pr.label.isSymbol("arr"):
v = DCompound(kind: DCompoundKind.`arr`)
result = fromPreserve(v.`arr`, pr)
elif isRecord(pr) and pr.label.isSymbol("dict"):
v = DCompound(kind: DCompoundKind.`dict`)
result = fromPreserve(v.`dict`, pr)
proc `cRec`*[E = void](`label`: Preserve[E]; `arity`: BiggestInt | Preserve[E]): Preserve[
E] =
## Preserves constructor for ``CRec``.
initRecord[E](symbol[E]("rec"), toPreserve(`label`, E), toPreserve(`arity`, E))
proc toPreserveHook*(`crec`: CRec; E: typedesc): Preserve[E] =
initRecord[E](symbol[E]("rec"), toPreserve(`crec`.`label`, E),
toPreserve(`crec`.`arity`, E))
proc `cArr`*[E = void](`arity`: BiggestInt | Preserve[E]): Preserve[E] =
## Preserves constructor for ``CArr``.
initRecord[E](symbol[E]("arr"), toPreserve(`arity`, E))
proc toPreserveHook*(`carr`: CArr; E: typedesc): Preserve[E] =
initRecord[E](symbol[E]("arr"), toPreserve(`carr`.`arity`, E))
proc `cDict`*[E = void](): Preserve[E] =
## Preserves constructor for ``CDict``.
initRecord[E](symbol[E]("dict"))
proc toPreserveHook*(`cdict`: CDict; E: typedesc): Preserve[E] =
initRecord[E](symbol[E]("dict"))
proc `$`*[E](x: Pattern[E] | DDiscard | DBind[E] | DLit[E] | DCompound[E] |
CRec[E] |
CArr |
CDict): string =
`$`(toPreserve(x, E))
proc `encode`*[E](x: Pattern[E] | DDiscard | DBind[E] | DLit[E] | DCompound[E] |
CRec[E] |
CArr |
CDict): seq[byte] =
encode(toPreserve(x, E))