diff --git a/protocols b/protocols index b42230b..ca92d99 160000 --- a/protocols +++ b/protocols @@ -1 +1 @@ -Subproject commit b42230b96a6f8665fdd8e56a52a5e76072a6d182 +Subproject commit ca92d99c524d99b6d3be04a0ba5383ec5a65b550 diff --git a/src/syndicate/patterns.nim b/src/syndicate/patterns.nim index 14891e9..725c438 100644 --- a/src/syndicate/patterns.nim +++ b/src/syndicate/patterns.nim @@ -10,11 +10,13 @@ from ./actors import Ref export dataspacePatterns.`$` type - CRec = dataspacePatterns.CRec[Ref] - DCompoundRec = dataspacePatterns.DCompoundRec[Ref] - DBind* = dataspacePatterns.DBind[Ref] - DLit* = dataspacePatterns.DLit[Ref] + 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] Pattern* = dataspacePatterns.Pattern[Ref] proc `?`*(d: DBind): Pattern = @@ -26,8 +28,26 @@ proc `?`*(d: DLit): Pattern = proc `?`*(d: DCompound): Pattern = Pattern(orKind: PatternKind.DCompound, dcompound: d) +proc `?`*(x: bool): Pattern = + ?DLit(value: AnyAtom(orKind: AnyAtomKind.`bool`, bool: x)) + +proc `?`*(x: float32): Pattern = + ?DLit(value: AnyAtom(orKind: AnyAtomKind.`float`, float: x)) + +proc `?`*(x: float64): Pattern = + ?DLit(value: AnyAtom(orKind: AnyAtomKind.`double`, double: x)) + +proc `?`*(x: int): Pattern = + ?DLit(value: AnyAtom(orKind: AnyAtomKind.`int`, int: x)) + proc `?`*(s: string): Pattern = - ?DLit(value: toPreserve(s, Ref)) + ?DLit(value: AnyAtom(orKind: AnyAtomKind.`string`, string: s)) + +proc `?`*(x: seq[byte]): Pattern = + ?DLit(value: AnyAtom(orKind: AnyAtomKind.`bytes`, bytes: x)) + +proc `?`*(x: Symbol): Pattern = + ?DLit(value: AnyAtom(orKind: AnyAtomKind.`symbol`, symbol: x)) proc drop*(): Pattern = Pattern(orKind: PatternKind.DDiscard) proc grab*(): Pattern = ?DBind(pattern: drop()) @@ -35,24 +55,59 @@ proc grab*(): Pattern = ?DBind(pattern: drop()) proc `?_`*(): Pattern = drop() proc `?*`*(): Pattern = grab() -proc `?`*(T: typedesc; bindings: openArray[(int, Pattern)]): Pattern = +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.hasCustomPragma(preservesRecord): - var label = tosymbol(T.getCustomPragmaVal(preservesRecord), Ref) + var + label = tosymbol(T.getCustomPragmaVal(preservesRecord), 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( - ctor: CRec(label: label, arity: bindings.len), - members: toTable bindings)) + label: label, fields: fields)) elif T is ref: `?`(pointerBase(T), bindings) else: - {.error: "no custom pragma on " & $T.} + {.error: "no preserves pragma on " & $T.} -proc observe*(pat: Pattern): Pattern = - # TODO: why doesn't Observe from ./protocols/dataspace.nim work? - ?DCompound( - orKind: DCompoundKind.rec, - rec: DCompoundRec( - ctor: CRec(label: toSymbol("Observe", Ref), arity: 2), - members: toTable {0 : pat, 1: `?_`()})) +proc `?`*(T: 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.hasCustomPragma(preservesRecord): + var + label = tosymbol(T.getCustomPragmaVal(preservesRecord), Ref) + fields = newSeq[Pattern]() + dummy: ptr T + for key, val in fieldPairs(dummy[]): + fields.add grab() + result = ?DCompound( + orKind: DCompoundKind.rec, + rec: DCompoundRec( + label: label, fields: fields)) + elif T is tuple: + var + arr = DCompoundArr() + dummy: ptr T + for key, val in fieldPairs(dummy[]): + arr.items.add ?(typeOf val) + result = ?DCompound( + orKind: DCompoundKind.arr, + arr: arr) + elif T is object: + var + dict = DCompoundDict() + dummy: ptr T + for key, val in fieldPairs(dummy[]): + dict.entries[key.toSymbol(Ref)] = grab() #?(typeOf val) + result = ?DCompound( + orKind: DCompoundKind.dict, + dict: dict) + elif T is ref: + ?pointerBase(T) + else: + grab() # capture any value diff --git a/src/syndicate/protocols/Tupfile b/src/syndicate/protocols/Tupfile index 5d98698..d4e422c 100644 --- a/src/syndicate/protocols/Tupfile +++ b/src/syndicate/protocols/Tupfile @@ -1,4 +1,6 @@ -include_rules +export XDG_CACHE_HOME + +!nim = |> nim compile -o:%o %f |> : ../../../preserves/src/preserves/preserves_schema_nim.nim |> !nim |> preserves_schema_nim @@ -17,6 +19,7 @@ schemas = \ sturdy.nim \ tcp.nim \ timer.nim \ + trace.nim \ transportAddress.nim \ worker.nim \ diff --git a/src/syndicate/protocols/dataspacePatterns.nim b/src/syndicate/protocols/dataspacePatterns.nim index 78349bf..e998450 100644 --- a/src/syndicate/protocols/dataspacePatterns.nim +++ b/src/syndicate/protocols/dataspacePatterns.nim @@ -1,36 +1,64 @@ import - std/typetraits, preserves, std/tables, std/tables, std/tables + std/typetraits, preserves, std/tables type - CRec*[E] {.preservesRecord: "rec".} = ref object - `label`*: Preserve[E] - `arity`*: int + AnyAtomKind* {.pure.} = enum + `bool`, `float`, `double`, `int`, `string`, `bytes`, `symbol`, `embedded` + AnyAtomBool* = bool + AnyAtomFloat* = float32 + AnyAtomDouble* = float64 + AnyAtomInt* = int + AnyAtomString* = string + AnyAtomBytes* = seq[byte] + AnyAtomSymbol* = Symbol + AnyAtomEmbedded*[E] = Preserve[E] + `AnyAtom`*[E] {.preservesOr.} = ref object + case orKind*: AnyAtomKind + of AnyAtomKind.`bool`: + `bool`*: AnyAtomBool + of AnyAtomKind.`float`: + `float`*: AnyAtomFloat + + of AnyAtomKind.`double`: + `double`*: AnyAtomDouble + + of AnyAtomKind.`int`: + `int`*: AnyAtomInt + + of AnyAtomKind.`string`: + `string`*: AnyAtomString + + of AnyAtomKind.`bytes`: + `bytes`*: AnyAtomBytes + + of AnyAtomKind.`symbol`: + `symbol`*: AnyAtomSymbol + + of AnyAtomKind.`embedded`: + `embedded`*: AnyAtomEmbedded[E] + + DLit*[E] {.preservesRecord: "lit".} = ref object - `value`*: Preserve[E] + `value`*: AnyAtom[E] DBind*[E] {.preservesRecord: "bind".} = ref object `pattern`*: Pattern[E] DDiscard* {.preservesRecord: "_".} = object - CArr* {.preservesRecord: "arr".} = object - `arity`*: int - DCompoundKind* {.pure.} = enum `rec`, `arr`, `dict` - DCompoundRec*[E] {.preservesRecord: "compound".} = ref object - `ctor`*: CRec[E] - `members`*: Table[int, Pattern[E]] + DCompoundRec*[E] {.preservesRecord: "rec".} = ref object + `label`*: Preserve[E] + `fields`*: seq[Pattern[E]] - DCompoundArr*[E] {.preservesRecord: "compound".} = ref object - `ctor`*: CArr - `members`*: Table[int, Pattern[E]] + DCompoundArr*[E] {.preservesRecord: "arr".} = ref object + `items`*: seq[Pattern[E]] - DCompoundDict*[E] {.preservesRecord: "compound".} = ref object - `ctor`*: CDict - `members`*: Table[Preserve[E], Pattern[E]] + DCompoundDict*[E] {.preservesRecord: "dict".} = ref object + `entries`*: Table[Preserve[E], Pattern[E]] `DCompound`*[E] {.preservesOr.} = ref object case orKind*: DCompoundKind @@ -44,8 +72,6 @@ type `dict`*: DCompoundDict[E] - CDict* {.preservesRecord: "dict".} = object - PatternKind* {.pure.} = enum `DDiscard`, `DBind`, `DLit`, `DCompound` `Pattern`*[E] {.preservesOr.} = ref object @@ -63,15 +89,15 @@ type `dcompound`*: DCompound[E] -proc `$`*[E](x: CRec[E] | DLit[E] | DBind[E] | DCompound[E] | Pattern[E]): string = +proc `$`*[E](x: AnyAtom[E] | DLit[E] | DBind[E] | DCompound[E] | Pattern[E]): string = `$`(toPreserve(x, E)) -proc encode*[E](x: CRec[E] | DLit[E] | DBind[E] | DCompound[E] | Pattern[E]): seq[ +proc encode*[E](x: AnyAtom[E] | DLit[E] | DBind[E] | DCompound[E] | Pattern[E]): seq[ byte] = encode(toPreserve(x, E)) -proc `$`*(x: DDiscard | CArr | CDict): string = +proc `$`*(x: DDiscard): string = `$`(toPreserve(x)) -proc encode*(x: DDiscard | CArr | CDict): seq[byte] = +proc encode*(x: DDiscard): seq[byte] = encode(toPreserve(x)) diff --git a/src/syndicate/protocols/protocol.nim b/src/syndicate/protocols/protocol.nim index 3d54a43..c8c9af3 100644 --- a/src/syndicate/protocols/protocol.nim +++ b/src/syndicate/protocols/protocol.nim @@ -18,6 +18,9 @@ type `assertion`*: Assertion[E] `handle`*: Handle + Extension*[E] {.preservesRecord: "label".} = ref object + `addFieldsCalledWithSimplePattern`*: seq[Preserve[E]] + Sync*[E] {.preservesRecord: "sync".} = ref object `peer`*: Preserve[E] @@ -29,7 +32,7 @@ type Assertion*[E] = Preserve[E] Handle* = int PacketKind* {.pure.} = enum - `Turn`, `Error` + `Turn`, `Error`, `Extension` `Packet`*[E] {.preservesOr.} = ref object case orKind*: PacketKind of PacketKind.`Turn`: @@ -38,6 +41,9 @@ type of PacketKind.`Error`: `error`*: Error[E] + of PacketKind.`Extension`: + `extension`*: Extension[E] + EventKind* {.pure.} = enum `Assert`, `Retract`, `Message`, `Sync` @@ -56,13 +62,15 @@ type `sync`*: Sync[E] -proc `$`*[E](x: Error[E] | Turn[E] | Message[E] | Assert[E] | Sync[E] | +proc `$`*[E](x: Error[E] | Turn[E] | Message[E] | Assert[E] | Extension[E] | + Sync[E] | TurnEvent[E] | Packet[E] | Event[E]): string = `$`(toPreserve(x, E)) -proc encode*[E](x: Error[E] | Turn[E] | Message[E] | Assert[E] | Sync[E] | +proc encode*[E](x: Error[E] | Turn[E] | Message[E] | Assert[E] | Extension[E] | + Sync[E] | TurnEvent[E] | Packet[E] | Event[E]): seq[byte] = diff --git a/src/syndicate/protocols/service.nim b/src/syndicate/protocols/service.nim index 47f8f3a..f61fb2d 100644 --- a/src/syndicate/protocols/service.nim +++ b/src/syndicate/protocols/service.nim @@ -3,16 +3,35 @@ import std/typetraits, preserves type - `State`* {.preservesOr.} = enum - `started`, `ready`, `failed`, `complete` + StateKind* {.pure.} = enum + `started`, `ready`, `failed`, `complete`, `userDefined` + StateUserDefined*[E] = Preserve[E] + `State`*[E] {.preservesOr.} = ref object + case orKind*: StateKind + of StateKind.`started`: + `started`* {.preservesLiteral: "started".}: bool + + of StateKind.`ready`: + `ready`* {.preservesLiteral: "ready".}: bool + + of StateKind.`failed`: + `failed`* {.preservesLiteral: "failed".}: bool + + of StateKind.`complete`: + `complete`* {.preservesLiteral: "complete".}: bool + + of StateKind.`userDefined`: + `userdefined`*: StateUserDefined[E] + + ServiceObject*[E] {.preservesRecord: "service-object".} = ref object `serviceName`*: Preserve[E] `object`*: Preserve[E] - CoreService*[E] {.preservesRecord: "core-service".} = ref object + RequireService*[E] {.preservesRecord: "require-service".} = ref object `serviceName`*: Preserve[E] - RequireService*[E] {.preservesRecord: "require-service".} = ref object + RestartService*[E] {.preservesRecord: "restart-service".} = ref object `serviceName`*: Preserve[E] RunService*[E] {.preservesRecord: "run-service".} = ref object @@ -20,19 +39,21 @@ type ServiceState*[E] {.preservesRecord: "service-state".} = ref object `serviceName`*: Preserve[E] - `state`*: State + `state`*: State[E] ServiceDependency*[E] {.preservesRecord: "depends-on".} = ref object `depender`*: Preserve[E] `dependee`*: ServiceState[E] -proc `$`*[E](x: ServiceObject[E] | CoreService[E] | RequireService[E] | +proc `$`*[E](x: State[E] | ServiceObject[E] | RequireService[E] | + RestartService[E] | RunService[E] | ServiceState[E] | ServiceDependency[E]): string = `$`(toPreserve(x, E)) -proc encode*[E](x: ServiceObject[E] | CoreService[E] | RequireService[E] | +proc encode*[E](x: State[E] | ServiceObject[E] | RequireService[E] | + RestartService[E] | RunService[E] | ServiceState[E] | ServiceDependency[E]): seq[byte] = diff --git a/src/syndicate/protocols/stream.nim b/src/syndicate/protocols/stream.nim index f4f6e4b..7cb4d82 100644 --- a/src/syndicate/protocols/stream.nim +++ b/src/syndicate/protocols/stream.nim @@ -27,7 +27,7 @@ type `sink`*: Preserve[E] `spec`*: Preserve[E] - `LineMode`* {.preservesOr.} = enum + `LineMode`* {.preservesOr, pure.} = enum `lf`, `crlf` SourceKind* {.pure.} = enum `sink`, `StreamError`, `credit` diff --git a/src/syndicate/protocols/sturdy.nim b/src/syndicate/protocols/sturdy.nim index b996539..2b94d15 100644 --- a/src/syndicate/protocols/sturdy.nim +++ b/src/syndicate/protocols/sturdy.nim @@ -1,30 +1,32 @@ import - std/typetraits, preserves, std/tables, std/tables + std/typetraits, preserves, std/tables type - CRec*[E] {.preservesRecord: "rec".} = ref object + PCompoundKind* {.pure.} = enum + `rec`, `arr`, `dict` + PCompoundRec*[E] {.preservesRecord: "rec".} = ref object `label`*: Preserve[E] - `arity`*: int + `fields`*: seq[Pattern[E]] - PCompound*[E] {.preservesRecord: "compound".} = ref object - `ctor`*: ConstructorSpec[E] - `members`*: PCompoundMembers[E] + PCompoundArr*[E] {.preservesRecord: "arr".} = ref object + `items`*: seq[Pattern[E]] - ConstructorSpecKind* {.pure.} = enum - `CRec`, `CArr`, `CDict` - `ConstructorSpec`*[E] {.preservesOr.} = ref object - case orKind*: ConstructorSpecKind - of ConstructorSpecKind.`CRec`: - `crec`*: CRec[E] + PCompoundDict*[E] {.preservesRecord: "dict".} = ref object + `entries`*: Table[Preserve[E], Pattern[E]] - of ConstructorSpecKind.`CArr`: - `carr`*: CArr + `PCompound`*[E] {.preservesOr.} = ref object + case orKind*: PCompoundKind + of PCompoundKind.`rec`: + `rec`*: PCompoundRec[E] + + of PCompoundKind.`arr`: + `arr`*: PCompoundArr[E] + + of PCompoundKind.`dict`: + `dict`*: PCompoundDict[E] - of ConstructorSpecKind.`CDict`: - `cdict`*: CDict - PAnd*[E] {.preservesRecord: "and".} = ref object `patterns`*: seq[Pattern[E]] @@ -32,7 +34,6 @@ type `pattern`*: Pattern[E] `template`*: Template[E] - TCompoundMembers*[E] = Table[Preserve[E], Template[E]] TRef* {.preservesRecord: "ref".} = object `binding`*: int @@ -42,16 +43,36 @@ type Lit*[E] {.preservesRecord: "lit".} = ref object `value`*: Preserve[E] - TCompound*[E] {.preservesRecord: "compound".} = ref object - `ctor`*: ConstructorSpec[E] - `members`*: TCompoundMembers[E] + TCompoundKind* {.pure.} = enum + `rec`, `arr`, `dict` + TCompoundRec*[E] {.preservesRecord: "rec".} = ref object + `label`*: Preserve[E] + `fields`*: seq[Template[E]] - `PAtom`* {.preservesOr.} = enum + TCompoundArr*[E] {.preservesRecord: "arr".} = ref object + `items`*: seq[Template[E]] + + TCompoundDict*[E] {.preservesRecord: "dict".} = ref object + `entries`*: Table[Preserve[E], Template[E]] + + `TCompound`*[E] {.preservesOr.} = ref object + case orKind*: TCompoundKind + of TCompoundKind.`rec`: + `rec`*: TCompoundRec[E] + + of TCompoundKind.`arr`: + `arr`*: TCompoundArr[E] + + of TCompoundKind.`dict`: + `dict`*: TCompoundDict[E] + + + `PAtom`* {.preservesOr, pure.} = enum `Boolean`, `Float`, `Double`, `SignedInteger`, `String`, `ByteString`, `Symbol` Attenuation*[E] = seq[Caveat[E]] PDiscard* {.preservesRecord: "_".} = object - + TemplateKind* {.pure.} = enum `TAttenuate`, `TRef`, `Lit`, `TCompound` `Template`*[E] {.preservesOr.} = ref object @@ -68,7 +89,7 @@ type of TemplateKind.`TCompound`: `tcompound`*: TCompound[E] - + CaveatKind* {.pure.} = enum `Rewrite`, `Alts` `Caveat`*[E] {.preservesOr.} = ref object @@ -79,11 +100,7 @@ type of CaveatKind.`Alts`: `alts`*: Alts[E] - - CArr* {.preservesRecord: "arr".} = object - `arity`*: int - PCompoundMembers*[E] = Table[Preserve[E], Pattern[E]] PNot*[E] {.preservesRecord: "not".} = ref object `pattern`*: Pattern[E] @@ -111,7 +128,7 @@ type of WireRefKind.`yours`: `yours`*: WireRefYours[E] - + TAttenuate*[E] {.preservesRecord: "attenuate".} = ref object `template`*: Template[E] `attenuation`*: Attenuation[E] @@ -120,8 +137,6 @@ type Alts*[E] {.preservesRecord: "or".} = ref object `alternatives`*: seq[Rewrite[E]] - CDict* {.preservesRecord: "dict".} = object - PatternKind* {.pure.} = enum `PDiscard`, `PAtom`, `PEmbedded`, `PBind`, `PAnd`, `PNot`, `Lit`, `PCompound` @@ -151,17 +166,12 @@ type of PatternKind.`PCompound`: `pcompound`*: PCompound[E] - -proc `$`*[E](x: CRec[E] | PCompound[E] | ConstructorSpec[E] | PAnd[E] | - Rewrite[E] | - TCompoundMembers[E] | - PBind[E] | - Lit[E] | + +proc `$`*[E](x: PCompound[E] | PAnd[E] | Rewrite[E] | PBind[E] | Lit[E] | TCompound[E] | Attenuation[E] | Template[E] | Caveat[E] | - PCompoundMembers[E] | PNot[E] | SturdyRef[E] | WireRef[E] | @@ -170,16 +180,11 @@ proc `$`*[E](x: CRec[E] | PCompound[E] | ConstructorSpec[E] | PAnd[E] | Pattern[E]): string = `$`(toPreserve(x, E)) -proc encode*[E](x: CRec[E] | PCompound[E] | ConstructorSpec[E] | PAnd[E] | - Rewrite[E] | - TCompoundMembers[E] | - PBind[E] | - Lit[E] | +proc encode*[E](x: PCompound[E] | PAnd[E] | Rewrite[E] | PBind[E] | Lit[E] | TCompound[E] | Attenuation[E] | Template[E] | Caveat[E] | - PCompoundMembers[E] | PNot[E] | SturdyRef[E] | WireRef[E] | @@ -188,8 +193,8 @@ proc encode*[E](x: CRec[E] | PCompound[E] | ConstructorSpec[E] | PAnd[E] | Pattern[E]): seq[byte] = encode(toPreserve(x, E)) -proc `$`*(x: TRef | PDiscard | CArr | Oid | CDict): string = +proc `$`*(x: TRef | PDiscard | Oid): string = `$`(toPreserve(x)) -proc encode*(x: TRef | PDiscard | CArr | Oid | CDict): seq[byte] = +proc encode*(x: TRef | PDiscard | Oid): seq[byte] = encode(toPreserve(x)) diff --git a/src/syndicate/protocols/timer.nim b/src/syndicate/protocols/timer.nim index 885861a..7b438c9 100644 --- a/src/syndicate/protocols/timer.nim +++ b/src/syndicate/protocols/timer.nim @@ -12,7 +12,7 @@ type `msecs`*: float64 `kind`*: TimerKind - `TimerKind`* {.preservesOr.} = enum + `TimerKind`* {.preservesOr, pure.} = enum `relative`, `absolute`, `clear` LaterThan* {.preservesRecord: "later-than".} = object `msecs`*: float64