Exemplo n.º 1
0
    def body(stmnt, symbol_table, end_switch):
        symbol_table = push(symbol_table)
        stack, statement = imap(symbol_table.__getitem__, ('__ stack __', '__ statement __'))
        symbol_table['__ break __'] = (end_switch, stack.stack_pointer)
        symbol_table['__ switch __'] = True

        allocation_table = []  # create an allocation table to update stack before jump in case of nested definitions
        switch_body_instrs = []
        cases = {'default': Offset(end_switch, loc(stmnt))}

        for instr in statement(stmnt.statement, symbol_table):
            if isinstance(getattr(instr, 'case', None), CaseStatement):
                start = Pass(loc(instr))
                allocation_table.append(
                    chain(
                        (start,),
                        update_stack(stmnt.stack.stack_pointer, instr.case.stack.stack_pointer, loc(instr)),
                        relative_jump(Offset(instr, loc(instr)), loc(instr)),
                    )
                )

                cases[error_if_not_type(exp(exp(instr.case)), (int, long, str))] = Offset(start, loc(instr))
                del instr.case
            switch_body_instrs.append(instr)

        max_switch_value = 2**(8*size_arrays_as_pointers(c_type(exp(stmnt)))) - 1
        for instr in jump_table(loc(stmnt), cases, allocation_table, max_switch_value, switch_body_instrs):
            yield instr
        _ = pop(symbol_table)
Exemplo n.º 2
0
def comma_expression(expr, symbol_table):
    expression = symbol_table['__ expression __']
    return chain(
        chain.from_iterable(
            chain(
                expression(e, symbol_table),
                allocate(
                    -size_arrays_as_pointers(c_type(e),
                                             overrides={VoidType: 0}), loc(e)))
            for e in exp(expr)[:-1]), expression(exp(expr)[-1], symbol_table))
Exemplo n.º 3
0
def constant_expression(tokens, symbol_table):
    _exp = symbol_table['__ logical_or_expression __'](tokens, symbol_table)

    # ENUM types ...
    if isinstance(_exp, IdentifierExpression) and isinstance(symbol_table.get(exp(_exp), type), ConstantExpression):
        _exp = symbol_table[exp(_exp)]

    if not isinstance(_exp, ConstantExpression):
        raise ValueError('{l} Expected a constant expression got {got}'.format(l=loc(_exp), got=_exp))
    return _exp
Exemplo n.º 4
0
def numeric_operator(value, expr, symbol_table):
    return symbol_table['__ expression __'](
        BinaryExpression(
            ConstantExpression(value, IntegerType(loc(expr)), loc(expr)),
            TOKENS.STAR,
            exp(expr),
            max(c_type(exp(expr)), IntegerType(loc(expr)))(loc(expr)),
            loc(expr),
        ),
        symbol_table,
    )
Exemplo n.º 5
0
def numeric_operator(value, expr, symbol_table):
    return symbol_table['__ expression __'](
        BinaryExpression(
            ConstantExpression(value, IntegerType(loc(expr)), loc(expr)),
            TOKENS.STAR,
            exp(expr),
            max(c_type(exp(expr)), IntegerType(loc(expr)))(loc(expr)),
            loc(expr),
        ),
        symbol_table,
    )
Exemplo n.º 6
0
def binary_exp(expr):
    if not all(imap(isinstance, (left_exp(expr), right_exp(expr)), repeat(ConstantExpression))):
        return expr

    exp_type = max(imap(c_type, (left_exp(expr), right_exp(expr))))(loc(expr))
    l_exp, r_exp, location = exp(left_exp(expr)), exp(right_exp(expr)), loc(expr)

    # noinspection PyUnresolvedReferences  '1 + 2 - 3 * 7 / 4'
    return binary_exp.rules[oper(expr)](
        expr=expr, left_exp=l_exp, right_exp=r_exp, location=location, exp_type=exp_type
    )
Exemplo n.º 7
0
def comma_expression(expr, symbol_table):
    expression = symbol_table['__ expression __']
    return chain(
        chain.from_iterable(
            chain(
                expression(e, symbol_table),
                allocate(-size_arrays_as_pointers(c_type(e), overrides={VoidType: 0}), loc(e))
            ) for e in exp(expr)[:-1]
        ),
        expression(exp(expr)[-1], symbol_table)
    )
Exemplo n.º 8
0
def while_statement(stmnt, symbol_table):
    start_of_loop, end_of_loop = imap(Pass, repeat(loc(stmnt), 2))
    return chain(
        (start_of_loop,),
        get_jump_false(size_arrays_as_pointers(c_type(exp(stmnt))))(
            symbol_table['__ expression __'](exp(stmnt), symbol_table), Offset(end_of_loop, loc(end_of_loop)), loc(end_of_loop)
        ),
        loop_body(stmnt.statement, symbol_table, start_of_loop, end_of_loop),
        relative_jump(Offset(start_of_loop, loc(start_of_loop)), loc(end_of_loop)),
        (end_of_loop,)
    )
