예제 #1
0
def Group(g, b_type=None):
    ef = None

    def prepare():
        for l in ef.listeners.itervalues():
            l.prepare()
        for e in ef.table.values():
            e.fresh = False
            for l in e.listeners.itervalues():
                l.prepare()

    def push(x):
        y = g(x)
        e = None
        if not (ef.table.has_key(y)):
            e = FEvent()
            ef.table[y] = e
            for l in ef.listeners.itervalues():
                l.push((y, e))
        else:
            e = ef.table[y]
        for l in e.listeners.itervalues():
            l.push(x)

    def finish():
        for e in ef.table.values():
            for l in e.listeners.itervalues():
                l.finish()
            e.fresh = True
        for l in ef.listeners.itervalues():
            l.finish()

    def terminate():
        for e in ef.table.values():
            for l in e.listeners.itervalues():
                l.terminate()
        for l in ef.listeners.itervalues():
            l.terminate()

    def type_fun(a):
        if a is not None and b_type is not None:
            return types.FType((b_type.type, types.FEventType(a.type)))
        else:
            return None

    ef = FEventFun(prepare=prepare,
                   push=push,
                   finish=finish,
                   terminate=terminate,
                   type_fun=type_fun)
    ef.table = {}
    return ef
예제 #2
0
def Ungroup(n, f, init, init_type=None):
    ef = None

    def go(x, y):
        for l in ef.listeners.itervalues():
            l.push((x, y))

    def mk_lpush(e):
        def g(z):
            (x, i, b, y) = ef.table[e]
            if not b:
                y = f(y, z)
                if not (n is None) and i == n - 1:
                    b = True
                    go(x, y)
                ef.table[e] = (x, i + 1, b, y)

        return g

    def mk_lterm(e):
        def g():
            (x, i, b, y) = ef.table[e]
            if not b:
                go(x, y)

        return g

    def push((x, e)):
        ef.table[e] = (x, 0, False, init)
        e.add_listener(FListener(push=mk_lpush(e), terminate=mk_lterm(e)))

    def type_fun(t):
        if t is None or init_type is None:
            return None
        try:
            (c, a) = t.type
        except (TypeError, ValueError):
            raise types.FTypeException("%s not an instance of (c * E a)" % a)
        f_out_type = f.type_fun(types.FType((init_type.type, a.type)))
        if not types.is_of_type(f_out_type, init_type):
            raise types.FTypeException(
                "%s not of expected type: f generates %s instead of %s" %
                (t, f_out_type, init_type))
        return types.FType((c, init_type.type))

    ef = FEventFun(push=push, type_fun=type_fun)
    ef.table = {}
    return ef
예제 #3
0
def Lift(g, in_type=None, out_type=None, type_fun=None):
    """Lift function g into an EF.  Optional type annotations {in,out}_type, or
    you can give a type conversion function, which overrides static types.
    
    Note that in_type and out_type MUST be wrapped in types.FType,or something
    with its interface, and type_fun should expect its input and output wrapped
    in the same class.
    
    A None type object acts as a signal to ignore type checking this
    type.  It should not throw type exceptions."""
    ef = None

    def push(x):
        y = g(x)
        for l in ef.listeners.itervalues():
            l.push(y)

    if type_fun is None:

        def type_fun(test_in_type):
            if in_type is None or types.is_of_type(test_in_type, in_type):
                return out_type
            else:
                raise types.FTypeException("%s not of type %s" %
                                           (test_in_type, in_type))

    ef = FEventFun(push=push, type_fun=type_fun)
    return ef
예제 #4
0
def LoopPre(c, ef1, c_type=None):
    ef = None

    def prepare():
        ef1.prepare()
        for l in ef.listeners.itervalues():
            l.prepare()

    def push(x):
        ef1.push((x, ef.cell.get()))

    def push2((y1, y2)):
        ef.cell.set(y2)
        for l in ef.listeners.itervalues():
            l.push(y1)

    def finish():
        ef1.finish()
        for l in ef.listeners.itervalues():
            l.finish()

    def terminate():
        ef1.terminate()
        for l in ef.listeners.itervalues():
            l.terminate()

    def type_fun(a):
        if a is None or c_type is None:
            return None
        eftype = ef1.type_fun(types.FType((a.type, c_type.type)))
        if eftype is None:
            return None
        (b, c) = eftype.type
        if not types.is_of_type(c_type, types.FType(c)):
            raise types.FTypeException("%s is not of type %s" % (c, c_type))
        return types.FType(b)

    ef = FEventFun(prepare=prepare,
                   push=push,
                   finish=finish,
                   terminate=terminate,
                   type_fun=type_fun)
    ef.cell = util.FRef()
    ef.cell.set(c)
    ef1.add_listener(FListener(push=push2))
    return ef
