Ejemplo 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)
Ejemplo n.º 2
0
def compound_statement(tokens, symbol_table):  #: '{' statement*  '}'
    _, symbol_table = error_if_not_value(tokens,
                                         TOKENS.LEFT_BRACE), push(symbol_table)
    statement = symbol_table['__ statement __']
    while peek(tokens, TOKENS.RIGHT_BRACE) != TOKENS.RIGHT_BRACE:
        yield statement(tokens, symbol_table)
    _ = error_if_not_value(tokens, TOKENS.RIGHT_BRACE) and pop(symbol_table)
Ejemplo n.º 3
0
def type_name_or_unary_expression(tokens, symbol_table):
    symbol_table = push(symbol_table)
    set_rules(type_name_or_postfix_expression, rules(symbol_table['__ postfix_expression __']))
    symbol_table['__ postfix_expression __'] = type_name_or_postfix_expression
    unary_exp = symbol_table['__ unary_expression __'](tokens, symbol_table)
    _ = pop(symbol_table)
    return unary_exp
Ejemplo n.º 4
0
def loop_body(body, symbol_table, continue_instr, break_instr):
    symbol_table = push(symbol_table)
    statement, stack = imap(symbol_table.__getitem__, ('__ statement __', '__ stack __'))
    symbol_table['__ continue __'] = (continue_instr, stack.stack_pointer)
    symbol_table['__ break __'] = (break_instr, stack.stack_pointer)
    for instr in statement(body, symbol_table):
        yield instr
    _ = pop(symbol_table)
Ejemplo n.º 5
0
def type_name_or_postfix_expression(tokens, symbol_table):
    symbol_table = push(symbol_table)
    symbol_table['__ compound_literal __'] = type_name_or_compound_literal
    primary_exp = symbol_table['__ primary_expression __'](tokens, symbol_table)
    _ = pop(symbol_table)
    # pop 'type_name_or_compound_literal' and type_name_or_postfix_expression ...
    postfix_expression_rules = rules(symbol_table['__ postfix_expression __'])
    if not isinstance(primary_exp, CType):  # it must have being an expression ...
        while peek_or_terminal(tokens) in postfix_expression_rules:
            primary_exp = postfix_expression_rules[peek(tokens)](tokens, symbol_table, primary_exp)
    return primary_exp  # otherwise it must have being a type_name ...
Ejemplo n.º 6
0
def declarations(tokens, symbol_table):
    # storage_class_specifier? type_name? init_declarator_list (';' or compound_statement) # declaration
    storage_class_specifier, specifier_qualifier_list, statement = imap(
        symbol_table.__getitem__,
        ('__ storage_class_specifier __', '__ specifier_qualifier_list __',
         '__ statement __'))
    storage_class = storage_class_specifier(tokens, symbol_table)
    base_type = specifier_qualifier_list(tokens, symbol_table)

    expecting_token = TOKENS.SEMICOLON
    if peek_or_terminal(tokens) == TOKENS.SEMICOLON:
        yield EmptyDeclaration(loc(consume(tokens)), storage_class)
    elif peek_or_terminal(tokens) is terminal:
        raise_error(
            '{l} Expected TOKENS.COMMA TOKENS.EQUAL TOKENS.SEMICOLON TOKENS.LEFT_BRACE got `{got}`'
            .format(l=loc(peek(tokens, EOFLocation)), got=peek(tokens, '')))
    else:
        for dec in init_declarator_list(tokens,
                                        symbol_table,
                                        base_type=base_type,
                                        storage_class=storage_class):
            dec.storage_class = storage_class
            if isinstance(
                    storage_class, TypeDef
            ):  # init_declarator_list adds the symbol as a decl to symbol_table
                symbol_table[name(dec)] = (symbol_table.pop(
                    name(dec)) or 1) and c_type(dec)  # replace dec by ctype
            elif peek_or_terminal(
                    tokens) == TOKENS.LEFT_BRACE and not error_if_not_type(
                        c_type(dec), FunctionType):
                symbol_table = push(symbol_table)
                symbol_table.update(
                    chain(
                        imap(
                            lambda a: (
                                name(a), a
                            ),  # add non variable list parameters to the symbol table ...
                            ifilterfalse(
                                lambda c: isinstance(c_type(c), VAListType),
                                c_type(dec))),
                        (('__ RETURN_TYPE __', c_type(c_type(dec))),
                         ('__ LABELS __', SymbolTable()))))
                yield FunctionDefinition(dec,
                                         next(statement(tokens, symbol_table)))
                expecting_token = (pop(symbol_table) or 1) and ''
            else:
                yield dec
                expecting_token = TOKENS.SEMICOLON
        _ = expecting_token and error_if_not_value(tokens, expecting_token)