Exemplo n.º 9
0
def do_while_statement(stmnt, symbol_table):
    start_of_loop, end_of_loop = Pass(loc(stmnt)), Pass(loc(stmnt))
    yield start_of_loop  # do while loops contain the update expression after their body ...
    for instr in loop_body(stmnt.statement, symbol_table, start_of_loop, end_of_loop):
        yield instr
    for instr in get_jump_true(size_arrays_as_pointers(c_type(exp(stmnt))))(
            symbol_table['__ expression __'](exp(stmnt), symbol_table),
            Offset(start_of_loop, loc(start_of_loop)),
            loc(start_of_loop)
    ):
        yield instr
    yield end_of_loop
Exemplo n.º 10
0
def constant_expression(tokens, symbol_table):
    _exp = symbol_table['__ logical_or_expression __'](tokens, symbol_table)

    # ENUM types ...
    if isinstance(_exp, IdentifierExpression) and isinstance(
            symbol_table.get(exp(_exp), type), ConstantExpression):
        _exp = symbol_table[exp(_exp)]

    if not isinstance(_exp, ConstantExpression):
        raise ValueError('{l} Expected a constant expression got {got}'.format(
            l=loc(_exp), got=_exp))
    return _exp
Exemplo n.º 11
0
 def dimensions(tokens):
     while peek(tokens) == TOKENS.LEFT_BRACKET:
         location = loc(consume(tokens))
         if peek(tokens) == TOKENS.RIGHT_BRACKET:
             size = None
         else:
             const_exp = constant_expression(tokens, symbol_table)
             _ = error_if_not_type(c_type(const_exp), IntegralType)
             if exp(const_exp) < 0:
                 raise ValueError('{l} array size is negative'.format(l=loc(const_exp)))
             size = exp(const_exp)
         _ = error_if_not_value(tokens, TOKENS.RIGHT_BRACKET)
         yield size, location
Exemplo n.º 12
0
 def dimensions(tokens):
     while peek(tokens) == TOKENS.LEFT_BRACKET:
         location = loc(consume(tokens))
         if peek(tokens) == TOKENS.RIGHT_BRACKET:
             size = None
         else:
             const_exp = constant_expression(tokens, symbol_table)
             _ = error_if_not_type(c_type(const_exp), IntegralType)
             if exp(const_exp) < 0:
                 raise ValueError(
                     '{l} array size is negative'.format(l=loc(const_exp)))
             size = exp(const_exp)
         _ = error_if_not_value(tokens, TOKENS.RIGHT_BRACKET)
         yield size, location
Exemplo n.º 13
0
def ternary_expression(expr, symbol_table):
    if_false_instr, end_of_conditional_instr = Pass(loc(expr)), Pass(loc(expr))
    expression = symbol_table['__ expression __']
    return chain(
        get_jump_false(size_arrays_as_pointers(c_type(exp(expr))))(
            expression(exp(expr), symbol_table),
            Offset(if_false_instr, loc(expr)),
            loc(expr)
        ),
        expression(left_exp(expr), symbol_table),
        relative_jump(Offset(end_of_conditional_instr, loc(end_of_conditional_instr)), loc(expr)),
        (if_false_instr,),
        expression(right_exp(expr), symbol_table),
        (end_of_conditional_instr,),
    )
Exemplo n.º 14
0
def ternary_expression(expr, symbol_table):
    if_false_instr, end_of_conditional_instr = Pass(loc(expr)), Pass(loc(expr))
    expression = symbol_table['__ expression __']
    return chain(
        get_jump_false(size_arrays_as_pointers(c_type(exp(expr))))(expression(
            exp(expr), symbol_table), Offset(if_false_instr, loc(expr)),
                                                                   loc(expr)),
        expression(left_exp(expr), symbol_table),
        relative_jump(
            Offset(end_of_conditional_instr, loc(end_of_conditional_instr)),
            loc(expr)),
        (if_false_instr, ),
        expression(right_exp(expr), symbol_table),
        (end_of_conditional_instr, ),
    )
Exemplo n.º 15
0
def switch_statement(stmnt, symbol_table):
    _ = (not isinstance(c_type(exp(stmnt)), IntegralType)) and raise_error(
        '{l} Expected an integral type got {g}'.format(g=c_type(exp(stmnt)),
                                                       l=loc(stmnt)))

    end_switch = Pass(loc(stmnt))
    stmnt.stack = deepcopy(symbol_table['__ stack __'])

    # if switch inside loop, only update end_instruct, since continue jumps to start of loop break goes to end of switch
    def body(stmnt, symbol_table, end_switch):
        symbol_table = push(symbol_table)
        stack, statement = imap(symbol_table.__getitem__,
                                ('__ stack __', '__ statement __'))
        symbol_table['__ break __'] = (end_switch, stack.stack_pointer)
        symbol_table['__ switch __'] = True

        allocation_table = [
        ]  # create an allocation table to update stack before jump in case of nested definitions
        switch_body_instrs = []
        cases = {'default': Offset(end_switch, loc(stmnt))}

        for instr in statement(stmnt.statement, symbol_table):
            if isinstance(getattr(instr, 'case', None), CaseStatement):
                start = Pass(loc(instr))
                allocation_table.append(
                    chain(
                        (start, ),
                        update_stack(stmnt.stack.stack_pointer,
                                     instr.case.stack.stack_pointer,
                                     loc(instr)),
                        relative_jump(Offset(instr, loc(instr)), loc(instr)),
                    ))

                cases[error_if_not_type(exp(exp(instr.case)),
                                        (int, long, str))] = Offset(
                                            start, loc(instr))
                del instr.case
            switch_body_instrs.append(instr)

        max_switch_value = 2**(8 *
                               size_arrays_as_pointers(c_type(exp(stmnt)))) - 1
        for instr in jump_table(loc(stmnt), cases, allocation_table,
                                max_switch_value, switch_body_instrs):
            yield instr
        _ = pop(symbol_table)

    return chain(symbol_table['__ expression __'](exp(stmnt), symbol_table),
                 body(stmnt, symbol_table, end_switch), (end_switch, ))
