Esempio n. 1
0
    def resolve_stateful_func(func, args):
        """Resolve a stateful function given argument expressions.

        :param func: An instance of StatefulFunc
        :param args: A list of argument expressions
        :return: An emit expression and a StateVar list.  All expressions
        have no free variables.
        """
        assert isinstance(func, StatefulFunc)
        state_var_names = func.statemods.keys()

        # Mangle state variable names to allow multiple invocations to coexist
        state_vars_mangled = [Parser.mangle(sv) for sv in state_var_names]
        mangle_dict = dict(zip(state_var_names, state_vars_mangled))

        statemods = []
        for name, (init_expr, update_expr) in func.statemods.iteritems():
            # Convert state mod references into appropriate expressions
            update_expr = sexpr.resolve_state_vars(update_expr,  # noqa
                state_var_names, mangle_dict)
            # Convert argument references into appropriate expressions
            update_expr = sexpr.resolve_function(update_expr,  # noqa
                dict(zip(func.args, args)))
            statemods.append(StateVar(mangle_dict[name],
                                      init_expr, update_expr))
        emit_expr = sexpr.resolve_state_vars(func.sexpr, state_var_names,
                                             mangle_dict)
        return emit_expr, statemods
Esempio n. 2
0
    def resolve_stateful_func(func, args):
        """Resolve a stateful function given argument expressions.

        :param func: An instance of StatefulFunc
        :param args: A list of argument expressions
        :return: An emit expression and a StateVar list.  All expressions
        have no free variables.
        """
        assert isinstance(func, StatefulFunc)
        state_var_names = func.statemods.keys()

        # Mangle state variable names to allow multiple invocations to coexist
        state_vars_mangled = [Parser.mangle(sv) for sv in state_var_names]
        mangle_dict = dict(zip(state_var_names, state_vars_mangled))

        statemods = []
        for name, (init_expr, update_expr) in func.statemods.iteritems():
            # Convert state mod references into appropriate expressions
            update_expr = sexpr.resolve_state_vars(update_expr,  # noqa
                state_var_names, mangle_dict)
            # Convert argument references into appropriate expressions
            update_expr = sexpr.resolve_function(update_expr,  # noqa
                dict(zip(func.args, args)))
            statemods.append(StateVar(mangle_dict[name],
                                      init_expr, update_expr))
        emit_expr = sexpr.resolve_state_vars(func.sexpr, state_var_names,
                                             mangle_dict)
        return emit_expr, statemods
Esempio n. 3
0
    def resolve_function(p, name, args):
        """Resolve a function invocation into an Expression instance.

        :param p: The parser context
        :param name: The name of the function
        :type name: string
        :param args: A list of argument expressions
        :type args: list of raco.expression.Expression instances
        :return: An expression with no free variables.
        """

        # try to get function from udf or system defined functions
        if name in Parser.udf_functions:
            func = Parser.udf_functions[name]
        else:
            func = expr_lib.lookup(name, len(args))

        if func is None:
            raise NoSuchFunctionException(name, p.lineno(0))
        if len(func.args) != len(args):
            raise InvalidArgumentList(name, func.args, p.lineno(0))

        if isinstance(func, Function):
            return sexpr.resolve_function(func.sexpr, dict(zip(func.args, args)))  # noqa
        elif isinstance(func, Apply):
            state_vars = func.statemods.keys()

            # Mangle state variable names to allow multiple invocations to
            # co-exist
            state_vars_mangled = [Parser.mangle(sv) for sv in state_vars]
            mangled = dict(zip(state_vars, state_vars_mangled))

            for sm_name, (init_expr, update_expr) in func.statemods.iteritems():  # noqa
                # Convert state mod references into appropriate expressions
                update_expr = sexpr.resolve_state_vars(update_expr,
                    state_vars, mangled)  # noqa
                # Convert argument references into appropriate expressions
                update_expr = sexpr.resolve_function(update_expr,
                    dict(zip(func.args, args)))  # noqa
                Parser.statemods.append((mangled[sm_name],
                    init_expr, update_expr))  # noqa
            return sexpr.resolve_state_vars(func.sexpr, state_vars, mangled)
        else:
            assert False
