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
.iter()
.map(|idx| ConstValue::U32(*idx).as_llvm(module))
.map(|idx_elem| module.values.get(idx_elem).unwrap().value_ref)
.collect();
LLVMBuildGEP2(

View File

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

View File

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

View File

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

View File

@ -136,15 +136,15 @@ impl Parse for PrimaryExpression {
while let Ok(index) = stream.parse::<ValueIndex>() {
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::<ValueIndex>() {
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<Self, Error> {
stream.expect(Token::BracketOpen)?;
if let Some(Token::DecimalValue(idx)) = stream.next() {
let expr = stream.parse()?;
stream.expect(Token::BracketClose)?;
Ok(ArrayValueIndex(idx))
} else {
return Err(stream.expected_err("array index (number)")?);
}
Ok(ArrayValueIndex(expr))
}
}

View File

@ -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(),

View File

@ -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),
})
}
}

View File

@ -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(']')

View File

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

View File

@ -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);

View File

@ -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

View File

@ -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()))),
}
}

View File

@ -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];
}