예제 #1
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
예제 #2
0
파일: compound.py 프로젝트: mzsk/c_compiler
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
예제 #3
0
    def test_composite_initializer(self):
        code = """
        struct {int a[100]; struct {int b; void *ptr; char sub[10];} values[10];} g = {
            .values[0] = {-1, (void *)-1},
            .a[0 ... 99] = 1,
            .values[1 ... 5] = {.b = 5},
            .values[6 ... 9].ptr = 1,
            .values[1].sub = {1},
            .values[1].sub[0] = 'a'
        };
        """
        expr = next(parse(preprocess(tokenize(source(code))))).initialization
        a = expr[0]
        values = expr[1]

        self.assertEqual(len(a), 100)
        self.assertEqual(len(values), 10)

        a_expr = ConstantExpression(1, integer_type)
        for e in imap(next, imap(lambda v: v.itervalues(), a.itervalues())):
            self.assertEqual(e, a_expr)

        self.assertEqual(values[0][0][0], ConstantExpression(-1, integer_type))
        self.assertEqual(values[0][1][0],
                         ConstantExpression(-1, void_pointer_type))

        b_expr = ConstantExpression(5, integer_type)
        for index in xrange(1, 6):
            self.assertEqual(values[index][0][0], b_expr)
            self.assertEqual(values[index][1][0],
                             EmptyExpression(integer_type))

        ptr_expr = ConstantExpression(1, void_pointer_type)
        for index in xrange(6, 10):
            self.assertEqual(values[index][1][0], ptr_expr)
            self.assertEqual(values[index][0][0],
                             EmptyExpression(void_pointer_type))

        self.assertEqual(values[1][2][0][0],
                         ConstantExpression(ord('a'), char_type))
예제 #4
0
def _return(tokens, symbol_table):
    location = loc(consume(tokens))
    ret_type = symbol_table['__ RETURN_TYPE __']

    ret_exp = EmptyExpression(VoidType(location), location)
    if peek_or_terminal(tokens) != TOKENS.SEMICOLON:
        ret_exp = symbol_table['__ expression __'](tokens, symbol_table)

    if not isinstance(ret_exp, EmptyExpression) and isinstance(ret_type, VoidType):
        raise ValueError('{l} void-function returning a value ...'.format(l=loc(ret_exp)))

    if not safe_type_coercion(c_type(ret_exp), ret_type):
        raise ValueError('{l} Unable to coerce from {f} to {t}'.format(l=loc(ret_exp), f=c_type(ret_exp), t=ret_type))

    return ReturnStatement(ret_exp, location)
예제 #5
0
def for_stmnt(tokens, symbol_table):
    location, _ = loc(error_if_not_value(tokens,
                                         TOKENS.FOR)), error_if_not_value(
                                             tokens, TOKENS.LEFT_PARENTHESIS)
    statement, expression = symbol_table['__ statement __'], symbol_table[
        '__ expression __']

    init_exp = EmptyExpression(VoidType(location), location)
    if peek_or_terminal(tokens) != TOKENS.SEMICOLON:
        init_exp = expression(tokens, symbol_table)
    _ = error_if_not_value(tokens, TOKENS.SEMICOLON)

    conditional_exp = TrueExpression(location)
    if peek_or_terminal(tokens) != TOKENS.SEMICOLON:
        conditional_exp = expression(tokens, symbol_table)
    _ = error_if_not_value(tokens, TOKENS.SEMICOLON)

    update_exp = EmptyExpression(VoidType(location), location)
    if peek_or_terminal(tokens) != TOKENS.RIGHT_PARENTHESIS:
        update_exp = expression(tokens, symbol_table)
    _ = error_if_not_value(tokens, TOKENS.RIGHT_PARENTHESIS)

    yield ForStatement(init_exp, conditional_exp, update_exp,
                       statement(tokens, symbol_table), location)
예제 #6
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
예제 #7
0
 def test_default_basic_type_initializer(self):
     code = "int b = {};"
     expr = next(parse(preprocess(tokenize(source(code))))).initialization
     self.assertEqual(EmptyExpression(integer_type), expr[0])
예제 #8
0
def max_type(ctypes):
    return max(ctypes, key=_size)


def initializer_defaults(ctype):
    return Initializer(
        enumerate(rules(initializer_defaults)[type(ctype)](ctype)), ctype,
        loc(c_type))


set_rules(
    initializer_defaults,
    chain(
        izip(scalar_types,
             repeat(lambda ctype: (EmptyExpression(ctype, loc(ctype)), ))),
        (
            (ArrayType,
             lambda ctype: imap(initializer_defaults,
                                repeat(c_type(ctype), ctype.length or 0))),
            (StructType, lambda ctype: imap(initializer_defaults,
                                            imap(c_type, members(ctype)))),
            (UnionType, lambda ctype:
             (initializer_defaults(max_type(imap(c_type, members(ctype)))), )),
        )),
)


def parse_initializer(expr, declaration):
    return set_default_initializer(
        expr, initializer_defaults(