11from llvmlite import ir
22import ast
3+ import logging
34from typing import Any
5+ from dataclasses import dataclass
46
57from .helper import HelperHandlerRegistry , handle_helper_call
68from .type_deducer import ctypes_to_ir
79from .binary_ops import handle_binary_op
810from .expr_pass import eval_expr , handle_expr
911
10- local_var_metadata : dict [str | Any , Any ] = {}
12+ logger = logging .getLogger (__name__ )
13+
14+
15+ @dataclass
16+ class LocalSymbol :
17+ var : ir .AllocaInstr
18+ ir_type : ir .Type
19+ metadata : Any = None
20+
21+ def __iter__ (self ):
22+ yield self .var
23+ yield self .ir_type
24+ yield self .metadata
1125
1226
1327def get_probe_string (func_node ):
@@ -47,13 +61,12 @@ def handle_assign(
4761 if isinstance (target , ast .Attribute ):
4862 # struct field assignment
4963 field_name = target .attr
50- if var_name in local_sym_tab and var_name in local_var_metadata :
51- struct_type = local_var_metadata [var_name ]
64+ if var_name in local_sym_tab :
65+ struct_type = local_sym_tab [var_name ]. metadata
5266 struct_info = structs_sym_tab [struct_type ]
53-
5467 if field_name in struct_info .fields :
5568 field_ptr = struct_info .gep (
56- builder , local_sym_tab [var_name ][ 0 ] , field_name
69+ builder , local_sym_tab [var_name ]. var , field_name
5770 )
5871 val = eval_expr (
5972 func ,
@@ -83,18 +96,21 @@ def handle_assign(
8396 elif isinstance (rval , ast .Constant ):
8497 if isinstance (rval .value , bool ):
8598 if rval .value :
86- builder .store (ir .Constant (ir .IntType (1 ), 1 ), local_sym_tab [var_name ][0 ])
99+ builder .store (
100+ ir .Constant (ir .IntType (1 ), 1 ), local_sym_tab [var_name ].var
101+ )
87102 else :
88- builder .store (ir .Constant (ir .IntType (1 ), 0 ), local_sym_tab [var_name ][0 ])
103+ builder .store (
104+ ir .Constant (ir .IntType (1 ), 0 ), local_sym_tab [var_name ].var
105+ )
89106 print (f"Assigned constant { rval .value } to { var_name } " )
90107 elif isinstance (rval .value , int ):
91108 # Assume c_int64 for now
92109 # var = builder.alloca(ir.IntType(64), name=var_name)
93110 # var.align = 8
94111 builder .store (
95- ir .Constant (ir .IntType (64 ), rval .value ), local_sym_tab [var_name ][ 0 ]
112+ ir .Constant (ir .IntType (64 ), rval .value ), local_sym_tab [var_name ]. var
96113 )
97- # local_sym_tab[var_name] = var
98114 print (f"Assigned constant { rval .value } to { var_name } " )
99115 elif isinstance (rval .value , str ):
100116 str_val = rval .value .encode ("utf-8" ) + b"\x00 "
@@ -108,7 +124,7 @@ def handle_assign(
108124 global_str .global_constant = True
109125 global_str .initializer = str_const
110126 str_ptr = builder .bitcast (global_str , ir .PointerType (ir .IntType (8 )))
111- builder .store (str_ptr , local_sym_tab [var_name ][ 0 ] )
127+ builder .store (str_ptr , local_sym_tab [var_name ]. var )
112128 print (f"Assigned string constant '{ rval .value } ' to { var_name } " )
113129 else :
114130 print ("Unsupported constant type" )
@@ -126,13 +142,13 @@ def handle_assign(
126142 # var = builder.alloca(ir_type, name=var_name)
127143 # var.align = ir_type.width // 8
128144 builder .store (
129- ir .Constant (ir_type , rval .args [0 ].value ), local_sym_tab [var_name ][0 ]
145+ ir .Constant (ir_type , rval .args [0 ].value ),
146+ local_sym_tab [var_name ].var ,
130147 )
131148 print (
132149 f"Assigned { call_type } constant "
133150 f"{ rval .args [0 ].value } to { var_name } "
134151 )
135- # local_sym_tab[var_name] = var
136152 elif HelperHandlerRegistry .has_handler (call_type ):
137153 # var = builder.alloca(ir.IntType(64), name=var_name)
138154 # var.align = 8
@@ -144,10 +160,8 @@ def handle_assign(
144160 local_sym_tab ,
145161 map_sym_tab ,
146162 structs_sym_tab ,
147- local_var_metadata ,
148163 )
149- builder .store (val [0 ], local_sym_tab [var_name ][0 ])
150- # local_sym_tab[var_name] = var
164+ builder .store (val [0 ], local_sym_tab [var_name ].var )
151165 print (f"Assigned constant { rval .func .id } to { var_name } " )
152166 elif call_type == "deref" and len (rval .args ) == 1 :
153167 print (f"Handling deref assignment { ast .dump (rval )} " )
@@ -164,18 +178,15 @@ def handle_assign(
164178 print ("Failed to evaluate deref argument" )
165179 return
166180 print (f"Dereferenced value: { val } , storing in { var_name } " )
167- builder .store (val [0 ], local_sym_tab [var_name ][0 ])
168- # local_sym_tab[var_name] = var
181+ builder .store (val [0 ], local_sym_tab [var_name ].var )
169182 print (f"Dereferenced and assigned to { var_name } " )
170183 elif call_type in structs_sym_tab and len (rval .args ) == 0 :
171184 struct_info = structs_sym_tab [call_type ]
172185 ir_type = struct_info .ir_type
173186 # var = builder.alloca(ir_type, name=var_name)
174187 # Null init
175- builder .store (ir .Constant (ir_type , None ), local_sym_tab [var_name ][0 ])
176- local_var_metadata [var_name ] = call_type
188+ builder .store (ir .Constant (ir_type , None ), local_sym_tab [var_name ].var )
177189 print (f"Assigned struct { call_type } to { var_name } " )
178- # local_sym_tab[var_name] = var
179190 else :
180191 print (f"Unsupported assignment call type: { call_type } " )
181192 elif isinstance (rval .func , ast .Attribute ):
@@ -198,12 +209,10 @@ def handle_assign(
198209 local_sym_tab ,
199210 map_sym_tab ,
200211 structs_sym_tab ,
201- local_var_metadata ,
202212 )
203213 # var = builder.alloca(ir.IntType(64), name=var_name)
204214 # var.align = 8
205- builder .store (val [0 ], local_sym_tab [var_name ][0 ])
206- # local_sym_tab[var_name] = var
215+ builder .store (val [0 ], local_sym_tab [var_name ].var )
207216 else :
208217 print ("Unsupported assignment call structure" )
209218 else :
@@ -227,7 +236,7 @@ def handle_cond(func, module, builder, cond, local_sym_tab, map_sym_tab):
227236 return None
228237 elif isinstance (cond , ast .Name ):
229238 if cond .id in local_sym_tab :
230- var = local_sym_tab [cond .id ][ 0 ]
239+ var = local_sym_tab [cond .id ]. var
231240 val = builder .load (var )
232241 if val .type != ir .IntType (1 ):
233242 # Convert nonzero values to true, zero to false
@@ -342,7 +351,6 @@ def process_stmt(
342351):
343352 print (f"Processing statement: { ast .dump (stmt )} " )
344353 if isinstance (stmt , ast .Expr ):
345- print (local_var_metadata )
346354 handle_expr (
347355 func ,
348356 module ,
@@ -351,7 +359,6 @@ def process_stmt(
351359 local_sym_tab ,
352360 map_sym_tab ,
353361 structs_sym_tab ,
354- local_var_metadata ,
355362 )
356363 elif isinstance (stmt , ast .Assign ):
357364 handle_assign (
@@ -401,6 +408,7 @@ def allocate_mem(
401408 module , builder , body , func , ret_type , map_sym_tab , local_sym_tab , structs_sym_tab
402409):
403410 for stmt in body :
411+ has_metadata = False
404412 if isinstance (stmt , ast .If ):
405413 if stmt .body :
406414 local_sym_tab = allocate_mem (
@@ -458,7 +466,7 @@ def allocate_mem(
458466 struct_info = structs_sym_tab [call_type ]
459467 ir_type = struct_info .ir_type
460468 var = builder .alloca (ir_type , name = var_name )
461- local_var_metadata [ var_name ] = call_type
469+ has_metadata = True
462470 print (
463471 f"Pre-allocated variable { var_name } "
464472 f"for struct { call_type } "
@@ -500,7 +508,11 @@ def allocate_mem(
500508 else :
501509 print ("Unsupported assignment value type" )
502510 continue
503- local_sym_tab [var_name ] = (var , ir_type )
511+
512+ if has_metadata :
513+ local_sym_tab [var_name ] = LocalSymbol (var , ir_type , call_type )
514+ else :
515+ local_sym_tab [var_name ] = LocalSymbol (var , ir_type )
504516 return local_sym_tab
505517
506518
@@ -662,7 +674,7 @@ def _expr_type(e):
662674 if found_type is None :
663675 found_type = t
664676 elif found_type != t :
665- raise ValueError ("Conflicting return types:" f" { found_type } vs { t } " )
677+ raise ValueError (f "Conflicting return types: { found_type } vs { t } " )
666678 return found_type or "None"
667679
668680
0 commit comments