From 3870b421a9af3d043612bd5a421176eeba2ae5d6 Mon Sep 17 00:00:00 2001 From: sofia Date: Wed, 16 Jul 2025 22:04:11 +0300 Subject: [PATCH] Refactor indexing/accessing a bit, no mutability --- reid-llvm-lib/src/compile.rs | 2 +- reid-llvm-lib/src/debug.rs | 2 +- reid-llvm-lib/src/lib.rs | 2 +- reid/src/ast/mod.rs | 6 ++-- reid/src/ast/parse.rs | 29 ++++++---------- reid/src/ast/process.rs | 6 ++-- reid/src/codegen.rs | 64 +++++++++++++++++++---------------- reid/src/mir/display.rs | 8 ++--- reid/src/mir/mod.rs | 4 +-- reid/src/mir/typecheck.rs | 7 ++-- reid/src/mir/typeinference.rs | 4 +-- reid/src/mir/types.rs | 4 +-- reid_src/array_structs.reid | 2 +- 13 files changed, 68 insertions(+), 72 deletions(-) diff --git a/reid-llvm-lib/src/compile.rs b/reid-llvm-lib/src/compile.rs index 51da435..b49ea16 100644 --- a/reid-llvm-lib/src/compile.rs +++ b/reid-llvm-lib/src/compile.rs @@ -487,7 +487,7 @@ impl InstructionHolder { let mut llvm_indices: Vec<_> = indices .iter() - .map(|idx| ConstValue::U32(*idx).as_llvm(module)) + .map(|idx_elem| module.values.get(idx_elem).unwrap().value_ref) .collect(); LLVMBuildGEP2( diff --git a/reid-llvm-lib/src/debug.rs b/reid-llvm-lib/src/debug.rs index 806a4ca..56b6778 100644 --- a/reid-llvm-lib/src/debug.rs +++ b/reid-llvm-lib/src/debug.rs @@ -128,7 +128,7 @@ impl Debug for Instr { instruction_value, &items .iter() - .map(|i| i.to_string()) + .map(|expr| format!("{:?}", expr)) .collect::>() .join(", "), ), diff --git a/reid-llvm-lib/src/lib.rs b/reid-llvm-lib/src/lib.rs index 9eee9cd..a4c870f 100644 --- a/reid-llvm-lib/src/lib.rs +++ b/reid-llvm-lib/src/lib.rs @@ -226,7 +226,7 @@ pub enum Instr { Load(InstructionValue, Type), Store(InstructionValue, InstructionValue), ArrayAlloca(Type, u32), - GetElemPtr(InstructionValue, Vec), + GetElemPtr(InstructionValue, Vec), GetStructElemPtr(InstructionValue, u32), /// Integer Comparison diff --git a/reid/src/ast/mod.rs b/reid/src/ast/mod.rs index 7d5c6f5..fe57b8c 100644 --- a/reid/src/ast/mod.rs +++ b/reid/src/ast/mod.rs @@ -44,8 +44,10 @@ pub enum ExpressionKind { VariableName(String), Literal(Literal), Array(Vec), - ArrayIndex(Box, u64), - StructIndex(Box, String), + /// Array-indexed, e.g. [] + Indexed(Box, Box), + /// Struct-accessed, e.g. . + Accessed(Box, String), Binop(BinaryOperator, Box, Box), FunctionCall(Box), BlockExpr(Box), diff --git a/reid/src/ast/parse.rs b/reid/src/ast/parse.rs index 40d58ce..9a2a0c1 100644 --- a/reid/src/ast/parse.rs +++ b/reid/src/ast/parse.rs @@ -136,15 +136,15 @@ impl Parse for PrimaryExpression { while let Ok(index) = stream.parse::() { match index { - ValueIndex::Array(ArrayValueIndex(idx)) => { + ValueIndex::Array(ArrayValueIndex(idx_expr)) => { expr = Expression( - ExpressionKind::ArrayIndex(Box::new(expr), idx), + ExpressionKind::Indexed(Box::new(expr), Box::new(idx_expr)), stream.get_range().unwrap(), ); } ValueIndex::Struct(StructValueIndex(name)) => { expr = Expression( - ExpressionKind::StructIndex(Box::new(expr), name), + ExpressionKind::Accessed(Box::new(expr), name), stream.get_range().unwrap(), ); } @@ -428,16 +428,10 @@ impl Parse for VariableReference { while let Ok(val) = stream.parse::() { match val { ValueIndex::Array(ArrayValueIndex(idx)) => { - var_ref = VariableReference( - VariableReferenceKind::ArrayIndex(Box::new(var_ref), idx), - stream.get_range().unwrap(), - ); + todo!(); } ValueIndex::Struct(StructValueIndex(name)) => { - var_ref = VariableReference( - VariableReferenceKind::StructIndex(Box::new(var_ref), name), - stream.get_range().unwrap(), - ); + todo!(); } } } @@ -515,18 +509,15 @@ impl Parse for ValueIndex { } } -#[derive(Debug, Clone, Copy)] -pub struct ArrayValueIndex(u64); +#[derive(Debug, Clone)] +pub struct ArrayValueIndex(Expression); impl Parse for ArrayValueIndex { fn parse(mut stream: TokenStream) -> Result { stream.expect(Token::BracketOpen)?; - if let Some(Token::DecimalValue(idx)) = stream.next() { - stream.expect(Token::BracketClose)?; - Ok(ArrayValueIndex(idx)) - } else { - return Err(stream.expected_err("array index (number)")?); - } + let expr = stream.parse()?; + stream.expect(Token::BracketClose)?; + Ok(ArrayValueIndex(expr)) } } diff --git a/reid/src/ast/process.rs b/reid/src/ast/process.rs index 4a9d24f..20fa4e3 100644 --- a/reid/src/ast/process.rs +++ b/reid/src/ast/process.rs @@ -224,10 +224,10 @@ impl ast::Expression { ast::ExpressionKind::Array(expressions) => { mir::ExprKind::Array(expressions.iter().map(|e| e.process()).collect()) } - ast::ExpressionKind::ArrayIndex(expression, idx) => mir::ExprKind::ArrayIndex( + ast::ExpressionKind::Indexed(expression, idx_expr) => mir::ExprKind::Indexed( Box::new(expression.process()), mir::TypeKind::Vague(mir::VagueType::Unknown), - *idx, + Box::new(idx_expr.process()), ), ast::ExpressionKind::StructExpression(struct_init) => mir::ExprKind::Struct( struct_init.name.clone(), @@ -237,7 +237,7 @@ impl ast::Expression { .map(|(n, e)| (n.clone(), e.process())) .collect(), ), - ast::ExpressionKind::StructIndex(expression, name) => mir::ExprKind::StructIndex( + ast::ExpressionKind::Accessed(expression, name) => mir::ExprKind::Accessed( Box::new(expression.process()), mir::TypeKind::Vague(mir::VagueType::Unknown), name.clone(), diff --git a/reid/src/codegen.rs b/reid/src/codegen.rs index ea153e4..8a5e820 100644 --- a/reid/src/codegen.rs +++ b/reid/src/codegen.rs @@ -9,7 +9,7 @@ use reid_lib::{ use crate::mir::{ self, types::ReturnType, IndexedVariableReference, NamedVariableRef, StructField, StructType, - TypeDefinitionKind, TypeKind, + TypeDefinitionKind, TypeKind, VagueLiteral, }; /// Context that contains all of the given modules as complete codegenerated @@ -415,11 +415,12 @@ impl mir::Expression { None } } - mir::ExprKind::ArrayIndex(expression, val_t, idx) => { + mir::ExprKind::Indexed(expression, val_t, idx_expr) => { let array = expression.codegen(scope)?; + let idx = idx_expr.codegen(scope)?; let ptr = scope .block - .build(Instr::GetElemPtr(array, vec![*idx as u32])) + .build(Instr::GetElemPtr(array, vec![idx])) .unwrap(); Some( @@ -451,17 +452,21 @@ impl mir::Expression { )) .unwrap(); - for (i, instr) in instr_list.iter().enumerate() { + for (index, instr) in instr_list.iter().enumerate() { + let index_expr = scope + .block + .build(Instr::Constant(ConstValue::U32(index as u32))) + .unwrap(); let ptr = scope .block - .build(Instr::GetElemPtr(array, vec![i as u32])) + .build(Instr::GetElemPtr(array, vec![index_expr])) .unwrap(); scope.block.build(Instr::Store(ptr, *instr)).unwrap(); } Some(array) } - mir::ExprKind::StructIndex(expression, type_kind, field) => { + mir::ExprKind::Accessed(expression, type_kind, field) => { let struct_val = expression.codegen(scope)?; let struct_ty = expression.return_type().ok()?.1.known().ok()?; @@ -521,29 +526,30 @@ impl IndexedVariableReference { mir::IndexedVariableReferenceKind::ArrayIndex(inner, idx) => { let inner_stack_val = inner.get_stack_value(scope, true)?; - let mut gep_instr = scope - .block - .build(Instr::GetElemPtr( - unsafe { *inner_stack_val.0.get_instr() }, - vec![*idx as u32], - )) - .unwrap(); + todo!(); + // let mut gep_instr = scope + // .block + // .build(Instr::GetElemPtr( + // unsafe { *inner_stack_val.0.get_instr() }, + // vec![*idx as u32], + // )) + // .unwrap(); - match &inner_stack_val.1 { - Type::Ptr(inner_ty) => { - if load_after_gep { - gep_instr = scope - .block - .build(Instr::Load(gep_instr, *inner_ty.clone())) - .unwrap() - } - Some(StackValue( - inner_stack_val.0.with_instr(gep_instr), - *inner_ty.clone(), - )) - } - _ => panic!("Tried to codegen indexing a non-indexable value!"), - } + // match &inner_stack_val.1 { + // Type::Ptr(inner_ty) => { + // if load_after_gep { + // gep_instr = scope + // .block + // .build(Instr::Load(gep_instr, *inner_ty.clone())) + // .unwrap() + // } + // Some(StackValue( + // inner_stack_val.0.with_instr(gep_instr), + // *inner_ty.clone(), + // )) + // } + // _ => panic!("Tried to codegen indexing a non-indexable value!"), + // } } mir::IndexedVariableReferenceKind::StructIndex(inner, field) => { let inner_stack_val = inner.get_stack_value(scope, true)?; @@ -647,7 +653,7 @@ impl mir::Literal { mir::Literal::U128(val) => ConstValue::U128(val), mir::Literal::Bool(val) => ConstValue::Bool(val), mir::Literal::String(val) => ConstValue::StringPtr(val.clone()), - mir::Literal::Vague(_) => panic!("Got vague literal!"), + mir::Literal::Vague(VagueLiteral::Number(val)) => ConstValue::I32(val as i32), }) } } diff --git a/reid/src/mir/display.rs b/reid/src/mir/display.rs index 38cf46f..547bee7 100644 --- a/reid/src/mir/display.rs +++ b/reid/src/mir/display.rs @@ -164,10 +164,10 @@ impl Display for ExprKind { ExprKind::FunctionCall(fc) => Display::fmt(fc, f), ExprKind::If(if_exp) => Display::fmt(&if_exp, f), ExprKind::Block(block) => Display::fmt(block, f), - ExprKind::ArrayIndex(expression, elem_ty, idx) => { + ExprKind::Indexed(expression, elem_ty, idx_expr) => { Display::fmt(&expression, f)?; write!(f, "<{}>", elem_ty)?; - write_index(f, *idx) + write_index(f, idx_expr) } ExprKind::Array(expressions) => { f.write_char('[')?; @@ -203,7 +203,7 @@ impl Display for ExprKind { } f.write_char('}') } - ExprKind::StructIndex(expression, type_kind, name) => { + ExprKind::Accessed(expression, type_kind, name) => { Display::fmt(&expression, f)?; write_access(f, name)?; write!(f, "<{}>", type_kind) @@ -309,7 +309,7 @@ impl Display for Metadata { } } -fn write_index(f: &mut std::fmt::Formatter<'_>, idx: u64) -> std::fmt::Result { +fn write_index(f: &mut std::fmt::Formatter<'_>, idx: impl std::fmt::Display) -> std::fmt::Result { f.write_char('[')?; Display::fmt(&idx, f)?; f.write_char(']') diff --git a/reid/src/mir/mod.rs b/reid/src/mir/mod.rs index 4514dca..b9babd5 100644 --- a/reid/src/mir/mod.rs +++ b/reid/src/mir/mod.rs @@ -192,8 +192,8 @@ pub struct Import(pub Vec, pub Metadata); #[derive(Debug)] pub enum ExprKind { Variable(NamedVariableRef), - ArrayIndex(Box, TypeKind, u64), - StructIndex(Box, TypeKind, String), + Indexed(Box, TypeKind, Box), + Accessed(Box, TypeKind, String), Array(Vec), Struct(String, Vec<(String, Expression)>), Literal(Literal), diff --git a/reid/src/mir/typecheck.rs b/reid/src/mir/typecheck.rs index 34a5565..6e9186b 100644 --- a/reid/src/mir/typecheck.rs +++ b/reid/src/mir/typecheck.rs @@ -504,7 +504,7 @@ impl Expression { Ok((_, ty)) => Ok(ty), Err(e) => Err(e), }, - ExprKind::ArrayIndex(expression, elem_ty, idx) => { + ExprKind::Indexed(expression, elem_ty, idx) => { // Try to unwrap hint type from array if possible let hint_t = hint_t.map(|t| match t { TypeKind::Array(type_kind, _) => &type_kind, @@ -513,9 +513,6 @@ impl Expression { let expr_t = expression.typecheck(state, hints, hint_t)?; if let TypeKind::Array(inferred_ty, len) = expr_t { - if len <= *idx { - return Err(ErrorKind::IndexOutOfBounds(*idx, len)); - } let ty = state.or_else( elem_ty.resolve_ref(hints).collapse_into(&inferred_ty), TypeKind::Vague(Vague::Unknown), @@ -564,7 +561,7 @@ impl Expression { } } } - ExprKind::StructIndex(expression, type_kind, field_name) => { + ExprKind::Accessed(expression, type_kind, field_name) => { // Resolve expected type let expected_ty = type_kind.resolve_ref(hints); diff --git a/reid/src/mir/typeinference.rs b/reid/src/mir/typeinference.rs index 1436c4b..4dfe1a5 100644 --- a/reid/src/mir/typeinference.rs +++ b/reid/src/mir/typeinference.rs @@ -249,7 +249,7 @@ impl Expression { ReturnKind::Soft => Ok(block_ref.1), } } - ExprKind::ArrayIndex(expression, index_ty, _) => { + ExprKind::Indexed(expression, index_ty, _) => { let expr_ty = expression.infer_types(state, type_refs)?; // Check that the resolved type is at least an array, no @@ -302,7 +302,7 @@ impl Expression { } } } - ExprKind::StructIndex(expression, type_kind, field_name) => { + ExprKind::Accessed(expression, type_kind, field_name) => { let expr_ty = expression.infer_types(state, type_refs)?; // Check that the resolved type is at least a struct, no diff --git a/reid/src/mir/types.rs b/reid/src/mir/types.rs index d989652..046a699 100644 --- a/reid/src/mir/types.rs +++ b/reid/src/mir/types.rs @@ -107,7 +107,7 @@ impl ReturnType for Expression { Block(block) => block.return_type(), FunctionCall(fcall) => fcall.return_type(), If(expr) => expr.return_type(), - ArrayIndex(expression, _, _) => { + Indexed(expression, _, _) => { let expr_type = expression.return_type()?; if let (_, TypeKind::Array(elem_ty, _)) = expr_type { Ok((ReturnKind::Soft, *elem_ty)) @@ -126,7 +126,7 @@ impl ReturnType for Expression { TypeKind::Array(Box::new(first.1), expressions.len() as u64), )) } - StructIndex(_, type_kind, _) => Ok((ReturnKind::Soft, type_kind.clone())), + Accessed(_, type_kind, _) => Ok((ReturnKind::Soft, type_kind.clone())), Struct(name, _) => Ok((ReturnKind::Soft, TypeKind::CustomType(name.clone()))), } } diff --git a/reid_src/array_structs.reid b/reid_src/array_structs.reid index 179c7fa..6fe8301 100644 --- a/reid_src/array_structs.reid +++ b/reid_src/array_structs.reid @@ -11,7 +11,7 @@ fn main() -> u32 { second: [6, 3, 17, 8], }]; - value[0].second[2] = 99; + // value[0].second[2] = 99; return value[0].second[2]; }