Esempio n. 4
0
    def resolve_function(p, name, args):
        """Resolve a function invocation into an Expression instance.

        :param p: The parser context
        :param name: The name of the function
        :type name: string
        :param args: A list of argument expressions
        :type args: list of raco.expression.Expression instances
        :return: An expression with no free variables.
        """

        # try to get function from udf or system defined functions
        if name in Parser.udf_functions:
            func = Parser.udf_functions[name]
        else:
            func = expr_lib.lookup(name, len(args))

        if isinstance(func, VariadicFunction):
            func = func.bind(*args)

        if func is None:
            raise NoSuchFunctionException(name, p.lineno(0))
        if len(func.args) != len(args):
            raise InvalidArgumentList(name, func.args, p.lineno(0))

        if isinstance(func, Function):
            return sexpr.resolve_function(func.sexpr, dict(zip(func.args, args)))  # noqa
        elif isinstance(func, StatefulFunc):
            emit_expr, statemods = Parser.resolve_stateful_func(func, args)
            Parser.statemods.extend(statemods)

            # If the aggregate is decomposable, construct local and remote
            # emitters and statemods.
            if name in Parser.decomposable_aggs:
                ds = Parser.decomposable_aggs[name]
                local_emit, local_statemods = Parser.resolve_stateful_func(
                    ds.local, args)

                # Problem: we must connect the local aggregate outputs to
                # the remote aggregate inputs.  At this stage, we don't have
                # enough information to construct argument expressions to
                # serve as input to the remote aggregate.  Instead, we
                # introduce a placeholder reference, which is referenced
                # relative to the start of the local aggregate output.
                remote_args = [sexpr.LocalAggregateOutput(i)
                               for i in range(len(ds.remote.args))]
                remote_emit, remote_statemods = Parser.resolve_stateful_func(
                    ds.remote, remote_args)

                # local and remote emitters may be tuple-valued; flatten them.
                local_emitters = get_emitters(local_emit)
                remote_emitters = get_emitters(remote_emit)
                ds = sexpr.DecomposableAggregateState(
                    local_emitters, local_statemods,
                    remote_emitters, remote_statemods)

                # Associate a decomposable state structure with the first
                # emitter.  Mark the remaining emitters as decomposable, but
                # without their own associated decomposed emitters and
                # statemods.
                emitters = get_emitters(emit_expr)
                emitters[0].set_decomposable_state(ds)
                for emt in emitters[1:]:
                    emt.set_decomposable_state(
                        sexpr.DecomposableAggregateState())
            return emit_expr
        else:
            assert False
Esempio n. 5
0
    def resolve_function(p, name, args):
        """Resolve a function invocation into an Expression instance.

        :param p: The parser context
        :param name: The name of the function
        :type name: string
        :param args: A list of argument expressions
        :type args: list of raco.expression.Expression instances
        :return: An expression with no free variables.
        """

        # try to get function from udf or system defined functions
        if name in Parser.udf_functions:
            func = Parser.udf_functions[name]
        else:
            func = expr_lib.lookup(name, len(args))

        if func is None:
            raise NoSuchFunctionException(name, p.lineno(0))
        if len(func.args) != len(args):
            raise InvalidArgumentList(name, func.args, p.lineno(0))

        if isinstance(func, Function):
            return sexpr.resolve_function(func.sexpr, dict(zip(func.args, args)))  # noqa
        elif isinstance(func, StatefulFunc):
            emit_expr, statemods = Parser.resolve_stateful_func(func, args)
            Parser.statemods.extend(statemods)

            # If the aggregate is decomposable, construct local and remote
            # emitters and statemods.
            if name in Parser.decomposable_aggs:
                ds = Parser.decomposable_aggs[name]
                local_emit, local_statemods = Parser.resolve_stateful_func(
                    ds.local, args)

                # Problem: we must connect the local aggregate outputs to
                # the remote aggregate inputs.  At this stage, we don't have
                # enough information to construct argument expressions to
                # serve as input to the remote aggregate.  Instead, we
                # introduce a placeholder reference, which is referenced
                # relative to the start of the local aggregate output.
                remote_args = [sexpr.LocalAggregateOutput(i)
                               for i in range(len(ds.remote.args))]
                remote_emit, remote_statemods = Parser.resolve_stateful_func(
                    ds.remote, remote_args)

                # local and remote emitters may be tuple-valued; flatten them.
                local_emitters = get_emitters(local_emit)
                remote_emitters = get_emitters(remote_emit)
                ds = sexpr.DecomposableAggregateState(
                    local_emitters, local_statemods,
                    remote_emitters, remote_statemods)

                # Associate a decomposable state structure with the first
                # emitter.  Mark the remaining emitters as decomposable, but
                # without their own associated decomposed emitters and
                # statemods.
                emitters = get_emitters(emit_expr)
                emitters[0].set_decomposable_state(ds)
                for emt in emitters[1:]:
                    emt.set_decomposable_state(
                        sexpr.DecomposableAggregateState())
            return emit_expr
        else:
            assert False