Пример #1
0
    def binaries(body, symbol_table):
        symbol_table = push(symbol_table)
        symbol_table['__ stack __'] = Stack()  # Each function call has its own Frame which is nothing more than a stack

        # Skip return address ...
        offset = size_arrays_as_pointers(void_pointer_type) + (
            # if function has zero return size then the return pointer will be omitted ...
            size_arrays_as_pointers(void_pointer_type) *
            bool(size_arrays_as_pointers(c_type(c_type(dec)), overrides={VoidType: 0}))
        )

        for parameter in c_type(dec):
            # monkey patch declarator objects add Load commands according to stack state; add to symbol table.
            symbol_table[name(parameter)] = bind_instructions(parameter, offset)
            assert not type(parameter) is ArrayType  # TODO: fix this.
            offset += size_arrays_as_pointers(c_type(parameter))

        symbol_table.update(
            izip(('__ CURRENT FUNCTION __', '__ LABELS __', '__ GOTOS __'), (dec, SymbolTable(), defaultdict(list)))
        )

        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)

        return chain(   # body of function ...
            chain.from_iterable(imap(symbol_table['__ statement __'], chain.from_iterable(body), repeat(symbol_table))),
            return_instrs(loc(dec)),        # default return instructions, in case one was not giving ...
            pop_symbol_table(symbol_table)  # pop symbol_table once complete ...
        )
Пример #2
0
def non_static_pointer_typed_definition_initialized_by_array_type(stmnt, symbol_table):
    stack, expression = utils.symbol_table.get_symbols(symbol_table, '__ stack __', '__ expression __')
    expr = declarations.initialization(stmnt)
    assert not isinstance(expr, (expressions.Initializer, expressions.CompoundLiteral))
    return chain(  # evaluate stack expression, which will push values on the stack and initialized pointer with sp
        cast(expression(expr, symbol_table), c_type(expr), c_type(stmnt), loc(stmnt)), load_stack_pointer(loc(stmnt))
    )
Пример #3
0
def element_selection(expr, symbol_table):
    instrs = symbol_table['__ expression __'](left_exp(expr), symbol_table)
    # if we are loading the structure then just remove the Load instr, calculate the elements offset and Load that elem
    if is_load(instrs):
        return element_instrs(c_type(left_exp(expr)),
                              right_exp(expr),
                              loc(expr),
                              load_instrs=all_but_last(instrs, Loads,
                                                       loc(expr)))

    struct_size, member_size = size(c_type(
        left_exp(expr))), size_arrays_as_pointers(c_type(expr))
    addr_instrs = add(  # calculate the loaded structured members address
        load_stack_pointer(loc(expr)),
        push(struct_member_offset(c_type(left_exp(expr)), right_exp(expr)),
             loc(expr)), loc(expr))
    return chain(  # copy the element then move it to the base of the structure and deallocate everything else
        set_instr(
            chain(  # load the value in question if its not an array (which is just an address ...)
                (addr_instrs if isinstance(c_type(expr), ArrayType) else load(
                    addr_instrs, member_size, loc(expr))),
                add(load_stack_pointer(loc(expr)),
                    push((struct_size + member_size), loc(expr)), loc(expr)),
            ),
            member_size,
            loc(expr)),
        allocate(-(struct_size - member_size), loc(
            expr))  # deallocate structure and copied member (set leaves value)
    )
Пример #4
0
 def __init__(self, left_exp, operator, right_exp, ctype, location=LocationNotSet):
     # error_if_not_assignable(left_exp, location) TODO: implement.
     if not safe_type_coercion(c_type(right_exp), c_type(left_exp)) or isinstance(c_type(left_exp), ArrayType):
         raise ValueError('{l} Cannot assign from type {from_type} to {to_type}'.format(
             l=location, from_type=c_type(right_exp), to_type=c_type(left_exp),
         ))
     super(AssignmentExpression, self).__init__(left_exp, operator, right_exp, ctype, location)