예제 #5
0
def Group(g, b_type=None):
    ef = None
    def prepare():
        for l in ef.listeners.itervalues():
            l.prepare()
        for e in ef.table.values():
            e.fresh = False
            for l in e.listeners.itervalues():
                l.prepare()
    def push(x):
        y = g(x)
        e = None
        if not (ef.table.has_key(y)):
            e = FEvent()
            ef.table[y] = e
            for l in ef.listeners.itervalues():
                l.push((y,e))
        else:
            e = ef.table[y]
        for l in e.listeners.itervalues():
            l.push(x)
    def finish():
        for e in ef.table.values():
            for l in e.listeners.itervalues():
                l.finish()
            e.fresh = True
        for l in ef.listeners.itervalues():
            l.finish()
    def terminate():
        for e in ef.table.values():
            for l in e.listeners.itervalues():
                l.terminate()            
        for l in ef.listeners.itervalues():
            l.terminate()
    def type_fun(a):
        if a is not None and b_type is not None:
            return types.FType((b_type.type, types.FEventType(a.type)))
        else:
            return None
    ef = FEventFun(prepare=prepare,
        push=push,
        finish=finish,
        terminate=terminate,
        type_fun=type_fun)
    ef.table = {}
    return ef
예제 #6
0
def First(ef1):
    ef = None

    def prepare():
        ef1.prepare()
        for l in ef.listeners.itervalues():
            l.prepare()

    def push((x1, x2)):
        ef.cell.set(x2)
        ef1.push(x1)

    def push2(y1):
        y2 = ef.cell.get()
        for l in ef.listeners.itervalues():
            l.push((y1, y2))

    def finish():
        ef1.finish()
        for l in ef.listeners.itervalues():
            l.finish()

    def terminate():
        ef1.terminate()
        for l in ef.listeners.itervalues():
            l.terminate()

    def type_fun(in_type):
        if in_type is None:
            return None
        try:
            (a, c) = in_type.type
        except ValueError:
            raise types.FTypeException("%s not of type (a * c)" % in_type)
        return types.FType((ef1.type_fun(types.FType(a)).type, c))

    ef = FEventFun(prepare=prepare,
                   push=push,
                   finish=finish,
                   terminate=terminate,
                   type_fun=type_fun)
    ef.cell = util.FRef()
    ef1.add_listener(FListener(push=push2))
    return ef
예제 #7
0
def Filter(g):
    ef = None

    def push(x):
        if g(x):
            for l in ef.listeners.itervalues():
                l.push(x)

    ef = FEventFun(push=push, type_fun=lambda a: a)
    return ef
예제 #8
0
def Ungroup(n,f,init, init_type=None):
    ef = None
    def go(x,y):
        for l in ef.listeners.itervalues():
            l.push((x,y))
    def mk_lpush(e):
        def g(z):            
            (x,i,b,y) = ef.table[e]
            if not b:
                y = f(y,z)
                if not (n is None) and i == n - 1:
                    b = True
                    go(x,y)
                ef.table[e] = (x,i+1,b,y)
        return g
    def mk_lterm(e):
        def g():
            (x,i,b,y) = ef.table[e]
            if not b:
                go(x,y)
        return g
    def push((x,e)):
        ef.table[e] = (x,0,False,init)
        e.add_listener(FListener(push=mk_lpush(e),terminate=mk_lterm(e)))
    def type_fun(t):
        if t is None or init_type is None:
            return None
        try:
            (c, a) = t.type
        except (TypeError, ValueError):
            raise types.FTypeException("%s not an instance of (c * E a)" % a)
        f_out_type = f.type_fun(types.FType((init_type.type, a.type)))
        if not types.is_of_type(f_out_type, init_type):
            raise types.FTypeException(
                "%s not of expected type: f generates %s instead of %s"
                % (t, f_out_type, init_type))
        return types.FType((c, init_type.type))
    ef = FEventFun(push=push,type_fun=type_fun)
    ef.table = {}
    return ef