Exemplo n.º 16
0
def update_scalar_type_initializer(desig_expr, default_values):
    assert len(default_values) == 1
    expr, desig = exp(desig_expr), designation(desig_expr, 0)
    if desig != 0:
        logger.warning('Excess Elements in initializer ...')
    else:
        default_values[0] = cast(expr, c_type(default_values[0]))
Exemplo n.º 17
0
def update_scalar_type_initializer(desig_expr, default_values):
    assert len(default_values) == 1
    expr, desig = exp(desig_expr), designation(desig_expr, 0)
    if desig != 0:
        logger.warning('Excess Elements in initializer ...')
    else:
        default_values[0] = cast(expr, c_type(default_values[0]))
Exemplo n.º 18
0
def init_declarator(tokens,
                    symbol_table,
                    base_type=CType(''),
                    storage_class=None):
    # : declarator ('=' assignment_expression or initializer)?
    decl = set_core_type(
        symbol_table['__ declarator __'](tokens, symbol_table), base_type)
    if peek_or_terminal(tokens) == TOKENS.EQUAL and consume(tokens):
        decl = Definition(name(decl), c_type(decl),
                          EmptyExpression(c_type(decl)), loc(decl),
                          storage_class)
        symbol_table[name(
            decl
        )] = decl  # we have to add it to the symbol table for things like `int a = a;`
        expr = initializer_or_assignment_expression(tokens, symbol_table)
        # if declaration is an array type and the expression is of string_type then convert to initializer for parsing
        if isinstance(c_type(decl), ArrayType) and isinstance(
                c_type(expr), StringType):
            expr = Initializer(
                enumerate(exp(expr)),
                ArrayType(c_type(c_type(expr)), len(c_type(expr)), loc(expr)),
                loc(expr))
        decl.initialization = parse_initializer(expr, decl) if isinstance(
            expr, Initializer) else expr
    else:
        symbol_table[name(decl)] = decl = Declaration(name(decl), c_type(decl),
                                                      loc(decl))
    return decl
Exemplo n.º 19
0
def update_composite_type_initializer(desig_expr, default_values):
    desig = designation(desig_expr)
    if desig > default_values:
        logger.warning('Excess elements in initializer ...')
    else:
        assert len(default_values[desig]) == 1
        default_values[desig][0] = cast(exp(desig_expr), c_type(default_values[desig][0]))
Exemplo n.º 20
0
def binary_exp(expr):
    if not all(
            imap(isinstance, (left_exp(expr), right_exp(expr)),
                 repeat(ConstantExpression))):
        return expr

    exp_type = max(imap(c_type, (left_exp(expr), right_exp(expr))))(loc(expr))
    l_exp, r_exp, location = exp(left_exp(expr)), exp(
        right_exp(expr)), loc(expr)

    # noinspection PyUnresolvedReferences  '1 + 2 - 3 * 7 / 4'
    return binary_exp.rules[oper(expr)](expr=expr,
                                        left_exp=l_exp,
                                        right_exp=r_exp,
                                        location=location,
                                        exp_type=exp_type)
Exemplo n.º 21
0
def address_of(expr, symbol_table):
    instrs = symbol_table['__ expression __'](exp(expr), symbol_table)
    value = next(instrs)
    for instr in instrs:
        yield value
        value = instr
    if not isinstance(value, Loads):
        yield value
Exemplo n.º 22
0
def range_designated_expr(start, tokens, symbol_table):
    constant_expression = symbol_table['__ constant_expression __']
    end = error_if_not_value(tokens, TOKENS.ELLIPSIS) and NumericalDesignation(
        exp(constant_expression(tokens, symbol_table))
    )
    return error_if_not_value(tokens, TOKENS.RIGHT_BRACKET) and RangeDesignatedExpression(
        start, end, _expr_or_designated_expr(tokens, symbol_table), loc(end)
    )
Exemplo n.º 23
0
def parse_range_designated_expr(desig_expr, default_values):
    first, last = designation(desig_expr)
    exhaust(
        imap(
            parse_designated_expr,
            imap(OffsetDesignatedExpression, xrange(first, last + 1),
                 repeat(exp(desig_expr)), repeat(loc(desig_expr))),
            repeat(default_values)))
Exemplo n.º 24
0
def range_designated_expr(start, tokens, symbol_table):
    constant_expression = symbol_table['__ constant_expression __']
    end = error_if_not_value(tokens, TOKENS.ELLIPSIS) and NumericalDesignation(
        exp(constant_expression(tokens, symbol_table)))
    return error_if_not_value(
        tokens, TOKENS.RIGHT_BRACKET) and RangeDesignatedExpression(
            start, end, _expr_or_designated_expr(tokens, symbol_table),
            loc(end))
