def compound_assignment(expr, symbol_table): assert all(imap(isinstance, imap(c_type, (left_exp(expr), right_exp(expr))), repeat(NumericType))) assert not isinstance(c_type(left_exp(expr)), ArrayType) if isinstance(left_exp(expr), IdentifierExpression) and \ base_c_type(c_type(left_exp(expr))) == base_c_type(c_type(right_exp(expr))) and \ size(c_type(left_exp(expr))) == size(c_type(right_exp(expr))): # check that both operands are of the same kind (integral vs numeric) and have the same size ... return simple_numeric_assignment_no_casting(expr, symbol_table, rules(compound_assignment)[oper(expr)]) max_type = max(imap(c_type, (left_exp(expr), right_exp(expr)))) # cast to largest type. expression = symbol_table['__ expression __'] left_instrs = cast( # cast to max_type patch_comp_left_instrs(expression(left_exp(expr), symbol_table), loc(expr), size(c_type(left_exp(expr)))), c_type(left_exp(expr)), max_type, loc(expr), ) right_instrs = cast(expression(right_exp(expr), symbol_table), c_type(right_exp(expr)), max_type, loc(expr)) return patch_comp_assignment( cast( # Cast the result back, swap the value and the destination address call set to save. rules(compound_assignment)[oper(expr)]( left_instrs, right_instrs, loc(expr), (max_type, c_type(left_exp(expr)), c_type(right_exp(expr))) ), max_type, c_type(expr), loc(expr) ), c_type(expr), loc(expr), )
def logical_operators(expr, symbol_table): expression = symbol_table['__ expression __'] return rules(logical_operators)[oper(expr)]( expression(left_exp(expr), symbol_table), expression(right_exp(expr), symbol_table), loc(expr), tuple(imap(size_arrays_as_pointers, imap(c_type, (expr, left_exp(expr), right_exp(expr))))) )
def subtraction_expression(_exp): if is_binary_pointer_expression(_exp): # if subtracting two pointers, then the return type is a LongType return BinaryExpression( left_exp(_exp), oper(_exp), right_exp(_exp), LongType(LongType(location=loc(_exp)), unsigned=True, location=loc(_exp)), location=loc(_exp) ) return _exp
def binary_exp(expr): if not all(imap(isinstance, (left_exp(expr), right_exp(expr)), repeat(ConstantExpression))): return expr exp_type = max(imap(c_type, (left_exp(expr), right_exp(expr))))(loc(expr)) l_exp, r_exp, location = exp(left_exp(expr)), exp(right_exp(expr)), loc(expr) # noinspection PyUnresolvedReferences '1 + 2 - 3 * 7 / 4' return binary_exp.rules[oper(expr)]( expr=expr, left_exp=l_exp, right_exp=r_exp, location=location, exp_type=exp_type )
def subtraction_expression(_exp): if is_binary_pointer_expression( _exp ): # if subtracting two pointers, then the return type is a LongType return BinaryExpression(left_exp(_exp), oper(_exp), right_exp(_exp), LongType(LongType(location=loc(_exp)), unsigned=True, location=loc(_exp)), location=loc(_exp)) return _exp
def relational_operators(expr, symbol_table): max_type = max(imap(c_type, (left_exp(expr), right_exp(expr)))) expression = symbol_table['__ expression __'] if isinstance(max_type, ArrayType): max_type = PointerType(c_type(max_type), loc(max_type)) left_instrs = expression(left_exp(expr), symbol_table) right_instrs = expression(right_exp(expr), symbol_table) return rules(relational_operators)[oper(expr)]( cast(left_instrs, c_type(left_exp(expr)), max_type, loc(expr)), cast(right_instrs, c_type(right_exp(expr)), max_type, loc(expr)), loc(expr), (c_type(expr), c_type(left_exp(expr)), c_type(right_exp(expr))), )
def arithmetic_and_bitwise_operators(expr, symbol_table): expression = symbol_table['__ expression __'] left_instrs = expression(left_exp(expr), symbol_table) right_instrs = expression(right_exp(expr), symbol_table) to_type = c_type(expr) if isinstance(to_type, ArrayType): to_type = PointerType(c_type(to_type), loc(c_type(expr))) return rules(arithmetic_and_bitwise_operators)[oper(expr)]( cast(left_instrs, c_type(left_exp(expr)), to_type, loc(expr)), cast(right_instrs, c_type(right_exp(expr)), to_type, loc(expr)), loc(expr), (to_type, c_type(left_exp(expr)), c_type(right_exp(expr))), )
def binary_exp(expr): if not all( imap(isinstance, (left_exp(expr), right_exp(expr)), repeat(ConstantExpression))): return expr exp_type = max(imap(c_type, (left_exp(expr), right_exp(expr))))(loc(expr)) l_exp, r_exp, location = exp(left_exp(expr)), exp( right_exp(expr)), loc(expr) # noinspection PyUnresolvedReferences '1 + 2 - 3 * 7 / 4' return binary_exp.rules[oper(expr)](expr=expr, left_exp=l_exp, right_exp=r_exp, location=location, exp_type=exp_type)
def binary_expression(expr, symbol_table): return rules(binary_expression)[oper(expr)](expr, symbol_table)
def unary_operator(expr, symbol_table): return rules(unary_operator)[oper(expr)](expr, symbol_table)
def tilde_operator(expr, symbol_table): return get_not_bitwise(size_arrays_as_pointers(c_type(expr)))( symbol_table['__ expression __'](exp(expr), symbol_table), loc(oper(expr)) )
def unary_exp(expr): # noinspection PyUnresolvedReferences return unary_exp.rules[oper(expr)](exp(expr)) if isinstance( exp(expr), ConstantExpression) else expr
def tilde_operator(expr, symbol_table): return get_not_bitwise(size_arrays_as_pointers(c_type(expr)))( symbol_table['__ expression __'](exp(expr), symbol_table), loc(oper(expr)))
def integral_type(tokens, symbol_table, l_exp): exp = get_binary_expression(tokens, symbol_table, l_exp, assignment_expression, IntegralType) return CompoundAssignmentExpression(left_exp(exp), oper(exp), right_exp(exp), c_type(l_exp)(loc(exp)), loc(exp))
def unary_exp(expr): # noinspection PyUnresolvedReferences return unary_exp.rules[oper(expr)](exp(expr)) if isinstance(exp(expr), ConstantExpression) else expr