예제 #9
0
def LoopPre(c, ef1, c_type=None):
    ef = None
    def prepare():
        ef1.prepare()
        for l in ef.listeners.itervalues():
            l.prepare()
    def push(x):
        ef1.push((x,ef.cell.get()))
    def push2((y1,y2)):
        ef.cell.set(y2)
        for l in ef.listeners.itervalues():
            l.push(y1)
    def finish():
        ef1.finish()
        for l in ef.listeners.itervalues():
            l.finish()
    def terminate():
        ef1.terminate()
        for l in ef.listeners.itervalues():
            l.terminate()
    def type_fun(a):
        if a is None or c_type is None:
            return None
        eftype = ef1.type_fun(types.FType((a.type, c_type.type)))
        if eftype is None:
            return None
        (b, c) = eftype.type
        if not types.is_of_type(c_type, types.FType(c)):
            raise types.FTypeException("%s is not of type %s" % (c, c_type))
        return types.FType(b)
    ef = FEventFun(
            prepare=prepare,
            push=push,
            finish=finish,
            terminate=terminate,
            type_fun = type_fun)
    ef.cell = util.FRef()
    ef.cell.set(c)
    ef1.add_listener(FListener(push=push2))
    return ef
예제 #10
0
def First(ef1):
    ef = None
    def prepare():
        ef1.prepare()
        for l in ef.listeners.itervalues():
            l.prepare()
    def push((x1,x2)):
        ef.cell.set(x2)
        ef1.push(x1)
    def push2(y1):
        y2 = ef.cell.get()
        for l in ef.listeners.itervalues():
            l.push((y1,y2))
    def finish():
        ef1.finish()
        for l in ef.listeners.itervalues():
            l.finish()
    def terminate():
        ef1.terminate()
        for l in ef.listeners.itervalues():
            l.terminate()
    def type_fun(in_type):
        if in_type is None:
            return None
        try:
            (a, c) = in_type.type
        except ValueError:
            raise types.FTypeException("%s not of type (a * c)" % in_type)
        return types.FType((ef1.type_fun(types.FType(a)).type, c))
    ef = FEventFun(
        prepare=prepare,
        push=push,
        finish=finish,
        terminate=terminate,
        type_fun=type_fun)
    ef.cell = util.FRef()
    ef1.add_listener(FListener(push=push2))
    return ef
예제 #11
0
def Compose(ef1, ef2):
    ef1.add_listener(ef2)

    def type_fun(t):
        if t is None:
            return None
        out1 = ef1.type_fun(t)
        if out1 is None:
            return None
        out2 = ef2.type_fun(out1)
        return out2

    ef = FEventFun(ef2.add_listener, ef1.prepare, ef1.push, ef1.finish,
                   ef1.terminate, type_fun)
    return ef
예제 #12
0
def Regroup(feq):
    # helper function to split a nested subevent
    def mk_subevent(e, outer_prepare, outer_push):
        sube_cell = util.FRef()

        def mk():
            sube = FEvent()
            sube.last_cell = util.FRef()
            return sube

        def subprepare():
            sube = sube_cell.get()
            sube.fresh = False
            for l in sube.listeners.itervalues():
                l.prepare()

        def subpush(x):
            sube = sube_cell.get()
            last = sube.last_cell.get()
            if not (last is None) and not (feq(last, x)):
                # terminate / create new subevent
                sube_old = sube
                sube = mk()
                subterminate()
                sube_cell.set(sube)
                subprepare()
                outer_prepare()
                outer_push(sube)
            for l in sube.listeners.itervalues():
                l.push(x)
            sube.last_cell.set(x)

        def subfinish():
            sube = sube_cell.get()
            for l in sube.listeners.itervalues():
                l.finish()
            sube.fresh = True

        def subterminate():
            sube = sube_cell.get()
            for l in sube.listeners.itervalues():
                l.terminate()

        sube = mk()
        sube_cell.set(sube)
        e.add_listener(FListener(subprepare, subpush, subfinish, subterminate))
        return sube

    ef = None

    def prepare():
        for l in ef.listeners.itervalues():
            l.prepare()

    def push((x, e)):
        outer_push = lambda e: push((x, e))
        sube = mk_subevent(e, prepare, outer_push)
        for l in ef.listeners.itervalues():
            l.push((x, sube))

    # TODO(astory): consider checking for correctness
    ef = FEventFun(push=push, type_fun=lambda a: a)
    return ef