Exemplo n.º 25
0
def parse_identifier_designated_expr(desig_expr, default_values):
    return parse_designated_expr(
        OffsetDesignatedExpression(
            offset(c_type(default_values),
                   designation(desig_expr)),  # get offset ...
            exp(desig_expr),
            loc(desig_expr)),
        default_values)
Exemplo n.º 26
0
def update_composite_type_initializer(desig_expr, default_values):
    desig = designation(desig_expr)
    if desig > default_values:
        logger.warning('Excess elements in initializer ...')
    else:
        assert len(default_values[desig]) == 1
        default_values[desig][0] = cast(exp(desig_expr),
                                        c_type(default_values[desig][0]))
Exemplo n.º 27
0
def address_of(expr, symbol_table):
    instrs = symbol_table['__ expression __'](exp(expr), symbol_table)
    value = next(instrs)
    for instr in instrs:
        yield value
        value = instr
    if not isinstance(value, Loads):
        yield value
Exemplo n.º 28
0
def parse_range_designated_expr(desig_expr, default_values):
    first, last = designation(desig_expr)
    exhaust(
        imap(
            parse_designated_expr,
            imap(OffsetDesignatedExpression, xrange(first, last + 1), repeat(exp(desig_expr)), repeat(loc(desig_expr))),
            repeat(default_values)
        )
    )
Exemplo n.º 29
0
def parse_identifier_designated_expr(desig_expr, default_values):
    return parse_designated_expr(
        OffsetDesignatedExpression(
            offset(c_type(default_values), designation(desig_expr)),  # get offset ...
            exp(desig_expr),
            loc(desig_expr)
        ),
        default_values
    )
Exemplo n.º 30
0
def case(tokens, symbol_table):
    location = loc(loc(consume(tokens)))
    constant_expression, statement = imap(
        symbol_table.__getitem__,
        ('__ constant_expression __', '__ statement __'))
    expr = constant_expression(tokens, symbol_table)
    _, _ = error_if_not_value(tokens, TOKENS.COLON), error_if_not_type(
        c_type(expr), IntegralType)
    switch_cases = symbol_table['__ SWITCH STATEMENT __']
    switch_exp = symbol_table['__ SWITCH EXPRESSION __']
    if c_type(expr) != c_type(switch_exp):
        raise ValueError(
            '{l} case exp type {g} differs from switch exp type {e}'.format(
                l=location, g=c_type(expr), e=c_type(switch_exp)))
    switch_cases[exp(expr)] = CaseStatement(expr,
                                            statement(tokens, symbol_table),
                                            location)
    yield switch_cases[exp(expr)]
Exemplo n.º 31
0
def parse_designated_union_expr(desig_expr, default_values):
    # care must be taken when dealing with union initializer, they may only set a single expression ...
    ctype, desig, expr = c_type(default_values), designation(desig_expr), exp(desig_expr)

    if isinstance(expr, DesignatedExpression):
        parse_designated_expr(expr, default_values)
    elif isinstance(expr, Initializer):
        set_default_initializer(expr, default_values)
    else:
        default_values[0] = expr
Exemplo n.º 32
0
def parse_default_offset_designated_expr(desig_expr, default_values):
    ctype, desig, expr = c_type(default_values), designation(desig_expr), exp(desig_expr)

    if isinstance(expr, DesignatedExpression) and error_if_not_type(ctype, (StructType, ArrayType)):
        parse_designated_expr(expr, default_values[desig])
    elif isinstance(expr, Initializer):
        default_values = default_values[desig] if isinstance(ctype, (StructType, ArrayType)) else default_values
        set_default_initializer(expr, default_values)
    else:
        update_default_value(desig_expr, default_values)
Exemplo n.º 33
0
def offset_designated_expr(tokens, symbol_table):  # '[' positive_integral (... positive_integral)? ']'
    constant_expression = error_if_not_value(tokens, TOKENS.LEFT_BRACKET) and symbol_table['__ constant_expression __']
    designation = NumericalDesignation(exp(constant_expression(tokens, symbol_table)))

    if peek_or_terminal(tokens) == TOKENS.ELLIPSIS:
        return range_designated_expr(designation, tokens, symbol_table)

    return error_if_not_value(tokens, TOKENS.RIGHT_BRACKET) and OffsetDesignatedExpression(
        designation, _expr_or_designated_expr(tokens, symbol_table)
    )
Exemplo n.º 34
0
def inc_dec(expr, symbol_table):
    assert not isinstance(c_type(expr), ArrayType) and isinstance(
        c_type(expr), IntegralType)
    value = rules(inc_dec)[type(expr)]
    if isinstance(c_type(expr), PointerType):
        value *= size_extended(c_type(c_type(expr)))

    return get_postfix_update(size(c_type(expr)))(all_but_last(
        symbol_table['__ expression __'](exp(expr), symbol_table), Loads,
        loc(expr)), value, loc(expr))
Exemplo n.º 35
0
def inc_dec(value, expr, symbol_table):
    return symbol_table['__ expression __'](
        CompoundAssignmentExpression(
            exp(expr), TOKENS.PLUS_EQUAL,
            ConstantExpression(
                value, IntegerType(loc(expr), unsigned=unsigned(c_type(expr))),
                loc(expr)),
            c_type(expr)(loc(expr)), loc(expr)),
        symbol_table,
    )
