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
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
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))
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)
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)
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
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])
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(