Пример #5
0
def element_selection(expr, symbol_table):
    instrs = symbol_table['__ expression __'](left_exp(expr), symbol_table)
    # if we are loading the structure then just remove the Load instr, calculate the elements offset and Load that elem
    if is_load(instrs):
        return element_instrs(
            c_type(left_exp(expr)), right_exp(expr), loc(expr), load_instrs=all_but_last(instrs, Loads, loc(expr))
        )

    struct_size, member_size = size(c_type(left_exp(expr))), size_arrays_as_pointers(c_type(expr))
    addr_instrs = add(  # calculate the loaded structured members address
        load_stack_pointer(loc(expr)),
        push(struct_member_offset(c_type(left_exp(expr)), right_exp(expr)), loc(expr)),
        loc(expr)
    )
    return chain(  # copy the element then move it to the base of the structure and deallocate everything else
        set_instr(
            chain(  # load the value in question if its not an array (which is just an address ...)
                (addr_instrs if isinstance(c_type(expr), ArrayType) else load(addr_instrs, member_size, loc(expr))),
                add(load_stack_pointer(loc(expr)), push((struct_size + member_size), loc(expr)), loc(expr)),
            ),
            member_size,
            loc(expr)
        ),
        allocate(-(struct_size - member_size), loc(expr))  # deallocate structure and copied member (set leaves value)
    )
Пример #6
0
def arguments(func_type):
    return chain(
        takewhile(lambda arg: not isinstance(c_type(arg), VAListType),
                  func_type),  # emit all non-variable arguments ...
        takewhile(lambda arg: isinstance(c_type(arg), VAListType),
                  repeat(func_type[-1]))  # continuously emit last parameter
    )
Пример #7
0
def element_section_pointer(expr, symbol_table):
    return element_instrs(
        c_type(c_type(left_exp(expr))),
        right_exp(expr),
        loc(expr),
        load_instrs=symbol_table['__ expression __'](left_exp(expr), symbol_table)
    )
Пример #8
0
 def __init__(self, c_decl, body):
     _ = error_if_not_type(c_type(c_decl), FunctionType)
     if not all(isinstance(arg, Declarator) for arg in c_type(c_decl)):
         raise ValueError('{l} FunctionDef must have concrete declarators as params'.format(l=loc(c_type(c_decl))))
     if not isinstance(body, CompoundStatement):
         raise ValueError('{l} FunctionDef body is not a compound statement, got {g}'.format(l=loc(c_decl), g=body))
     super(FunctionDefinition, self).__init__(name(c_decl), c_type(c_decl), body, loc(c_decl), c_decl.storage_class)
Пример #9
0
def non_static_default_typed_definition(stmnt, symbol_table):
    return cast(
        symbol_table['__ expression __'](declarations.initialization(stmnt), symbol_table),
        c_type(declarations.initialization(stmnt)),
        c_type(stmnt),
        loc(stmnt)
    )
Пример #10
0
def argument_address(func_type, cpu, mem):
    index = size(void_pointer_type) + (size(void_pointer_type) if size(
        c_type(c_type(func_type)), overrides={VoidType: 0}) else 0)

    for ctype in imap(c_type, func_type):
        yield cpu.base_pointer + index
        index += size(ctype)
Пример #11
0
def get_declaration_or_definition(decl, storage_class):
    _ = initialization(decl) and isinstance(storage_class, Extern) and raise_error(
        '{l} {ident} has both initialization expr and extern storage class'.format(l=loc(decl), ident=name(decl)))

    if isinstance(c_type(decl), (FunctionType, StructType)) and not name(decl) or isinstance(storage_class, Extern):
        return Declaration(name(decl), c_type(decl), loc(decl), storage_class)

    return Definition(name(decl), c_type(decl), initialization(decl), loc(decl), storage_class or Auto(loc(decl)))
Пример #12
0
def function_call(tokens, symbol_table, primary_exp):
    l = loc(consume(tokens))
    func_type = error_if_not_type(c_type(c_type(primary_exp)), FunctionType)
    # get expression arguments.
    expression_argument_list = ArgumentExpressionList(tuple(get_args(tokens, symbol_table, func_type)), l)
    return error_if_not_value(tokens, TOKENS.RIGHT_PARENTHESIS) and FunctionCallExpression(
        primary_exp, expression_argument_list, c_type(func_type)(l), l
    )
Пример #13
0
def dot_oper(tokens, symbol_table, primary_exp):
    l = (error_if_not_type(c_type(primary_exp),
                           (StructType, UnionType)) or 1) and loc(
                               consume(tokens))
    member_name = error_if_not_type(consume(tokens, ''), IDENTIFIER)
    return ElementSelectionExpression(
        primary_exp, member_name,
        c_type(member(c_type(primary_exp), member_name))(l), l)
