def parse_functions(
    bels: list, char_locs: CharLocs, parsed: Parsed, errors: Errors
) -> Tuple[Parsed, Errors]:
    """Parse functions from BEL using paren, comma, quote character locations

    Args:
        bels: BEL string as list of chars
        char_locs: paren, comma, quote character locations
        errors: Any error messages generated during the parse

    Returns:
        (functions, errors): function names and locations and error messages
    """
    parens = char_locs["parens"]

    # Handle partial top-level function name
    if not parens:
        bels_len = len(bels) - 1
        span = (0, bels_len)
        parsed[span] = {
            "name": "".join(bels),
            "type": "Function",
            "span": span,
            "name_span": (span),
            "function_level": "top",
        }
        return parsed, errors

    for sp in sorted(parens):  # sp = starting paren, ep = ending_paren
        ep, function_level = parens[sp]

        # Functions can't have a space between function name and left paren
        if bels[sp - 1] == " ":
            continue

        # look in front of start paren for function name
        for i in range(sp - 1, 0, -1):
            if bels[i] in [" ", ",", "("]:  # function name upstream boundary chars
                if i < sp - 1:
                    if ep == -1:
                        span = (i + 1, len(bels) - 1)
                    else:
                        span = (i + 1, ep)

                    parsed[span] = {
                        "name": "".join(bels[i + 1 : sp]),
                        "type": "Function",
                        "span": span,
                        "name_span": (i + 1, sp - 1),
                        "parens_span": (sp, ep),
                        "function_level": function_level,
                    }
                break
        else:
            if ep == -1:
                span = (0, len(bels) - 1)
            else:
                span = (0, ep)

            parsed[span] = {
                "name": "".join(bels[0:sp]),
                "type": "Function",
                "span": span,
                "name_span": (0, sp - 1),
                "parens_span": (sp, ep),
                "function_level": function_level,
            }

    return parsed, errors
Parse functions from BEL using paren, comma, quote character locations

    Args:
        bels: BEL string as list of chars
        char_locs: paren, comma, quote character locations
        errors: Any error messages generated during the parse

    Returns:
        (functions, errors): function names and locations and error messages