def Snapshot(b1, e2): e = None def prepare(): e.fresh = False for l in e.listeners.itervalues(): l.prepare() def push(b): a = b1.pull() for l in e.listeners.itervalues(): l.push((a, b)) def finish(): for l in e.listeners.itervalues(): l.finish() e.fresh = True def terminate(): for l in e.listeners.itervalues(): l.terminate() e2.add_listener(FListener(prepare, push, finish, terminate)) e = FEvent(type=types.FEventType((b1.type, e2.type))) return e
def unit_test(i, ef, o): if RUN_TESTS: def location(): (filename, lineno) = inspect.stack()[2][1:3] return "File \"" + filename + "\", line " + str(lineno) (ei, go) = RawEvent() e = Apply(ei, ef) def f(x): y = o.pop(0) if x != y: print "%s: Unit test error\nexpected %s\nbut found %s" % ( location(), str(y), str(x)) e.add_listener(FListener(push=f)) for x in i: go(x) for l in ei.listeners.itervalues(): l.terminate() if len(o) != 0: print "%s: Unit test error\nextra outputs %s" % (location(), str(o)) return
def Hold(a, e1): b = None def pull(): return b.cell.get() def push(a): b.cell.set(a) b = FBehavior(pull, types.FBehaviorType(e1.type)) b.cell = util.FRef() b.cell.set(a) e1.add_listener(FListener(push=push)) return b
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
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
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
def Split(e): e1 = None e2 = None def prepare(): e1.fresh = False e2.fresh = False for l in e1.listeners.itervalues(): l.prepare() for l in e2.listeners.itervalues(): l.prepare() def push((x1, x2)): for l in e1.listeners.itervalues(): l.push(x1) for l in e2.listeners.itervalues(): l.push(x2) def finish(): for l in e1.listeners.itervalues(): l.finish() for l in e2.listeners.itervalues(): l.finish() e1.fresh = True e2.fresh = True def terminate(): for l in e1.listeners.itervalues(): l.terminate() for l in e2.listeners.itervalues(): l.terminate() t1 = t2 = None if e.type is not None: try: (r1, r2) = e.type.type (t1, t2) = (types.FType(r1), types.FType(r2)) except (TypeError, ValueError): raise types.FTypeException("%s not of type %s" % (e.type, "a * b")) e1 = FEvent(type=t1) e2 = FEvent(type=t2) e.add_listener(FListener(prepare, push, finish, terminate)) return (e1, e2)
def debug_test(i, ef): if DEBUG: def location(): (filename, lineno) = inspect.stack()[2][1:3] return "File \"" + filename + "\", line " + str(lineno) (ei, go) = RawEvent() e = Apply(ei, ef) o = [] def f(x): o.append(x) e.add_listener(FListener(push=f)) for x in i: go(x) ei.terminate() print "%s: Test result:\n%s" % (location(), str(o)) return
def Apply(e1, ef2): e = None def prepare(): e.fresh = False ef2.prepare() def push(x): ef2.push(x) def finish(): ef2.finish() e.fresh = True e1.add_listener(FListener(prepare, push, finish, ef2.terminate)) t = None if ef2.type_fun is not None: t = ef2.type_fun(e1.type) e = FEvent(ef2.add_listener, type=t) return e
def unit_test_merge(i, ef, o): if RUN_TESTS: def location(): (filename, lineno) = inspect.stack()[2][1:3] return "File \"" + filename + "\", line " + str(lineno) (eia, goa) = RawEvent() (eib, gob) = RawEvent() e = ef(eia, eib) def f((p, q)): (x, y) = (None, None) if len(o) > 0: (x, y) = o.pop(0) if (x, y) != (p, q): print sys.stderr, "%s: Unit test error\nexpected %s\nbut found %s" % ( location(), str((x, y)), str((p, q))) e.add_listener(FListener(push=f)) for (a, b) in i: if not (a is None) and not (b is None): # This isn't truly a parallel call (goa(a), gob(b)) elif not (a is None): goa(a) elif not (b is None): gob(b) for l in eia.listeners.itervalues(): l.terminate() for l in eib.listeners.itervalues(): l.terminate() if len(o) != 0: print sys.stderr, "%s: Unit test error\nextra outputs %s" % ( location(), str(o)) return
def push((x, e)): ef.table[e] = (x, 0, False, init) e.add_listener(FListener(push=mk_lpush(e), terminate=mk_lterm(e)))
def Merge(e1, e2): e = None def prepare(): e.fresh = False for l in e.listeners.itervalues(): l.prepare() def push1(x1): if e2.fresh or e2.cell.get() != None: x2 = e2.cell.get() for l in e.listeners.itervalues(): l.push((x1, x2)) e2.cell.set(None) else: e1.cell.set(x1) def push2(x2): if e1.fresh or e1.cell.get() != None: x1 = e1.cell.get() for l in e.listeners.itervalues(): l.push((x1, x2)) e1.cell.set(None) else: e2.cell.set(x2) def finish(): x1 = e1.cell.get() x2 = e2.cell.get() e1.cell.set(None) e2.cell.set(None) if x2 != None: for l in e.listeners.itervalues(): l.push((None, x2)) if x1 != None: for l in e.listeners.itervalues(): l.push((x1, None)) for l in e.listeners.itervalues(): l.finish() e.fresh = True def terminate1(): e.term1 = True if e.term2: for l in e.listeners.itervalues(): l.terminate() def terminate2(): e.term2 = True if e.term1: for l in e.listeners.itervalues(): l.terminate() e1.add_listener(FListener(prepare, push1, finish, terminate1)) e2.add_listener(FListener(prepare, push2, finish, terminate2)) if e1.type is None or e2.type is None: out_type = None else: # TODO(astory): option out_type = types.FType((e1.type.type, e2.type.type)) e = FEvent(type=out_type) e.term1 = False e.term2 = False e1.cell = util.FRef() e2.cell = util.FRef() return e