Exemplo n.º 36
0
def switch_statement(stmnt, symbol_table):
    _ = (not isinstance(c_type(exp(stmnt)), IntegralType)) and raise_error(
        '{l} Expected an integral type got {g}'.format(g=c_type(exp(stmnt)), l=loc(stmnt))
    )

    end_switch = Pass(loc(stmnt))
    stmnt.stack = deepcopy(symbol_table['__ stack __'])

    # if switch inside loop, only update end_instruct, since continue jumps to start of loop break goes to end of switch
    def body(stmnt, symbol_table, end_switch):
        symbol_table = push(symbol_table)
        stack, statement = imap(symbol_table.__getitem__, ('__ stack __', '__ statement __'))
        symbol_table['__ break __'] = (end_switch, stack.stack_pointer)
        symbol_table['__ switch __'] = True

        allocation_table = []  # create an allocation table to update stack before jump in case of nested definitions
        switch_body_instrs = []
        cases = {'default': Offset(end_switch, loc(stmnt))}

        for instr in statement(stmnt.statement, symbol_table):
            if isinstance(getattr(instr, 'case', None), CaseStatement):
                start = Pass(loc(instr))
                allocation_table.append(
                    chain(
                        (start,),
                        update_stack(stmnt.stack.stack_pointer, instr.case.stack.stack_pointer, loc(instr)),
                        relative_jump(Offset(instr, loc(instr)), loc(instr)),
                    )
                )

                cases[error_if_not_type(exp(exp(instr.case)), (int, long, str))] = Offset(start, loc(instr))
                del instr.case
            switch_body_instrs.append(instr)

        max_switch_value = 2**(8*size_arrays_as_pointers(c_type(exp(stmnt)))) - 1
        for instr in jump_table(loc(stmnt), cases, allocation_table, max_switch_value, switch_body_instrs):
            yield instr
        _ = pop(symbol_table)

    return chain(
        symbol_table['__ expression __'](exp(stmnt), symbol_table), body(stmnt, symbol_table, end_switch), (end_switch,)
    )
Exemplo n.º 37
0
def parse_designated_union_expr(desig_expr, default_values):
    # care must be taken when dealing with union initializer, they may only set a single expression ...
    ctype, desig, expr = c_type(default_values), designation(desig_expr), exp(
        desig_expr)

    if isinstance(expr, DesignatedExpression):
        parse_designated_expr(expr, default_values)
    elif isinstance(expr, Initializer):
        set_default_initializer(expr, default_values)
    else:
        default_values[0] = expr
Exemplo n.º 38
0
def inc_dec(value, expr, symbol_table):
    return symbol_table['__ expression __'](
        CompoundAssignmentExpression(
            exp(expr),
            TOKENS.PLUS_EQUAL,
            ConstantExpression(value, IntegerType(loc(expr), unsigned=unsigned(c_type(expr))), loc(expr)),
            c_type(expr)(loc(expr)),
            loc(expr)
        ),
        symbol_table,
    )
Exemplo n.º 39
0
def inc_dec(expr, symbol_table):
    assert not isinstance(c_type(expr), ArrayType) and isinstance(c_type(expr), IntegralType)
    value = rules(inc_dec)[type(expr)]
    if isinstance(c_type(expr), PointerType):
        value *= size_extended(c_type(c_type(expr)))

    return get_postfix_update(size(c_type(expr)))(
        all_but_last(symbol_table['__ expression __'](exp(expr), symbol_table), Loads, loc(expr)),
        value,
        loc(expr)
    )
Exemplo n.º 40
0
def for_statement(stmnt, symbol_table):
    start_of_loop, end_of_loop, upd_expression = imap(Pass, repeat(loc(stmnt), 3))
    expression, statement, stack = imap(
        symbol_table.__getitem__, ('__ expression __', '__ statement __', '__ stack __')
    )
    return chain(
        statement(stmnt.init_exp, symbol_table),  # loop initialization.
        (start_of_loop,),  # start of conditional

        # loop invariant.
        get_jump_false(size_arrays_as_pointers(c_type(exp(stmnt))))(
            expression(exp(stmnt), symbol_table), Offset(end_of_loop, loc(end_of_loop)), loc(stmnt)
        ),

        loop_body(stmnt.statement, symbol_table, upd_expression, end_of_loop),

        (upd_expression,),
        statement(stmnt.upd_exp, symbol_table),  # loop update.
        relative_jump(Offset(start_of_loop, loc(start_of_loop)), loc(stmnt)),
        (end_of_loop,)
    )
Exemplo n.º 41
0
def if_statement(stmnt, symbol_table):
    end_of_if, end_of_else = Pass(loc(stmnt)), Pass(loc(stmnt))
    expression, statement = imap(symbol_table.__getitem__, ('__ expression __', '__ statement __'))
    for instr in chain(
        get_jump_false(size_arrays_as_pointers(c_type(exp(stmnt))))(
            expression(exp(stmnt), symbol_table), Offset(end_of_if, loc(end_of_if)), loc(end_of_if)
        ),
        statement(stmnt.statement, symbol_table)
    ):
        yield instr

    else_stmnt = stmnt.else_statement.statement
    if else_stmnt:
        for instr in chain(
            relative_jump(Offset(end_of_else, loc(end_of_else)), loc(stmnt)),
            (end_of_if,),
            statement(else_stmnt, symbol_table),
            (end_of_else,),
        ):
            yield instr
    else:
        yield end_of_if
