def visit_PrimCall(self, expr):
    t = expr.type
    args = self.visit_expr_list(expr.args)
    
    # parenthesize any compound expressions 
    for i, arg_expr in enumerate(expr.args):
      if not isinstance(arg_expr, (Var, Const)):
        args[i] = "(" + args[i] + ")"
        
    p = expr.prim 
    if p == prims.add:
      #return "%s + %s" % (args[0], args[1])
      return self.add(args[0], args[1])
    if p == prims.subtract:
      #return "%s - %s" % (args[0], args[1])
      return self.sub(args[0],args[1])
    elif p == prims.multiply:
      return self.mul(args[0], args[1])
      # return "%s * %s" % (args[0], args[1])
    elif p == prims.divide:
      return self.div(args[0], args[1])
      # return "%s / %s" % (args[0], args[1])
    elif p == prims.negative:
      if t == Bool:
        return "1 - %s" % args[0]
      else:
        return "-%s" % args[0]
    elif p == prims.abs:
      x  = args[0]
      return " %s >= 0 ? %s  : -%s" % (x,x,x)
    
    elif p == prims.bitwise_and:
      return "%s & %s" % (args[0], args[1])
    elif p == prims.bitwise_or:
      return "%s | %s" % (args[0], args[1])
    elif p == prims.bitwise_not:
      return "~%s" % args[0]
    
    elif p == prims.logical_and:
      return self.and_(args[0], args[1])
      
    elif p == prims.logical_or:
      return self.or_(args[0], args[1])
    
    elif p == prims.logical_not:
      return self.not_(args[0])
      
    elif p == prims.equal:
      return self.eq(args[0], args[1], t)
    
    elif p == prims.not_equal:
      return self.neq(args[0], args[1], t)
    
    elif p == prims.greater:
      return self.gt(args[0], args[1], t)
      
    elif p == prims.greater_equal:
      return self.gte(args[0], args[1], t)
    
    elif p == prims.less:
      return self.lt(args[0], args[1], t)
    
    elif p == prims.less_equal:
      return self.lte(args[0], args[1], t)
    
    elif p == prims.remainder:
      x,y = args
      if t == Float32: return "fmod(%s, %s)" % (x,y)
      elif t == Float64: return "fmod(%s, %s)" % (x,y)
      assert isinstance(t, (BoolT, IntT)), "Modulo not implemented for %s" % t
      rem = self.fresh_var(t, "rem", "%s %% %s" % (x,y))
      y_is_negative = self.fresh_var(t, "y_is_negative", "%s < 0" % y)
      rem_is_negative = self.fresh_var(t, "rem_is_negative", "%s < 0" % rem)
      y_nonzero = self.fresh_var(t, "y_nonzero", "%s != 0" % y)
      rem_nonzero = self.fresh_var(t, "rem_nonzero", "%s != 0" % rem)
      neither_zero = self.fresh_var(t, "neither_zero", "%s && %s" % (y_nonzero, rem_nonzero))
      diff_signs = self.fresh_var(t, "diff_signs", "%s ^ %s" % (y_is_negative, rem_is_negative))
      should_flip = self.fresh_var(t, "should_flip", "%s && %s" % (neither_zero, diff_signs))
      flipped_rem = self.fresh_var(t, "flipped_rem", "%s + %s" % (y, rem))
      return "%s ? %s : %s" % (should_flip, flipped_rem, rem)
    elif p == prims.fmod:
      if t == Float32: return "fmodf(%s, %s)" % (args[0], args[1])
      elif t == Float64: return "fmod(%s, %s)" % (args[0], args[1])
      return "%s %% %s" % (args[0], args[1])
    elif p == prims.maximum:
      x,y = args
      return "(%s > %s) ? %s : %s" % (x,y,x,y)
    elif p == prims.minimum:
      x,y = args
      return "(%s < %s) ? %s : %s" % (x,y,x,y)
    
    elif p == prims.power:
      if t == Float32: 
        return "powf(%s, %s)" % (args[0], args[1])
      else:
        return "pow(%s, %s)" % (args[0], args[1])
    
    elif isinstance(t, FloatT):
      # many float prims implemented using the same name in math.h
      name = p.name
      if name.startswith("arc"):
        # arccos -> acos
        name = "a" + name[3:]
      if t == Float32: name = name + "f" 
      if len(args) == 1:
        return "%s(%s)" % (name, args[0])
      else:
        assert len(args) == 2, "Unexpected prim %s with %d args (%s)" % (p, len(args), args)
        return "%s(%s, %s)" % (name, args[0], args[1])
  
    else:
      assert False, "Prim not yet implemented: %s" % p
dataset/ETHPy150Open iskandr/parakeet/parakeet/c_backend/fn_compiler.py/FnCompiler.visit_PrimCall/original