cps/spec

Search:
Group by:
Source   Edit  

boring utilities likely useful to multiple pieces of cps machinery

Types

Callback[C; R; P] = object
  fn*: P                     ## 
                             ## the bootstrap for continuation C
  rs*: proc (c: var C): R {.nimcall.} ## 
                                      ## the result fetcher for continuation C
Source   Edit  
Continuation = ref object of ContinuationObj
Source   Edit  
ContinuationObj = object of RootObj
  fn*: proc (c: sink Continuation): Continuation {.nimcall.} ## 
                                                             ## The `fn` points to the next continuation leg.
  mom*: Continuation ## 
                     ## If this Continuation was invoked by another Continuation,
                     ## the `mom` will hold that parent Continuation to form a
                     ## linked-list approximating a stack.
  ex*: ref Exception         ## The unhandled exception of the continuation.
  when cpsTraceDeque:
    frames*: Deque[TraceFrame] ## Tracing for all prior hooks
  when cpsStackFrames:
    stack*: TraceFrame       ## Stack-like semantic record
Source   Edit  
ContinuationProc[T] = proc (c: sink T): T {.nimcall.}
Source   Edit  
Hook = enum
  Coop = "coop",            ## returns control to the dispatcher
  Trace = "trace",          ## executed at entry to each continuation leg
  Alloc = "alloc",          ## performs allocation of a new continuation
  Dealloc = "dealloc",      ## performs deallocation of a continuation
  Pass = "pass",            ## transfers control-flow between continuations
  Boot = "boot",            ## prepares a continuation for initial use
  Unwind = "unwind",        ## controlled "bubble-up" for exception handling
  Head = "head",            ## invoked when a new continuation has no parent
  Tail = "tail",            ## invoked when a new continuation has a parent
  Stack = "stack"            ## invoked to annotate stack semantics
these are hook procedure names; the string value matches the name of the symbol we'll call to perform the hook. Source   Edit  
State {.pure.} = enum
  Running,                  ## The continuation is active and running and can be resumed
  Dismissed,                ## The continuation is currently somewhere else
  Finished                   ## The continuation is finished and can no longer be resumed
Representation of the state of a continuation. Source   Edit  
TraceFrame = object
  hook*: Hook                ## the hook that provoked the trace entry
  fun*: string               ## a short label for the notable symbol
  info*: LineInfo            ## the source of the notable symbol
a record of where the continuation has been Source   Edit  

Consts

cpsStackFrames {.booldefine, used.} = true
Source   Edit  
cpsTraceDeque {.booldefine, used.} = true
Source   Edit  
traceDequeSize {.intdefine, used.} = 4096
Source   Edit  

Procs

proc bootstrapSymbol(n: NimNode): NormNode {....raises: [], tags: [], forbids: [].}
find the return type of the bootstrap Source   Edit  
proc breakLabel(n: NormNode): NormNode {....raises: [], tags: [], forbids: [].}
Return the break label of a break statement or a cpsBreak annotation Source   Edit  
proc copyOrVoid(n: NimNode): NimNode {....raises: [], tags: [], forbids: [].}
if the node is empty, ident"void"; else, a copy of the node Source   Edit  
proc cpsCallbackTypeDef(tipe: NimNode; n: NimNode): NimNode {.
    ...raises: [Exception], tags: [RootEffect], forbids: [].}
looks like cpsTransformProc but applies to proc typedefs; this is where we create our calling convention concept Source   Edit  
proc createCallback(sym: NimNode): NimNode {....raises: [Exception],
    tags: [RootEffect], forbids: [].}
create a new Callback object construction Source   Edit  
proc emptyAsNil(n: NimNode): NimNode {....raises: [], tags: [], forbids: [].}
normalize nil, nnkEmpty to nnkNilLit Source   Edit  
proc enbasen(n: NimNode): TypeExpr {....raises: [], tags: [], forbids: [].}
find the parent type of the given symbol/type Source   Edit  
proc ensimilate(source, destination: NormNode): Call {....raises: [], tags: [],
    forbids: [].}
perform a call to convert the destination to the source's type; the source can be any of a few usual suspects... Source   Edit  
proc filterPragma(ns: seq[PragmaAtom]; liftee: Name): NormNode {....raises: [],
    tags: [], forbids: [].}
