tcStmt ret (PrintStatement (l::loc) argsE) = tcStmtBlock l "print statement" $ do
    argsE' <- withExprC ReadOnlyExpr $ mapM (tcVariadicArg (tcExpr Nothing)) argsE
    xs <- forM argsE' $ \argE' -> do
        tx <- newTyVar True False Nothing
        pparg <- ppVariadicArg pp argE'
        newTypedVar "print" tx False $ Just pparg
    topTcCstrM_ l $ SupportedPrint (map (\(x,y) -> (False,Left $ fmap typed x,y)) argsE') xs
    let exs = map (fmap (Typed l) . varExpr) xs
    let t = StmtType $ Set.singleton $ StmtFallthru $ ComplexT Void
    return (PrintStatement (Typed l t) (zip exs $ map snd argsE'),t)
tcStmt ret (PrintStatement (l::loc) argsE) = tcStmtBlock l "print statement" $ do
    argsE' <- withExprC ReadOnlyExpr $ mapM (tcVariadicArg (tcExpr Nothing)) argsE
    xs <- forM argsE' $ \argE' -> do
        tx <- newTyVar True False Nothing
        pparg <- ppVariadicArg pp argE'
        newTypedVar "print" tx False $ Just pparg
    topTcCstrM_ l $ SupportedPrint (map (\(x,y) -> (False,Left $ fmap typed x,y)) argsE') xs
    let exs = map (fmap (Typed l) . varExpr) xs
    let t = StmtType $ Set.singleton $ StmtFallthru $ ComplexT Void
    return (PrintStatement (Typed l t) (zip exs $ map snd argsE'),t)
tcStmt ret (PrintStatement (l::loc) argsE) = tcStmtBlock l "print statement" $ do
    argsE' <- withExprC ReadOnlyExpr $ mapM (tcVariadicArg (tcExpr Nothing)) argsE
    xs <- forM argsE' $ \argE' -> do
        tx <- newTyVar True False Nothing
        pparg <- ppVariadicArg pp argE'
        newTypedVar "print" tx False $ Just pparg
    topTcCstrM_ l $ SupportedPrint (map (\(x,y) -> (False,Left $ fmap typed x,y)) argsE') xs
    let exs = map (fmap (Typed l) . varExpr) xs
    let t = StmtType $ Set.singleton $ StmtFallthru $ ComplexT Void
    return (PrintStatement (Typed l t) (zip exs $ map snd argsE'),t)