Exemplo n.º 42
0
def parse_default_offset_designated_expr(desig_expr, default_values):
    ctype, desig, expr = c_type(default_values), designation(desig_expr), exp(
        desig_expr)

    if isinstance(expr, DesignatedExpression) and error_if_not_type(
            ctype, (StructType, ArrayType)):
        parse_designated_expr(expr, default_values[desig])
    elif isinstance(expr, Initializer):
        default_values = default_values[desig] if isinstance(
            ctype, (StructType, ArrayType)) else default_values
        set_default_initializer(expr, default_values)
    else:
        update_default_value(desig_expr, default_values)
Exemplo n.º 43
0
def if_statement(stmnt, symbol_table):
    end_of_if, end_of_else = Pass(loc(stmnt)), Pass(loc(stmnt))
    expression, statement = imap(symbol_table.__getitem__,
                                 ('__ expression __', '__ statement __'))
    for instr in chain(
            get_jump_false(size_arrays_as_pointers(c_type(exp(stmnt))))(
                expression(exp(stmnt), symbol_table),
                Offset(end_of_if, loc(end_of_if)), loc(end_of_if)),
            statement(stmnt.statement, symbol_table)):
        yield instr

    else_stmnt = stmnt.else_statement.statement
    if else_stmnt:
        for instr in chain(
                relative_jump(Offset(end_of_else, loc(end_of_else)),
                              loc(stmnt)),
            (end_of_if, ),
                statement(else_stmnt, symbol_table),
            (end_of_else, ),
        ):
            yield instr
    else:
        yield end_of_if
Exemplo n.º 44
0
def return_statement(stmnt, symbol_table):
    # TODO: check if we can omit the setting the return value if if it is immediately removed ...
    return_type = c_type(c_type(symbol_table['__ CURRENT FUNCTION __']))
    assert not isinstance(c_type(return_type), ArrayType)
    if isinstance(return_type, VoidType) or not exp(stmnt):
     # just return if void type or expr is empty or size of expression is zero.
        return return_instrs(loc(stmnt))

    return chain(
        cast(symbol_table['__ expression __'](exp(stmnt), symbol_table), c_type(exp(stmnt)), return_type, loc(stmnt)),
        set_instr(
            load(
                add(load_base_stack_pointer(loc(stmnt)), push(size(void_pointer_type), loc(stmnt)), loc(stmnt)),
                size(void_pointer_type),
                loc(stmnt)
            ),
            size(return_type),
            loc(stmnt)
        ),
        # TODO: see if we can remove the following instr, since pop_frame will reset the base and stack pointers
        # allocate(-size(return_type), loc(stmnt)),  # Set leaves the value on the stack
        return_instrs(loc(stmnt))
    )
Exemplo n.º 45
0
def update_default_value(desig_expr, default_values):
    ctype, desig, expr = c_type(default_values), designation(desig_expr), exp(desig_expr)
    if desig >= len(default_values):
        logger.warning(
            '{0} Excess element {1} {2} in initializer, it will be ignored ... '.format(
                loc(desig_expr), desig, expr
            ))
    else:
        _ = (not safe_type_coercion(c_type(expr), c_type(default_values[desig]))) and raise_error(
            '{l} Unable to coerce from {f} to {t}'.format(l=loc(expr), f=c_type(expr), t=c_type(default_values[desig]))
        )
        update_func = update_composite_type_initializer \
            if isinstance(ctype, (StructType, ArrayType)) else update_scalar_type_initializer
        update_func(desig_expr, default_values)
Exemplo n.º 46
0
def offset_designated_expr(
        tokens,
        symbol_table):  # '[' positive_integral (... positive_integral)? ']'
    constant_expression = error_if_not_value(
        tokens,
        TOKENS.LEFT_BRACKET) and symbol_table['__ constant_expression __']
    designation = NumericalDesignation(
        exp(constant_expression(tokens, symbol_table)))

    if peek_or_terminal(tokens) == TOKENS.ELLIPSIS:
        return range_designated_expr(designation, tokens, symbol_table)

    return error_if_not_value(
        tokens, TOKENS.RIGHT_BRACKET) and OffsetDesignatedExpression(
            designation, _expr_or_designated_expr(tokens, symbol_table))
Exemplo n.º 47
0
def init_declarator(tokens, symbol_table, base_type=CType(''), storage_class=None):
    # : declarator ('=' assignment_expression or initializer)?
    decl = set_core_type(symbol_table['__ declarator __'](tokens, symbol_table), base_type)
    if peek_or_terminal(tokens) == TOKENS.EQUAL and consume(tokens):
        decl = Definition(name(decl), c_type(decl), EmptyExpression(c_type(decl)), loc(decl), storage_class)
        symbol_table[name(decl)] = decl  # we have to add it to the symbol table for things like `int a = a;`
        expr = initializer_or_assignment_expression(tokens, symbol_table)
        # if declaration is an array type and the expression is of string_type then convert to initializer for parsing
        if isinstance(c_type(decl), ArrayType) and isinstance(c_type(expr), StringType):
            expr = Initializer(
                enumerate(exp(expr)), ArrayType(c_type(c_type(expr)), len(c_type(expr)), loc(expr)), loc(expr)
            )
        decl.initialization = parse_initializer(expr, decl) if isinstance(expr, Initializer) else expr
    else:
        symbol_table[name(decl)] = decl = Declaration(name(decl), c_type(decl), loc(decl))
    return decl
