Skip to content

Commit 17f60d7

Browse files
committed
Add _process_*_in_fval to helper_utils
1 parent d18c69f commit 17f60d7

1 file changed

Lines changed: 69 additions & 8 deletions

File tree

pythonbpf/helper/helper_utils.py

Lines changed: 69 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,9 @@ def _handle_fstring_print(joined_str, module, builder, func,
8585
if isinstance(value, ast.Constant):
8686
_process_constant_in_fstring(value, fmt_parts, exprs)
8787
elif isinstance(value, ast.FormattedValue):
88-
_process_formatted_value(value, fmt_parts, exprs,
89-
local_sym_tab, struct_sym_tab,
90-
local_var_metadata)
88+
_process_fval(value, fmt_parts, exprs,
89+
local_sym_tab, struct_sym_tab,
90+
local_var_metadata)
9191

9292

9393
def _process_constant_in_fstring(cst, fmt_parts, exprs):
@@ -102,16 +102,77 @@ def _process_constant_in_fstring(cst, fmt_parts, exprs):
102102
f"Unsupported constant type in f-string: {type(cst.value)}")
103103

104104

105-
def _process_formatted_value(fval, fmt_parts, exprs,
106-
local_sym_tab, struct_sym_tab,
107-
local_var_metadata):
105+
def _process_fval(fval, fmt_parts, exprs,
106+
local_sym_tab, struct_sym_tab,
107+
local_var_metadata):
108108
"""Process formatted values in f-string."""
109109
logger.debug(f"Processing formatted value: {ast.dump(fval)}")
110110

111111
if isinstance(fval.value, ast.Name):
112-
pass
112+
_process_name_in_fval(fval.value, fmt_parts, exprs, local_sym_tab)
113113
elif isinstance(fval.value, ast.Attribute):
114-
pass
114+
_process_attr_in_fval(fval.value, fmt_parts, exprs,
115+
local_sym_tab, struct_sym_tab,
116+
local_var_metadata)
115117
else:
116118
raise NotImplementedError(
117119
f"Unsupported formatted value type in f-string: {type(fval.value)}")
120+
121+
122+
def _process_name_in_fval(name_node, fmt_parts, exprs, local_sym_tab):
123+
"""Process name nodes in formatted values."""
124+
if local_sym_tab and name_node.id in local_sym_tab:
125+
_, var_type = local_sym_tab[name_node.id]
126+
_populate_fval(var_type, name_node, fmt_parts, exprs)
127+
128+
129+
def _process_attr_in_fval(attr_node, fmt_parts, exprs,
130+
local_sym_tab, struct_sym_tab,
131+
local_var_metadata):
132+
"""Process attribute nodes in formatted values."""
133+
if (isinstance(attr_node.value, ast.Name) and
134+
local_sym_tab and attr_node.value.id in local_sym_tab):
135+
var_name = attr_node.value.id
136+
field_name = attr_node.attr
137+
138+
if not local_var_metadata or var_name not in local_var_metadata:
139+
raise ValueError(
140+
f"Variable metadata for '{var_name}' not found in local variable metadata")
141+
142+
var_type = local_sym_tab[var_name][1]
143+
if var_type not in struct_sym_tab:
144+
raise ValueError(
145+
f"Struct type '{var_type}' for variable '{var_name}' not found in struct symbol table")
146+
147+
struct_info = struct_sym_tab[var_type]
148+
if field_name not in struct_info.fields:
149+
raise ValueError(
150+
f"Field '{field_name}' not found in struct '{var_type}'")
151+
152+
field_type = struct_info.field_type(field_name)
153+
_populate_fval(field_type, attr_node, fmt_parts, exprs)
154+
else:
155+
raise NotImplementedError(
156+
"Only simple attribute access on local variables is supported in f-strings.")
157+
158+
159+
def _populate_fval(ftype, node, fmt_parts, exprs):
160+
"""Populate format parts and expressions based on field type."""
161+
if isinstance(ftype, ir.IntType):
162+
# TODO: We print as signed integers only for now
163+
if ftype.width == 64:
164+
fmt_parts.append("%lld")
165+
exprs.append(node)
166+
elif ftype.width == 32:
167+
fmt_parts.append("%d")
168+
exprs.append(node)
169+
else:
170+
raise NotImplementedError(
171+
f"Unsupported integer width in f-string: {ftype.width}")
172+
elif ftype == ir.PointerType(ir.IntType(8)):
173+
# NOTE: We assume i8* is a string
174+
fmt_parts.append("%s")
175+
exprs.append(node)
176+
else:
177+
raise NotImplementedError(
178+
f"Unsupported field type in f-string: {ftype}")

0 commit comments

Comments
 (0)