示例#1
0
def build_func_arg(block, ast_node):
    # argument: (test (comp_for)? | test '=' test | '**' test | '*' test);
    childs = ast_node.children
    if len(childs) == 3:  # test = test
        left = build_test_stmt(childs[0])
        right = build_test_stmt(childs[2])
        return KeyWordArg(block, childs[0], left_instr=left, right_instr=right)

    if isinstance(childs[0], DP.TestContext):
        test_node, *childs = childs
        test_instr = build_test_stmt(block, test_node)
        if len(childs) == 0:
            return test_instr

        assert len(childs) == 1 and isinstance(childs[0], DP.Comp_forContext)
        generator_node = childs[0]
        return build_generator_expr(block, test_instr, generator_node)

    else:  # either *args or **kwargs style var
        text = ast_node_text(childs[0])
        child_instr = build_test_stmt(block, childs[1])
        if text == "**":
            return KeyWordArgVar(block=block,
                                 ast_node=childs[1],
                                 child_instr=child_instr)
        else:
            return ArgListVar(block=block,
                              ast_node=childs[1],
                              child_instr=child_instr)
示例#2
0
def build_aug_assign_stmt(block, ast_node):
    # augassign_stmt: testlist_star_expr augassign (yield_expr | testlist);
    # augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=' | '**=' | '//=');

    left_instr = build_test_star_stmt(block, ast_node.children[0])
    aug_node = ast_node.children[1]

    if isinstance(ast_node.children[-1], DP.TestlistContext):
        right_instr = build_test_list(block, ast_node.children[-1])
    else:
        right_instr = build_yield_expr(block, ast_node.children[-1])

    # get the operator without the "=" at the end
    op_text = ast_node_text(aug_node)[:-1]
    op_cls = math_operator_classes[op_text]
    op_instr = op_cls(block=block,
                      ast_node=aug_node,
                      left_instr=left_instr,
                      right_instr=right_instr)
    block.add_instr(op_instr)

    assign = Assign(block=block,
                    ast_node=aug_node,
                    left_instr=left_instr,
                    right_instr=op_instr)
    block.add_instr(assign)

    return assign
示例#3
0
def build_if_statement(block, ast_node):
    #  if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ('else' ':' suite)?;
    childs = ast_node.children
    cond = build_test_stmt(block, childs[1])
    if_block = IfCondition(cond=cond, parent=block, ast_node=ast_node)
    build_suite(if_block, childs[3])

    childs = childs[4:]
    while childs:
        if ast_node_text(childs[0]) == 'else':
            else_block = ElseBlock(parent=block, ast_node=childs[0])
            if_block.else_block = else_block
            build_suite(else_block, childs[2])
            break
        else:
            cond = build_test_stmt(block, childs[1])
            elif_block = ElifCondition(parent=block,
                                       ast_node=childs[0],
                                       cond=cond)
            build_suite(elif_block, childs[3])
            childs = childs[4:]
            if_block.add_elif(elif_block)

    block.add_instr(if_block)
    return if_block
示例#4
0
def build_kw_args(block, ast_node):
    # named_kw_args: type_qual? '**' NAME ;
    type_qual = None
    if len(ast_node.children) > 2:
        type_qual = build_type_qual(block, ast_node.children[0])

    name = ast_node_text(ast_node.children[-1])
    return StarKwFuncArg(block, ast_node, name, type_qual)
示例#5
0
def build_type_qual(block, ast_node):
    # type_qual: NAME (template_def)? ;
    type_name = ast_node_text(ast_node.children[0])
    template_def = None
    if len(ast_node.children) > 1:
        template_def = build_template_def(block, ast_node.children[1])

    return TypeQualifier(block, ast_node, type_name, template_def)
示例#6
0
def build_atom(block, ast_node):
    child = ast_node.children[0]
    if isinstance(child, DP.LiteralContext):
        return build_literal(block, child)
    elif isinstance(child, DP.Bare_nameContext):
        return BareName(block, child, ast_node_text(child))
    elif isinstance(child, DP.Atom_list_exprContext):
        return build_atom_list_expr(block, child)
    elif isinstance(child, DP.Atom_dict_exprContext):
        return build_atom_dict_expr(block, child)
    else:
        raise_unknown_ast_node(block, child)
示例#7
0
def build_factor_expr(block, ast_node):
    if len(ast_node.children) == 1:
        return build_power_expr(block, ast_node.children[0])

    # factor: ('+' | '-' | '~') factor | power;
    op_node, right_node = ast_node.children
    right_expr = build_factor_expr(block, right_node)
    op_text = ast_node_text(op_node)
    instr_class = factor_operator_classes[op_text]
    instr = instr_class(block=block, ast_node=op_node, child_instr=right_expr)
    block.add_instr(instr)

    return instr
示例#8
0
def build_atom_trailer(block, atom, ast_node):
    # trailer: '('(arglist)? ')' | '[' subscriptlist ']' | '.' NAME;
    # Array / Dict subscript notation
    first_char = ast_node_text(ast_node.children[0])
    if first_char == '[':
        return build_subscript_list(block, atom, ast_node.children[1])
    elif first_char == '.':
        bare_name = BareName(block=block,
                             ast_node=ast_node.children[1],
                             text=ast_node_text(ast_node.children[1]))
        dot_op = DotOperator(block=block,
                             ast_node=ast_node,
                             left_instr=atom,
                             right_instr=bare_name)
        return dot_op
    elif first_char == '(':  # function call
        args = []
        if len(ast_node.children) == 3:
            args = build_func_arg_list(block, ast_node.children[1])
        return FuncCall(block=block,
                        ast_node=ast_node.children[0],
                        func_ptr_instr=atom,
                        args=args)