Exemplo n.º 48
0
def cast_exp(expr):
    if c_type(expr) == c_type(exp(expr)):
        return exp(expr)
    if isinstance(exp(expr), ConstantExpression) and not isinstance(c_type(exp(expr)), ArrayType):
        to_type = c_type(expr)
        expr = exp(expr)
        location = loc(expr)
        if isinstance(expr, EmptyExpression):
            return EmptyExpression(to_type, loc(expr))
        if isinstance(to_type, IntegralType):
            return ConstantExpression(int(exp(expr)), to_type(location), location)
        if isinstance(to_type, FloatType):
            return ConstantExpression(float(exp(expr)), to_type(location), location)
    return expr
Exemplo n.º 49
0
def update_default_value(desig_expr, default_values):
    ctype, desig, expr = c_type(default_values), designation(desig_expr), exp(
        desig_expr)
    if desig >= len(default_values):
        logger.warning(
            '{0} Excess element {1} {2} in initializer, it will be ignored ... '
            .format(loc(desig_expr), desig, expr))
    else:
        _ = (not safe_type_coercion(c_type(expr), c_type(
            default_values[desig]))) and raise_error(
                '{l} Unable to coerce from {f} to {t}'.format(
                    l=loc(expr),
                    f=c_type(expr),
                    t=c_type(default_values[desig])))
        update_func = update_composite_type_initializer \
            if isinstance(ctype, (StructType, ArrayType)) else update_scalar_type_initializer
        update_func(desig_expr, default_values)
Exemplo n.º 50
0
def exclamation_operator(expr, symbol_table):
    if not isinstance(c_type(exp(expr)), NumericType):
        raise ValueError('{l} exclamation operator only supports numeric types got {g}'.format(
            l=loc(expr), g=c_type(exp(expr))
        ))
    assert not isinstance(c_type(exp(expr)), ArrayType)
    expression = symbol_table['__ expression __']
    return get_compare(size_arrays_as_pointers(c_type(exp(expr))))(
        expression(exp(expr), symbol_table),
        expression(ConstantExpression(0, c_type(exp(expr))(loc(expr)), loc(expr),), symbol_table),
        loc(expr),
        (load_zero_flag(loc(expr)),)
    )
Exemplo n.º 51
0
def cast_exp(expr):
    if c_type(expr) == c_type(exp(expr)):
        return exp(expr)
    if isinstance(exp(expr), ConstantExpression) and not isinstance(
            c_type(exp(expr)), ArrayType):
        to_type = c_type(expr)
        expr = exp(expr)
        location = loc(expr)
        if isinstance(expr, EmptyExpression):
            return EmptyExpression(to_type, loc(expr))
        if isinstance(to_type, IntegralType):
            return ConstantExpression(int(exp(expr)), to_type(location),
                                      location)
        if isinstance(to_type, FloatType):
            return ConstantExpression(float(exp(expr)), to_type(location),
                                      location)
    return expr
Exemplo n.º 52
0
def parse_enum_members(tokens, symbol_table):
    constant_expression = symbol_table['__ constant_expression __']
    location, members, current_value = loc(consume(tokens)), OrderedDict(), 0

    while peek(tokens, TOKENS.RIGHT_BRACE) != TOKENS.RIGHT_BRACE:
        ident = error_if_not_type(consume(tokens, ''), IDENTIFIER)
        value = ConstantExpression(current_value, IntegerType(location), location)
        if peek_or_terminal(tokens) == TOKENS.EQUAL and consume(tokens):
            value = constant_expression(tokens, symbol_table)
            _ = error_if_not_type(c_type(value), IntegerType)
        current_value = error_if_not_type(exp(value), (int, long))

        symbol_table[ident] = value  # Add value to symbol_table
        members[ident] = Definition(ident, c_type(value), value, location)

        _ = peek_or_terminal(tokens) == TOKENS.COMMA and consume(tokens)
    _ = error_if_not_value(tokens, TOKENS.RIGHT_BRACE)

    return members
Exemplo n.º 53
0
def initializer_desig_exprs(initializer, default_values):
    previous_desig_offset_mag = -1
    for expr_or_desig_expr in initializer.itervalues():
        if not isinstance(expr_or_desig_expr, DesignatedExpression):  # assign default designation if none present ...
            expr_or_desig_expr = DefaultOffsetDesignationExpression(
                previous_desig_offset_mag + 1,  # use previous designation ...
                expr_or_desig_expr,
                loc(expr_or_desig_expr)
            )
        elif isinstance(expr_or_desig_expr, IdentifierDesignatedExpression):  # if designation is an identifier
            expr_or_desig_expr = OffsetDesignatedExpression(
                offset(c_type(default_values), designation(expr_or_desig_expr)),  # get offset ...
                exp(expr_or_desig_expr),
                loc(expr_or_desig_expr)
            )
        expand_defaults(expr_or_desig_expr, default_values)  # expand defaults for incomplete array types

        yield expr_or_desig_expr
        previous_desig_offset_mag = max_designation_mag(expr_or_desig_expr)  # record designation in case we need new 1