Source   Edit  
proc getContSym(n: NormNode): Name {....raises: [], tags: [], forbids: [].}
Retrieve the continuation symbol from n, provided that n is a cpsCont. Source   Edit  
proc hash(n: NimNode): Hash {....raises: [], tags: [], forbids: [].}
Hash a NimNode via it's representation Source   Edit  
proc isCpsBlock(n: NormNode): bool {....raises: [], tags: [], forbids: [].}
true if the block n contains a cps call anywhere at all; this is used to figure out if a block needs tailcall handling... Source   Edit  
proc isCpsBreak(n: NormNode): bool {....raises: [], tags: [], forbids: [].}
Return whether a node is a {.cpsBreak.} annotation Source   Edit  
proc isCpsCall(n: NormNode): bool {....raises: [], tags: [], forbids: [].}
true if this node holds a call to a cps procedure Source   Edit  
proc isCpsCont(n: NormNode): bool {....raises: [], tags: [], forbids: [].}
Return whether the given procedure is a cps continuation Source   Edit  
func isCpsContinue(n: NormNode): bool {....raises: [], tags: [], forbids: [].}
Return whether a node is a {.cpsContinue.} annotation Source   Edit  
proc isCpsConvCall(n: NormNode): bool {....raises: [], tags: [], forbids: [].}
true if this node holds a cps call that might be nested within one or more conversions. Source   Edit  
func isCpsPending(n: NormNode): bool {....raises: [], tags: [], forbids: [].}
Return whether a node is a {.cpsPending.} annotation Source   Edit  
proc isCpsTerminate(n: NormNode): bool {....raises: [], tags: [], forbids: [].}
Return whether n is a cpsTerminate annotation Source   Edit  
proc isScopeExit(n: NormNode): bool {....raises: [], tags: [], forbids: [].}
Return whether the given node signify a CPS scope exit Source   Edit  
proc isVoodooCall(n: NormNode): bool {....raises: [], tags: [], forbids: [].}
true if this is a call to a voodoo procedure Source   Edit  
proc makeErrorShim(n: NimNode): NimNode {....raises: [], tags: [], forbids: [].}
Upgrades a procedure to serve as a CPS primitive, generating errors out of .cps. context and taking continuations as input. Source   Edit  
func matchCpsBreak(): NormMatcher {....raises: [], tags: [], forbids: [].}
create a matcher matching cpsBreak with an empty label Source   Edit  
func matchCpsBreak(label: NormNode): NormMatcher {....raises: [], tags: [],
    forbids: [].}
create a matcher matching cpsBreak with the given label and cpsBreak without any label Source   Edit  
func newCpsBreak(n: NormNode; label = newNilLit().NormNode): NormNode {.
    ...raises: [], tags: [], forbids: [].}
Source   Edit  
func newCpsContinue(n: NormNode): NormNode {....raises: [], tags: [], forbids: [].}
Source   Edit  
func newCpsPending(): PragmaStmt {....raises: [], tags: [], forbids: [].}
Produce a {.cpsPending.} annotation Source   Edit  
proc newCpsTerminate(): NormNode {....raises: [], tags: [], forbids: [].}
Source   Edit  
proc nilAsEmpty(n: NimNode): NimNode {....raises: [], tags: [], forbids: [].}
normalize nil, nnkNilLit to nnkEmpty Source   Edit  
proc pragmaArgument(n: NormNode; s: string): NormNode {....raises: [], tags: [],
    forbids: [].}
from foo() or proc foo() {.some: Pragma.}, retrieve Pragma Source   Edit  
proc recover[C, R, P](callback: Callback[C, R, P]; continuation: var C): R

Using a callback, recover the result of the given continuation. This is equivalent to running () on a continuation which was created with whelp against a procedure call.

If the continuation is in the running State, this operation will trampoline the continuation until it is finished. The result will then be recovered from the continuation environment.

It is a Defect to attempt to recover the result of a dismissed continuation.

Source   Edit  
proc renderStackFrames(): seq[string] {.cpsVoodooCall, ...raises: [], tags: [],
                                        forbids: [].}
Source   Edit  
proc renderStackFrames(c: Continuation): seq[string] {....raises: [ValueError],
    tags: [], forbids: [].}
Render a "stack" trace for the continuation as a sequence of lines. Source   Edit  
proc renderTraceDeque(): seq[string] {.cpsVoodooCall, ...raises: [], tags: [],
                                       forbids: [].}
Source   Edit  
proc renderTraceDeque(c: Continuation): seq[string] {....raises: [ValueError],
    tags: [], forbids: [].}
Render a traceback for the continuation as a sequence of lines. Source   Edit  
proc stripPragma(n: NormNode; s: static[string]): NormNode
filter a pragma with the matching name from various nodes Source   Edit  
proc stripPragma(n: PragmaStmt; s: static[string]): PragmaStmt
filter a pragma with the matching name Source   Edit  
proc trampoline[T: Continuation](c: sink T): T
This is the basic trampoline: it will run the continuation until the continuation is no longer in the Running state. Source   Edit  
func wrappedFinally(n, final: NormNode): NormNode {....raises: [], tags: [],
    forbids: [].}
