コード例 #1
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, ),
    )
コード例 #2
0
ファイル: constant.py プロジェクト: mzsk/c_compiler
def const_string_expr(expr):  # strings are embedded ...
    data = static_binaries(expr)
    _initial_data = peek(data)  # there should be at least one char, '\0'
    _push = push(Address(_initial_data, loc(expr)), loc(expr))
    return chain(
        relative_jump(Offset(peek(_push, loc(expr)), loc(expr)), loc(expr)),
        consume_all(data, _push))
コード例 #3
0
def goto_statement(stmnt, symbol_table):
    labels, gotos, stack = imap(symbol_table.__getitem__, ('__ LABELS __', '__ GOTOS __', '__ stack __'))

    if stmnt.label in labels:  # Label previously defined either in current or previous scope ... nothing to do ...
        instr, stack_pointer = labels[stmnt.label]
        instrs = chain(
            update_stack(stack_pointer, stack.stack_pointer, loc(stmnt)),
            relative_jump(Offset(instr, loc(stmnt)), loc(stmnt))
        )
    else:
        # Label has yet to be defined ...
        # Basically we need to update the relative jump and the amount to which we need to update the stack ...
        # TODO: find/use a better approach, we can't use Address since it'll be translated ...
        alloc_instr = Allocate(loc(stmnt), Offset(Integer(0), loc(stmnt)))
        jump_instr = RelativeJump(loc(stmnt), Offset(None, loc(stmnt)))

        gotos[stmnt.label].append((alloc_instr, jump_instr, stack.stack_pointer))
        instrs = (alloc_instr, jump_instr)

    return instrs
コード例 #4
0
def continue_statement(stmnt, symbol_table):
    try:
        instr, stack_pointer = symbol_table['__ continue __']
    except KeyError as _:
        raise ValueError('{l} continue statement outside loop statement, could not calc jump addr'.format(
            l=loc(stmnt)
        ))
    return chain(
        update_stack(symbol_table['__ stack __'].stack_pointer, stack_pointer, loc(stmnt)),
        relative_jump(Offset(instr, loc(stmnt)), loc(stmnt))
    )
コード例 #5
0
ファイル: statement.py プロジェクト: mzsk/c_compiler
def static_definition(stmnt, symbol_table):
    def load_address(self, location):
        return push(Address(self._initial_data, location), location)

    data = static_def_binaries(stmnt, (Pass(loc(stmnt)),))
    stmnt._initial_data = peek(data)
    stmnt.end_of_data = Pass(loc(stmnt))
    stmnt.load_address = bind_load_address_func(load_address, stmnt)
    symbol_table[declarations.name(stmnt)] = stmnt
    return chain(  # jump over embedded data ...
        relative_jump(Offset(stmnt.end_of_data, loc(stmnt)), loc(stmnt)), consume_all(data), (stmnt.end_of_data,)
    )
コード例 #6
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
コード例 #7
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)
コード例 #8
0
def call_function(function_call_expr, symbol_table):
    l, expr = loc(function_call_expr), left_exp(function_call_expr)
    return chain(  # if expression is a simple identifier of function type, no need for AbsoluteJump, use RelativeJump
        set_base_stack_pointer(load_stack_pointer(l), l),
        relative_jump(
            Offset(symbol_table[name(expr)].get_address_obj(l).obj, l), l),
    ) if isinstance(expr, IdentifierExpression) and isinstance(
        c_type(expr), FunctionType
    ) else absolute_jump(
        chain(
            symbol_table['__ expression __'](
                expr, symbol_table),  # load callee address
            # calculate new base stack pointer excluding the callees address ...
            # give the callee a new frame... if we where to reset the base stack ptr before evaluating the left_expr
            # we run the risk of failing to properly load function address if it was store as a local function pointer
            set_base_stack_pointer(
                add(load_stack_pointer(l), push(size(void_pointer_type), l),
                    l), l)),
        l)