def generate_code(self, code_builder: OpCodeBuilder): self.expr1.generate_code(code_builder) self.expr2.generate_code(code_builder) if self.op_type is BinaryOpType.Eq or self.op_type is BinaryOpType.Neq or self.op_type is BinaryOpType.Add: t1, t2 = code_builder.get_type(self.expr1), code_builder.get_type(self.expr2) subst = t1.unify(t2) # To handle cases with empty list t1, t2 = t1.substitute(subst), t2.substitute(subst) if self.op_type is BinaryOpType.Eq: code = codes.Eq() name = '__refeq' elif self.op_type is BinaryOpType.Neq: code = codes.Ne() name = '__neq' # TODO elif self.op_type is BinaryOpType.Add: if isinstance(t1, InferenceBool) or isinstance(t1, InferenceTuple): raise NoFunctionInstanceError('__add', [t1, t2]) code = codes.Add() name = '__add' if t1.is_scalar() and t2.is_scalar(): # If scalar, compare directly with appropriate instruction code_builder.add(code) else: # Else call custom equality testing function code_builder.add_call( fun_name=name, arg_types=[t1, t2], hide=True ) else: code = { BinaryOpType.Add: codes.Add(), BinaryOpType.Sub: codes.Sub(), BinaryOpType.Mul: codes.Mul(), BinaryOpType.Div: codes.Div(), BinaryOpType.Lt: codes.Lt(), BinaryOpType.Leq: codes.Le(), BinaryOpType.Geq: codes.Ge(), BinaryOpType.Gt: codes.Gt(), BinaryOpType.Mod: codes.Mod(), BinaryOpType.And: codes.And(), BinaryOpType.Or: codes.Or(), BinaryOpType.Cons: codes.CreateListCons(), }.get(self.op_type) assert code is not None, 'Unknown binary operator' code_builder.add(code)
def generate_code(self, code_builder: OpCodeBuilder): arg_types = [code_builder.get_type(e) for e in self.expressions] for e in self.expressions: e.generate_code(code_builder) code_builder.add_call(self.function_name.value, arg_types)