@VisitorCore.visit.dispatch
def visit(self, node: astx.PrintExpr) -> None:
"""
title: Visit PrintExpr nodes.
parameters:
node:
type: astx.PrintExpr
"""
self.visit_child(node.message)
message_value = safe_pop(self.result_stack)
if message_value is None:
raise Exception("Invalid message in PrintExpr")
message_type = message_value.type
ptr: ir.Value
if (
isinstance(message_type, ir.PointerType)
and message_type.pointee == self._llvm.INT8_TYPE
):
ptr = message_value
elif is_int_type(message_type):
int_arg, int_fmt = self._normalize_int_for_printf(message_value)
int_fmt_gv = self._get_or_create_format_global(int_fmt)
ptr = self._snprintf_heap(int_fmt_gv, [int_arg])
elif isinstance(
message_type, (ir.HalfType, ir.FloatType, ir.DoubleType)
):
if isinstance(message_type, (ir.HalfType, ir.FloatType)):
float_arg = self._llvm.ir_builder.fpext(
message_value, self._llvm.DOUBLE_TYPE, "print_to_double"
)
else:
float_arg = message_value
float_fmt_gv = self._get_or_create_format_global("%.6f")
ptr = self._snprintf_heap(float_fmt_gv, [float_arg])
else:
raise Exception(
f"Unsupported message type in PrintExpr: {message_type}"
)
puts_fn = self.require_runtime_symbol("libc", "puts")
self._llvm.ir_builder.call(puts_fn, [ptr])
self.result_stack.append(ir.Constant(self._llvm.INT32_TYPE, 0))