Exemplo n.º 54
0
def parse_enum_members(tokens, symbol_table):
    constant_expression = symbol_table['__ constant_expression __']
    location, members, current_value = loc(consume(tokens)), OrderedDict(), 0

    while peek(tokens, TOKENS.RIGHT_BRACE) != TOKENS.RIGHT_BRACE:
        ident = error_if_not_type(consume(tokens, ''), IDENTIFIER)
        value = ConstantExpression(current_value, IntegerType(location),
                                   location)
        if peek_or_terminal(tokens) == TOKENS.EQUAL and consume(tokens):
            value = constant_expression(tokens, symbol_table)
            _ = error_if_not_type(c_type(value), IntegerType)
        current_value = error_if_not_type(exp(value), (int, long))

        symbol_table[ident] = value  # Add value to symbol_table
        members[ident] = Definition(ident, c_type(value), value, location)

        _ = peek_or_terminal(tokens) == TOKENS.COMMA and consume(tokens)
    _ = error_if_not_value(tokens, TOKENS.RIGHT_BRACE)

    return members
Exemplo n.º 55
0
def exclamation_operator(expr, symbol_table):
    if not isinstance(c_type(exp(expr)), NumericType):
        raise ValueError(
            '{l} exclamation operator only supports numeric types got {g}'.
            format(l=loc(expr), g=c_type(exp(expr))))
    assert not isinstance(c_type(exp(expr)), ArrayType)
    expression = symbol_table['__ expression __']
    return get_compare(size_arrays_as_pointers(c_type(exp(expr))))(
        expression(exp(expr), symbol_table),
        expression(
            ConstantExpression(
                0,
                c_type(exp(expr))(loc(expr)),
                loc(expr),
            ), symbol_table), loc(expr), (load_zero_flag(loc(expr)), ))
Exemplo n.º 56
0
def initializer_desig_exprs(initializer, default_values):
    previous_desig_offset_mag = -1
    for expr_or_desig_expr in initializer.itervalues():
        if not isinstance(expr_or_desig_expr, DesignatedExpression
                          ):  # assign default designation if none present ...
            expr_or_desig_expr = DefaultOffsetDesignationExpression(
                previous_desig_offset_mag + 1,  # use previous designation ...
                expr_or_desig_expr,
                loc(expr_or_desig_expr))
        elif isinstance(expr_or_desig_expr, IdentifierDesignatedExpression
                        ):  # if designation is an identifier
            expr_or_desig_expr = OffsetDesignatedExpression(
                offset(c_type(default_values),
                       designation(expr_or_desig_expr)),  # get offset ...
                exp(expr_or_desig_expr),
                loc(expr_or_desig_expr))
        expand_defaults(
            expr_or_desig_expr,
            default_values)  # expand defaults for incomplete array types

        yield expr_or_desig_expr
        previous_desig_offset_mag = max_designation_mag(
            expr_or_desig_expr)  # record designation in case we need new 1
Exemplo n.º 57
0
    def body(stmnt, symbol_table, end_switch):
        symbol_table = push(symbol_table)
        stack, statement = imap(symbol_table.__getitem__,
                                ('__ stack __', '__ statement __'))
        symbol_table['__ break __'] = (end_switch, stack.stack_pointer)
        symbol_table['__ switch __'] = True

        allocation_table = [
        ]  # create an allocation table to update stack before jump in case of nested definitions
        switch_body_instrs = []
        cases = {'default': Offset(end_switch, loc(stmnt))}

        for instr in statement(stmnt.statement, symbol_table):
            if isinstance(getattr(instr, 'case', None), CaseStatement):
                start = Pass(loc(instr))
                allocation_table.append(
                    chain(
                        (start, ),
                        update_stack(stmnt.stack.stack_pointer,
                                     instr.case.stack.stack_pointer,
                                     loc(instr)),
                        relative_jump(Offset(instr, loc(instr)), loc(instr)),
                    ))

                cases[error_if_not_type(exp(exp(instr.case)),
                                        (int, long, str))] = Offset(
                                            start, loc(instr))
                del instr.case
            switch_body_instrs.append(instr)

        max_switch_value = 2**(8 *
                               size_arrays_as_pointers(c_type(exp(stmnt)))) - 1
        for instr in jump_table(loc(stmnt), cases, allocation_table,
                                max_switch_value, switch_body_instrs):
            yield instr
        _ = pop(symbol_table)
Exemplo n.º 58
0
def cast_expression(expr, symbol_table):
    return cast(symbol_table['__ expression __'](exp(expr), symbol_table),
                c_type(exp(expr)), c_type(expr), loc(expr))
Exemplo n.º 59
0
 def assert_base_element(self, element):
     machine_word_type = word_type_factories[get_word_type_name(c_type(element))]
     self.assertEqual(base_element(self.cpu, self.mem, machine_word_type), exp(element))