Ejemplo n.º 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)
Ejemplo n.º 8
0
def declarations(tokens, symbol_table):
    # storage_class_specifier? type_name? init_declarator_list (';' or compound_statement) # declaration
    storage_class_specifier, specifier_qualifier_list, statement = imap(
        symbol_table.__getitem__,
        ('__ storage_class_specifier __', '__ specifier_qualifier_list __', '__ statement __')
    )
    storage_class = storage_class_specifier(tokens, symbol_table)
    base_type = specifier_qualifier_list(tokens, symbol_table)

    expecting_token = TOKENS.SEMICOLON
    if peek_or_terminal(tokens) == TOKENS.SEMICOLON:
        yield EmptyDeclaration(loc(consume(tokens)), storage_class)
    elif peek_or_terminal(tokens) is terminal:
        raise_error('{l} Expected TOKENS.COMMA TOKENS.EQUAL TOKENS.SEMICOLON TOKENS.LEFT_BRACE got `{got}`'.format(
            l=loc(peek(tokens, EOFLocation)), got=peek(tokens, '')
        ))
    else:
        for dec in init_declarator_list(tokens, symbol_table, base_type=base_type, storage_class=storage_class):
            dec.storage_class = storage_class
            if isinstance(storage_class, TypeDef):  # init_declarator_list adds the symbol as a decl to symbol_table
                symbol_table[name(dec)] = (symbol_table.pop(name(dec)) or 1) and c_type(dec)  # replace dec by ctype
            elif peek_or_terminal(tokens) == TOKENS.LEFT_BRACE and not error_if_not_type(c_type(dec), FunctionType):
                symbol_table = push(symbol_table)
                symbol_table.update(chain(
                    imap(
                        lambda a: (name(a), a),  # add non variable list parameters to the symbol table ...
                        ifilterfalse(lambda c: isinstance(c_type(c), VAListType), c_type(dec))
                    ),
                    (('__ RETURN_TYPE __', c_type(c_type(dec))), ('__ LABELS __', SymbolTable()))
                ))
                yield FunctionDefinition(dec, next(statement(tokens, symbol_table)))
                expecting_token = (pop(symbol_table) or 1) and ''
            else:
                yield dec
                expecting_token = TOKENS.SEMICOLON
        _ = expecting_token and error_if_not_value(tokens, expecting_token)
Ejemplo n.º 9
0
 def _pop_symbol_table(symbol_table):  # Pop symbol table once we have gone through the whole body ...
     _ = pop(symbol_table)
     yield EmptyStatement()
Ejemplo n.º 10
0
 def pop_symbol_table(symbol_table, location=loc(
     dec)):  # pop symbol table once all binaries have being emitted
     yield (pop(symbol_table) or 1) and Pass(location)
Ejemplo n.º 11
0
def pop_macros(macros):
    yield (pop(macros) or 1) and empty_token
Ejemplo n.º 12
0
def compound_statement(tokens, symbol_table):  #: '{' statement*  '}'
    _, symbol_table = error_if_not_value(tokens, TOKENS.LEFT_BRACE), push(symbol_table)
    statement = symbol_table['__ statement __']
    while peek(tokens, TOKENS.RIGHT_BRACE) != TOKENS.RIGHT_BRACE:
        yield statement(tokens, symbol_table)
    _ = error_if_not_value(tokens, TOKENS.RIGHT_BRACE) and pop(symbol_table)
Ejemplo n.º 13
0
def pop_macros(macros):
    yield (pop(macros) or 1) and empty_token
Ejemplo n.º 14
0
 def pop_symbol_table(symbol_table, location=loc(dec)):  # pop symbol table once all binaries have being emitted
     yield (pop(symbol_table) or 1) and Pass(location)