Implements @mixin and @function

def _do_functions(self, rule, p_selectors, p_parents, p_children, scope, media, c_lineno, c_property, c_codestr, code, name):
        """
        Implements @mixin and @function
        """
        if name:
            funct, params, _ = name.partition('(')
            funct = funct.strip()
            params = split_params(depar(params + _))
            defaults = {}
            new_params = []
            for param in params:
                param, _, default = param.partition(':')
                param = param.strip()
                default = default.strip()
                if param:
                    new_params.append(param)
                    if default:
                        default = self.apply_vars(
                            default, rule[CONTEXT], None, rule)
                        defaults[param] = default
            context = rule[CONTEXT].copy()
            for p in new_params:
                context.pop(p, None)
            mixin = [list(new_params), defaults, self.
                     apply_vars(c_codestr, context, None, rule)]
            if code == '@function':
                def _call(mixin):
                    def __call(R, *args, **kwargs):
                        m_params = mixin[0]
                        m_vars = rule[CONTEXT].copy()
                        m_vars.update(mixin[1])
                        m_codestr = mixin[2]
                        for i, a in enumerate(args):
                            m_vars[m_params[i]] = a
                        m_vars.update(kwargs)
                        _options = rule[OPTIONS].copy()
                        _rule = spawn_rule(R, codestr=m_codestr, context=m_vars, options=_options, deps=set(), properties=[], final=False, lineno=c_lineno)
                        self.manage_children(_rule, p_selectors, p_parents,
                                             p_children, (scope or '') + '', R[MEDIA])
                        ret = _rule[OPTIONS].pop('@return', '')
                        return ret
                    return __call
                _mixin = _call(mixin)
                _mixin.mixin = mixin
                mixin = _mixin
            # Insert as many @mixin options as the default parameters:
            while len(new_params):
                rule[OPTIONS]['%s %s:%d' % (code, funct,
                                            len(new_params))] = mixin
                param = new_params.pop()
                if param not in defaults:
                    break
            if not new_params:
                rule[OPTIONS][code + ' ' + funct + ':0'] = mixin