'Tries to map keyword arguments to declared positional arguments.
Returns self to try a Python call, None to report an error
or a SimpleCallNode if the mapping succeeds.'

def map_to_simple_call_node(self):

    if (not isinstance(self.positional_args, TupleNode)):
        return self
    if (not self.keyword_args.is_dict_literal):
        return self
    function = self.function
    entry = getattr(function, 'entry', None)
    if (not entry):
        return self
    function_type = entry.type
    if function_type.is_ptr:
        function_type = function_type.base_type
    if (not function_type.is_cfunction):
        return self
    pos_args = self.positional_args.args
    kwargs = self.keyword_args
    declared_args = function_type.args
    if entry.is_cmethod:
        declared_args = declared_args[1:]
    if (len(pos_args) > len(declared_args)):
        error(self.pos, ('function    call    got    too    many    positional    arguments,    expected    %d,    got    %s' % (len(declared_args), len(pos_args))))
        return None
    matched_args = set([arg.name for arg in declared_args[:len(pos_args)] if arg.name])
    unmatched_args = declared_args[len(pos_args):]
    matched_kwargs_count = 0
    args = list(pos_args)
    seen = set(matched_args)
    has_errors = False
    for arg in kwargs.key_value_pairs:
        name = arg.key.value
        if (name in seen):
            error(arg.pos, ("argument    '%s'    passed    twice" % name))
            has_errors = True
        seen.add(name)
    for (decl_arg, arg) in zip(unmatched_args, kwargs.key_value_pairs):
        name = arg.key.value
        if (decl_arg.name == name):
            matched_args.add(name)
            matched_kwargs_count += 1
            args.append(arg.value)
        else:
            break
    from .UtilNodes import EvalWithTempExprNode, LetRefNode
    temps = []
    if (len(kwargs.key_value_pairs) > matched_kwargs_count):
        unmatched_args = declared_args[len(args):]
        keywords = dict([(arg.key.value, ((i + len(pos_args)), arg)) for (i, arg) in enumerate(kwargs.key_value_pairs)])
        first_missing_keyword = None
        for decl_arg in unmatched_args:
            name = decl_arg.name
            if (name not in keywords):
                if (not first_missing_keyword):
                    first_missing_keyword = name
                continue
            elif first_missing_keyword:
                if entry.as_variable:
                    return self
                error(self.pos, ("C    function    call    is    missing    argument    '%s'" % first_missing_keyword))
                return None
            (pos, arg) = keywords[name]
            matched_args.add(name)
            matched_kwargs_count += 1
            if arg.value.is_simple():
                args.append(arg.value)
            else:
                temp = LetRefNode(arg.value)
                assert temp.is_simple()
                args.append(temp)
                temps.append((pos, temp))
        if temps:
            final_args = []
            new_temps = []
            first_temp_arg = temps[0][(-1)]
            for arg_value in args:
                if (arg_value is first_temp_arg):
                    break
                if arg_value.is_simple():
                    final_args.append(arg_value)
                else:
                    temp = LetRefNode(arg_value)
                    new_temps.append(temp)
                    final_args.append(temp)
            if new_temps:
                args = final_args
            temps = (new_temps + [arg for (i, arg) in sorted(temps)])
    for arg in kwargs.key_value_pairs:
        name = arg.key.value
        if (name not in matched_args):
            has_errors = True
            error(arg.pos, ("C    function    got    unexpected    keyword    argument    '%s'" % name))
    if has_errors:
        return None
    node = SimpleCallNode(self.pos, function=function, args=args)
    for temp in temps[::(-1)]:
        node = EvalWithTempExprNode(temp, node)
    return node