Пример #14
0
def definition(dec, symbol_table):  # Global definition.
    assert not isinstance(c_type(dec), FunctionType)
    symbol_table[name(dec)] = bind_load_instructions(dec)
    symbol_table[name(dec)].symbol = Data(  # Add reference of symbol to definition to keep track of references
        # static binaries, (packed binaries since machine may require alignment ...)
        name(dec), static_def_binaries(dec), size(c_type(dec)), dec.storage_class, loc(dec),
    )
    return symbol_table[name(dec)].symbol
Пример #15
0
def argument_address(func_type, cpu, mem):
    index = size(void_pointer_type) + (
        size(void_pointer_type) if size(c_type(c_type(func_type)), overrides={VoidType: 0}) else 0
    )

    for ctype in imap(c_type, func_type):
        yield cpu.base_pointer + index
        index += size(ctype)
Пример #16
0
def declaration(stmnt, symbol_table):
    # This are non-global declarations they don't require any space
    # but they could be referenced (extern, or function type)
    symbol_type = Code if isinstance(c_type(stmnt), FunctionType) else Data
    stmnt.symbol = symbol_type(declarations.name(stmnt), (), None, stmnt.storage_class, loc(stmnt))
    stmnt.symbol.size = size(c_type(stmnt), overrides={FunctionType: None})
    symbol_table[declarations.name(stmnt)] = stmnt
    yield Pass(loc(stmnt))
Пример #17
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,
    )
Пример #18
0
def expand_defaults(desig_expr, default_values):
    desig, ctype = max_designation_mag(desig_expr), c_type(default_values)

    length_diff = getattr(ctype, 'length',
                          0) is None and (desig - len(default_values) + 1)
    _ = length_diff > 0 and default_values.update(  # expand defaults if incomplete ArrayType ...
        enumerate(
            initializer_defaults(ArrayType(c_type(ctype),
                                           length_diff)).itervalues(),
            len(default_values)))
Пример #19
0
def subscript_oper(tokens, symbol_table, primary_exp):
    location = error_if_not_type(c_type(primary_exp), PointerType) and loc(
        consume(tokens))
    expr = symbol_table['__ expression __'](
        tokens, symbol_table)  # subscript must be of Integral Type.
    _ = error_if_not_value(tokens, TOKENS.RIGHT_BRACKET) and error_if_not_type(
        c_type(expr), IntegralType)
    return ArraySubscriptingExpression(primary_exp, expr,
                                       c_type(c_type(primary_exp))(location),
                                       location)
Пример #20
0
def function_call(tokens, symbol_table, primary_exp):
    l = loc(consume(tokens))
    func_type = error_if_not_type(c_type(c_type(primary_exp)), FunctionType)
    # get expression arguments.
    expression_argument_list = ArgumentExpressionList(
        tuple(get_args(tokens, symbol_table, func_type)), l)
    return error_if_not_value(
        tokens, TOKENS.RIGHT_PARENTHESIS) and FunctionCallExpression(
            primary_exp, expression_argument_list,
            c_type(func_type)(l), l)
Пример #21
0
def identifier_expression(expr, symbol_table):
    # Defaults to Load, assignment expression will update it to set.
    dec = symbol_table[name(expr)]
    if isinstance(
            c_type(dec),
        (FunctionType,
         ArrayType)):  # Function/Array Types are nothing more than addresses.
        return dec.load_address(loc(expr))
    return load(dec.load_address(loc(expr)),
                size_arrays_as_pointers(c_type(expr)), loc(expr))
Пример #22
0
def __return__(value,
               cpu,
               mem,
               os,
               func_signature=FunctionType(IntegerType(SysCallLocation), (),
                                           SysCallLocation)):
    cpu.instr_pointer = mem[cpu.base_pointer +
                            word_size]  # get return instruction ...
    assert size(c_type(c_type(func_signature))) == word_size
    mem[cpu.base_pointer + 2 * word_size] = value
Пример #23
0
def convert_declaration_to_definition(decl):
    _ = isinstance(decl, FunctionDefinition) and raise_error(
        '{l} Nested function definitions are not allowed.'.format(l=loc(decl)))
    # Non Function declaration without storage class is set to auto
    if type(decl) is Declaration and not isinstance(
            c_type(decl), FunctionType) and decl.storage_class is not Extern:
        decl = Definition(  # all non-function-declarations within compound statements are definitions ...
            name(decl), c_type(decl), EmptyExpression(c_type(decl), loc(decl)),
            loc(decl), decl.storage_class or Auto(loc(decl)))
    return decl
