@@ -27,7 +27,7 @@ def get_probe_string(func_node):
2727 return "helper"
2828
2929
30- def handle_assign (func , module , builder , stmt , map_sym_tab , local_sym_tab ):
30+ def handle_assign (func , module , builder , stmt , map_sym_tab , local_sym_tab , structs_sym_tab ):
3131 """Handle assignment statements in the function body."""
3232 if len (stmt .targets ) != 1 :
3333 print ("Unsupported multiassignment" )
@@ -36,12 +36,35 @@ def handle_assign(func, module, builder, stmt, map_sym_tab, local_sym_tab):
3636 num_types = ("c_int32" , "c_int64" , "c_uint32" , "c_uint64" )
3737
3838 target = stmt .targets [0 ]
39- if not isinstance (target , ast .Name ):
39+ print (f"Handling assignment to { ast .dump (target )} " )
40+ if not isinstance (target , ast .Name ) and not isinstance (target , ast .Attribute ):
4041 print ("Unsupported assignment target" )
4142 return
42- var_name = target .id
43+ var_name = target .id if isinstance ( target , ast . Name ) else target . value . id
4344 rval = stmt .value
44- if isinstance (rval , ast .Constant ):
45+ if isinstance (target , ast .Attribute ):
46+ # struct field assignment
47+ field_name = target .attr
48+ if var_name in local_sym_tab and var_name in local_var_metadata :
49+ struct_type = local_var_metadata [var_name ]
50+ struct_info = structs_sym_tab [struct_type ]
51+
52+ if field_name in struct_info ["fields" ]:
53+ field_idx = struct_info ["fields" ][field_name ]
54+ struct_ptr = local_sym_tab [var_name ]
55+ field_ptr = builder .gep (
56+ struct_ptr , [ir .Constant (ir .IntType (32 ), 0 ),
57+ ir .Constant (ir .IntType (32 ), field_idx )],
58+ inbounds = True )
59+ val = eval_expr (func , module , builder , rval ,
60+ local_sym_tab , map_sym_tab )
61+ if val is None :
62+ print ("Failed to evaluate struct field assignment" )
63+ return
64+ builder .store (val , field_ptr )
65+ print (f"Assigned to struct field { var_name } .{ field_name } " )
66+ return
67+ elif isinstance (rval , ast .Constant ):
4568 if isinstance (rval .value , bool ):
4669 if rval .value :
4770 builder .store (ir .Constant (ir .IntType (1 ), 1 ),
@@ -92,10 +115,46 @@ def handle_assign(func, module, builder, stmt, map_sym_tab, local_sym_tab):
92115 builder .store (val , local_sym_tab [var_name ])
93116 # local_sym_tab[var_name] = var
94117 print (f"Dereferenced and assigned to { var_name } " )
118+ elif call_type in structs_sym_tab and len (rval .args ) == 0 :
119+ struct_info = structs_sym_tab [call_type ]
120+ ir_type = struct_info ["type" ]
121+ # var = builder.alloca(ir_type, name=var_name)
122+ # Null init
123+ builder .store (ir .Constant (ir_type , None ),
124+ local_sym_tab [var_name ])
125+ local_var_metadata [var_name ] = call_type
126+ print (f"Assigned struct { call_type } to { var_name } " )
127+ # local_sym_tab[var_name] = var
95128 else :
96129 print (f"Unsupported assignment call type: { call_type } " )
97130 elif isinstance (rval .func , ast .Attribute ):
98- if isinstance (rval .func .value , ast .Call ) and isinstance (rval .func .value .func , ast .Name ):
131+ print (f"Assignment call attribute: { ast .dump (rval .func )} " )
132+ if isinstance (rval .func .value , ast .Name ):
133+ # probably a struct access
134+ var_name = rval .func .value .id
135+ field_name = rval .func .attr
136+
137+ print (f"Handling struct field assignment"
138+ f"{ var_name } .{ field_name } " )
139+
140+ if var_name in local_sym_tab and var_name in local_var_metadata :
141+ struct_type = local_var_metadata [var_name ]
142+ struct_info = structs_sym_tab [struct_type ]
143+
144+ if field_name in struct_info ["fields" ]:
145+ field_idx = struct_info ["fields" ][field_name ]
146+ struct_ptr = local_sym_tab [var_name ]
147+ field_ptr = builder .gep (
148+ struct_ptr , [ir .Constant (ir .IntType (32 ), 0 ),
149+ ir .Constant (ir .IntType (32 ), field_idx )],
150+ inbounds = True )
151+ val = eval_expr (func , module , builder , rval ,
152+ local_sym_tab , map_sym_tab )
153+ if val is None :
154+ print ("Failed to evaluate struct field assignment" )
155+ return
156+ builder .store (val , field_ptr )
157+ elif isinstance (rval .func .value , ast .Call ) and isinstance (rval .func .value .func , ast .Name ):
99158 map_name = rval .func .value .func .id
100159 method_name = rval .func .attr
101160 if map_name in map_sym_tab :
@@ -226,7 +285,8 @@ def process_stmt(func, module, builder, stmt, local_sym_tab, map_sym_tab, struct
226285 if isinstance (stmt , ast .Expr ):
227286 handle_expr (func , module , builder , stmt , local_sym_tab , map_sym_tab )
228287 elif isinstance (stmt , ast .Assign ):
229- handle_assign (func , module , builder , stmt , map_sym_tab , local_sym_tab )
288+ handle_assign (func , module , builder , stmt , map_sym_tab ,
289+ local_sym_tab , structs_sym_tab )
230290 elif isinstance (stmt , ast .AugAssign ):
231291 raise SyntaxError ("Augmented assignment not supported" )
232292 elif isinstance (stmt , ast .If ):
@@ -304,9 +364,6 @@ def allocate_mem(module, builder, body, func, ret_type, map_sym_tab, local_sym_t
304364 struct_info = structs_sym_tab [call_type ]
305365 ir_type = struct_info ["type" ]
306366 var = builder .alloca (ir_type , name = var_name )
307-
308- # Null init
309- builder .store (ir .Constant (ir_type , None ), var )
310367 local_var_metadata [var_name ] = call_type
311368 print (
312369 f"Pre-allocated variable { var_name } for struct { call_type } " )
0 commit comments