Store LocalSymbol in allocate_mem

This commit is contained in:
Pragyansh Chaturvedi
2025-10-02 04:27:10 +05:30
parent 2fd2a46838
commit dadcb69f1c

View File

@ -93,19 +93,16 @@ def handle_assign(
elif isinstance(rval, ast.Constant): elif isinstance(rval, ast.Constant):
if isinstance(rval.value, bool): if isinstance(rval.value, bool):
if rval.value: if rval.value:
builder.store(ir.Constant(ir.IntType(1), 1), builder.store(ir.Constant(ir.IntType(1), 1), local_sym_tab[var_name][0])
local_sym_tab[var_name][0])
else: else:
builder.store(ir.Constant(ir.IntType(1), 0), builder.store(ir.Constant(ir.IntType(1), 0), local_sym_tab[var_name][0])
local_sym_tab[var_name][0])
print(f"Assigned constant {rval.value} to {var_name}") print(f"Assigned constant {rval.value} to {var_name}")
elif isinstance(rval.value, int): elif isinstance(rval.value, int):
# Assume c_int64 for now # Assume c_int64 for now
# var = builder.alloca(ir.IntType(64), name=var_name) # var = builder.alloca(ir.IntType(64), name=var_name)
# var.align = 8 # var.align = 8
builder.store( builder.store(
ir.Constant(ir.IntType(64), ir.Constant(ir.IntType(64), rval.value), local_sym_tab[var_name][0]
rval.value), local_sym_tab[var_name][0]
) )
# local_sym_tab[var_name] = var # local_sym_tab[var_name] = var
print(f"Assigned constant {rval.value} to {var_name}") print(f"Assigned constant {rval.value} to {var_name}")
@ -120,8 +117,7 @@ def handle_assign(
global_str.linkage = "internal" global_str.linkage = "internal"
global_str.global_constant = True global_str.global_constant = True
global_str.initializer = str_const global_str.initializer = str_const
str_ptr = builder.bitcast( str_ptr = builder.bitcast(global_str, ir.PointerType(ir.IntType(8)))
global_str, ir.PointerType(ir.IntType(8)))
builder.store(str_ptr, local_sym_tab[var_name][0]) builder.store(str_ptr, local_sym_tab[var_name][0])
print(f"Assigned string constant '{rval.value}' to {var_name}") print(f"Assigned string constant '{rval.value}' to {var_name}")
else: else:
@ -140,8 +136,7 @@ def handle_assign(
# var = builder.alloca(ir_type, name=var_name) # var = builder.alloca(ir_type, name=var_name)
# var.align = ir_type.width // 8 # var.align = ir_type.width // 8
builder.store( builder.store(
ir.Constant( ir.Constant(ir_type, rval.args[0].value), local_sym_tab[var_name][0]
ir_type, rval.args[0].value), local_sym_tab[var_name][0]
) )
print( print(
f"Assigned {call_type} constant " f"Assigned {call_type} constant "
@ -187,8 +182,7 @@ def handle_assign(
ir_type = struct_info.ir_type ir_type = struct_info.ir_type
# var = builder.alloca(ir_type, name=var_name) # var = builder.alloca(ir_type, name=var_name)
# Null init # Null init
builder.store(ir.Constant(ir_type, None), builder.store(ir.Constant(ir_type, None), local_sym_tab[var_name][0])
local_sym_tab[var_name][0])
local_var_metadata[var_name] = call_type local_var_metadata[var_name] = call_type
print(f"Assigned struct {call_type} to {var_name}") print(f"Assigned struct {call_type} to {var_name}")
# local_sym_tab[var_name] = var # local_sym_tab[var_name] = var
@ -259,8 +253,7 @@ def handle_cond(func, module, builder, cond, local_sym_tab, map_sym_tab):
print(f"Undefined variable {cond.id} in condition") print(f"Undefined variable {cond.id} in condition")
return None return None
elif isinstance(cond, ast.Compare): elif isinstance(cond, ast.Compare):
lhs = eval_expr(func, module, builder, cond.left, lhs = eval_expr(func, module, builder, cond.left, local_sym_tab, map_sym_tab)[0]
local_sym_tab, map_sym_tab)[0]
if len(cond.ops) != 1 or len(cond.comparators) != 1: if len(cond.ops) != 1 or len(cond.comparators) != 1:
print("Unsupported complex comparison") print("Unsupported complex comparison")
return None return None
@ -313,8 +306,7 @@ def handle_if(
else: else:
else_block = None else_block = None
cond = handle_cond(func, module, builder, stmt.test, cond = handle_cond(func, module, builder, stmt.test, local_sym_tab, map_sym_tab)
local_sym_tab, map_sym_tab)
if else_block: if else_block:
builder.cbranch(cond, then_block, else_block) builder.cbranch(cond, then_block, else_block)
else: else:
@ -419,6 +411,7 @@ def allocate_mem(
module, builder, body, func, ret_type, map_sym_tab, local_sym_tab, structs_sym_tab module, builder, body, func, ret_type, map_sym_tab, local_sym_tab, structs_sym_tab
): ):
for stmt in body: for stmt in body:
has_metadata = False
if isinstance(stmt, ast.If): if isinstance(stmt, ast.If):
if stmt.body: if stmt.body:
local_sym_tab = allocate_mem( local_sym_tab = allocate_mem(
@ -459,8 +452,7 @@ def allocate_mem(
ir_type = ctypes_to_ir(call_type) ir_type = ctypes_to_ir(call_type)
var = builder.alloca(ir_type, name=var_name) var = builder.alloca(ir_type, name=var_name)
var.align = ir_type.width // 8 var.align = ir_type.width // 8
print( print(f"Pre-allocated variable {var_name} of type {call_type}")
f"Pre-allocated variable {var_name} of type {call_type}")
elif HelperHandlerRegistry.has_handler(call_type): elif HelperHandlerRegistry.has_handler(call_type):
# Assume return type is int64 for now # Assume return type is int64 for now
ir_type = ir.IntType(64) ir_type = ir.IntType(64)
@ -477,7 +469,7 @@ def allocate_mem(
struct_info = structs_sym_tab[call_type] struct_info = structs_sym_tab[call_type]
ir_type = struct_info.ir_type ir_type = struct_info.ir_type
var = builder.alloca(ir_type, name=var_name) var = builder.alloca(ir_type, name=var_name)
local_var_metadata[var_name] = call_type has_metadata = True
print( print(
f"Pre-allocated variable {var_name} " f"Pre-allocated variable {var_name} "
f"for struct {call_type}" f"for struct {call_type}"
@ -519,7 +511,11 @@ def allocate_mem(
else: else:
print("Unsupported assignment value type") print("Unsupported assignment value type")
continue continue
local_sym_tab[var_name] = (var, ir_type)
if has_metadata:
local_sym_tab[var_name] = LocalSymbol(var, ir_type, call_type)
else:
local_sym_tab[var_name] = LocalSymbol(var, ir_type)
return local_sym_tab return local_sym_tab
@ -681,8 +677,7 @@ def infer_return_type(func_node: ast.FunctionDef):
if found_type is None: if found_type is None:
found_type = t found_type = t
elif found_type != t: elif found_type != t:
raise ValueError("Conflicting return types:" f"{ raise ValueError(f"Conflicting return types:{found_type} vs {t}")
found_type} vs {t}")
return found_type or "None" return found_type or "None"
@ -719,8 +714,7 @@ def assign_string_to_array(builder, target_array_ptr, source_string_ptr, array_l
char = builder.load(src_ptr) char = builder.load(src_ptr)
# Store character in target # Store character in target
dst_ptr = builder.gep( dst_ptr = builder.gep(target_array_ptr, [ir.Constant(ir.IntType(32), 0), idx])
target_array_ptr, [ir.Constant(ir.IntType(32), 0), idx])
builder.store(char, dst_ptr) builder.store(char, dst_ptr)
# Increment counter # Increment counter
@ -731,6 +725,5 @@ def assign_string_to_array(builder, target_array_ptr, source_string_ptr, array_l
# Ensure null termination # Ensure null termination
last_idx = ir.Constant(ir.IntType(32), array_length - 1) last_idx = ir.Constant(ir.IntType(32), array_length - 1)
null_ptr = builder.gep( null_ptr = builder.gep(target_array_ptr, [ir.Constant(ir.IntType(32), 0), last_idx])
target_array_ptr, [ir.Constant(ir.IntType(32), 0), last_idx])
builder.store(ir.Constant(ir.IntType(8), 0), null_ptr) builder.store(ir.Constant(ir.IntType(8), 0), null_ptr)