Пример #24
0
def subtract(l_instrs, r_instrs, location, operand_types):
    exp_c_type, left_exp_c_type, right_exp_c_type = operand_types
    if all(imap(isinstance, operand_types[1:], repeat(PointerType))):  # subtracting two pointers ...
        return divide(
            subtract.rules[base_c_type(void_pointer_type)][size(void_pointer_type)](l_instrs, r_instrs, location),
            push(size_extended(c_type(c_type(left_exp_c_type))), location),
            location,
            operand_types
        )

    return pointer_arithmetic(l_instrs, r_instrs, location, operand_types)
Пример #25
0
def assign(expr, symbol_table):
    expression = symbol_table['__ expression __']
    return set_instr(
        chain(
            cast(expression(right_exp(expr), symbol_table), c_type(right_exp(expr)), c_type(expr), loc(expr)),
            # remove default Load instruction, emit Set instruction ...
            all_but_last(expression(left_exp(expr), symbol_table), Loads, loc(expr)),
        ),
        size_arrays_as_pointers(c_type(expr)),  # get the size exp returns an array make sure its treated as pointer ...
        loc(expr),
    )
Пример #26
0
def calculate_pointer_offset(instrs, pointer_type, location):
    return multiply(
        instrs,
        push(size_extended(c_type(pointer_type)), location),
        location,
        (
            PointerType(c_type(pointer_type), location=location),
            pointer_type,
            LongType(LongType(location=location), location=location, unsigned=True)
        )
    )
Пример #27
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,
    )
Пример #28
0
def convert_declaration_to_definition(decl):
    _ = isinstance(decl, FunctionDefinition) and raise_error(
        '{l} Nested function definitions are not allowed.'.format(l=loc(decl)))
    # Non Function declaration without storage class is set to auto
    if type(decl) is Declaration and not isinstance(c_type(decl), FunctionType) and decl.storage_class is not Extern:
        decl = Definition(  # all non-function-declarations within compound statements are definitions ...
            name(decl),
            c_type(decl),
            EmptyExpression(c_type(decl), loc(decl)),
            loc(decl),
            decl.storage_class or Auto(loc(decl))
        )
    return decl
Пример #29
0
def get_declaration_or_definition(decl, storage_class):
    _ = initialization(decl) and isinstance(
        storage_class, Extern) and raise_error(
            '{l} {ident} has both initialization expr and extern storage class'
            .format(l=loc(decl), ident=name(decl)))

    if isinstance(c_type(decl),
                  (FunctionType, StructType)) and not name(decl) or isinstance(
                      storage_class, Extern):
        return Declaration(name(decl), c_type(decl), loc(decl), storage_class)

    return Definition(name(decl), c_type(decl), initialization(decl),
                      loc(decl), storage_class or Auto(loc(decl)))
Пример #30
0
def set_default_initializer(initializer, default_values):
    # Complete ArrayTypes with initializer containing a single non designated expression assign the value through out
    if isinstance(c_type(default_values), ArrayType) \
            and not isinstance(initializer[0], DesignatedExpression) \
            and len(initializer) == 1 \
            and c_type(default_values).length is not None:
        initializer = Initializer(
            enumerate(repeat(initializer[0], len(c_type(default_values)))),
            c_type(default_values)(loc(initializer)),
            loc(initializer)
        )
    exhaust(imap(parse_designated_expr, initializer_desig_exprs(initializer, default_values), repeat(default_values)))
    return default_values
Пример #31
0
 def __init__(self, c_decl, body):
     _ = error_if_not_type(c_type(c_decl), FunctionType)
     if not all(isinstance(arg, Declarator) for arg in c_type(c_decl)):
         raise ValueError(
             '{l} FunctionDef must have concrete declarators as params'.
             format(l=loc(c_type(c_decl))))
     if not isinstance(body, CompoundStatement):
         raise ValueError(
             '{l} FunctionDef body is not a compound statement, got {g}'.
             format(l=loc(c_decl), g=body))
     super(FunctionDefinition,
           self).__init__(name(c_decl), c_type(c_decl), body, loc(c_decl),
                          c_decl.storage_class)
Пример #32
0
def defaults(ctype, designations=None):
    designations = designations or OrderedDict()
    if isinstance(ctype, NumericType):
        designations[0] = ConstantExpression(0, ctype(loc(ctype)), loc(ctype))
    elif isinstance(ctype, ArrayType):
        for index in xrange(len(ctype)):
            designations[index] = defaults(c_type(ctype))
    elif isinstance(ctype, StructType):
        for offset, member_name in enumerate(ctype.members):
            designations[offset] = defaults(c_type(ctype.members[member_name]))
    else:
        raise ValueError('{l} Unable to generate default expression for ctype {c}'.format(l=loc(ctype), c=ctype))
    return designations
