Refactor indexing/accessing a bit, no mutability

This commit is contained in:
Sofia 2025-07-16 22:04:11 +03:00
parent 4ad871ff3d
commit 3870b421a9
13 changed files with 68 additions and 72 deletions

View File

@ -487,7 +487,7 @@ impl InstructionHolder {
let mut llvm_indices: Vec<_> = indices let mut llvm_indices: Vec<_> = indices
.iter() .iter()
.map(|idx| ConstValue::U32(*idx).as_llvm(module)) .map(|idx_elem| module.values.get(idx_elem).unwrap().value_ref)
.collect(); .collect();
LLVMBuildGEP2( LLVMBuildGEP2(

View File

@ -128,7 +128,7 @@ impl Debug for Instr {
instruction_value, instruction_value,
&items &items
.iter() .iter()
.map(|i| i.to_string()) .map(|expr| format!("{:?}", expr))
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(", "), .join(", "),
), ),

View File

@ -226,7 +226,7 @@ pub enum Instr {
Load(InstructionValue, Type), Load(InstructionValue, Type),
Store(InstructionValue, InstructionValue), Store(InstructionValue, InstructionValue),
ArrayAlloca(Type, u32), ArrayAlloca(Type, u32),
GetElemPtr(InstructionValue, Vec<u32>), GetElemPtr(InstructionValue, Vec<InstructionValue>),
GetStructElemPtr(InstructionValue, u32), GetStructElemPtr(InstructionValue, u32),
/// Integer Comparison /// Integer Comparison

View File

@ -44,8 +44,10 @@ pub enum ExpressionKind {
VariableName(String), VariableName(String),
Literal(Literal), Literal(Literal),
Array(Vec<Expression>), Array(Vec<Expression>),
ArrayIndex(Box<Expression>, u64), /// Array-indexed, e.g. <expr>[<expr>]
StructIndex(Box<Expression>, String), Indexed(Box<Expression>, Box<Expression>),
/// Struct-accessed, e.g. <expr>.<expr>
Accessed(Box<Expression>, String),
Binop(BinaryOperator, Box<Expression>, Box<Expression>), Binop(BinaryOperator, Box<Expression>, Box<Expression>),
FunctionCall(Box<FunctionCallExpression>), FunctionCall(Box<FunctionCallExpression>),
BlockExpr(Box<Block>), BlockExpr(Box<Block>),

View File

@ -136,15 +136,15 @@ impl Parse for PrimaryExpression {
while let Ok(index) = stream.parse::<ValueIndex>() { while let Ok(index) = stream.parse::<ValueIndex>() {
match index { match index {
ValueIndex::Array(ArrayValueIndex(idx)) => { ValueIndex::Array(ArrayValueIndex(idx_expr)) => {
expr = Expression( expr = Expression(
ExpressionKind::ArrayIndex(Box::new(expr), idx), ExpressionKind::Indexed(Box::new(expr), Box::new(idx_expr)),
stream.get_range().unwrap(), stream.get_range().unwrap(),
); );
} }
ValueIndex::Struct(StructValueIndex(name)) => { ValueIndex::Struct(StructValueIndex(name)) => {
expr = Expression( expr = Expression(
ExpressionKind::StructIndex(Box::new(expr), name), ExpressionKind::Accessed(Box::new(expr), name),
stream.get_range().unwrap(), stream.get_range().unwrap(),
); );
} }
@ -428,16 +428,10 @@ impl Parse for VariableReference {
while let Ok(val) = stream.parse::<ValueIndex>() { while let Ok(val) = stream.parse::<ValueIndex>() {
match val { match val {
ValueIndex::Array(ArrayValueIndex(idx)) => { ValueIndex::Array(ArrayValueIndex(idx)) => {
var_ref = VariableReference( todo!();
VariableReferenceKind::ArrayIndex(Box::new(var_ref), idx),
stream.get_range().unwrap(),
);
} }
ValueIndex::Struct(StructValueIndex(name)) => { ValueIndex::Struct(StructValueIndex(name)) => {
var_ref = VariableReference( todo!();
VariableReferenceKind::StructIndex(Box::new(var_ref), name),
stream.get_range().unwrap(),
);
} }
} }
} }
@ -515,18 +509,15 @@ impl Parse for ValueIndex {
} }
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone)]
pub struct ArrayValueIndex(u64); pub struct ArrayValueIndex(Expression);
impl Parse for ArrayValueIndex { impl Parse for ArrayValueIndex {
fn parse(mut stream: TokenStream) -> Result<Self, Error> { fn parse(mut stream: TokenStream) -> Result<Self, Error> {
stream.expect(Token::BracketOpen)?; stream.expect(Token::BracketOpen)?;
if let Some(Token::DecimalValue(idx)) = stream.next() { let expr = stream.parse()?;
stream.expect(Token::BracketClose)?; stream.expect(Token::BracketClose)?;
Ok(ArrayValueIndex(idx)) Ok(ArrayValueIndex(expr))
} else {
return Err(stream.expected_err("array index (number)")?);
}
} }
} }

View File

@ -224,10 +224,10 @@ impl ast::Expression {
ast::ExpressionKind::Array(expressions) => { ast::ExpressionKind::Array(expressions) => {
mir::ExprKind::Array(expressions.iter().map(|e| e.process()).collect()) 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()), Box::new(expression.process()),
mir::TypeKind::Vague(mir::VagueType::Unknown), mir::TypeKind::Vague(mir::VagueType::Unknown),
*idx, Box::new(idx_expr.process()),
), ),
ast::ExpressionKind::StructExpression(struct_init) => mir::ExprKind::Struct( ast::ExpressionKind::StructExpression(struct_init) => mir::ExprKind::Struct(
struct_init.name.clone(), struct_init.name.clone(),
@ -237,7 +237,7 @@ impl ast::Expression {
.map(|(n, e)| (n.clone(), e.process())) .map(|(n, e)| (n.clone(), e.process()))
.collect(), .collect(),
), ),
ast::ExpressionKind::StructIndex(expression, name) => mir::ExprKind::StructIndex( ast::ExpressionKind::Accessed(expression, name) => mir::ExprKind::Accessed(
Box::new(expression.process()), Box::new(expression.process()),
mir::TypeKind::Vague(mir::VagueType::Unknown), mir::TypeKind::Vague(mir::VagueType::Unknown),
name.clone(), name.clone(),

View File

@ -9,7 +9,7 @@ use reid_lib::{
use crate::mir::{ use crate::mir::{
self, types::ReturnType, IndexedVariableReference, NamedVariableRef, StructField, StructType, self, types::ReturnType, IndexedVariableReference, NamedVariableRef, StructField, StructType,
TypeDefinitionKind, TypeKind, TypeDefinitionKind, TypeKind, VagueLiteral,
}; };
/// Context that contains all of the given modules as complete codegenerated /// Context that contains all of the given modules as complete codegenerated
@ -415,11 +415,12 @@ impl mir::Expression {
None None
} }
} }
mir::ExprKind::ArrayIndex(expression, val_t, idx) => { mir::ExprKind::Indexed(expression, val_t, idx_expr) => {
let array = expression.codegen(scope)?; let array = expression.codegen(scope)?;
let idx = idx_expr.codegen(scope)?;
let ptr = scope let ptr = scope
.block .block
.build(Instr::GetElemPtr(array, vec![*idx as u32])) .build(Instr::GetElemPtr(array, vec![idx]))
.unwrap(); .unwrap();
Some( Some(
@ -451,17 +452,21 @@ impl mir::Expression {
)) ))
.unwrap(); .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 let ptr = scope
.block .block
.build(Instr::GetElemPtr(array, vec![i as u32])) .build(Instr::GetElemPtr(array, vec![index_expr]))
.unwrap(); .unwrap();
scope.block.build(Instr::Store(ptr, *instr)).unwrap(); scope.block.build(Instr::Store(ptr, *instr)).unwrap();
} }
Some(array) Some(array)
} }
mir::ExprKind::StructIndex(expression, type_kind, field) => { mir::ExprKind::Accessed(expression, type_kind, field) => {
let struct_val = expression.codegen(scope)?; let struct_val = expression.codegen(scope)?;
let struct_ty = expression.return_type().ok()?.1.known().ok()?; let struct_ty = expression.return_type().ok()?.1.known().ok()?;
@ -521,29 +526,30 @@ impl IndexedVariableReference {
mir::IndexedVariableReferenceKind::ArrayIndex(inner, idx) => { mir::IndexedVariableReferenceKind::ArrayIndex(inner, idx) => {
let inner_stack_val = inner.get_stack_value(scope, true)?; let inner_stack_val = inner.get_stack_value(scope, true)?;
let mut gep_instr = scope todo!();
.block // let mut gep_instr = scope
.build(Instr::GetElemPtr( // .block
unsafe { *inner_stack_val.0.get_instr() }, // .build(Instr::GetElemPtr(
vec![*idx as u32], // unsafe { *inner_stack_val.0.get_instr() },
)) // vec![*idx as u32],
.unwrap(); // ))
// .unwrap();
match &inner_stack_val.1 { // match &inner_stack_val.1 {
Type::Ptr(inner_ty) => { // Type::Ptr(inner_ty) => {
if load_after_gep { // if load_after_gep {
gep_instr = scope // gep_instr = scope
.block // .block
.build(Instr::Load(gep_instr, *inner_ty.clone())) // .build(Instr::Load(gep_instr, *inner_ty.clone()))
.unwrap() // .unwrap()
} // }
Some(StackValue( // Some(StackValue(
inner_stack_val.0.with_instr(gep_instr), // inner_stack_val.0.with_instr(gep_instr),
*inner_ty.clone(), // *inner_ty.clone(),
)) // ))
} // }
_ => panic!("Tried to codegen indexing a non-indexable value!"), // _ => panic!("Tried to codegen indexing a non-indexable value!"),
} // }
} }
mir::IndexedVariableReferenceKind::StructIndex(inner, field) => { mir::IndexedVariableReferenceKind::StructIndex(inner, field) => {
let inner_stack_val = inner.get_stack_value(scope, true)?; 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::U128(val) => ConstValue::U128(val),
mir::Literal::Bool(val) => ConstValue::Bool(val), mir::Literal::Bool(val) => ConstValue::Bool(val),
mir::Literal::String(val) => ConstValue::StringPtr(val.clone()), 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),
}) })
} }
} }

View File

@ -164,10 +164,10 @@ impl Display for ExprKind {
ExprKind::FunctionCall(fc) => Display::fmt(fc, f), ExprKind::FunctionCall(fc) => Display::fmt(fc, f),
ExprKind::If(if_exp) => Display::fmt(&if_exp, f), ExprKind::If(if_exp) => Display::fmt(&if_exp, f),
ExprKind::Block(block) => Display::fmt(block, 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)?; Display::fmt(&expression, f)?;
write!(f, "<{}>", elem_ty)?; write!(f, "<{}>", elem_ty)?;
write_index(f, *idx) write_index(f, idx_expr)
} }
ExprKind::Array(expressions) => { ExprKind::Array(expressions) => {
f.write_char('[')?; f.write_char('[')?;
@ -203,7 +203,7 @@ impl Display for ExprKind {
} }
f.write_char('}') f.write_char('}')
} }
ExprKind::StructIndex(expression, type_kind, name) => { ExprKind::Accessed(expression, type_kind, name) => {
Display::fmt(&expression, f)?; Display::fmt(&expression, f)?;
write_access(f, name)?; write_access(f, name)?;
write!(f, "<{}>", type_kind) 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('[')?; f.write_char('[')?;
Display::fmt(&idx, f)?; Display::fmt(&idx, f)?;
f.write_char(']') f.write_char(']')

View File

@ -192,8 +192,8 @@ pub struct Import(pub Vec<String>, pub Metadata);
#[derive(Debug)] #[derive(Debug)]
pub enum ExprKind { pub enum ExprKind {
Variable(NamedVariableRef), Variable(NamedVariableRef),
ArrayIndex(Box<Expression>, TypeKind, u64), Indexed(Box<Expression>, TypeKind, Box<Expression>),
StructIndex(Box<Expression>, TypeKind, String), Accessed(Box<Expression>, TypeKind, String),
Array(Vec<Expression>), Array(Vec<Expression>),
Struct(String, Vec<(String, Expression)>), Struct(String, Vec<(String, Expression)>),
Literal(Literal), Literal(Literal),

View File

@ -504,7 +504,7 @@ impl Expression {
Ok((_, ty)) => Ok(ty), Ok((_, ty)) => Ok(ty),
Err(e) => Err(e), 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 // Try to unwrap hint type from array if possible
let hint_t = hint_t.map(|t| match t { let hint_t = hint_t.map(|t| match t {
TypeKind::Array(type_kind, _) => &type_kind, TypeKind::Array(type_kind, _) => &type_kind,
@ -513,9 +513,6 @@ impl Expression {
let expr_t = expression.typecheck(state, hints, hint_t)?; let expr_t = expression.typecheck(state, hints, hint_t)?;
if let TypeKind::Array(inferred_ty, len) = expr_t { if let TypeKind::Array(inferred_ty, len) = expr_t {
if len <= *idx {
return Err(ErrorKind::IndexOutOfBounds(*idx, len));
}
let ty = state.or_else( let ty = state.or_else(
elem_ty.resolve_ref(hints).collapse_into(&inferred_ty), elem_ty.resolve_ref(hints).collapse_into(&inferred_ty),
TypeKind::Vague(Vague::Unknown), 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 // Resolve expected type
let expected_ty = type_kind.resolve_ref(hints); let expected_ty = type_kind.resolve_ref(hints);

View File

@ -249,7 +249,7 @@ impl Expression {
ReturnKind::Soft => Ok(block_ref.1), 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)?; let expr_ty = expression.infer_types(state, type_refs)?;
// Check that the resolved type is at least an array, no // 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)?; let expr_ty = expression.infer_types(state, type_refs)?;
// Check that the resolved type is at least a struct, no // Check that the resolved type is at least a struct, no

View File

@ -107,7 +107,7 @@ impl ReturnType for Expression {
Block(block) => block.return_type(), Block(block) => block.return_type(),
FunctionCall(fcall) => fcall.return_type(), FunctionCall(fcall) => fcall.return_type(),
If(expr) => expr.return_type(), If(expr) => expr.return_type(),
ArrayIndex(expression, _, _) => { Indexed(expression, _, _) => {
let expr_type = expression.return_type()?; let expr_type = expression.return_type()?;
if let (_, TypeKind::Array(elem_ty, _)) = expr_type { if let (_, TypeKind::Array(elem_ty, _)) = expr_type {
Ok((ReturnKind::Soft, *elem_ty)) Ok((ReturnKind::Soft, *elem_ty))
@ -126,7 +126,7 @@ impl ReturnType for Expression {
TypeKind::Array(Box::new(first.1), expressions.len() as u64), 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()))), Struct(name, _) => Ok((ReturnKind::Soft, TypeKind::CustomType(name.clone()))),
} }
} }

View File

@ -11,7 +11,7 @@ fn main() -> u32 {
second: [6, 3, 17, 8], second: [6, 3, 17, 8],
}]; }];
value[0].second[2] = 99; // value[0].second[2] = 99;
return value[0].second[2]; return value[0].second[2];
} }