def make_retrieval_code(self): """Make code for retrieving the value of the aggregate result, including demanding it. """ incaggr = self.incaggr params_l = L.List(tuple(L.ln(p) for p in incaggr.params), L.Load()) if incaggr.has_demand: code = L.pe(''' DEMQUERY(NAME, PARAMS_L, RES.smlookup(AGGRMASK, PARAMS_T)) ''', subst={ 'NAME': incaggr.name, 'PARAMS_L': params_l, 'PARAMS_T': L.tuplify(incaggr.params), 'RES': incaggr.name, 'AGGRMASK': incaggr.aggrmask.make_node() }) else: code = L.pe(''' RES.smdeflookup(AGGRMASK, PARAMS_T, ZERO) ''', subst={ 'RES': incaggr.name, 'AGGRMASK': incaggr.aggrmask.make_node(), 'PARAMS_T': L.tuplify(incaggr.params), 'ZERO': self.make_zero_mapval_expr(), }) code = self.make_proj_mapval_code(code) return code
def leaf_to_expr(root, path): """Turn a leaf path into a series of subscript expressions that obtain the leaf value from the root value. """ node = root for i in path: node = L.Subscript(node, L.Index(L.Num(i)), L.Load()) return node
def make_projkey(self, val): """If this mask has no 'u' components, given a value for a tuple, construct a key expression out of the non-wildcard components. """ components = [] for i, c in enumerate(self.parts): if c == 'b': # val[i] expr = L.Subscript(val, L.Index(L.Num(i)), L.Load()) components.append(expr) elif c == 'w': pass elif c.isdigit(): pass else: assert () return L.tuplify(components)
def make_flattup_code(tuptype, in_node, out_node, tempvar): """Given a tuple tree type, make code to take the tuple given by the expression in_node and store the flattened form in the tuple given by out_node. """ def leaf_to_expr(root, path): """Turn a leaf path into a series of subscript expressions that obtain the leaf value from the root value. """ node = root for i in path: node = L.Subscript(node, L.Index(L.Num(i)), L.Load()) return node leaves = tuptype_leaves(tuptype) code = () # If in_expr is just a variable name, use it as is. # Otherwise store it in a temporary variable to avoid redundant # evaluation of in_expr. if isinstance(in_node, L.Name): root_node = in_node else: rootname = tempvar code += L.pc(''' ROOT = IN_NODE ''', subst={ 'IN_NODE': in_node, 'ROOT': L.sn(rootname) }) root_node = L.ln(rootname) flattuple_expr = L.Tuple( tuple(leaf_to_expr(root_node, leaf) for leaf in leaves), L.Load()) code += L.pc(''' OUT_NODE = FLATTUP ''', subst={ 'FLATTUP': flattuple_expr, 'OUT_NODE': out_node }) return code
def trel_bindmatch(trel, mask, vars, body, *, typecheck): """Make code to pattern match over a tuple relation.""" assert len(mask) >= 2 tup, *elts = vars arity = get_trel(trel) assert arity == len(elts) bvars, uvars, _eqs = mask.split_vars(vars) if mask.parts[0] == 'b': # Kick it over to setmatch(). The set being matched is # a singleton containing a tuple whose first component # is the passed-in tuple, and whose remaining components # are those of the passed-in tuple, i.e. # # (tup, tup[0], ..., tup[n]) # # This allows the mask to work correctly with arbitrary # equality components, wildcards, etc. singtup_elts = (L.ln(tup),) for i in range(arity): singtup_elts += (L.pe('TUP[IND]', subst={'TUP': L.ln(tup), 'IND': L.Num(i)}),) singtup = L.Tuple(singtup_elts, L.Load()) code = L.pc(''' for UVARS in setmatch({SINGTUP}, MASK, BVARS): BODY ''', subst={'UVARS': L.tuplify(uvars, lval=True), 'SINGTUP': singtup, 'MASK': mask.make_node(), 'BVARS': L.tuplify(bvars), '<c>BODY': body}) # If any other part of the mask besides the first component # is bound, we need to confirm that it is consistent with # the tuple value of the first component. var_parts = list(enumerate(zip(vars, mask.parts))) conds = [L.pe('TUP[IND] == VAR', subst={'TUP': L.ln(tup), 'IND': L.Num(i), 'VAR': L.ln(var)}) for i, (var, part) in var_parts if i > 0 if part == 'b'] if len(conds) == 0: cond = None elif len(conds) == 1: cond = conds[0] else: cond = L.BoolOp(L.And(), conds) if cond is not None: code = L.pc(''' if COND: CODE ''', subst={'COND': cond, '<c>CODE': code}) if typecheck: code = L.pc(''' if isinstance(TUP, tuple) and len(TUP) == ARITY: CODE ''', subst={'TUP': L.ln(tup), 'ARITY': L.Num(arity), '<c>CODE': code}) # TODO: Case where first component is unbound but all other # components are bound, in which case we can avoid a map lookup. else: code = L.pc(''' for UVARS in setmatch(SET, MASK, BVARS): BODY ''', subst={'UVARS': L.tuplify(uvars, lval=True), 'SET': L.ln(trel), 'MASK': mask.make_node(), 'BVARS': L.tuplify(bvars), '<c>BODY': body}) return code