Пример #33
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)),)
    )
Пример #34
0
def get_binary_expression(tokens, symbol_table, l_exp, right_exp_func, exp_type):
    operator = consume(tokens)
    r_exp = right_exp_func(tokens, symbol_table)

    exp_type = max(imap(error_if_not_type, imap(c_type, (l_exp, r_exp)), repeat(exp_type)))
    if operator in LOGICAL_OPERATIONS:
        exp_type = logical_type

    if operator not in supported_operations(c_type(l_exp)):
        raise ValueError('{l} ctype {g} does not support {o}'.format(l=loc(l_exp), g=c_type(l_exp), o=operator))
    if operator not in supported_operations(c_type(r_exp)):
        raise ValueError('{l} ctype {g} does not support {o}'.format(l=loc(r_exp), g=c_type(r_exp), o=operator))

    return BinaryExpression(l_exp, operator, r_exp, exp_type(location=loc(operator)), loc(operator))
Пример #35
0
def definition(dec, symbol_table):  # Global definition.
    assert not isinstance(c_type(dec), FunctionType)
    symbol_table[name(dec)] = bind_load_instructions(dec)
    symbol_table[name(
        dec
    )].symbol = Data(  # Add reference of symbol to definition to keep track of references
        # static binaries, (packed binaries since machine may require alignment ...)
        name(dec),
        static_def_binaries(dec),
        size(c_type(dec)),
        dec.storage_class,
        loc(dec),
    )
    return symbol_table[name(dec)].symbol
Пример #36
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
Пример #37
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
Пример #38
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)
Пример #39
0
def set_default_initializer(initializer, default_values):
    # Complete ArrayTypes with initializer containing a single non designated expression assign the value through out
    if isinstance(c_type(default_values), ArrayType) \
            and not isinstance(initializer[0], DesignatedExpression) \
            and len(initializer) == 1 \
            and c_type(default_values).length is not None:
        initializer = Initializer(
            enumerate(repeat(initializer[0], len(c_type(default_values)))),
            c_type(default_values)(loc(initializer)), loc(initializer))
    exhaust(
        imap(parse_designated_expr,
             initializer_desig_exprs(initializer, default_values),
             repeat(default_values)))
    return default_values
Пример #40
0
def defaults(ctype, designations=None):
    designations = designations or OrderedDict()
    if isinstance(ctype, NumericType):
        designations[0] = ConstantExpression(0, ctype(loc(ctype)), loc(ctype))
    elif isinstance(ctype, ArrayType):
        for index in xrange(len(ctype)):
            designations[index] = defaults(c_type(ctype))
    elif isinstance(ctype, StructType):
        for offset, member_name in enumerate(ctype.members):
            designations[offset] = defaults(c_type(ctype.members[member_name]))
    else:
        raise ValueError(
            '{l} Unable to generate default expression for ctype {c}'.format(
                l=loc(ctype), c=ctype))
    return designations
Пример #41
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)), ))
Пример #42
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, ))
Пример #43
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]))
Пример #44
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]))
Пример #45
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)
Пример #46
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]))
Пример #47
0
def func_type(expr):
    if isinstance(c_type(expr), FunctionType):
        return c_type(expr)
    elif isinstance(c_type(expr), PointerType) and isinstance(c_type(c_type(expr)), FunctionType):
        return c_type(c_type(expr))
    else:
        raise ValueError('{l} Expected FunctionType or Pointer to FunctionType got {g}'.format(
            l=loc(expr), g=c_type(expr)
        ))
Пример #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
Пример #49
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]))
Пример #50
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)
Пример #51
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)
Пример #52
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
    )
Пример #53
0
def statement(stmnt, symbol_table):
    is_expression = isinstance(stmnt, expressions.Expression)

    # Set entry point to False if its an expression or use statement function if present otherwise None.
    instrs = rules(statement)[type(stmnt)](stmnt, symbol_table)
    # Almost all Expression statements leave a value on the stack, so we must remove it.
    if stmnt and is_expression:
        instrs = chain(instrs, allocate(-size(c_type(stmnt), overrides={VoidType: 0}), loc(stmnt)))
    return instrs
Пример #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