示例#9
0
def build_template_def(block, ast_node):
    # template_def: '<' (template_args)? '>' ;
    # template_args: NAME (',' NAME)* ','?;
    if len(ast_node.children) == 2:
        return TemplateDef(block, ast_node, [])

    args = ast_node.children[1].children
    arg_names = []
    while args:
        first_arg, *args = args
        arg_names.append(ast_node_text(first_arg))
        if args:
            comma_, *args = args

    return TemplateDef(block, ast_node, arg_names)
示例#10
0
def build_classdef(block, ast_node):
    # 'class' NAME ('(' (arglist)? ')')? ':' suite;
    class_name = ast_node_text(ast_node.children[1])

    supers = []
    for child in ast_node.children:
        if isinstance(child, DP.ArglistContext):
            supers = build_func_arg_list(block, child)
            break

    class_instr = ClassDef(parent=block,
                           ast_node=ast_node,
                           class_name=class_name,
                           supers=supers)
    class_instr.body = build_suite(class_instr, ast_node.children[-1])
    block.add_instr(class_instr)
示例#11
0
def build_term_expr(block, ast_node):
    # term: factor(('*' | '@' | '/' | '%' | '//') factor) *;
    left_expr = build_factor_expr(block, ast_node.children[0])
    if len(ast_node.children) == 1:
        return left_expr

    childs = ast_node.children[1:]
    while len(childs) > 0:
        op_node, right_node, *childs = childs
        right_expr = build_factor_expr(block, right_node)
        op_text = ast_node_text(op_node)
        instr_class = term_operator_classes[op_text]
        instr = instr_class(block=block,
                            ast_node=op_node,
                            left_instr=left_expr,
                            right_instr=right_expr)
        block.add_instr(instr)
        left_expr = instr

    return left_expr
示例#12
0
def build_arith_expr(block, ast_node):
    # arith_expr: term(('+' | '-') term) *;
    left_expr = build_term_expr(block, ast_node.children[0])
    if len(ast_node.children) == 1:
        return left_expr

    childs = ast_node.children[1:]
    while len(childs) > 0:
        op_node, right_node, *childs = childs
        right_expr = build_term_expr(block, right_node)
        op_text = ast_node_text(op_node)
        instr_class = arith_operator_classes[op_text]
        instr = instr_class(block=block,
                            ast_node=op_node,
                            left_instr=left_expr,
                            right_instr=right_expr)
        block.add_instr(instr)
        left_expr = instr

    return left_expr
示例#13
0
def build_named_arg(block, ast_node):
    # namedarg: type_qual? NAME ('=' test) ? ;
    childs = ast_node.children

    type_qual, default_value = None, None

    if isinstance(childs[0], DP.Type_qualContext):
        type_qual, *childs = childs
        type_qual = build_type_qual(block, type_qual)

    name, childs = ast_node_text(childs[0]), childs[1:]

    if childs:  # has a test statement
        default_value = build_test_stmt(block, childs[1])

    return NamedFuncArg(block=block,
                        ast_node=ast_node,
                        name=name,
                        type_qual=type_qual,
                        default_value=default_value)
示例#14
0
def build_comparison(block, ast_node):
    # comparison: expr (comp_op expr) *;
    child_instrs = []
    left_expr = build_expression(block, ast_node.children[0])
    operator_cls = None

    if len(ast_node.children) == 1:
        return left_expr
    # Will be multi-comparison, only chainable comparisons valid
    if len(ast_node.children) > 3:
        operator_lookup = multi_comparison_operator_classes
    # <left> <comp> <right>, all binary comparisons valid
    else:
        operator_lookup = binary_comparison_operator_classes

    for child in ast_node.children[1:]:
        if isinstance(child, DP.Comp_opsContext):
            op = ast_node_text(child)

            try:
                operator_cls = operator_lookup[op]
            except KeyError:
                raise ParseException(
                    f"Unrecognized comparison operator {op} at {ast_location_str(child)}"
                )
        else:
            right_expr = build_expression(block, child)
            operator_instr = operator_cls(block=block,
                                          ast_node=child,
                                          left_instr=left_expr,
                                          right_instr=right_expr)
            child_instrs.append(operator_instr)
            left_expr = right_expr

    if len(child_instrs) == 1:
        block.add_instr(child_instrs[0])
        return child_instrs[0]
    else:
        multi_comp = MultiComparison(block, ast_node, child_instrs)
        block.add_instr(multi_comp)
        return multi_comp
示例#15
0
def build_func_def(block, ast_node):
    # funcdef: 'def' NAME parameters ('->' test)? ':' suite;

    def_, func_name, params, *childs = ast_node.children
    *childs, colon_, suite = childs

    returns = None
    if childs:  # have unparsed tokens, is "-> <return>"
        arrow_, ret_type = childs
        returns = build_test_stmt(block, ret_type)

    name_instr = ast_node_text(func_name)
    params_instr = build_parameters(block, params)
    func = FuncDef(ast_node=ast_node,
                   parent=block,
                   name=name_instr,
                   params=params_instr,
                   returns=returns)
    func.body = build_suite(func, ast_node.children[-1])
    block.add_instr(func)
    return func