rewrite a try/except/finally into try/try-except/finally Source   Edit  
proc writeStackFrames() {.cpsVoodooCall, ...raises: [], tags: [], forbids: [].}
Source   Edit  
proc writeStackFrames(c: Continuation) {....raises: [ValueError, IOError],
    tags: [WriteIOEffect], forbids: [].}
Write a "stack" trace for the continuation. Source   Edit  
proc writeTraceDeque() {.cpsVoodooCall, ...raises: [], tags: [], forbids: [].}
Source   Edit  
proc writeTraceDeque(c: Continuation) {....raises: [ValueError, IOError],
                                        tags: [WriteIOEffect], forbids: [].}
Write a traceback for the continuation. Source   Edit  

Macros

macro call[C; R; P](callback: Callback[C, R, P]; arguments: varargs[typed]): C
Invoke a callback with the given arguments; returns a continuation. Source   Edit  
macro cpsMagic(n: untyped): untyped

Applied to a procedure to generate a version which lacks the first argument and return value, which are those of a Continuation.

This new magical will compile correctly inside CPS procedures though it never takes a Continuation argument and produces no return value.

The target procedure of a cpsMagic pragma returns the Continuation to which control-flow should return; this is usually the same value passed into the procedure, but this is not required nor is it checked!

Source   Edit  
macro cpsVoodoo(n: untyped): untyped
Similar to a cpsMagic where the first argument is concerned, but may specify a return value which is usable inside the CPS procedure. Source   Edit  
macro etype(e: enum): string
Coop -> "Coop", not "coop" Source   Edit  
macro trampolineIt[T: Continuation](supplied: T; body: untyped)
This trampoline allows the user to interact with the continuation prior to each leg of its execution. The continuation will be exposed by a variable named it inside the body. Source   Edit  

Templates

template colon(a, b: NimNode): NimNode
for constructing foo: bar in a ctor Source   Edit  
template colon(a: string | NimNode; b: string | int): NimNode
for constructing foo: bar in a ctor Source   Edit  
template colon(a: string; b: NimNode): NimNode
for constructing foo: bar in a ctor Source   Edit  
template cpsBootstrap(whelp: typed) {.pragma.}
the symbol for creating a continuation -- technically, a whelp() Source   Edit  
template cpsBreak(label: typed = nil) {.pragma.}
this is a break statement in a cps block Source   Edit  
template cpsCall() {.pragma.}
a cps call Source   Edit  
template cpsCallback() {.pragma.}
this is a callback typedef Source   Edit  
template cpsCallbackShim(whelp: typed) {.pragma.}
the symbol for creating a continuation which returns a continuation base Source   Edit  
template cpsCont() {.pragma.}
this is a continuation Source   Edit  
template cpsContinue() {.pragma.}
this is a continue statement in a cps block Source   Edit  
template cpsEnvironment(tipe: typed) {.pragma.}
the environment type that composed the target Source   Edit  
template cpsHasException(cont, ex: typed) {.pragma.}
the continuation has an exception stored in ex, with cont being the continuation symbol used. Source   Edit  
template cpsLift() {.pragma.}
lift this proc|type Source   Edit  
template cpsMagicCall() {.pragma.}
a magic call Source   Edit  
template cpsMustJump() {.pragma.}
cps calls and magic calls jump Source   Edit  
template cpsPending() {.pragma.}
this is the last continuation Source   Edit  
template cpsResult(result: typed) {.pragma.}
the procedure that returns the result of the continuation Source   Edit  
template cpsReturnType(tipe: typed) {.pragma.}
the return type of the continuation Source   Edit  
template cpsTerminate() {.pragma.}
this is the end of this procedure Source   Edit  
template cpsVoodooCall() {.pragma.}
a voodoo call Source   Edit  
template debugAnnotation(s: typed; n: NimNode; body: untyped) {.dirty.}
Source   Edit  
template dot(a, b: NimNode): NimNode
for constructing foo.bar Source   Edit  
template dot(a: NimNode; b: string): NimNode
for constructing .(foo, "bar") Source   Edit  
template eq(a, b: NimNode): NimNode
for constructing foo=bar in a call Source   Edit  
template eq(a: string; b: NimNode): NimNode
for constructing foo=bar in a call Source   Edit  
template rewriteIt(n: typed; body: untyped): NormNode
Source   Edit